/// <summary> /// Collects queued impressions. /// </summary> public static void CollectQueuedImpressions() { Presentation p = null; IMessageQueue queue = null; GenericMessageBody body = null; IEnumerable <Message> messages = null; IDictionary <int, int> addedImpressions = null; List <Tuple <GenericMessageBody, Message> > dispatchedMessages = null; if (!_isCollecting) { _isCollecting = true; queue = MessageQueueManager.Current.GetQueue(MessageQueueType.Impressions); messages = queue.GetMessages().ToList(); dispatchedMessages = new List <Tuple <GenericMessageBody, Message> >(); if (messages != null && messages.Any()) { try { using (var repository = new Storage.Repositories.NHibernateRepository <Impression>()) { foreach (var m in messages) { try { body = GenericMessageBody.FromString(m.Body); if (body != null) { repository.Update(new Impression() { PresentationId = body.GetParameter <int>("PresentationId"), PresentationUserId = body.GetParameter <int>("PresentationUserId"), Timestamp = m.Created }); dispatchedMessages.Add(new Tuple <GenericMessageBody, Message>(body, m)); } } catch (Exception ex) { _log.Error(string.Format("Failed to collect message with Id '{0}'", m.Id), ex); } } } queue.RemoveMessages(dispatchedMessages.Select(m => m.Item2)); addedImpressions = dispatchedMessages.GroupBy(t => t.Item1.GetParameter <int>("PresentationId")).ToDictionary(g => g.Key, g => g.Count()); using (var repository = new Storage.Repositories.RavenRepository <Presentation>()) { foreach (var imp in addedImpressions) { try { p = repository.Select(imp.Key); if (p != null && p.TotalImpressions < 10000) { p.TotalImpressions += imp.Value; repository.Update(p); } } catch (Exception ex) { _log.Error(string.Format("Failed to update total impressions for infographic with Id '{0}'", imp.Key), ex); } } } if (addedImpressions != null && addedImpressions.Any()) { CollectSocialImpacts(addedImpressions.Keys); } } catch (Exception ex) { _log.Error(string.Format("Failed to collect {0} impression(s).", messages.Count()), ex); } } _isCollecting = false; } }
/// <summary> /// Dispatches queued messages. /// </summary> public static void DispatchQueuedMessages() { MailMessage mail = null; bool canDispatch = false; IMessageQueue queue = null; int connectionPortIndex = 0; GenericMessageBody body = null; string recipient = string.Empty; MailAddress replyToOverride = null; IEnumerable <Message> messages = null; string feedbackSender = string.Empty; List <Message> dispatchedMessages = null; int[] connectionPorts = new int[] { 587, 465 }; int feedbackSenderStart = -1, feedbackSenderEnd = -1; HashSet <string> dispatchedMessageMap = new HashSet <string>(); WebExceptionStatus errorStatus = WebExceptionStatus.UnknownError; Func <string, string> sanitizeEmailAddress = email => { var result = Regex.Replace(email, "@{1,}", "@").Trim(); result = result.Replace(",", "."); if (result.EndsWith("@")) { result += "trashbinemailaddress.com"; } if (result.StartsWith("@")) { result = "noreply" + result; } result = result.Trim(); result = Regex.Replace(result, @"\s|;", "_"); return(result); }; if (!_isDispatching) { _isDispatching = true; queue = MessageQueueManager.Current.GetQueue(MessageQueueType.Email); messages = queue.GetMessages().ToList(); dispatchedMessages = new List <Message>(); dispatchedMessageMap = new HashSet <string>(); if (messages != null && messages.Any()) { _log.Info(string.Format("Dispatching {0} message(s)...", messages.Count())); try { using (var client = new SmtpClient()) { foreach (var m in messages) { canDispatch = true; mail = new MailMessage(); mail.IsBodyHtml = false; mail.From = new MailAddress("*****@*****.**", "Pavel Volgarev"); mail.To.Add("*****@*****.**"); mail.Subject = m.Subject; body = GenericMessageBody.FromString(m.Body); if (body != null) { mail.To.Clear(); mail.IsBodyHtml = true; recipient = body.GetParameter <string>("Recipient"); if (!string.IsNullOrEmpty(recipient) && recipient.IndexOf("@") > 0) { mail.To.Add(sanitizeEmailAddress(recipient)); mail.Body = body.GetParameter <string>("Body"); mail.ReplyToList.Add("*****@*****.**"); } else { canDispatch = false; if (!dispatchedMessageMap.Contains(m.Id)) { dispatchedMessageMap.Add(m.Id); dispatchedMessages.Add(m); } } } else { mail.Body = m.Body; if (mail.Subject.IndexOf("howdy", StringComparison.InvariantCultureIgnoreCase) >= 0) { feedbackSenderStart = mail.Body.IndexOf("--"); if (feedbackSenderStart >= 0) { feedbackSenderEnd = mail.Body.IndexOf("#", feedbackSenderStart + 2); if (feedbackSenderEnd >= 0) { feedbackSender = mail.Body.Substring(feedbackSenderStart + 2, feedbackSenderEnd - (feedbackSenderStart + 2)).Trim().Replace("<", "<").Replace(">", ">"); if (feedbackSender.IndexOf('@') > 0) { try { replyToOverride = new MailAddress(feedbackSender); } catch (FormatException) { } catch (ArgumentException) { } if (replyToOverride != null) { mail.ReplyToList.Add(replyToOverride); } } } } } } if (canDispatch) { connectionPortIndex = -1; do { try { if (connectionPortIndex >= 0 && connectionPortIndex < connectionPorts.Length) { client.Port = connectionPorts[connectionPortIndex]; } if (!dispatchedMessageMap.Contains(m.Id)) { dispatchedMessageMap.Add(m.Id); dispatchedMessages.Add(m); } client.Send(mail); break; } catch (Exception ex) { _log.Error(string.Format("Failed to dispatch message with Id '{0}'", m.Id), ex); if (ex.InnerException is WebException) { errorStatus = (ex.InnerException as WebException).Status; // When connection can't be made, we're going to try different ports (explicit/implicit SSL). if (errorStatus == WebExceptionStatus.ConnectFailure) { connectionPortIndex++; } } else if ((ex.Message ?? string.Empty).IndexOf("timeout", System.StringComparison.OrdinalIgnoreCase) >= 0) { connectionPortIndex++; } } }while (connectionPortIndex < connectionPorts.Length); } } } queue.RemoveMessages(dispatchedMessages); dispatchedMessageMap.Clear(); } catch (Exception ex) { _log.Error(string.Format("Failed to dispatch {0} message(s).", messages.Count()), ex); } } _isDispatching = false; } }