def test_before_personalization_filter(self):
        def personalize(event):
            edc = event.data["context"]
            event.data["html"] = event.data["html"].replace("PHP", "Python")
            edc["SUBSCRIBER_SALUTATION"] = "Dear Ms. Jane Doe"

        provideHandler(personalize, [IBeforePersonalizationEvent])

        try:
            receiver = {
                "email": "*****@*****.**",
                "fullname": "John Doe",
                "firstname": "John",
                "lastname": "Doe",
                "salutation": "Dear Mr.",
                # "nl_language": "de",
            }
            html = """
            <h1>PHP ist toll!</h1>
            {{SUBSCRIBER_SALUTATION}}
            """
            issue_data_fetcher = IIssueDataFetcher(self.newsletter.issue)
            issue_data = issue_data_fetcher.personalize(receiver, html)
            self.assertIn("Dear Ms. Jane Doe", issue_data)
        finally:
            getGlobalSiteManager().unregisterHandler(
                personalize, [IBeforePersonalizationEvent])
예제 #2
0
 def test_placeholder_month_year(self):
     receiver = {
         "email": "*****@*****.**",
         "fullname": "John Doe",
         "firstname": "John",
         "lastname": "Doe",
         "salutation": "Dear Mr.",
     }
     html = """
     <h1>Plone ist toll!</h1>
     {{ SUBSCRIBER_SALUTATION }}
     {{ month }}/{{ year }}
     """
     now = datetime.now()
     effective_date = datetime(year=now.year, month=now.month, day=now.day + 2)
     self.newsletter.issue.effective_date = effective_date
     self.assertNotEqual(
         self.newsletter.issue.modified(), self.newsletter.issue.effective()
     )
     issue_data_fetcher = IIssueDataFetcher(self.newsletter.issue)
     issue_data = issue_data_fetcher.personalize(receiver, html)
     self.assertIn(
         "{0}/{1}".format(
             self.newsletter.issue.effective().month(),
             self.newsletter.issue.effective().year(),
         ),
         issue_data,
     )
    def test_before_personalization_filter(self):
        def _personalize(event):
            edc = event.data['context']
            event.data['html'] = event.data['html'].replace('PHP', 'Python')
            edc['SUBSCRIBER_SALUTATION'] = 'Dear Ms. Jane Doe'

        provideHandler(_personalize, [IBeforePersonalizationEvent])
        try:
            receiver = {
                'email': '*****@*****.**',
                'fullname': 'John Doe',
                'firstname': 'John',
                'lastname': 'Doe',
                'salutation': 'Dear Mr.',
                'nl_language': 'de'
            }
            html = '''
            <h1>PHP ist toll!</h1>
            {{SUBSCRIBER_SALUTATION}}
            '''
            issue_data_fetcher = IIssueDataFetcher(self.newsletter.issue)
            issue_data = issue_data_fetcher._personalize(receiver, html)
            self.assertIn('Dear Ms. Jane Doe', issue_data)
        finally:
            getGlobalSiteManager().unregisterHandler(
                _personalize, [IBeforePersonalizationEvent])
    def test_fetching_issue_data(self):

        receiver = {
            "email": "*****@*****.**",
            "fullname": "John Doe",
            "firstname": "John",
            "lastname": "Doe",
            "salutation": "Dear Mr.",
        }
        html = """
        <h1></h1>
        {{SUBSCRIBER_SALUTATION}}
        """
        issue_data_fetcher = IIssueDataFetcher(self.newsletter.issue)
        issue_data = issue_data_fetcher.personalize(receiver, html)
        self.assertIn("Dear Mr. John Doe", issue_data)
예제 #5
0
 def get_preview(self):
     """ Return the rendered HTML version with all placeholder,
         for admin preview.
     """
     test_receiver = {
         'email': '*****@*****.**',
         'fullname': 'John Doe',
         'firstname': 'John',
         'lastname': 'Doe',
         'salutation': 'Dear Mr.',
         'nl_language': 'de',
         'uid': 'xyz',
     }
     issuedatafetcher = IIssueDataFetcher(self.context)
     preview_html = issuedatafetcher.preview_html(disable_filter=True,
                                                  receiver=test_receiver)
     return preview_html
