Пример #1
0
        public MailingScheduledViewModel(Translator translator, IDatabase db, Session session, Mailing mailing)
            : this(translator, session)
        {
            Id         = mailing.Id.Value.ToString();
            Title      = mailing.Title.Value.EscapeHtml();
            Recipients = mailing.RecipientFeed.Value.Name.Value[translator.Language];

            if (mailing.RecipientTag.Value != null)
            {
                Recipients = " / " + mailing.RecipientTag.Value.Name.Value[translator.Language];
            }

            if (mailing.RecipientLanguage.Value.HasValue)
            {
                Recipients = " / " + mailing.RecipientLanguage.Value.Value.Translate(translator);
            }

            var number = db
                         .Query <Contact>()
                         .Count(p => p.ActiveSubscriptions.Any(m => m.Feed == mailing.RecipientFeed.Value) &&
                                (mailing.RecipientTag.Value == null || p.TagAssignments.Any(t => t.Tag == mailing.RecipientTag.Value)));

            Recipients += " / " + translator.Get("Mailing.Scheduled.Fields.Recipients.Contacts", "Contacts in the recipients field on the scheduled mailing page", "circa {0} contacts", number);

            Subject = mailing.Subject.Value.EscapeHtml();

            var sendingDate =
                mailing.SendingDate.Value.HasValue ?
                mailing.SendingDate.Value.Value.ToLocalTime().ToString("dd.MM.yyyy HH:mm") :
                string.Empty;
            var sentDate =
                mailing.SentDate.Value.HasValue ?
                mailing.SentDate.Value.Value.ToLocalTime().ToString("dd.MM.yyyy HH:mm") :
                string.Empty;

            switch (mailing.Status.Value)
            {
            case MailingStatus.Scheduled:
                Status = translator.Get("Mailing.Scheduled.Field.Status.Scheduled", "Scheduled status in the status field the scheduled mailing page", "Scheduled for {0}", sendingDate).EscapeHtml();
                break;

            case MailingStatus.Sending:
                Status = translator.Get("Mailing.Scheduled.Field.Status.Sending", "Sending status in the status field the scheduled mailing page", "Sending since {0}", sendingDate).EscapeHtml();
                break;

            case MailingStatus.Sent:
                Status = translator.Get("Mailing.Scheduled.Field.Status.Sent", "Sent status in the status field the scheduled mailing page", "Sent at {0}", sentDate).EscapeHtml();
                break;

            case MailingStatus.Canceled:
                Status = translator.Get("Mailing.Scheduled.Field.Status.Canceled", "Canceled status in the status field the scheduled mailing page", "Canceled").EscapeHtml();
                break;

            default:
                throw new NotSupportedException();
            }

            Sendings = new List <MailingSendingViewModel>(db
                                                          .Query <Sending>(DC.Equal("mailingid", mailing.Id.Value))
                                                          .Select(s => new MailingSendingViewModel(translator, s)));

            Cancelable = mailing.Status.Value == MailingStatus.Scheduled ||
                         mailing.Status.Value == MailingStatus.Sending;
        }
