예제 #1
0
    def unsubscribe(self):
        """ """
        if protect is not None:
            alsoProvides(self.request,
                         protect.interfaces.IDisableCSRFProtection)
        putils = getToolByName(self.context, "plone_utils")
        uid = self.request.get("subscriber")

        newsletter = self.context
        if not INewsletter.providedBy(newsletter):
            putils.addPortalMessage(
                _("Please use the correct unsubscribe url!"), "error")
            return self.request.response.redirect(
                api.portal.get_navigation_root(self).absolute_url())

        # We do the deletion as the owner of the newsletter object
        # so that this is possible without login.
        owner = newsletter.getWrappedOwner()
        newSecurityManager(newsletter, owner)
        subscriber = api.content.get(UID=uid)
        if subscriber is None or not INewsletterSubscriber.providedBy(
                subscriber):
            putils.addPortalMessage(_("An error occured"), "error")
        else:
            del newsletter[subscriber.id]
            putils.addPortalMessage(_("You have been unsubscribed."))

        return self.request.response.redirect(
            api.portal.get_navigation_root(self).absolute_url())
예제 #2
0
    def send_issue(self):
        """
        sets workflow state to sending and then redirects to step2 with UID as
        parameter as simple safety belt.
        """
        PostOnly(self.request)
        if 'test' in self.request.form:  # test must not modify the state
            self.context.send()
            api.portal.show_message(
                message=_('The issue test sending has been initiated.'),
                request=self.request,
            )
            return self.request.response.redirect(self.context.absolute_url())

        if self.context.issue_queue is not None:
            self._send_issue_prepare()
            self.context.queue_issue_for_sendout()
            api.portal.show_message(
                message=_(
                    'The issue sending has been initiated in the background.'
                ),
                request=self.request,
            )
            return self.request.response.redirect(self.context.absolute_url())

        # No queuing but direct send
        self.send_issue_immediately()
        api.portal.show_message(
            message=_(
                'The issue has been generated and sent to the mail server.'
            ),
            request=self.request,
        )
        return self.request.response.redirect(self.context.absolute_url())
예제 #3
0
    def confirm_subscriber(self):
        hashkey = self.request.get('hkey')
        enl_registration_tool = queryUtility(IENLRegistrationTool,
                                             'enl_registration_tool')
        regdataobj = enl_registration_tool.get(hashkey)
        messages = IStatusMessage(self.request)
        if regdataobj:
            easynewsletter = self.portal.unrestrictedTraverse(
                regdataobj.path_to_easynewsletter)
            valid_email, error_code = easynewsletter.addSubscriber(
                regdataobj.subscriber, regdataobj.firstname,
                regdataobj.lastname, regdataobj.name_prefix,
                regdataobj.nl_language, regdataobj.organization,
                regdataobj.salutation)
            if valid_email:

                # now delete the regobj
                del enl_registration_tool[hashkey]
                messages.addStatusMessage(
                    _("Your subscription was successfully confirmed."), "info")
            else:
                messages.addStatusMessage(MESSAGE_CODE[error_code], "error")
            self._msg_redirect(easynewsletter)
        else:
            messages.addStatusMessage(_("Please enter a valid email address."),
                                      "error")
        return self.request.response.redirect(self.context.absolute_url())
예제 #4
0
    def confirm_subscriber(self):
        hashkey = self.request.get('hkey')
        enl_registration_tool = queryUtility(
            IENLRegistrationTool, 'enl_registration_tool')
        regdataobj = enl_registration_tool.get(hashkey)
        messages = IStatusMessage(self.request)
        if regdataobj:
            easynewsletter = self.portal.unrestrictedTraverse(
                regdataobj.path_to_easynewsletter)
            valid_email, error_code = easynewsletter.addSubscriber(
                regdataobj.subscriber,
                regdataobj.firstname,
                regdataobj.lastname,
                regdataobj.name_prefix,
                regdataobj.nl_language,
                regdataobj.organization,
                regdataobj.salutation
            )
            if valid_email:

                # now delete the regobj
                del enl_registration_tool[hashkey]
                messages.addStatusMessage(
                    _("Your subscription was successfully confirmed."), "info")
            else:
                messages.addStatusMessage(MESSAGE_CODE[error_code], "error")
            self._msg_redirect(easynewsletter)
        else:
            messages.addStatusMessage(
                _("Please enter a valid email address."), "error")
        return self.request.response.redirect(self.context.absolute_url())
예제 #5
0
 def send_unsubscribe_email(self, subscriber):
     newsletter = self.context
     catalog = getToolByName(self.context, "portal_catalog")
     query = {}
     query["portal_type"] = "ENLSubscriber"
     query["email"] = subscriber
     results = catalog.unrestrictedSearchResults(query)
     messages = IStatusMessage(self.request)
     if results:
         subscriber_brain = results[0]
         unsubscribe_url = self.newsletter_url +\
             '/unsubscribe?subscriber=' + subscriber_brain.UID
         msg_text = """%s: %s""" % (
             newsletter.getUnsubscribe_string(), unsubscribe_url)
         api.portal.send_email(
             recipient=subscriber,
             sender=self.context.email_from_address,
             subject=_(u"confirm newsletter unsubscription"),
             body=msg_text,
         )
         messages.addStatusMessage(
             _("We send you an email, please confirm this unsubscription."),
             "info")
     else:
         # todo: write an extra error msg if a plone user wants to
         # unsubscribe himself
         messages.addStatusMessage(
             _("Your email address could not be found in subscribers."),
             "error")
예제 #6
0
    def __call__(self):
        """
        sets workflow state to sending and then redirects to step2 with UID as
        parameter as simple safety belt.
        """
        PostOnly(self.request)
        if self.is_test:  # test must not modify the state
            self.send()
            api.portal.show_message(
                message=_("The issue test sending has been initiated."),
                request=self.request,
            )
            return self.request.response.redirect(self.context.absolute_url())

        # XXX implement this:
        # if self.context.issue_queue is not None:
        #     self._send_issue_prepare()
        #     self.context.queue_issue_for_sendout()
        #     api.portal.show_message(
        #         message=_("The issue sending has been initiated in the background."),
        #         request=self.request,
        #     )
        #     return self.request.response.redirect(self.context.absolute_url())

        # No queuing but direct send
        # self._send_issue_prepare()
        self.send_issue_immediately()
        api.portal.show_message(
            message=_(
                "The issue has been generated and sent to the mail server."),
            request=self.request,
        )
        return self.request.response.redirect(self.context.absolute_url())