예제 #6
0
 def get_preview(self):
     """Return the rendered HTML version with all placeholder,
     for admin preview.
     """
     test_receiver = {
         "email": "*****@*****.**",
         "fullname": "John Doe",
         "firstname": "John",
         "lastname": "Doe",
         "salutation": "Dear Mr.",
         "nl_language": "de",
         "uid": "xyz",
     }
     issuedatafetcher = IIssueDataFetcher(self.context)
     preview_html = issuedatafetcher.preview_html(
         disable_filter=True, receiver=test_receiver
     )
     return preview_html
예제 #7
0
    def get_preview(self):
        """ Return the rendered HTML version with all placeholder,
            for admin preview.
        """
        test_receiver = {
            'email': '*****@*****.**',
            'fullname': 'John Doe',
            'firstname': 'John',
            'lastname': 'Doe',
            'salutation': 'Dear Mr.',
            'nl_language': 'de',
            'uid': 'xyz',

        }
        issuedatafetcher = IIssueDataFetcher(self.context)
        preview_html = issuedatafetcher.preview_html(
            disable_filter=True, receiver=test_receiver)
        return preview_html
예제 #8
0
 def test_placeholder_calendar_week(self):
     receiver = {
         "email": "*****@*****.**",
         "fullname": "John Doe",
         "firstname": "John",
         "lastname": "Doe",
         "salutation": "Dear Mr.",
     }
     html = """
     <h1>Plone ist toll!</h1>
     {{ SUBSCRIBER_SALUTATION }}
     {{ calendar_week }}
     """
     now = datetime.now()
     effective_date = now + timedelta(2)
     self.newsletter.issue.effective_date = effective_date
     self.assertNotEqual(self.newsletter.issue.modified(),
                         self.newsletter.issue.effective())
     issue_data_fetcher = IIssueDataFetcher(self.newsletter.issue)
     issue_data = issue_data_fetcher.personalize(receiver, html)
     self.assertIn(self.newsletter.issue.effective().strftime("%V"),
                   issue_data)
예제 #9
0
    def send(self):
        """Sends the newsletter, sending might be queued for async send out."""

        # check for workflow
        current_state = api.content.get_state(obj=self.context)
        if not self.is_test and current_state != "sending":
            raise ValueError("Executed send in wrong review state!")

        # get hold of the parent Newsletter object#
        enl = self.context.get_newsletter()
        sender_name = self.request.get("sender_name") or enl.sender_name
        sender_email = self.request.get("sender_email") or enl.sender_email
        # get Plone email_charset
        # charset = get_email_charset()
        receivers = self._get_recipients()

        # determine MailHost first (build-in vs. external)
        delivery_service_name = "mailhost"  # XXX enl.delivery_dervice
        if delivery_service_name == "mailhost":
            self.mail_host = api.portal.get_tool("MailHost")
        else:
            self.mail_host = getUtility(IMailHost, name=delivery_service_name)
        log.info('Using mail delivery service "%r"' % self.mail_host)

        send_counter = 0
        send_error_counter = 0

        issue_data_fetcher = IIssueDataFetcher(self.context)
        # get issue subject an rendered output data
        issue_data = issue_data_fetcher()
        # import pdb; pdb.set_trace()  # NOQA: E702
        for receiver in receivers:
            personalized_html = issue_data_fetcher.personalize(
                receiver, issue_data["body_html"])
            # get plain text version
            personalized_plaintext = issue_data_fetcher.create_plaintext_message(
                personalized_html)

            m = Message(
                html=personalized_html,
                text=personalized_plaintext,
                subject=issue_data["subject"],
                mail_from=(sender_name, sender_email),
                mail_to=(receiver["fullname"], receiver["email"]),
            )
            m.transformer.local_loader = LocalLoader()
            m.transform(
                images_inline=True,
                load_images=True,
                base_url=self.context.absolute_url(),
                cssutils_logging_level=logging.ERROR,
            )

            send_status = {
                "successful": None,
                "error": None,
                "datetime": datetime.now(),
            }

            msg_string = ""
            try:
                msg_string = m.as_string()
            except Exception as e:  # noqa
                send_status["successful"] = False
                send_status["error"] = e
                log.exception(
                    'Building newsletter email for "%s" failed, with error "%s"!'
                    % (receiver["email"], e))
                send_error_counter += 1
                continue

            if "HTTPLoaderError" in msg_string:
                log.exception("Transform message failed: {0}".format(
                    m.as_string()))

            try:
                self.mail_host.send(msg_string, immediate=True)
                send_status["successful"] = True
                log.info('Send newsletter to "%s"' % receiver["email"])
                send_counter += 1
            except Exception as e:  # noqa
                send_status["successful"] = False
                send_status["error"] = e
                log.exception(
                    'Sending newsletter to "%s" failed, with error "%s"!' %
                    (receiver["email"], e))
                send_error_counter += 1
            finally:
                receiver["status"] = send_status
        # Add information to annotations
        status_adapter = ISendStatus(self.context)
        if status_adapter:
            status_adapter.add_records(receivers)
        log.info(
            "Newsletter was sent to (%s) receivers. (%s) errors occurred!" %
            (send_counter, send_error_counter))

        # change status only for a 'regular' send operation (not 'is_test')
        if not self.is_test:
            self.request["enlwf_guard"] = True
            api.content.transition(obj=self.context,
                                   transition="sending_completed")
            self.request["enlwf_guard"] = False
            self.context.setEffectiveDate(datetime.now())
            self.context.reindexObject(idxs=["effective"])
            msg_type = "info"
            additional_warning = ""
            if send_error_counter:
                msg_type = "warn"
                additional_warning = _(
                    "\nPlease check the log files, for more details!")
            api.portal.show_message(
                message=_(
                    "Newsletter was sent to ({0}) receivers. ({1}) errors occurred!{2}"
                    .format(send_counter, send_error_counter,
                            additional_warning)),
                request=self.request,
                type=msg_type,
            )