Пример #2
0
        public MailingModule()
        {
            this.RequiresAuthentication();

            Get["/mailing"] = parameters =>
            {
                return(View["View/mailing.sshtml",
                            new MailingViewModel(Translator, CurrentSession)]);
            };
            Get["/mailing/list"] = parameters =>
            {
                return(View["View/mailinglist.sshtml",
                            new MailingListViewModel(Translator, Database, CurrentSession)]);
            };
            Get["/mailing/add"] = parameters =>
            {
                return(View["View/mailingedit.sshtml",
                            new MailingEditViewModel(Translator, Database, CurrentSession)]);
            };
            Post["/mailing/add/{id}"] = parameters =>
            {
                string idString = parameters.id;
                var    model    = JsonConvert.DeserializeObject <MailingEditViewModel>(ReadBody());
                var    status   = CreateStatus();

                if (Guid.TryParse(idString, out Guid id))
                {
                    var mailing = new Mailing(id);
                    status.AssignStringRequired("Title", mailing.Title, model.Title);
                    status.AssignObjectIdString("RecipientFeed", mailing.RecipientFeed, model.RecipientFeed);
                    status.AssignObjectIdString("RecipientTag", mailing.RecipientTag, model.RecipientTag);
                    status.AssignEnumIntString("RecipientLanguage", mailing.RecipientLanguage, model.RecipientLanguage);
                    status.AssignObjectIdString("SenderGroup", mailing.Sender, model.SenderGroup);
                    status.AssignObjectIdString("Header", mailing.Header, model.Header);
                    status.AssignObjectIdString("Footer", mailing.Footer, model.Footer);
                    status.AssignStringRequired("Subject", mailing.Subject, model.Subject);
                    var worker = new HtmlWorker(model.HtmlText);
                    mailing.HtmlText.Value  = worker.CleanHtml;
                    mailing.PlainText.Value = worker.PlainText;
                    mailing.Creator.Value   = CurrentSession.User;

                    if (status.IsSuccess)
                    {
                        if (status.HasAccess(mailing.RecipientFeed.Value, PartAccess.Mailings, AccessRight.Write) &&
                            (mailing.Sender.Value == null || status.HasAccess(mailing.Sender.Value, PartAccess.Mailings, AccessRight.Write)))
                        {
                            Database.Save(mailing);
                            Notice("{0} added mailing {1}", CurrentSession.User.UserName.Value, mailing);
                        }
                    }
                }
                else
                {
                    status.SetErrorNotFound();
                }

                return(status.CreateJsonData());
            };
            Get["/mailing/edit/{id}"] = parameters =>
            {
                string idString = parameters.id;
                var    mailing  = Database.Query <Mailing>(idString);

                if (mailing != null)
                {
                    if (mailing.Status.Value == MailingStatus.New)
                    {
                        return(View["View/mailingedit.sshtml",
                                    new MailingEditViewModel(Translator, Database, CurrentSession, mailing)]);
                    }
                    else
                    {
                        return(View["View/mailingscheduled.sshtml",
                                    new MailingScheduledViewModel(Translator, Database, CurrentSession, mailing)]);
                    }
                }

                return(Response.AsRedirect("/mailing"));
            };
            Post["/mailing/edit/{id}"] = parameters =>
            {
                string idString = parameters.id;
                var    model    = JsonConvert.DeserializeObject <MailingEditViewModel>(ReadBody());
                var    mailing  = Database.Query <Mailing>(idString);
                var    status   = CreateStatus();

                if (status.ObjectNotNull(mailing))
                {
                    if (mailing.Status.Value == MailingStatus.New)
                    {
                        status.AssignStringRequired("Title", mailing.Title, model.Title);
                        status.AssignObjectIdString("RecipientFeed", mailing.RecipientFeed, model.RecipientFeed);
                        status.AssignObjectIdString("RecipientTag", mailing.RecipientTag, model.RecipientTag);
                        status.AssignEnumIntString("RecipientLanguage", mailing.RecipientLanguage, model.RecipientLanguage);
                        status.AssignObjectIdString("SenderGroup", mailing.Sender, model.SenderGroup);
                        status.AssignObjectIdString("Header", mailing.Header, model.Header);
                        status.AssignObjectIdString("Footer", mailing.Footer, model.Footer);
                        status.AssignStringRequired("Subject", mailing.Subject, model.Subject);
                        var worker = new HtmlWorker(model.HtmlText);
                        mailing.HtmlText.Value  = worker.CleanHtml;
                        mailing.PlainText.Value = worker.PlainText;
                        mailing.Creator.Value   = CurrentSession.User;

                        if (status.IsSuccess)
                        {
                            if (status.HasAccess(mailing.RecipientFeed.Value, PartAccess.Mailings, AccessRight.Write) &&
                                (mailing.Sender.Value == null || status.HasAccess(mailing.Sender.Value, PartAccess.Mailings, AccessRight.Write)))
                            {
                                Database.Save(mailing);
                                Notice("{0} changed mailing {1}", CurrentSession.User.UserName.Value, mailing);
                            }
                        }
                    }
                    else
                    {
                        status.SetErrorAccessDenied();
                    }
                }

                return(status.CreateJsonData());
            };
            Post["/mailing/test"] = parameters =>
            {
                var model  = JsonConvert.DeserializeObject <MailingEditViewModel>(ReadBody());
                var worker = new HtmlWorker(model.HtmlText);
                var header = Database.Query <MailingElement>(model.Header);
                var footer = Database.Query <MailingElement>(model.Footer);
                var sender = Database.Query <Group>(model.SenderGroup);

                var htmlText  = worker.CleanHtml;
                var plainText = worker.PlainText;

                if (header != null)
                {
                    htmlText  = HtmlWorker.ConcatHtml(header.HtmlText.Value, htmlText);
                    plainText = header.PlainText.Value + plainText;
                }

                if (footer != null)
                {
                    htmlText  = HtmlWorker.ConcatHtml(htmlText, footer.HtmlText.Value);
                    plainText = plainText + footer.PlainText.Value;
                }

                var contact = Database
                              .Query <Contact>()
                              .Where(p => HasAccess(p, PartAccess.Contact, AccessRight.Read))
                              .FirstOrDefault();

                if (contact == null)
                {
                    return(PostResult.Failed(
                               Translate("Mailing.Edit.Test.Failed", "Failed message on sending test mail in mailing edit page", "E-Mail could not be sent.")));
                }

                var templator = new Templator(new ContactContentProvider(Translator, contact));
                htmlText  = templator.Apply(htmlText);
                plainText = templator.Apply(plainText);

                try
                {
                    var language = CurrentSession.User.Language.Value;
                    var from     = new MailboxAddress(
                        sender.MailName.Value[language],
                        sender.MailAddress.Value[language]);
                    var to        = new MailboxAddress(model.TestAddress);
                    var senderKey = sender.GpgKeyId.Value == null ? null :
                                    new GpgPrivateKeyInfo(
                        sender.GpgKeyId.Value,
                        sender.GpgKeyPassphrase.Value);
                    var content  = new Multipart("alternative");
                    var textPart = new TextPart("plain")
                    {
                        Text = plainText
                    };
                    textPart.ContentTransferEncoding = ContentEncoding.QuotedPrintable;
                    content.Add(textPart);
                    var htmlPart = new TextPart("html")
                    {
                        Text = htmlText
                    };
                    htmlPart.ContentTransferEncoding = ContentEncoding.QuotedPrintable;
                    content.Add(htmlPart);

                    Global.Mail.Send(from, to, senderKey, null, model.Subject, content);
                    Notice("{0} tests mailing with subject {1}", CurrentSession.User.UserName.Value, model.Subject);

                    return(PostResult.Success(
                               Translate("Mailing.Edit.Test.Success", "Success message on sending test mail in mailing edit page", "Test E-Mail sent.")));
                }
                catch
                {
                    return(PostResult.Failed(
                               Translate("Mailing.Edit.Test.Failed", "Failed message on sending test mail in mailing edit page", "E-Mail could not be sent.")));
                }
            };
            Get["/mailing/send/{id}"] = parameters =>
            {
                string idString = parameters.id;
                var    mailing  = Database.Query <Mailing>(idString);

                if (mailing != null)
                {
                    if (HasAccess(mailing.RecipientFeed.Value, PartAccess.Mailings, AccessRight.Write) &&
                        (mailing.Sender.Value == null || HasAccess(mailing.Sender.Value, PartAccess.Mailings, AccessRight.Write)))
                    {
                        return(View["View/mailingsend.sshtml",
                                    new MailingSendViewModel(Translator, Database, CurrentSession, mailing)]);
                    }
                }

                return(AccessDenied());
            };
            Post["/mailing/send/{id}"] = parameters =>
            {
                string idString = parameters.id;
                var    model    = JsonConvert.DeserializeObject <MailingSendViewModel>(ReadBody());
                var    mailing  = Database.Query <Mailing>(idString);
                var    status   = CreateStatus();

                if (status.ObjectNotNull(mailing))
                {
                    status.AssignDateString("Date", mailing.SendingDate, model.Date, true);
                    status.AddAssignTimeString("Time", mailing.SendingDate, model.Time);

                    if (status.IsSuccess)
                    {
                        if (status.HasAccess(mailing.RecipientFeed.Value, PartAccess.Mailings, AccessRight.Write) &&
                            (mailing.Sender.Value == null || status.HasAccess(mailing.Sender.Value, PartAccess.Mailings, AccessRight.Write)))
                        {
                            mailing.SendingDate.Value = mailing.SendingDate.Value.Value.ToUniversalTime();
                            mailing.Status.Value      = MailingStatus.Scheduled;
                            Database.Save(mailing);
                            Notice("{0} sent mailing {1}", CurrentSession.User.UserName.Value, mailing);
                        }
                    }
                }

                return(status.CreateJsonData());
            };
            Get["/mailing/delete/{id}"] = parameters =>
            {
                string idString = parameters.id;
                var    mailing  = Database.Query <Mailing>(idString);
                var    status   = CreateStatus();

                if (status.ObjectNotNull(mailing))
                {
                    if (status.HasAccess(mailing.RecipientFeed.Value, PartAccess.Mailings, AccessRight.Write) &&
                        (mailing.Sender.Value == null || status.HasAccess(mailing.Sender.Value, PartAccess.Mailings, AccessRight.Write)))
                    {
                        using (var transaction = Database.BeginTransaction())
                        {
                            mailing.Delete(Database);
                            transaction.Commit();
                            Notice("{0} deleted mailing {1}", CurrentSession.User.UserName.Value, mailing);
                        }
                    }
                }

                return(status.CreateJsonData());
            };
            Get["/mailing/cancel/{id}"] = parameters =>
            {
                string idString = parameters.id;
                var    mailing  = Database.Query <Mailing>(idString);
                var    status   = CreateStatus();

                if (status.ObjectNotNull(mailing))
                {
                    if (status.HasAccess(mailing.RecipientFeed.Value, PartAccess.Mailings, AccessRight.Write) &&
                        (mailing.Sender.Value == null || status.HasAccess(mailing.Sender.Value, PartAccess.Mailings, AccessRight.Write)))
                    {
                        if (mailing.Status.Value == MailingStatus.Scheduled ||
                            mailing.Status.Value == MailingStatus.Sending)
                        {
                            using (var transaction = Database.BeginTransaction())
                            {
                                mailing.Status.Value = MailingStatus.Canceled;
                                Database.Save(mailing);
                                transaction.Commit();
                                Notice("{0} canceled mailing {1}", CurrentSession.User.UserName.Value, mailing);
                            }
                        }
                        else
                        {
                            status.SetErrorAccessDenied();
                        }
                    }
                }

                return(status.CreateJsonData());
            };
            Get["/mailing/copy/{id}"] = parameters =>
            {
                string idString = parameters.id;
                var    mailing  = Database.Query <Mailing>(idString);
                var    status   = CreateStatus();

                if (status.ObjectNotNull(mailing))
                {
                    if (status.HasAccess(mailing.RecipientFeed.Value, PartAccess.Mailings, AccessRight.Write) &&
                        (mailing.Sender.Value == null || status.HasAccess(mailing.Sender.Value, PartAccess.Mailings, AccessRight.Write)))
                    {
                        var newMailing = new Mailing(Guid.NewGuid());
                        newMailing.Title.Value = mailing.Title.Value +
                                                 Translate("Mailing.Copy.Postfix", "Postfix of copied mailings", " (Copy)");
                        newMailing.RecipientFeed.Value     = mailing.RecipientFeed.Value;
                        newMailing.RecipientTag.Value      = mailing.RecipientTag.Value;
                        newMailing.RecipientLanguage.Value = mailing.RecipientLanguage.Value;
                        newMailing.Sender.Value            = mailing.Sender.Value;
                        newMailing.Header.Value            = mailing.Header.Value;
                        newMailing.Footer.Value            = mailing.Footer.Value;
                        newMailing.Subject.Value           = mailing.Subject.Value;
                        newMailing.HtmlText.Value          = mailing.HtmlText.Value;
                        newMailing.PlainText.Value         = mailing.PlainText.Value;
                        newMailing.Creator.Value           = CurrentSession.User;
                        newMailing.CreatedDate.Value       = DateTime.UtcNow;
                        newMailing.Status.Value            = MailingStatus.New;
                        Database.Save(newMailing);
                        Notice("{0} copied mailing {1}", CurrentSession.User.UserName.Value, mailing);
                    }
                }

                return(status.CreateJsonData());
            };
        }