예제 #7
0
 def send_unsubscribe_email(self, subscriber):
     newsletter = self.context
     catalog = getToolByName(self.context, "portal_catalog")
     query = {}
     query["portal_type"] = "ENLSubscriber"
     query["email"] = subscriber
     results = catalog.unrestrictedSearchResults(query)
     messages = IStatusMessage(self.request)
     if results:
         subscriber_brain = results[0]
         unsubscribe_url = self.newsletter_url +\
             '/unsubscribe?subscriber=' + subscriber_brain.UID
         msg_text = """%s: %s""" % (newsletter.getUnsubscribe_string(),
                                    unsubscribe_url)
         settings = get_portal_mail_settings()
         api.portal.send_email(
             recipient=subscriber,
             sender=settings.email_from_address,
             subject=_(u"confirm newsletter unsubscription"),
             body=msg_text,
         )
         messages.addStatusMessage(
             _("We send you an email, please confirm this unsubscription."),
             "info")
     else:
         # todo: write an extra error msg if a plone user wants to
         # unsubscribe himself
         messages.addStatusMessage(
             _("Your email address could not be found in subscribers."),
             "error")
    def register_subscriber(self):
        """
        """
        subscriber = self.request.get("subscriber")
        fullname = self.request.get("fullname", "")
        salutation = self.request.get("salutation", "")
        organization = self.request.get("organization", "")
        path_to_easynewsletter = self.request.get("newsletter")
        # remove leading slash from paths like: /mynewsletter
        path_to_easynewsletter = path_to_easynewsletter.strip('/')
        newsletter_container = self.portal.restrictedTraverse(path_to_easynewsletter)
        messages = IStatusMessage(self.request)
        if not salutation:
            messages.addStatusMessage(_("Please choose a salutation."), "error")
            return self.request.response.redirect(newsletter_container.absolute_url())
        if not subscriber:
            messages.addStatusMessage(_("Please enter a valid email address."), "error")
            return self.request.response.redirect(newsletter_container.absolute_url())
        from Products.validation.validators.BaseValidators import EMAIL_RE
        EMAIL_RE = "^" + EMAIL_RE
        mo = re.search(EMAIL_RE, subscriber)
        if not mo:
            messages.addStatusMessage(_("Please enter a valid email address."), "error")
            return self.request.response.redirect(newsletter_container.absolute_url())
        if subscriber in newsletter_container.objectIds():
            messages.addStatusMessage(_("Your email address is already registered."), "error")
            return self.request.response.redirect(newsletter_container.absolute_url())
        subscriber_data = {}
        subscriber_data["subscriber"] = subscriber
        subscriber_data["fullname"] = fullname
        subscriber_data["salutation"] = salutation
        subscriber_data["organization"] = organization
        subscriber_data["path_to_easynewsletter"] = path_to_easynewsletter

        # use password reset tool to create a hash
        pwr_data = self._requestReset(subscriber)
        hashkey = pwr_data['randomstring']
        enl_registration_tool = queryUtility(IENLRegistrationTool, 'enl_registration_tool')
        if hashkey not in enl_registration_tool.objectIds():
            enl_registration_tool[hashkey] = RegistrationData(hashkey, **subscriber_data)
            msg_subject = newsletter_container.getRawSubscriber_confirmation_mail_subject().replace(
                "${portal_url}", self.portal_url.strip('http://'))
            confirmation_url = self.portal_url + '/confirm-subscriber?hkey=' + str(hashkey)
            msg_text = newsletter_container.getRawSubscriber_confirmation_mail_text().replace("${newsletter_title}", newsletter_container.Title())
            msg_text = msg_text.replace("${subscriber_email}", subscriber)
            msg_text = msg_text.replace("${confirmation_url}", confirmation_url)
            msg_sender = self.portal.getProperty('email_from_address')
            msg_receiver = subscriber
            msg = MIMEText(msg_text)
            msg['To']= msg_receiver
            msg['From'] = msg_sender
            msg['Subject'] = msg_subject
            #msg.epilogue   = ''
            self.portal.MailHost.send(msg.as_string())
            messages.addStatusMessage(_("Your email has been registered. \
                A confirmation email was sent to your address. Please check \
                your inbox and click on the link in the email in order to \
                confirm your subscription."), "info")
        self.request.response.redirect(newsletter_container.absolute_url())
예제 #9
0
class IENLSettings(Interface):
    """
    """

    allowed_content_aggregation_types = schema.List(
        required=False,
        title=_(u'Allowed content aggregation types'),
        description=_(u'Content types which will be visbile in the Content'
                      u' aggregation sources reference field.'),
        value_type=schema.TextLine(title=_('Content type')),
    )
예제 #10
0
class EditForm(base.EditForm):
    """
    """
    if IS_PLONE_5:
        schema = INewsletterSubscriberPortlet
    else:  # BBB
        form_fields = form.Fields(INewsletterSubscriberPortlet)

    label = _(u"Edit Newsletter portlet")
    description = _(
        u"This portlet displays the subscriber add form of a newsletter.")
 def delete(self):
     """delete all the selected subscribers"""
     ids = self.request.get("subscriber_ids", [])
     if not ids:
         msg = _("No subscriber selected!")
         api.portal.show_message(msg, request=self.request, type="error")
         return False
     existing = self.context.objectIds()
     # avoid wrong id to be submitted
     to_remove = [i for i in ids if i in existing]
     self.context.manage_delObjects(to_remove)
     msg = _("subscriber/s deleted successfully")
     api.portal.show_message(msg, request=self.request, type="info")
     return True
예제 #12
0
class INewsletterSubscriber(model.Schema):
    """Marker interface and Dexterity Python Schema for NewsletterSubscriber"""

    salutation = schema.Choice(
        title=_("EasyNewsletter_label_salutation", default="Salutation"),
        description=_("EasyNewsletter_help_salutation", default=""),
        vocabulary="Products.EasyNewsletter.Salutations",
        required=False,
    )

    name_prefix = schema.TextLine(
        title=_("EasyNewsletter_label_name_prefix", default="Name Prefix"),
        description=_("EasyNewsletter_help_name_prefix", default=""),
        default="",
        required=False,
    )

    firstname = schema.TextLine(
        title=_("EasyNewsletter_label_firstname", default="First Name"),
        required=False,
    )

    lastname = schema.TextLine(title=_("EasyNewsletter_label_lastname",
                                       default="Last Name"),
                               required=False)

    organization = schema.TextLine(
        title=_("EasyNewsletter_label_organization", default="Organization"),
        required=False,
    )

    email = schema.TextLine(title=_("EasyNewsletter_label_email",
                                    default="Email"),
                            required=True)
예제 #13
0
 def send_issue(self):
     """
     """
     putils = getToolByName(self.context, "plone_utils")
     self.context.send()
     putils.addPortalMessage(_("The issue has been send."))
     return self.request.response.redirect(self.context.absolute_url())