예제 #10
0
 def get_public_body(self):
     """Return the rendered HTML version without placeholders."""
     issuedatafetcher = IIssueDataFetcher(self.context)
     preview_html = issuedatafetcher.preview_html()
     return preview_html
예제 #11
0
 def get_public_body(self):
     """ Return the rendered HTML version without placeholders.
     """
     issuedatafetcher = IIssueDataFetcher(self.context)
     preview_html = issuedatafetcher.preview_html()
     return preview_html
    def send(self, recipients=[]):
        """Sends the newsletter.
           An optional list of dicts (keys=fullname|mail) can be passed in
           for sending a newsletter out addresses != subscribers.
        """
        # preparations
        request = self.REQUEST
        test = hasattr(request, 'test')
        current_state = api.content.get_state(obj=self)

        # check for workflow
        if not (test or recipients) and current_state != 'sending':
            raise ValueError('Executed send in wrong review state!')

        # get hold of the parent Newsletter object#
        enl = self.getNewsletter()

        # get sender name
        sender_name = request.get('sender_name')
        if not sender_name:
            sender_name = enl.getSenderName()
        # don't use Header() with a str and a charset arg, even if
        # it is correct this would generate a encoded header and mail
        # server may not support utf-8 encoded header
        from_header = Header(safe_unicode(sender_name))

        # get sender e-mail
        sender_email = request.get('sender_email')
        if not sender_email:
            sender_email = enl.getSenderEmail()
        from_header.append(u'<%s>' % safe_unicode(sender_email))

        # determine MailHost first (build-in vs. external)
        deliveryServiceName = enl.getDeliveryService()
        if deliveryServiceName == 'mailhost':
            mail_host = getToolByName(enl, 'MailHost')
        else:
            mail_host = getUtility(IMailHost, name=deliveryServiceName)
        log.info('Using mail delivery service "%r"' % mail_host)

        send_counter = 0
        send_error_counter = 0

        charset = get_email_charset()
        if not recipients:
            receivers = self._send_recipients()
        issue_data_fetcher = IIssueDataFetcher(self)
        for receiver in receivers:
            # get complete issue data
            issue_data = issue_data_fetcher(receiver)

            # create multipart mail
            outer = MIMEMultipart('alternative')
            outer['To'] = Header(u'<%s>' % safe_unicode(receiver['email']))
            outer['From'] = from_header
            outer['Subject'] = issue_data['subject_header']
            outer.epilogue = ''

            # Attach text part
            text_part = MIMEText(issue_data['body_plain'], 'plain', charset)

            # Attach html part with images
            html_part = MIMEMultipart('related')
            html_text = MIMEText(issue_data['body_html'], 'html', charset)
            html_part.attach(html_text)
            # Add images to the message
            for image in issue_data['images_to_attach']:
                html_part.attach(image)
            outer.attach(text_part)
            outer.attach(html_part)

            try:
                mail_host.send(outer.as_string())
                log.info('Send newsletter to "%s"' % receiver['email'])
                send_counter += 1
            except Exception, e:  # noqa
                log.exception(
                    'Sending newsletter to "%s" failed, with error "%s"!' %
                    (receiver['email'], e))
                send_error_counter += 1
    def send(self):
        """Sends the newsletter, sending might be queued for async send out.
        """

        # check for workflow
        current_state = api.content.get_state(obj=self.context)
        if not self.is_test and current_state != 'sending':
            raise ValueError('Executed send in wrong review state!')

        # get hold of the parent Newsletter object#
        enl = self.context.get_newsletter()
        sender_name = self.request.get('sender_name') or enl.sender_name
        sender_email = self.request.get('sender_email') or enl.sender_email
        # get Plone email_charset
        # charset = get_email_charset()
        receivers = self._get_recipients()

        # determine MailHost first (build-in vs. external)
        delivery_service_name = 'mailhost'  # XXX enl.delivery_dervice
        if delivery_service_name == 'mailhost':
            self.mail_host = api.portal.get_tool('MailHost')
        else:
            self.mail_host = getUtility(IMailHost, name=delivery_service_name)
        log.info('Using mail delivery service "%r"' % self.mail_host)

        send_counter = 0
        send_error_counter = 0

        issue_data_fetcher = IIssueDataFetcher(self.context)
        # get issue data
        issue_data = issue_data_fetcher()
        for receiver in receivers:
            send_status = {
                'successful': None,
                'error': None,
                'datetime': datetime.now(),
            }
            try:
                personalized_html = issue_data_fetcher.personalize(
                    receiver, issue_data['body_html']
                )
                # get plain text version
                personalized_plaintext = issue_data_fetcher.create_plaintext_message(
                    personalized_html
                )

                m = emails.Message(
                    html=personalized_html,
                    text=personalized_plaintext,
                    subject=issue_data['subject'],
                    mail_from=(sender_name, sender_email),
                    mail_to=(receiver['fullname'], receiver['email']),
                )
                m.transform(
                    images_inline=True,
                    base_url=self.context.absolute_url(),
                    cssutils_logging_level=logging.ERROR,
                )
                message_string = m.as_string()
                if 'HTTPLoaderError' in message_string:
                    log.exception(u"Transform message failed: {0}".format(message_string))
                try:
                    self.mail_host.send(message_string, immediate=True)
                    send_status['successful'] = True
                    log.info('Send newsletter to "%s"' % receiver['email'])
                    send_counter += 1
                except Exception as e:  # noqa
                    send_status['successful'] = False
                    send_status['error'] = e
                    log.exception(
                        'Sending newsletter to "%s" failed, with error "%s"!'
                        % (receiver['email'], e)
                    )
                    send_error_counter += 1
            except Exception as e:
                send_status['successful'] = False
                send_status['error'] = e
                log.exception(
                    'Sending newsletter failed, with error "{0}"!'.format(e)
                )
                send_error_counter += 1
            finally:
                receiver['status'] = send_status

        if not self.is_test:
            # Add information to annotations
            status_adapter = ISendStatus(self.context)
            if status_adapter:
                status_adapter.add_records(receivers)
        log.info(
            'Newsletter was sent to (%s) receivers. (%s) errors occurred!'
            % (send_counter, send_error_counter)
        )

        # change status only for a 'regular' send operation (not 'is_test')
        if not self.is_test:
            self.request['enlwf_guard'] = True
            api.content.transition(obj=self.context, transition='sending_completed')
            self.request['enlwf_guard'] = False
            self.context.setEffectiveDate(DateTime())
            self.context.reindexObject(idxs=['effective'])
            msg_type = "info"
            additional_warning = ""
            if send_error_counter:
                msg_type = "warn"
                additional_warning = _(
                    "\nPlease check the log files, for more details!"
                )
            api.portal.show_message(
                message=_(
                    'Newsletter was sent to ({0}) receivers. ({1}) errors occurred!{2}'.format(
                        send_counter, send_error_counter, additional_warning
                    )
                ),
                request=self.request,
                type=msg_type,
            )