Пример #3
0
        public MailingSendViewModel(Translator translator, IDatabase db, Session session, Mailing mailing)
            : this(translator, session)
        {
            Id            = mailing.Id.Value.ToString();
            Title         = mailing.Title.Value.EscapeHtml();
            RecipientFeed = mailing.RecipientFeed.Value.Name.Value[translator.Language];

            if (mailing.RecipientTag.Value != null)
            {
                RecipientTag = mailing.RecipientTag.Value.Name.Value[translator.Language];
            }
            else
            {
                RecipientTag = translator.Get("Mailing.Edit.Field.RecipientTags.None", "No selection in the recipient tag field of the edit mailing page", "None");
            }

            RecipientNumber = "~" + db
                              .Query <Contact>()
                              .Where(p => p.ActiveSubscriptions.Any(m => m.Feed == mailing.RecipientFeed.Value) &&
                                     (mailing.RecipientTag.Value == null || p.TagAssignments.Any(t => t.Tag == mailing.RecipientTag.Value)))
                              .Count().ToString();

            Subject = mailing.Subject.Value.EscapeHtml();
        }
Пример #4
0
 public MailingEditViewModel(Translator translator, IDatabase db, Session session, Mailing mailing)
     : this(translator, session)
 {
     Method         = "edit";
     Id             = mailing.Id.Value.ToString();
     Title          = mailing.Title.Value.EscapeHtml();
     Subject        = mailing.Subject.Value.EscapeHtml();
     HtmlText       = mailing.HtmlText.Value;
     RecipientFeeds = new List <NamedIdViewModel>(db
                                                  .Query <Feed>()
                                                  .Where(o => session.HasAccess(o, PartAccess.Mailings, AccessRight.Write))
                                                  .Select(o => new NamedIdViewModel(translator, o, mailing.RecipientFeed.Value == o))
                                                  .OrderBy(o => o.Name));
     RecipientTags = new List <NamedIdViewModel>(db
                                                 .Query <Tag>()
                                                 .Where(t => t.Usage.Value.HasFlag(TagUsage.Mailing))
                                                 .Select(t => new NamedIdViewModel(translator, t, mailing.RecipientTag.Value == t))
                                                 .OrderBy(t => t.Name));
     RecipientTags.Add(new NamedIdViewModel(translator.Get("Mailing.Edit.Field.RecipientTags.None", "No selection in the recipient tag field of the edit mailing page", "None"), false, mailing.RecipientTag.Value == null));
     RecipientLanguages = new List <NamedIntViewModel>();
     RecipientLanguages.Add(new NamedIntViewModel(translator, Language.English, mailing.RecipientLanguage.Value == Language.English));
     RecipientLanguages.Add(new NamedIntViewModel(translator, Language.German, mailing.RecipientLanguage.Value == Language.German));
     RecipientLanguages.Add(new NamedIntViewModel(translator, Language.French, mailing.RecipientLanguage.Value == Language.French));
     RecipientLanguages.Add(new NamedIntViewModel(translator, Language.Italian, mailing.RecipientLanguage.Value == Language.Italian));
     RecipientLanguages.Add(new NamedIntViewModel(translator.Get("Mailing.Edit.Field.RecipientLanguage.None", "No selection in the recipient language field of the edit mailing page", "None"), false, mailing.RecipientLanguage.Value == null));
     SenderGroups = new List <NamedIdViewModel>(db
                                                .Query <Group>()
                                                .Where(g => session.HasAccess(g, PartAccess.Mailings, AccessRight.Write))
                                                .Select(g => new NamedIdViewModel(translator, g, mailing.Sender.Value == g))
                                                .OrderBy(g => g.Name));
     Headers = new List <NamedIdViewModel>(db
                                           .Query <MailingElement>()
                                           .Where(e => e.Type.Value == MailingElementType.Header)
                                           .Select(e => new NamedIdViewModel(e, mailing.Header.Value == e))
                                           .OrderBy(e => e.Name));
     Headers.Add(new NamedIdViewModel(translator.Get("Mailing.Edit.Field.Headers.None", "No selection in the header field of the edit mailing page", "None"), false, mailing.Header.Value == null));
     Footers = new List <NamedIdViewModel>(db
                                           .Query <MailingElement>()
                                           .Where(e => e.Type.Value == MailingElementType.Footer)
                                           .Select(e => new NamedIdViewModel(e, mailing.Footer.Value == e))
                                           .OrderBy(e => e.Name));
     Footers.Add(new NamedIdViewModel(translator.Get("Mailing.Edit.Field.Footers.None", "No selection in the footer field of the edit mailing page", "None"), false, mailing.Footer.Value == null));
 }