예제 #14
0
 def send_issue(self):
     """
     """
     putils = getToolByName(self.context, "plone_utils")
     self.context.send()
     putils.addPortalMessage(_("The issue has been send."))
     return self.request.response.redirect(self.context.absolute_url())
    def __call__(self, context):
        items = []

        registry = getUtility(IRegistry)
        output_templates = registry.get(
            "Products.EasyNewsletter.output_templates")
        for key, value in output_templates.items():
            items.append(VocabItem(key, value))
        if not len(items):
            items.append(
                VocabItem(
                    "output_default",
                    _("enl_label_default_output_template",
                      "Default output template"),
                ))

        # Fix context if you are using the vocabulary in DataGridField.
        # See https://github.com/collective/collective.z3cform.datagridfield/issues/31:  # NOQA: 501
        if not IDexterityContent.providedBy(context):
            req = getRequest()
            context = req.PARENTS[0]

        # create a list of SimpleTerm items:
        terms = []
        for item in items:
            terms.append(
                SimpleTerm(value=item.token,
                           token=str(item.token),
                           title=item.value))
        # Create a SimpleVocabulary from the terms list and return it:
        return SimpleVocabulary(terms)
 def delete(self):
     """ delete all the selected subscribers
     """
     msg_manager = IStatusMessage(self.request)
     ids = self.request.get('subscriber_ids', [])
     if not ids:
         msg = _(u"No subscriber selected!")
         msg_manager.addStatusMessage(msg, type='error')
         return False
     existing = self.context.objectIds()
     # avoid wrong id to be submitted
     to_remove = [i for i in ids if i in existing]
     self.context.manage_delObjects(to_remove)
     msg = _(u"subscriber/s deleted successfully")
     msg_manager.addStatusMessage(msg, type="info")
     return True
 def get_delivery_services(self):
     result = atapi.DisplayList()
     result.add(u'mailhost', _(u'EasyNewsletter_label_PloneMailHost', u'Default Plone Mailhost'))
     for utility in getUtilitiesFor(IMailHost):
         if utility[0]:
             result.add(utility[0], utility[0])
     return result
 def delete(self):
     """ delete all the selected subscribers
     """
     msg_manager = IStatusMessage(self.request)
     ids = self.request.get('subscriber_ids', [])
     if not ids:
         msg = _(u"No subscriber selected!")
         msg_manager.addStatusMessage(msg, type='error')
         return False
     existing = self.context.objectIds()
     # avoid wrong id to be submitted
     to_remove = [i for i in ids if i in existing]
     self.context.manage_delObjects(to_remove)
     msg = _(u"subscriber/s deleted successfully")
     msg_manager.addStatusMessage(msg, type="info")
     return True
 def __call__(self, value=None, *args, **kwargs):
     instance = kwargs.get('instance')
     if instance is not None:
         folder = instance.aq_parent
         identifier = getToolByName(instance, 'plone_utils').normalizeString(value).lower()
         if folder._getOb(identifier, instance) != instance:
             return _(u"Duplicate registration.")
     return 1
예제 #20
0
 def get_subscriber_sources(self):
     result = atapi.DisplayList()
     result.add(u'default', _(
         u'EasyNewsletter_label_noSource',
         u'no external subscriber source'))
     for utility in getUtilitiesFor(ISubscriberSource):
         result.add(utility[0], utility[0])
     return result
예제 #21
0
 def get_delivery_services(self):
     result = atapi.DisplayList()
     result.add(u'mailhost', _(
         u'EasyNewsletter_label_PloneMailHost', u'Default Plone Mailhost'))
     for utility in getUtilitiesFor(IMailHost):
         if utility[0]:
             result.add(utility[0], utility[0])
     return result
class ICollectionAsNewsletterAggregationSource(model.Schema):
    """ """

    model.fieldset(
        "settings",
        label=_("Settings"),
        fields=["aggregation_template"],
    )

    aggregation_template = schema.Choice(
        title=_("Newsletter aggregation template"),
        description=
        _('The <a href="https://productseasynewsletter.readthedocs.io/en/latest/#aggregation-templates">aggregation template</a> used by the Newsletter to render Collection items for the Newsletter.'
          ),
        vocabulary="Products.EasyNewsletter.AggregationTemplates",
        # defaultFactory=get_default_aggregation_template,
        required=True,
    )
예제 #23
0
 def send_unsubscribe_email(self, subscriber):
     newsletter = self.context
     catalog = api.portal.get_tool(name="portal_catalog")
     query = {}
     query["portal_type"] = "Newsletter Subscriber"
     query["email"] = subscriber
     results = catalog.unrestrictedSearchResults(query)
     if results:
         subscriber_brain = results[0]
         unsubscribe_url = (
             self.newsletter_url + "/unsubscribe?subscriber=" + subscriber_brain.UID
         )
         unsubscribe_header_msgid = _(
             "you_requested_to_unsubscribe",
             default="You requested to unsubscribe from the following newsletter: ${title}",
             mapping={"title": newsletter.title},
         )
         msg_text = "{0}\n{1}: {2}".format(
             translate(unsubscribe_header_msgid),
             newsletter.unsubscribe_string,
             unsubscribe_url,
         )
         settings = get_portal_mail_settings()
         api.portal.send_email(
             recipient=subscriber,
             sender=settings.email_from_address,
             subject="{0}: {1}".format(
                 newsletter.title, _("confirm newsletter unsubscription")
             ),
             body=msg_text,
         )
         api.portal.show_message(
             message=_("We send you an email, please confirm this unsubscription."),
             request=self.request,
             type="info",
         )
     else:
         # todo: write an extra error msg if a plone user wants to
         # unsubscribe himself
         api.portal.show_message(
             message=_("Your email address could not be found in subscribers."),
             request=self.request,
             type="error",
         )
    def subscribers(self):
        query = dict(
            portal_type="Newsletter Subscriber",
            context=self.context,
            sort_on="email",
        )
        form = self.request.form
        for k in self.searchable_params:
            if form.get(k):
                if k == "SearchableText":
                    searchterm = form.get(k)
                    if not searchterm.endswith("*"):
                        searchterm += "*"
                    query[k] = searchterm
                else:
                    query[k] = form.get(k)
        subscribers = list()

        # Plone subscribers
        for brain in api.content.find(**query):
            if brain.salutation:
                salutation = config.SALUTATION.get(brain.salutation, "")
            else:
                salutation = ""
            subscribers.append(
                dict(
                    id=brain.getId,
                    source="plone",
                    deletable=True,
                    email=brain.email,
                    getURL=brain.getURL(),
                    salutation=salutation,
                    name_prefix=brain.name_prefix,
                    firstname=brain.firstname,
                    lastname=brain.lastname,
                    nl_language=brain.nl_language,
                    organization=brain.organization,
                )
            )

        # External subscribers
        ext_subcriber_source = self.context.get('subscriber_source')
        if ext_subcriber_source:
            if ext_subcriber_source != "default":
                try:
                    external_source = getUtility(
                        ISubscriberSource, name=ext_subcriber_source
                    )
                except ComponentLookupError:
                    log.warn(_(u'label_ext_subcriber_source_failed', default=u"External subscriber lookup failed"))
                else:
                    for subscriber in external_source.getSubscribers(self.context):
                        subscriber["source"] = ext_subcriber_source
                        subscribers.append(subscriber)

        return subscribers
예제 #25
0
 def confirm_subscriber(self):
     hashkey = self.request.get("hkey")
     enl_registration_tool = queryUtility(IENLRegistrationTool,
                                          "enl_registration_tool")
     regdataobj = enl_registration_tool.get(hashkey)
     messages = IStatusMessage(self.request)
     if regdataobj:
         portal = api.portal.get()
         easynewsletter = portal.unrestrictedTraverse(
             regdataobj.path_to_easynewsletter)
         email = regdataobj.subscriber
         plone_utils = api.portal.get_tool(name="plone_utils")
         subscriber_id = plone_utils.normalizeString(email)
         try:
             execute_under_special_role(
                 portal,
                 "Contributor",
                 api.content.create,
                 type="Newsletter Subscriber",
                 id=subscriber_id,
                 language=self.context.language,
                 email=email,
                 firstname=regdataobj.firstname,
                 lastname=regdataobj.lastname,
                 name_prefix=regdataobj.name_prefix,
                 # nl_language=regdataobj.nl_language,
                 organization=regdataobj.organization,
                 salutation=regdataobj.salutation,
                 container=easynewsletter,
             )
         except BadRequest:
             error_code = "email_exists"
             messages.addStatusMessage(MESSAGE_CODE[error_code], "error")
         else:
             # now delete the regobj
             del enl_registration_tool[hashkey]
             messages.addStatusMessage(
                 _("Your subscription was successfully confirmed."), "info")
         return self._msg_redirect(easynewsletter)
     else:
         messages.addStatusMessage(_("Please enter a valid email address."),
                                   "error")
     return self.request.response.redirect(self.context.absolute_url())
    def test_vocab_plone_users(self):
        vocab_name = "Products.EasyNewsletter.PloneUsers"
        factory = getUtility(IVocabularyFactory, vocab_name)
        self.assertTrue(IVocabularyFactory.providedBy(factory))

        vocabulary = factory(self.portal)
        self.assertTrue(IVocabularyTokenized.providedBy(vocabulary))
        self.assertEqual(
            vocabulary.getTerm(self.jane.getId()).title, _("Jane Doe - [email protected]")
        )
예제 #27
0
class IPloneUserGroupRecipients(model.Schema):
    """ """

    model.fieldset(
        "recipients",
        label=_("Recipients"),
        fields=["plone_receiver_members", "plone_receiver_groups"],
    )

    plone_receiver_members = schema.Set(
        title=_(
            "EasyNewsletter_label_ploneReceiverMembers",
            default="Plone Members to receive the newsletter",
        ),
        description=_(
            "EasyNewsletter_help_ploneReceiverMembers",
            default="Choose Plone Members which should receive \
                    the newsletter. Changing this setting does not affect \
                    already existing issues.",
        ),
        value_type=schema.Choice(
            vocabulary="Products.EasyNewsletter.PloneUsers"),
        required=False,
        defaultFactory=get_default_plone_receiver_members,
    )

    plone_receiver_groups = schema.Set(
        title=_(
            "EasyNewsletter_label_ploneReceiverGroups",
            default="Plone Groups to receive the newsletter",
        ),
        description=_(
            "EasyNewsletter_help_ploneReceiverGroups",
            default="Choose Plone Groups which should receive \
                    the newsletter. Changing this setting does not affect \
                    already existing issues.",
        ),
        value_type=schema.Choice(
            vocabulary="Products.EasyNewsletter.PloneGroups"),
        required=False,
        defaultFactory=get_default_plone_receiver_groups,
    )
예제 #28
0
    def test_vocab_salutations(self):
        vocab_name = 'Products.EasyNewsletter.Salutations'
        factory = getUtility(IVocabularyFactory, vocab_name)
        self.assertTrue(IVocabularyFactory.providedBy(factory))

        vocabulary = factory(self.portal)
        self.assertTrue(IVocabularyTokenized.providedBy(vocabulary))
        self.assertEqual(
            vocabulary.getTerm('ms').title,
            _(u'Ms'),
        )
예제 #29
0
 def __call__(self):
     if 'reset_statistics' in self.request.form:
         status_adapter = ISendStatus(self.context)
         if status_adapter:
             status_adapter.clear()
             api.portal.show_message(
                 message=_('Newsletter issue statistics have been reset.'),
                 request=self.request,
                 type='info',
             )
     return super(NewsletterIssueStatistics, self).__call__()
예제 #30
0
    def test_vocab_aggregation_templates(self):
        vocab_name = "Products.EasyNewsletter.AggregationTemplates"
        factory = getUtility(IVocabularyFactory, vocab_name)
        self.assertTrue(IVocabularyFactory.providedBy(factory))

        vocabulary = factory(self.portal)
        self.assertTrue(IVocabularyTokenized.providedBy(vocabulary))
        self.assertEqual(
            vocabulary.getTerm("aggregation_generic_listing").title,
            _("Generic Listing"),
        )
    def test_vocab_output_templates(self):
        vocab_name = "Products.EasyNewsletter.OutputTemplates"
        factory = getUtility(IVocabularyFactory, vocab_name)
        self.assertTrue(IVocabularyFactory.providedBy(factory))

        vocabulary = factory(self.portal)
        self.assertTrue(IVocabularyTokenized.providedBy(vocabulary))
        self.assertEqual(
            vocabulary.getTerm("output_default").title,
            _("Default output template"),
        )
 def get_aggregation_templates(self):
     """ Return registered aggregation templates as DisplayList """
     result = atapi.DisplayList()
     registry = getUtility(IRegistry)
     aggregation_templates = registry.get(
         'Products.EasyNewsletter.content_aggregation_templates')
     for key, value in aggregation_templates.items():
         result.add(key, value)
     result.add(u'custom',
                _(u'enl_label_custom_template', u'Custom template field'))
     return result
    def unsubscribe(self):
        """
        """

        putils = getToolByName(self.context, "plone_utils")
        catalog = getToolByName(self.context, "reference_catalog")
        uid = self.request.get("subscriber")

        subscriber = catalog.lookupObject(uid)
        if subscriber is None:
            putils.addPortalMessage(_("An error occured"), "error")
        else:
            newsletter = self.context
            # We do the deletion as the owner of the newsletter object
            # so that this is possible without login.
            owner = newsletter.getWrappedOwner()
            newSecurityManager(newsletter, owner)
            del newsletter[subscriber.id]
            putils.addPortalMessage(_("You have been unsubscribed."))

        return self.request.response.redirect(self.context.absolute_url())
예제 #34
0
    def test_vocab_plone_groups(self):
        vocab_name = 'Products.EasyNewsletter.PloneGroups'
        factory = getUtility(IVocabularyFactory, vocab_name)
        self.assertTrue(IVocabularyFactory.providedBy(factory))

        vocabulary = factory(self.portal)
        self.assertTrue(IVocabularyTokenized.providedBy(vocabulary))

        self.assertEqual(
            vocabulary.getTerm(self.vip.getId()).title,
            _(u'VIP'),
        )
예제 #35
0
    def unsubscribe(self):
        """
        """

        putils = getToolByName(self.context, "plone_utils")
        catalog = getToolByName(self.context, "reference_catalog")
        uid = self.request.get("subscriber")

        subscriber = catalog.lookupObject(uid)
        if subscriber is None:
            putils.addPortalMessage(_("An error occured"), "error")
        else:
            newsletter = self.context
            # We do the deletion as the owner of the newsletter object
            # so that this is possible without login.
            owner = newsletter.getWrappedOwner()
            newSecurityManager(newsletter, owner)
            del newsletter[subscriber.id]
            putils.addPortalMessage(_("You have been unsubscribed."))

        return self.request.response.redirect(self.context.absolute_url())