Пример #5
0
        private void RunSending(IDatabase database, Mailing mailing)
        {
            int remainingCount = 0;

            foreach (var sending in database.Query <Sending>(DC.Equal("mailingid", mailing.Id.Value)))
            {
                if (sending.Status.Value == SendingStatus.Created)
                {
                    if (_maxMailsCount > 0)
                    {
                        _maxMailsCount--;
                        var header    = mailing.Header.Value;
                        var footer    = mailing.Footer.Value;
                        var htmlText  = mailing.HtmlText.Value;
                        var plainText = mailing.PlainText.Value;

                        if (header != null)
                        {
                            htmlText  = HtmlWorker.ConcatHtml(header.HtmlText.Value, htmlText);
                            plainText = header.PlainText.Value + plainText;
                        }

                        if (footer != null)
                        {
                            htmlText  = HtmlWorker.ConcatHtml(htmlText, footer.HtmlText.Value);
                            plainText = plainText + footer.PlainText.Value;
                        }

                        var translation = new Translation(database);
                        var translator  = new Translator(translation, sending.Address.Value.Contact.Value.Language.Value);
                        var templator   = new Templator(new ContactContentProvider(translator, sending.Address.Value.Contact.Value));
                        htmlText  = templator.Apply(htmlText);
                        plainText = templator.Apply(plainText);

                        try
                        {
                            var language = sending.Address.Value.Contact.Value.Language.Value;
                            var from     = new MimeKit.MailboxAddress(
                                mailing.Sender.Value.MailName.Value[language],
                                mailing.Sender.Value.MailAddress.Value[language]);
                            var to = new MimeKit.MailboxAddress(
                                sending.Address.Value.Contact.Value.ShortHand,
                                sending.Address.Value.Address.Value);
                            var senderKey = mailing.Sender.Value.GpgKeyId.Value == null ? null :
                                            new GpgPrivateKeyInfo(
                                mailing.Sender.Value.GpgKeyId.Value,
                                mailing.Sender.Value.GpgKeyPassphrase.Value);
                            var content  = new Multipart("alternative");
                            var textPart = new TextPart("plain")
                            {
                                Text = plainText
                            };
                            textPart.ContentTransferEncoding = ContentEncoding.QuotedPrintable;
                            content.Add(textPart);
                            var htmlPart = new TextPart("html")
                            {
                                Text = htmlText
                            };
                            htmlPart.ContentTransferEncoding = ContentEncoding.QuotedPrintable;
                            content.Add(htmlPart);

                            Global.Mail.Send(from, to, senderKey, null, mailing.Subject.Value, content);
                            sending.Status.Value   = SendingStatus.Sent;
                            sending.SentDate.Value = DateTime.UtcNow;
                            database.Save(sending);
                            Journal(database, mailing, sending.Address.Value.Contact.Value,
                                    "MailTask.Journal.Sent",
                                    "Journal entry sent mail",
                                    "Task sent mail {0}",
                                    t => mailing.Title.Value);
                        }
                        catch (Exception exception)
                        {
                            sending.Status.Value         = SendingStatus.Failed;
                            sending.FailureMessage.Value = exception.Message;
                            sending.SentDate.Value       = DateTime.UtcNow;
                            database.Save(sending);
                            Journal(database, mailing, sending.Address.Value.Contact.Value,
                                    "MailTask.Journal.Failed",
                                    "Journal entry sending mail failed",
                                    "Task failed sending mail {0}",
                                    t => mailing.Title.Value);
                        }
                    }
                    else
                    {
                        remainingCount++;
                    }
                }
            }

            if (remainingCount < 1)
            {
                mailing.Status.Value   = MailingStatus.Sent;
                mailing.SentDate.Value = DateTime.UtcNow;
                database.Save(mailing);
                Global.Log.Notice("Mailing {0} has finished sending", mailing.Title);
            }
            else
            {
                Global.Log.Notice("Mailing {0} needs to send {1} more mails", mailing.Title, remainingCount);
            }
        }