예제 #36
0
    def __call__(self):
        """ """
        alsoProvides(self.request, protect.interfaces.IDisableCSRFProtection)
        uid = self.request.get("subscriber")

        newsletter = self.context
        if not INewsletter.providedBy(newsletter):
            api.portal.show_message(
                message=_("Please use the correct unsubscribe url!"),
                request=self.request,
                type="error",
            )
            return self.request.response.redirect(
                api.portal.get_navigation_root(self).absolute_url()
            )

        # We do the deletion as the owner of the newsletter object
        # so that this is possible without login.
        owner = newsletter.getWrappedOwner()
        newSecurityManager(newsletter, owner)
        subscriber = api.content.get(UID=uid)
        if subscriber is None or not INewsletterSubscriber.providedBy(subscriber):
            api.portal.show_message(
                message=_("An error occured"),
                request=self.request,
                type="error",
            )
        else:
            del newsletter[subscriber.id]
            api.portal.show_message(
                message=_("You have been unsubscribed."),
                request=self.request,
                type="info",
            )

        return self.request.response.redirect(
            api.portal.get_navigation_root(self).absolute_url()
        )
예제 #37
0
    def __call__(self, context):
        items = [
            VocabItem("ms", _("Ms")),
            VocabItem("mr", _("Mr")),
        ]

        # Fix context if you are using the vocabulary in DataGridField.
        # See https://github.com/collective/collective.z3cform.datagridfield/issues/31:  # NOQA: 501
        if not IDexterityContent.providedBy(context):
            req = getRequest()
            context = req.PARENTS[0]

        # create a list of SimpleTerm items:
        terms = []
        for item in items:
            terms.append(
                SimpleTerm(
                    value=item.token,
                    token=str(item.token),
                    title=item.value,
                ))
        # Create a SimpleVocabulary from the terms list and return it:
        return SimpleVocabulary(terms)
 def __call__(self):
     text = self.render_aggregation_sources()
     self.context.text = RichTextValue(
         raw=text,
         mimeType="text/html",
         outputMimeType="text/html",
     )
     api.portal.show_message(
         message=_("Newsletter content successfully aggregated."),
         request=self.request,
         type="info",
     )
     self.request.response.setHeader("Pragma", "no-cache")
     self.request.response.setHeader("Cache-Control", "no-cache")
     return self.request.response.redirect(self.context.absolute_url(), status=301)
예제 #39
0
 def get_output_templates(self):
     """ Return registered output templates as DisplayList """
     result = atapi.DisplayList()
     registry = getUtility(IRegistry)
     output_templates = registry.get(
         'Products.EasyNewsletter.output_templates')
     if not output_templates:
         return result
     for key, value in output_templates.items():
         result.add(key, value)
     if not len(result):
         result.add(u'output_default', _(
             u'enl_label_default_output_template',
             u'Default output template'))
     return result
    def __call__(self):
        """Returns a CSV file with all newsletter subscribers.
        """
        context = aq_inner(self.context)
        ctool = getToolByName(context, 'portal_catalog')

        # Create CSV file
        filename = tempfile.mktemp()
        file = open(filename, 'wb')
        csvWriter = UnicodeWriter(file,
                                  {'delimiter': ',',
                                   'quotechar': '"',
                                   'quoting': csv.QUOTE_MINIMAL})
        CSV_HEADER_I18N = [self.context.translate(_(x)) for x in CSV_HEADER]
        csvWriter.writerow(CSV_HEADER_I18N)
        for subscriber in ctool(portal_type='ENLSubscriber',
                                path='/'.join(self.context.getPhysicalPath()),
                                sort_on='email'):
            obj = subscriber.getObject()
            csvWriter.writerow([obj.salutation,
                                obj.name_prefix,
                                obj.firstname,
                                obj.lastname,
                                obj.nl_language,
                                obj.email,
                                obj.organization])
        file.close()
        data = open(filename, "r").read()

        # Create response
        response = context.REQUEST.response
        response.addHeader(
            'Content-Disposition',
            "attachment; filename=easynewsletter-subscribers.csv")
        response.addHeader('Content-Type', 'text/csv')
        response.addHeader('Content-Length', "%d" % len(data))
        response.addHeader('Pragma', "no-cache")
        response.addHeader(
            'Cache-Control',
            "must-revalidate, post-check=0, pre-check=0, public")
        response.addHeader('Expires', "0")

        # Return CSV data
        return data
from AccessControl import ClassSecurityInfo
from Products.Archetypes import atapi
from Products.EasyNewsletter import EasyNewsletterMessageFactory as _
from Products.EasyNewsletter import config
from Products.EasyNewsletter.interfaces import IENLSubscriber
from zope.interface import implementer


schema = atapi.BaseSchema + atapi.Schema(
    (
        atapi.StringField(
            "title",
            required=False,
            widget=atapi.StringWidget(
                visible={"edit": "invisible", "view": "invisible"},
                label=_(u"EasyNewsletter_label_title", default=u"Title"),
                i18n_domain="EasyNewsletter",
            ),
        ),
        atapi.StringField(
            "salutation",
            required=False,
            vocabulary=config.SALUTATION,
            widget=atapi.SelectionWidget(
                label=_(u"EasyNewsletter_label_salutation", default="Salutation"),
                description=_("EasyNewsletter_help_salutation", default=u""),
                i18n_domain="EasyNewsletter",
                format="select",
            ),
        ),
        atapi.StringField(
    def create_subscribers(self, csv_data=None):
        """Create newsletter subscribers from uploaded CSV file.
        """

        # Do nothing if no submit button was hit
        if 'form.button.Import' not in self.request.form:
            return

        context = aq_inner(self.context)
        lang = context.Language()
        # plone_utils = getToolByName(self.context, 'plone_utils')
        # encoding = plone_utils.getSiteEncoding()
        existing = self.context.objectIds()
        # messages = IStatusMessage(self.request)
        success = []
        fail = []

        # Show error if no file was specified
        filename = self.request.form.get('csv_upload', None)
        if not filename:
            msg = _('No file specified.')
            IStatusMessage(self.request).addStatusMessage(msg, type='error')
            return self.request.response.redirect(
                context.absolute_url() + '/@@upload_csv')

        # Show error if no data has been provided in the file
        reader = UnicodeReader(filename)
        header = reader.next()
        CSV_HEADER_I18N = [self.context.translate(_(x)) for x in CSV_HEADER]
        if header != CSV_HEADER_I18N:
            logger.info("Got header %s\n Expected:%s" % (
                header, CSV_HEADER_I18N))
            msg = _(
                'Wrong specification of the CSV file. ' +
                'Please correct it and retry.')
            IStatusMessage(self.request).addStatusMessage(msg, type='error')
            return self.request.response.redirect(
                context.absolute_url() + '/@@upload_csv')

        for subscriber in reader:
            # Check the length of the line
            if len(subscriber) != 7:
                msg = _('The number of items in the line is not correct. \
                        It should be 7. Check your CSV file.')
                fail.append(
                    {'failure': msg})
            else:
                salutation = subscriber[0]
                name_prefix = subscriber[1]
                firstname = subscriber[2]
                lastname = subscriber[3]
                nl_language = subscriber[4]
                email = subscriber[5]
                organization = subscriber[6]
                id = normalize_id(email)
                if id in existing:
                    msg = _('This email address is already registered.')
                    fail.append(
                        {'salutation': salutation,
                         'name_prefix': name_prefix,
                         'firstname': firstname,
                         'lastname': lastname,
                         'nl_language': nl_language,
                         'email': email,
                         'organization': organization,
                         'failure': msg})
                else:
                    title = email + " - " + ' '.join([lastname,
                                                      firstname])
                    try:
                        self.context.invokeFactory(
                            'ENLSubscriber',
                            id=id,
                            title=title,
                            description="",
                            language=lang)
                        sub = context[id]
                        sub.email = email
                        sub.name_prefix = name_prefix
                        sub.firstname = firstname
                        sub.lastname = lastname
                        sub.nl_language = nl_language
                        sub.organization = organization
                        sub.salutation = salutation
                        obj = self.context.get(id, None)
                        obj.reindexObject()
                        # update existing
                        existing.append(id)
                        success.append({
                            'salutation': salutation,
                            'name_prefix': name_prefix,
                            'firstname': firstname,
                            'lastname': lastname,
                            'nl_language': nl_language,
                            'email': email,
                            'organization': organization
                        })
                    except Exception, e:
                        fail.append({
                            'salutation': salutation,
                            'name_prefix': name_prefix,
                            'firstname': firstname,
                            'lastname': lastname,
                            'nl_language': nl_language,
                            'email': email,
                            'organization': organization,
                            'failure': (
                                'An error occured while creating ' +
                                'this subscriber: %s') % str(e)})
from Products.Archetypes import atapi
from Products.CMFCore.utils import getToolByName
from Products.EasyNewsletter import EasyNewsletterMessageFactory as _
from Products.EasyNewsletter import config
from Products.EasyNewsletter.interfaces import IENLTemplate
from Products.TemplateFields import ZPTField
from zope.interface import implementer


schema = atapi.BaseSchema + atapi.Schema((

    ZPTField(
        'body',
        validators=('zptvalidator', ),
        widget=atapi.TextAreaWidget(
            label=_(u'label_body_zpt', default=u'Newsletter Template'),
            description=_(
                'help_body_zpt',
                default=u'This is a Zope Page Template file that is used for \
                     rendering the newsletter mail.'),
            i18n_domain="plone",
            rows=30,
        ),
    ),

    atapi.TextField(
        'description',
        accessor="Description",
        widget=atapi.TextAreaWidget(
            label=_(u"label_description", default=u'Description'),
            description=_(
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)


def normalize_id(astring):
    return getUtility(IIDNormalizer).normalize(astring)


CSV_HEADER = [
    _(u"salutation"),
    _(u"name_prefix"),
    _(u"firstname"),
    _(u"lastname"),
    _(u"nl_language"),
    _(u"email"),
    _(u"organization")
]


class IEnl_Subscribers_View(Interface):
    """
    Enl_Subscribers_View interface
    """

else:
    from Products.Archetypes.atapi import RichWidget as RichTextWidget


log = logging.getLogger("Products.EasyNewsletter")


schema = atapi.Schema((
    # TODO: provide a default value here from portals email_from_address
    atapi.StringField(
        'senderEmail',
        required=True,
        validators=('isEmail', ),
        widget=atapi.StringWidget(
            label=_(
                u"EasyNewsletter_label_senderEmail",
                default=u"Sender email"),
            description=_(
                u"EasyNewsletter_help_senderEmail",
                default=u"Default for the sender address of the newsletters."),
            i18n_domain='EasyNewsletter',
        ),
    ),

    atapi.StringField(
        'senderName',
        widget=atapi.StringWidget(
            label=_(
                u"EasyNewsletter_label_senderName",
                default=u"Sender name"),
            description=_(
예제 #46
0
 def title(self):
     """
     """
     return _(u"Newsletter subscriber portlet")
from Products.EasyNewsletter.interfaces import IReceiversMemberFilter, IReceiversGroupFilter
from Products.EasyNewsletter.interfaces import IEasyNewsletter
from Products.EasyNewsletter.interfaces import ISubscriberSource
from Products.EasyNewsletter import config
from Products.EasyNewsletter import EasyNewsletterMessageFactory as _

import logging
log = logging.getLogger("Products.EasyNewsletter")


schema = atapi.Schema((
    atapi.StringField('senderEmail',
        required = True,
        validators = ('isEmail', ),
        widget = atapi.StringWidget(
            label = _(u"EasyNewsletter_label_senderEmail",
                default=u"Sender email"),
            description = _(u"EasyNewsletter_help_senderEmail",
                default=u"Default for the sender address of the newsletters."),
            i18n_domain = 'EasyNewsletter',
        ),
    ),

    atapi.StringField('senderName',
        widget = atapi.StringWidget(
            label = _(u"EasyNewsletter_label_senderName",
                default=u"Sender name"),
            description = _(u"EasyNewsletter_help_senderName",
                default=u"Default for the sender name of the newsletters."),
            i18n_domain = 'EasyNewsletter',
        )
    ),
예제 #48
0
import re
from Products.Archetypes.atapi import DisplayList
from Products.EasyNewsletter import EasyNewsletterMessageFactory as _


PROJECTNAME = "EasyNewsletter"


PLACEHOLDERS = ["UNSUBSCRIBE", "SUBSCRIBER_SALUTATION"]


SALUTATION = DisplayList(
    (
        ("", _(u"label_choose_saluation", "Choose salutation...")),
        ("ms", _(u"label_salutation_ms", "Ms.")),
        ("mr", _(u"label_salutation_mr", "Mr.")),
    )
)


MESSAGE_CODE = {
    "email_added": "Your email has been registered. A confirmation email was \
        sent to your address. Please check your inbox and click on the link in \
        the email in order to confirm your subscription.",
    "invalid_email": "Please enter a valid email address.",
    "email_exists": "Your email address is already registered.",
    "invalid_hashkey": "Please enter a valid email address.",
    "subscription_confirmed": "Your subscription was successfully confirmed.",
}

예제 #49
0
    from Products.EasyNewsletter.zamqp.handler import zamqp_queue_issue
    has_zamqp = True

log = logging.getLogger("Products.EasyNewsletter")


schema = atapi.Schema((
    atapi.TextField(
        'text',
        allowable_content_types=(
            'text/plain', 'text/structured', 'text/html',
            'application/msword'),
        default_output_type='text/html',
        widget=atapi.RichWidget(
            rows=30,
            label=_('EasyNewsletter_label_text', default=u'Text'),
            description=_(
                u'description_text_issue',
                default=u'The main content of the mailing. You can use \
                    the topic criteria to collect content or put manual \
                    content in. This will included in outgoing mails.'),
            i18n_domain='EasyNewsletter',
        ),
    ),

    atapi.BooleanField(
        'excludeAllSubscribers',
        default_method="get_excludeAllSubscribers_defaults",
        widget=atapi.BooleanWidget(
            label=_(
                u'label_excludeAllExternalSubscribers',
from plone.i18n.normalizer.interfaces import IIDNormalizer

from Products.CMFCore.utils import getToolByName
from Products.Five import BrowserView
from Products.statusmessages.interfaces import IStatusMessage

from Products.EasyNewsletter import EasyNewsletterMessageFactory as _
from Products.EasyNewsletter.config import SALUTATION
from Products.EasyNewsletter.interfaces import ISubscriberSource


def normalize_id(astring):
    return getUtility(IIDNormalizer).normalize(astring)


CSV_HEADER = [_(u"salutation"), _(u"fullname"), _(u"email"), _(u"organization"), ]


class IEnl_Subscribers_View(Interface):
    """
    Enl_Subscribers_View interface
    """


class Enl_Subscribers_View(BrowserView):
    """
    Enl_Subscribers_View browser view
    """
    implements(IEnl_Subscribers_View)

    # TODO: we should move these indexes from FieldIndex to ZCTextIndex
            folder = instance.aq_parent
            identifier = getToolByName(instance, 'plone_utils').normalizeString(value).lower()
            if folder._getOb(identifier, instance) != instance:
                return _(u"Duplicate registration.")
        return 1

validation.register(NoDuplicateValidator())


schema = atapi.BaseSchema + atapi.Schema((

    atapi.StringField('title',
        required = False,
        widget = atapi.StringWidget(
            visible = {'edit': 'invisible', 'view': 'invisible'},
            label = _(u'EasyNewsletter_label_title', default=u'Title'),
            description = _(u'EasyNewsletter_help_title', default=u''),
            i18n_domain = 'EasyNewsletter',
        ),
    ),

     atapi.StringField('salutation',
        required = False,
        vocabulary = config.SALUTATION,
        widget = atapi.SelectionWidget(
            label = _(u'EasyNewsletter_label_salutation',
                default='Salutation'),
            description = _('EasyNewsletter_help_salutation', default=u''),
            i18n_domain = 'EasyNewsletter',
            format = 'select',
        ),
예제 #52
0
# flake8: noqa
# from zope.i18n import translate
from Products.Archetypes.atapi import DisplayList
from Products.EasyNewsletter import EasyNewsletterMessageFactory as _
import re

PROJECTNAME = "EasyNewsletter"

ENL_ISSUE_TYPES = ['ENLIssue']
ENL_EDITHELPER_TYPES =['EasyNewsletter', 'ENLIssue']

PLACEHOLDERS = ["UNSUBSCRIBE", "SUBSCRIBER_SALUTATION"]


SALUTATION = DisplayList((
    ('', _(u"label_choose_saluation", "Choose salutation...")),
    ("ms", _(u"label_salutation_ms", "Ms.")),
    ("mr", _(u"label_salutation_mr", "Mr.")),
))

NL_LANGUAGE = DisplayList((
    ('', _(u"label_choose_nl_language", "Choose language...")),
    ("de", _(u"label_salutation_de", "DE")),
    ("en", _(u"label_salutation_en", "EN")),
    ("fr", _(u"label_salutation_fr", "FR")),
))

MESSAGE_CODE = {
    "email_added": _(
        u"email_added",
        default=u"Your email has been registered. A confirmation email was"
예제 #53
0
    def register_subscriber(self):
        """
        """
        props = getToolByName(self, "portal_properties").site_properties
        charset = props.getProperty("default_charset")
        subscriber = self.request.get("subscriber")
        lastname = self.request.get("name", "")
        firstname = self.request.get("firstname", "")
        name_prefix = self.request.get("name_prefix", "")
        portal_state = getMultiAdapter(
            (self.context.aq_inner, self.request),
            name=u'plone_portal_state'
        )
        current_language = portal_state.language()
        nl_language = self.request.get("nl_language", current_language)
        salutation = self.request.get("salutation", "")
        organization = self.request.get("organization", "")
        path_to_easynewsletter = self.request.get("newsletter")
        # remove leading slash from paths like: /mynewsletter
        path_to_easynewsletter = path_to_easynewsletter.strip('/')
        newsletter_container = self.portal.unrestrictedTraverse(
            path_to_easynewsletter)
        messages = IStatusMessage(self.request)

        if not subscriber:
            messages.addStatusMessage(
                _("Please enter a valid email address."), "error")
            return self._msg_redirect(newsletter_container)

        mo = re.search(EMAIL_RE, subscriber)
        if not mo:
            messages.addStatusMessage(
                _("Please enter a valid email address."), "error")
            return self._msg_redirect(newsletter_container)
        norm = queryUtility(IIDNormalizer)
        normalized_subscriber = norm.normalize(subscriber)
        if normalized_subscriber in newsletter_container.objectIds():
            messages.addStatusMessage(
                _("Your email address is already registered."), "error")
            return self._msg_redirect(newsletter_container)
        subscriber_data = {}
        subscriber_data["subscriber"] = subscriber
        subscriber_data["lastname"] = lastname
        subscriber_data["firstname"] = firstname
        subscriber_data["name_prefix"] = name_prefix
        subscriber_data["nl_language"] = nl_language
        subscriber_data["salutation"] = salutation
        subscriber_data["organization"] = organization
        subscriber_data["path_to_easynewsletter"] = path_to_easynewsletter

        # use password reset tool to create a hash
        pwr_data = self._requestReset(subscriber)
        hashkey = pwr_data['randomstring']
        enl_registration_tool = queryUtility(
            IENLRegistrationTool, 'enl_registration_tool')
        if hashkey not in enl_registration_tool.objectIds():
            enl_registration_tool[hashkey] = RegistrationData(
                hashkey, **subscriber_data)
            msg_subject = newsletter_container\
                .getRawSubscriber_confirmation_mail_subject().replace(
                    "${portal_url}", self.portal_url.strip('http://'))
            confirmation_url = self.portal_url + '/confirm-subscriber?hkey=' +\
                str(hashkey)
            msg_text = newsletter_container\
                .getRawSubscriber_confirmation_mail_text().replace(
                    "${newsletter_title}", newsletter_container.Title())
            msg_text = msg_text.replace("${subscriber_email}", subscriber)
            msg_text = msg_text.replace(
                "${confirmation_url}", confirmation_url)
            msg_sender = self.portal.getProperty('email_from_address')
            msg_receiver = subscriber
            msg = MIMEText(msg_text, "plain", charset)
            msg['To'] = msg_receiver
            msg['From'] = msg_sender
            msg['Subject'] = msg_subject
            # msg.epilogue   = ''
            self.portal.MailHost.send(msg.as_string())

            messages.addStatusMessage(_("Your email has been registered. \
                A confirmation email was sent to your address. Please check \
                your inbox and click on the link in the email in order to \
                confirm your subscription."), "info")
            return self._msg_redirect(newsletter_container)
    def create_subscribers(self, csv_data=None):
        """Create newsletter subscribers from uploaded CSV file.
        """

        # Do nothing if no submit button was hit
        if 'form.button.Import' not in self.request.form:
            return

        context = aq_inner(self.context)
        plone_utils = getToolByName(self.context, 'plone_utils')
        encoding = plone_utils.getSiteEncoding()
        existing = self.context.objectIds()
        messages = IStatusMessage(self.request)
        success = []
        fail = []
        data = []

        # Show error if no file was specified
        filename = self.request.form.get('csv_upload', None)
        if not filename:
            msg = _('No file specified.')
            IStatusMessage(self.request).addStatusMessage(msg, type='error')
            return self.request.response.redirect(context.absolute_url() + '/@@upload_csv')

        # Show error if no data has been provided in the file
        reader = csv.reader(filename)
        header = reader.next()
        if header != CSV_HEADER:
            msg = _('Wrong specification of the CSV file. Please correct it and retry.')
            IStatusMessage(self.request).addStatusMessage(msg, type='error')
            return self.request.response.redirect(context.absolute_url() + '/@@upload_csv')

        for subscriber in reader:
            # Check the length of the line
            if len(subscriber) != 4:
                msg = _('The number of items in the line is not correct. \
                        It should be 4. Check your CSV file.')
                fail.append(
                    {'failure': msg})
            else:
                salutation = subscriber[0]
                fullname = subscriber[1]
                email = subscriber[2]
                organization = subscriber[3]
                id = plone_utils.normalizeString(email)
                if id in existing:
                    msg = _('This email address is already registered.')
                    fail.append(
                        {'salutation': salutation,
                         'fullname': fullname,
                         'email': email,
                         'organization': organization,
                         'failure': msg})
                else:
                    title = email + " - " + fullname
                    try:
                        self.context.invokeFactory('ENLSubscriber',
                            id=id,
                            title=title,
                            description="")
                        sub = context[id]
                        sub.email = email
                        sub.fullname = fullname.decode(encoding)
                        sub.organization = organization.decode(encoding)
                        sub.salutation = salutation.decode(encoding)
                        obj = self.context.get(id, None)
                        obj.reindexObject()
                        success.append(
                                {'salutation': salutation,
                                 'fullname': fullname,
                                 'email': email,
                                 'organization': organization})
                    except Exception, e:
                        fail.append(
                            {'salutation': salutation,
                             'fullname': fullname,
                             'email': email,
                             'organization': organization,
                             'failure': 'An error occured while creating this subscriber: %s' % str(e)})
예제 #55
0
from Products.EasyNewsletter.utils.ENLHTMLParser import ENLHTMLParser
#from Products.EasyNewsletter.utils.mail import create_html_mail
from Products.EasyNewsletter.utils import safe_portal_encoding
from Products.CMFPlone.utils import safe_unicode

import logging
log = logging.getLogger("Products.EasyNewsletter")


schema = atapi.Schema((
    atapi.TextField('text',
        allowable_content_types = ('text/plain', 'text/structured', 'text/html', 'application/msword'),
        default_output_type = 'text/html',
        widget = atapi.RichWidget(
            rows = 30,
            label = _('EasyNewsletter_label_text', default=u'Text'),
            description = _(u'description_text_issue',
                default=u'The main content of the mailing. You can use the topic \
                    criteria to collect content or put manual content in. \
                    This will included in outgoing mails.'),
            i18n_domain = 'EasyNewsletter',
        ),
    ),

    atapi.BooleanField('sendToAllPloneMembers',
        default_method = "get_sendToAllPloneMembers_defaults",
        widget = atapi.BooleanWidget(
            label = _(u'label_sendToAllPloneMembers',
                default=u'Send to all Plone members'),
            description = _(u'help_sendToAllPloneMembers',
                default=u'If checked, the newsletter/mailing is send to all \
from Products.TemplateFields import ZPTField
from Products.CMFCore.utils import getToolByName
from zope.interface import implements

from Products.EasyNewsletter import config
from Products.EasyNewsletter.interfaces import IENLTemplate
from Products.EasyNewsletter import EasyNewsletterMessageFactory as _


schema = atapi.BaseSchema + atapi.Schema(
    (
        ZPTField(
            "body",
            validators=("zptvalidator",),
            widget=atapi.TextAreaWidget(
                label=_(u"label_body_zpt", default=u"Newsletter Template"),
                description=_(
                    "help_body_zpt",
                    default=u"This is a Zope Page Template file that is used for \
                     rendering the newsletter mail.",
                ),
                i18n_domain="plone",
                rows=30,
            ),
        ),
        atapi.TextField(
            "description",
            accessor="Description",
            widget=atapi.TextAreaWidget(
                label=_(u"label_description", default=u"Description"),
                description=_(u"help_description", default=u"Enter a value for description."),
예제 #57
0
else:
    from Products.Archetypes.atapi import RichWidget as RichTextWidget


log = logging.getLogger('Products.EasyNewsletter')


schema = atapi.Schema((
    atapi.TextField(
        'text',
        allowable_content_types=(
            'text/html', 'text/x-plone-outputfilters-html'),
        default_output_type='text/x-plone-outputfilters-html',
        widget=RichTextWidget(
            rows=30,
            label=_('EasyNewsletter_label_text', default=u'Text'),
            description=_(
                u'description_text_issue',
                default=u'The main content of the mailing. You can use \
                    the Collections to collect content or put manual \
                    content in. This will included in outgoing mails.'),
            i18n_domain='EasyNewsletter',
        ),
    ),

    atapi.BooleanField(
        'excludeAllSubscribers',
        default_method='get_excludeAllSubscribers_defaults',
        widget=atapi.BooleanWidget(
            label=_(
                u'label_excludeAllExternalSubscribers',
예제 #58
0
from Products.CMFPlone.utils import safe_unicode

import logging

log = logging.getLogger("Products.EasyNewsletter")


schema = atapi.Schema(
    (
        atapi.TextField(
            "text",
            allowable_content_types=("text/plain", "text/structured", "text/html", "application/msword"),
            default_output_type="text/html",
            widget=atapi.RichWidget(
                rows=30,
                label=_("EasyNewsletter_label_text", default=u"Text"),
                description=_(
                    u"description_text_issue",
                    default=u"The main content of the mailing. You can use the topic \
                    criteria to collect content or put manual content in. \
                    This will included in outgoing mails.",
                ),
                i18n_domain="EasyNewsletter",
            ),
        ),
        atapi.BooleanField(
            "sendToAllPloneMembers",
            default_method="get_sendToAllPloneMembers_defaults",
            widget=atapi.BooleanWidget(
                label=_(u"label_sendToAllPloneMembers", default=u"Send to all Plone members"),
                description=_(