示例#1
0
 def handleApply(self, action):
     data, errors = self.extractData()
     if 'email' in data:
         # Fetch MailChimp settings
         registry = getUtility(IRegistry)
         mailchimp_settings = registry.forInterface(IMailchimpSettings)
         if len(mailchimp_settings.api_key) == 0:
             return
         mailchimp = PostMonkey(mailchimp_settings.api_key)
         # Fetch MailChimp lists
         # XXX, Todo: For now we just fetch the first list.
         try:
             lists = mailchimp.lists()['data']
             list_id = lists[0]['id']
         except MailChimpException, error:
             raise WidgetActionExecutionError(
                 Invalid(
                     _(u"Could not fetch list from mailchimp.com: %s" %
                       error)))
         # Subscribe to MailChimp list
         try:
             mailchimp.listSubscribe(id=list_id,
                                     email_address=data['email'])
         except MailChimpException, error:
             raise WidgetActionExecutionError(
                 'email',
                 Invalid(_(u"Could not subscribe to newsletter: %s" %
                           error)))
 def handleApply(self, action):
     data, errors = self.extractData()
     if 'email' in data:
         # Fetch MailChimp settings
         registry = getUtility(IRegistry)
         mailchimp_settings = registry.forInterface(IMailchimpSettings)
         if len(mailchimp_settings.api_key) == 0:
             return
         mailchimp = PostMonkey(mailchimp_settings.api_key)
         # Fetch MailChimp lists
         # XXX, Todo: For now we just fetch the first list.
         try:
             lists = mailchimp.lists()['data']
             list_id = lists[0]['id']
         except MailChimpException, error:
             raise WidgetActionExecutionError(
                 Invalid(_(u"Could not fetch list from mailchimp.com: %s" %
                     error)))
         # Subscribe to MailChimp list
         try:
             mailchimp.listSubscribe(
                 id=list_id,
                 email_address=data['email'])
         except MailChimpException, error:
             raise WidgetActionExecutionError(
                 'email',
                 Invalid(_(
                     u"Could not subscribe to newsletter: %s" % error)))
 def handle_error(self, error, data):
     # Current api v3 documentation only lists errors in the 400 and 500
     # range.  The 400 code can mean a lot of things...
     if error.code == 400:
         error_msg = _(
             u"mailchimp_error_msg_already_subscribed",
             default=u"Could not subscribe to newsletter. "
             u"Either the email '${email}' is already subscribed "
             u"or something else is wrong. Try again later.",
             mapping={u"email": data['email']},
         )
         translated_error_msg = self.context.translate(error_msg)
         raise WidgetActionExecutionError('email',
                                          Invalid(translated_error_msg))
     elif error.code == 220:
         error_msg = _(
             u"mailchimp_error_msg_banned",
             default=u"Could not subscribe to newsletter. "
             u"The email '${email}' has been banned.",
             mapping={u"email": data['email']},
         )
         translated_error_msg = self.context.translate(error_msg)
         raise WidgetActionExecutionError('email',
                                          Invalid(translated_error_msg))
     else:
         error_msg = _(
             u"mailchimp_error_msg",
             default=u"Could not subscribe to newsletter. "
             u"Please contact the site administrator: "
             u"'${error}'",
             mapping={u"error": error},
         )
         translated_error_msg = self.context.translate(error_msg)
         raise ActionExecutionError(Invalid(translated_error_msg))
class INewsletterSubscribe(Interface):
    email = schema.TextLine(
        title=_(u"Email address"),
        description=_(u"help_email",
                      default=u"Please enter your email address."),
        required=True,
        constraint=validate_email)
class MailchimpSettingsEditForm(controlpanel.RegistryEditForm):

    schema = IMailchimpSettings
    label = _(u"MailChimp settings")
    description = _(u"""""")

    def updateFields(self):
        super(MailchimpSettingsEditForm, self).updateFields()

    def updateWidgets(self):
        super(MailchimpSettingsEditForm, self).updateWidgets()
示例#6
0
    def handleApply(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        # Retrieve list_id either from a hidden field in the form or fetch
        # the first list from mailchimp.
        list_id = data.get('list_id') or self.mailchimp.default_list_id()
        # list_id has to be updated for merge_fields=data to work if None
        if "list_id" in data and not data.get('list_id'):
            data['list_id'] = list_id

        # interest groups
        interests = {}
        interest_groups = data.pop('interest_groups', [])
        if self.available_interest_groups and interest_groups:
            # Create dictionary with as keys the interest groups, and as
            # values always True.
            interests = dict.fromkeys(interest_groups, True)

        # Use email_type if one is provided by the form, if not choose the
        # default email type from the control panel settings.
        email_type = data.get(
            'email_type') or self.mailchimp_settings.email_type

        # Subscribe to MailChimp list
        try:
            self.mailchimp.subscribe(
                list_id=list_id,
                email_address=data['email'],
                email_type=email_type,
                interests=interests,
                merge_fields=data,
            )
        except MailChimpException as error:
            return self.handle_error(error, data)

        if self.mailchimp_settings.double_optin:
            message = _(
                u"We have to confirm your email address. In order to " +
                u"finish the newsletter subscription, click on the link " +
                u"inside the email we just send you.")
        else:
            message = _(
                u"You have been subscribed to our newsletter succesfully.")

        IStatusMessage(self.context.REQUEST).addStatusMessage(message,
                                                              type="info")
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        site = getNavigationRootObject(self.context, portal)
        self.request.response.redirect(site.absolute_url())
    def handle_unsubscribe(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        list_id = data.get('list_id') or self.mailchimp.default_list_id()
        email = data['email']

        update_data = {}
        if data.get('unsubscribe'):
            update_data['status'] = 'unsubscribed'
        else:
            interest_groups = {}
            for group in data.get('interest_groups', []):
                interest_groups[group] = False
            update_data['interests'] = interest_groups

        try:
            self.mailchimp.update_subscriber(
                list_id, email_address=email, **update_data
            )
        except MailChimpException as error:
            if error.code != 404:
                # If a subscriber did not exist we don't want to announce
                # it. Treat only != 404 as an error.
                IStatusMessage(self.request).addStatusMessage(
                    _(
                        u'mailchimp_unsubscribe_error_msg',
                        default=u'We could not unsubscribe you from '
                        u'the newsletter. '
                        u"Please contact the site administrator: "
                        u"'${error}'",
                        mapping={u"error": error},
                    ),
                    type="info",
                )

        IStatusMessage(self.request).addStatusMessage(
            _(
                u'mailchimp_unsubscribed_msg',
                default=(
                    u'Thank you. You have been unsubscribed from '
                    u'the Newsletter.'
                ),
            ),
            type="info",
        )

        portal = getSite()
        self.request.response.redirect(portal.absolute_url())
示例#8
0
    def handle_unsubscribe(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        list_id = data.get('list_id') or self.mailchimp.default_list_id()
        email = data['email']

        update_data = {}
        if data.get('unsubscribe'):
            update_data['status'] = 'unsubscribed'
        else:
            interest_groups = {}
            if data.get('interest_groups'):
                for group in data.get('interest_groups', []):
                    interest_groups[group] = False
                update_data['interests'] = interest_groups

        try:
            self.mailchimp.update_subscriber(list_id,
                                             email_address=email,
                                             **update_data)
        except MailChimpException as error:
            if error.code != 404:
                # If a subscriber did not exist we don't want to announce
                # it. Treat only != 404 as an error.
                IStatusMessage(self.request).addStatusMessage(
                    _(
                        u'mailchimp_unsubscribe_error_msg',
                        default=u'We could not unsubscribe you from '
                        u'the newsletter. '
                        u"Please contact the site administrator: "
                        u"'${error}'",
                        mapping={u"error": error},
                    ),
                    type="info",
                )

        IStatusMessage(self.request).addStatusMessage(
            _(
                u'mailchimp_unsubscribed_msg',
                default=(u'Thank you. You have been unsubscribed from '
                         u'the Newsletter.'),
            ),
            type="info",
        )

        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        site = getNavigationRootObject(self.context, portal)
        self.request.response.redirect(site.absolute_url())
示例#9
0
    def handleApply(self, action):
        data, errors = self.extractData()
        if 'email' not in data:
            return
        mailchimp = getUtility(IMailchimpLocator)
        # Retrieve list_id either from a hidden field in the form or fetch
        # the first list from mailchimp.
        if 'list_id' in data and data['list_id'] is not None:
            list_id = data['list_id']
        else:
            list_id = mailchimp.default_list_id()

        # Groupings
        interests = {}
        if 'interest_groups' in data and data['interest_groups'] is not None:
            interest_grouping = mailchimp.groups(list_id=list_id)
            if interest_grouping and data['interest_groups']:
                # Create dictionary with as keys the interest groups, and as
                # values always True.
                interests = dict.fromkeys(data['interest_groups'], True)

        # Use email_type if one is provided by the form, if not choose the
        # default email type from the control panel settings.
        if 'email_type' in data:
            email_type = data['email_type']
        else:
            email_type = 'HTML'
        # Subscribe to MailChimp list
        try:
            mailchimp.subscribe(
                list_id=list_id,
                email_address=data['email'],
                email_type=email_type,
                interests=interests
            )
        except MailChimpException as error:
            return self.handle_error(error, data)
        registry = getUtility(IRegistry)
        mailchimp_settings = registry.forInterface(IMailchimpSettings)
        if mailchimp_settings.double_optin:
            message = _(
                u"We have to confirm your email address. In order to " +
                u"finish the newsletter subscription, click on the link " +
                u"inside the email we just send you.")
        else:
            message = _(
                u"You have been subscribed to our newsletter succesfully.")
        IStatusMessage(self.context.REQUEST).addStatusMessage(
            message, type="info")
        portal = getSite()
        self.request.response.redirect(portal.absolute_url())
    def handleApply(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        # Retrieve list_id either from a hidden field in the form or fetch
        # the first list from mailchimp.
        list_id = data.get('list_id') or self.mailchimp.default_list_id()

        # interest groups
        interests = {}
        interest_groups = data.pop('interest_groups', [])
        if self.available_interest_groups and interest_groups:
            # Create dictionary with as keys the interest groups, and as
            # values always True.
            interests = dict.fromkeys(interest_groups, True)

        # Use email_type if one is provided by the form, if not choose the
        # default email type from the control panel settings.
        email_type = data.get('email_type', 'HTML')

        # Subscribe to MailChimp list
        try:
            self.mailchimp.subscribe(
                list_id=list_id,
                email_address=data['email'],
                email_type=email_type,
                interests=interests,
                merge_fields=data,
            )
        except MailChimpException as error:
            return self.handle_error(error, data)

        if self.mailchimp_settings.double_optin:
            message = _(
                u"We have to confirm your email address. In order to "
                + u"finish the newsletter subscription, click on the link "
                + u"inside the email we just send you."
            )
        else:
            message = _(
                u"You have been subscribed to our newsletter succesfully."
            )

        IStatusMessage(self.context.REQUEST).addStatusMessage(
            message, type="info"
        )
        portal = getSite()
        self.request.response.redirect(portal.absolute_url())
示例#11
0
class NewsletterSubscriberForm(form.Form):
    fields = field.Fields(INewsletterSubscribe)
    ignoreContext = True
    label = _(u"Subscribe to newsletter")

    def updateActions(self):
        super(NewsletterSubscriberForm, self).updateActions()
        self.actions['subscribe'].addClass('context')

    @button.buttonAndHandler(_(u"subscribe_to_newsletter_button",
                               default=u"Subscribe"),
                             name='subscribe')
    def handleApply(self, action):
        data, errors = self.extractData()
        if 'email' in data:
            # Fetch MailChimp settings
            registry = getUtility(IRegistry)
            mailchimp_settings = registry.forInterface(IMailchimpSettings)
            if len(mailchimp_settings.api_key) == 0:
                return
            mailchimp = PostMonkey(mailchimp_settings.api_key)
            # Fetch MailChimp lists
            # XXX, Todo: For now we just fetch the first list.
            try:
                lists = mailchimp.lists()['data']
                list_id = lists[0]['id']
            except MailChimpException, error:
                raise WidgetActionExecutionError(
                    Invalid(
                        _(u"Could not fetch list from mailchimp.com: %s" %
                          error)))
            # Subscribe to MailChimp list
            try:
                mailchimp.listSubscribe(id=list_id,
                                        email_address=data['email'])
            except MailChimpException, error:
                raise WidgetActionExecutionError(
                    'email',
                    Invalid(_(u"Could not subscribe to newsletter: %s" %
                              error)))

            IStatusMessage(self.context.REQUEST).addStatusMessage(
                _(u"We have to confirm your email address. In order to " +
                  "finish the newsletter subscription, click on the link " +
                  "inside the email we just send you."),
                type="info")
            portal = getSite()
            self.request.response.redirect(portal.absolute_url())
示例#12
0
class INewsletterUnsubscribe(Interface):

    email = schema.TextLine(
        title=_(u"Email address"),
        description=_(u"help_email",
                      default=u"Please enter your email address."),
        required=True,
        constraint=validate_email,
    )

    list_id = schema.TextLine(title=_(u"List ID"), required=False)

    interest_groups = schema.Tuple(
        title=_(
            u'mailchimp_unsubscribe_interest_groups',
            default=u"Unsubscribe only form the following interest groups",
        ),
        description=_(u"mailchimp_help_unsubscribe_interest_groups",
                      default=u""),
        value_type=schema.Choice(
            vocabulary="collective.mailchimp.vocabularies.InterestGroups"),
        required=False,
    )

    unsubscribe = schema.Bool(
        title=_(
            u'mailchimp_unsubscribe_newsletter',
            default=u"Unsubscribe from the complete newsletter",
        ),
        description=_(u'mailchimp_help_unsubscribe_newsletter', default=u''),
    )
示例#13
0
class MailchimpSettingsEditForm(controlpanel.RegistryEditForm):

    schema = IMailchimpSettings
    label = _(u"MailChimp settings")
    description = _(u"""""")

    def update(self):
        self.updateCache()
        super(MailchimpSettingsEditForm, self).update()

    def updateFields(self):
        super(MailchimpSettingsEditForm, self).updateFields()

    def updateWidgets(self):
        super(MailchimpSettingsEditForm, self).updateWidgets()

    def updateCache(self):
        mailchimp = getUtility(IMailchimpLocator)
        mailchimp.updateCache()
示例#14
0
class INewsletterSubscribe(Interface):

    email = schema.TextLine(title=_(u"Email address"),
                            description=_(
                                u"help_email",
                                default=u"Please enter your email address."),
                            required=True,
                            constraint=validate_email)

    interest_groups = schema.Tuple(
        title=_(u"Interest groups"),
        description=_(u"help_interest_groups", default=u""),
        value_type=schema.Choice(
            vocabulary="collective.mailchimp.vocabularies.InterestGroups", ),
        required=False,
    )

    email_type = schema.Choice(
        title=_(u"Mail format"),
        vocabulary="collective.mailchimp.vocabularies.EmailType",
        default="text",
        required=False,
    )

    list_id = schema.TextLine(title=_(u"List ID"), required=False)
示例#15
0
 def handle_error(self, error, data):
     # Current api v3 documentation only lists errors in the 400 and 500
     # range.  The 400 code can mean a lot of things...
     if error.code == 400:
         error_msg = _(
             u"mailchimp_error_msg_already_subscribed",
             default=u"Could not subscribe to newsletter. "
                     u"Either the email '${email}' is already subscribed "
                     u"or something else is wrong. Try again later.",
             mapping={u"email": data['email']})
         translated_error_msg = self.context.translate(error_msg)
         raise WidgetActionExecutionError(
             'email',
             Invalid(translated_error_msg)
         )
     elif error.code == 220:
         error_msg = _(
             u"mailchimp_error_msg_banned",
             default=u"Could not subscribe to newsletter. "
                     u"The email '${email}' has been banned.",
             mapping={u"email": data['email']})
         translated_error_msg = self.context.translate(error_msg)
         raise WidgetActionExecutionError(
             'email',
             Invalid(translated_error_msg)
         )
     else:
         error_msg = _(
             u"mailchimp_error_msg",
             default=u"Could not subscribe to newsletter. "
                     u"Please contact the site administrator: "
                     u"'${error}'",
             mapping={u"error": error})
         translated_error_msg = self.context.translate(error_msg)
         raise ActionExecutionError(
             Invalid(translated_error_msg)
         )
示例#16
0
class NewsletterSubscriberForm(extensible.ExtensibleForm, form.Form):
    fields = field.Fields(INewsletterSubscribe)
    ignoreContext = True
    id = "newsletter-subscriber-form"
    label = _(u"Subscribe to newsletter")

    def updateActions(self):
        super(NewsletterSubscriberForm, self).updateActions()
        self.actions['subscribe'].addClass('context')

    def updateFields(self):
        super(NewsletterSubscriberForm, self).updateFields()
        self.fields['interest_groups'].widgetFactory = \
            CheckBoxFieldWidget
        self.fields['email_type'].widgetFactory = \
            RadioFieldWidget

    def updateWidgets(self):
        super(NewsletterSubscriberForm, self).updateWidgets()
        # Show/hide mail format option widget
        registry = getUtility(IRegistry)
        mailchimp_settings = registry.forInterface(IMailchimpSettings)
        if not mailchimp_settings.email_type_is_optional:
            self.widgets['email_type'].mode = HIDDEN_MODE
        # Retrieve the list id either from the request/form or fall back to
        # the default_list setting.
        if 'list_id' in self.context.REQUEST:
            list_id = self.context.REQUEST['list_id']
        elif 'form.widgets.list_id' in self.request.form:
            list_id = self.request.form['form.widgets.list_id']
        else:
            list_id = mailchimp_settings.default_list
        self.widgets['list_id'].mode = HIDDEN_MODE
        self.widgets['list_id'].value = list_id
        # Show/hide interest_groups widget
        mailchimp = getUtility(IMailchimpLocator)
        groups = mailchimp.groups(list_id=list_id)
        if not groups:
            self.widgets['interest_groups'].mode = HIDDEN_MODE
        if 'preselect_group' in self.context.REQUEST:
            for group_index in self.request['preselect_group']:
                group_index = int(group_index)
                self.widgets['interest_groups']\
                    .items[group_index]['checked'] = True

    @button.buttonAndHandler(_(u"subscribe_to_newsletter_button",
                               default=u"Subscribe"),
                             name='subscribe')
    def handleApply(self, action):
        data, errors = self.extractData()
        if 'email' in data:
            mailchimp = getUtility(IMailchimpLocator)

            # Retrieve list_id either from a hidden field in the form or fetch
            # the first list from mailchimp.
            if 'list_id' in data:
                list_id = data['list_id']
            else:
                list_id = mailchimp.default_list_id()

            # Groupings
            if 'interest_groups' in data:
                interest_grouping = mailchimp.groups(list_id=list_id)
                if interest_grouping and data['interest_groups']:
                    data['groupings'] = [{
                        'id':
                        interest_grouping['id'],
                        'groups':
                        ",".join(data['interest_groups']),
                    }]

            # Use email_type if one is provided by the form, if not choose the
            # default email type from the control panel settings.
            if 'email_type' in data:
                email_type = data['email_type']
            else:
                email_type = None
            # Subscribe to MailChimp list
            try:
                mailchimp.subscribe(
                    list_id=list_id,
                    email_address=data['email'],
                    merge_vars=data,
                    email_type=email_type,
                )
            except MailChimpException, error:
                if error.code == 214:
                    error_msg = _(
                        u"mailchimp_error_msg_already_subscribed",
                        default=u"Could not subscribe to newsletter. "
                        u"The email '${email}' is already subscribed.",
                        mapping={u"email": data['email']})
                    translated_error_msg = self.context.translate(error_msg)
                    raise WidgetActionExecutionError(
                        'email', Invalid(translated_error_msg))
                elif error.code == 220:
                    error_msg = _(
                        u"mailchimp_error_msg_banned",
                        default=u"Could not subscribe to newsletter. "
                        u"The email '${email}' has been banned.",
                        mapping={u"email": data['email']})
                    translated_error_msg = self.context.translate(error_msg)
                    raise WidgetActionExecutionError(
                        'email', Invalid(translated_error_msg))
                else:
                    error_msg = _(
                        u"mailchimp_error_msg",
                        default=u"Could not subscribe to newsletter. "
                        u"Please contact the site administrator: "
                        u"'${error}'",
                        mapping={u"error": error})
                    translated_error_msg = self.context.translate(error_msg)
                    raise ActionExecutionError(Invalid(translated_error_msg))

            IStatusMessage(self.context.REQUEST).addStatusMessage(
                _(u"We have to confirm your email address. In order to " +
                  u"finish the newsletter subscription, click on the link " +
                  u"inside the email we just send you."),
                type="info")
            portal = getSite()
            self.request.response.redirect(portal.absolute_url())
示例#17
0
class NewsletterSubscriberForm(extensible.ExtensibleForm, form.Form):
    fields = field.Fields(INewsletterSubscribe)
    ignoreContext = True
    id = "newsletter-subscriber-form"
    label = _(u"Subscribe to newsletter")

    def updateActions(self):
        super(NewsletterSubscriberForm, self).updateActions()
        self.actions['subscribe'].addClass('context')

    def updateFields(self):
        super(NewsletterSubscriberForm, self).updateFields()
        self.fields['interest_groups'].widgetFactory = CheckBoxFieldWidget
        self.fields['email_type'].widgetFactory = RadioFieldWidget

    def updateWidgets(self):
        super(NewsletterSubscriberForm, self).updateWidgets()
        widgets = self.widgets
        registry = getUtility(IRegistry)
        self.mailchimp_settings = registry.forInterface(IMailchimpSettings)
        self.mailchimp = getUtility(IMailchimpLocator)

        # Show/hide mail format option widget
        if not self.mailchimp_settings.email_type_is_optional:
            widgets['email_type'].mode = HIDDEN_MODE

        # Retrieve the list id either from the request/form or fall back to
        # the default_list setting.
        list_id = self.context.REQUEST.get('list_id')
        list_id = list_id or self.request.form.get('form.widgets.list_id')
        list_id = list_id or self.mailchimp_settings.default_list
        widgets['list_id'].mode = HIDDEN_MODE
        widgets['list_id'].value = list_id

        # Show/hide interest_groups widget
        self.available_interest_groups = self.mailchimp.groups(list_id=list_id)
        if not self.available_interest_groups or \
           self.available_interest_groups.get('total_items') == 0:
            widgets['interest_groups'].mode = HIDDEN_MODE

        preselected_groups = self.request.get('preselected_group', [])
        for group_index in preselected_groups:
            group_index = int(group_index)
            widgets['interest_groups'].items[group_index]['checked'] = True

    @button.buttonAndHandler(
        _(u"subscribe_to_newsletter_button", default=u"Subscribe"),
        name='subscribe',
    )
    def handleApply(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        # Retrieve list_id either from a hidden field in the form or fetch
        # the first list from mailchimp.
        list_id = data.get('list_id') or self.mailchimp.default_list_id()
        # list_id has to be updated for merge_fields=data to work if None
        if "list_id" in data and not data.get('list_id'):
            data['list_id'] = list_id

        # interest groups
        interests = {}
        interest_groups = data.pop('interest_groups', [])
        if self.available_interest_groups and interest_groups:
            # Create dictionary with as keys the interest groups, and as
            # values always True.
            interests = dict.fromkeys(interest_groups, True)

        # Use email_type if one is provided by the form, if not choose the
        # default email type from the control panel settings.
        email_type = data.get(
            'email_type') or self.mailchimp_settings.email_type

        # Subscribe to MailChimp list
        try:
            self.mailchimp.subscribe(
                list_id=list_id,
                email_address=data['email'],
                email_type=email_type,
                interests=interests,
                merge_fields=data,
            )
        except MailChimpException as error:
            return self.handle_error(error, data)

        if self.mailchimp_settings.double_optin:
            message = _(
                u"We have to confirm your email address. In order to " +
                u"finish the newsletter subscription, click on the link " +
                u"inside the email we just send you.")
        else:
            message = _(
                u"You have been subscribed to our newsletter succesfully.")

        IStatusMessage(self.context.REQUEST).addStatusMessage(message,
                                                              type="info")
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        site = getNavigationRootObject(self.context, portal)
        self.request.response.redirect(site.absolute_url())

    def handle_error(self, error, data):
        # Current api v3 documentation only lists errors in the 400 and 500
        # range.  The 400 code can mean a lot of things...
        if error.code == 400:
            error_msg = _(
                u"mailchimp_error_msg_already_subscribed",
                default=u"Could not subscribe to newsletter. "
                u"Either the email '${email}' is already subscribed "
                u"or something else is wrong. Try again later.",
                mapping={u"email": data['email']},
            )
            translated_error_msg = self.context.translate(error_msg)
            raise WidgetActionExecutionError('email',
                                             Invalid(translated_error_msg))
        elif error.code == 220:
            error_msg = _(
                u"mailchimp_error_msg_banned",
                default=u"Could not subscribe to newsletter. "
                u"The email '${email}' has been banned.",
                mapping={u"email": data['email']},
            )
            translated_error_msg = self.context.translate(error_msg)
            raise WidgetActionExecutionError('email',
                                             Invalid(translated_error_msg))
        else:
            error_msg = _(
                u"mailchimp_error_msg",
                default=u"Could not subscribe to newsletter. "
                u"Please contact the site administrator: "
                u"'${error}'",
                mapping={u"error": error},
            )
            translated_error_msg = self.context.translate(error_msg)
            raise ActionExecutionError(Invalid(translated_error_msg))
class IMailchimpSettings(Interface):
    """Global mailchimp settings. This describes records stored in the
    configuration registry and obtainable via plone.registry.
    """

    api_key = schema.TextLine(
        title=_(u"MailChimp API Key"),
        description=_(u"help_api_key",
                      default=u"Enter in your MailChimp key here (.e.g. " +
                      "'8b785dcabe4b5aa24ef84201ea7dcded-us4'). Log into " +
                      "mailchimp.com, go to account -> extras -> API Keys & " +
                      "Authorized Apps and copy the API Key to this field."),
        default=u"",
        required=True)

    debug = schema.Bool(
        title=_(u"Debug MailChimp"),
        description=_(u"help_debug",
                      default=u""),
        required=True,
        default=False)

    ssl = schema.Bool(
        title=_(u"SSL"),
        description=_(u"help_ssl",
                      default=u""),
        required=True,
        default=True)

    cache_sec = schema.Int(
        title=_(u"Cache Sec"),
        description=_(u"help_cache_sec",
                      default=u""),
        required=True,
        default=500)

    available_fields = schema.Choice(
        title=_(u"Available fields"),
        description=_(u"help_available_fields",
                      default=u""),
        vocabulary=available_fields,
        required=False)

    lists_email_type = schema.TextLine(
        title=_(u"lists_email_type"),
        description=_(u"help_lists_email_type",
                      default=u""),
        required=True,
        default=u'html',)

    lists_double_optin = schema.Bool(
        title=_(u"lists_double_optin"),
        description=_(u"help_lists_double_optin",
                      default=u""),
        required=True,
        default=True)

    lists_update_existing = schema.Bool(
        title=_(u"lists_update_existing"),
        description=_(u"help_lists_update_existing",
                      default=u""),
        required=True,
        default=False)

    lists_replace_interests = schema.Bool(
        title=_(u"lists_replace_interests"),
        description=_(u"help_lists_replace_interests",
                      default=u""),
        required=True,
        default=True)

    @invariant
    def valid_api_key(obj):
        registry = getUtility(IRegistry)
        mailchimp_settings = registry.forInterface(IMailchimpSettings)
        if len(mailchimp_settings.api_key) == 0:
            return
        mailchimp = PostMonkey(mailchimp_settings.api_key)
        try:
            return mailchimp.ping()
        except:
            raise Invalid(u"Your MailChimp API key is not valid. Please go " +
                "to mailchimp.com and check your API key.")
示例#19
0
class IMailchimpSettings(Interface):
    """Global mailchimp settings. This describes records stored in the
    configuration registry and obtainable via plone.registry.
    """

    api_key = schema.TextLine(
        title=_(u"MailChimp API Key"),
        description=_(
            u"help_api_key",
            default=u"Enter in your MailChimp key here (.e.g. " +
            u"'8b785dcabe4b5aa24ef84201ea7dcded-us4'). Log into " +
            u"mailchimp.com, go to account -> extras -> API Keys & " +
            u"Authorized Apps and copy the API Key to this field."),
        default=u"",
        required=True)

    email_type = schema.Choice(
        title=_(u"email_type"),
        description=_(
            u"help_email_type",
            default=u"Email type preference for the email (html, text, or "
            u"mobile defaults to html)"),
        vocabulary="collective.mailchimp.vocabularies.EmailType",
        default="text",
        required=True,
    )

    email_type_is_optional = schema.Bool(
        title=_(u"email_type_is_optional"),
        description=_(
            u"help_email_type_is_optional",
            default=u"Let users choose their email type preference in the "
            u"newsletter subscription form."),
        required=True,
        default=False)

    default_list = schema.Choice(
        title=_(u"default_list"),
        description=_(
            u"help_default_list",
            default=u"Default list which is used in the @@newsletter view if "
            u"no list_id param is provided."),
        vocabulary="collective.mailchimp.vocabularies.AvailableLists",
        required=False,
    )

    double_optin = schema.Bool(
        title=_(u"double_optin"),
        description=_(
            u"help_double_optin",
            default=u"Flag to control whether a double opt-in confirmation "
            u"message is sent, defaults to true. Abusing this may "
            u"cause your account to be suspended."),
        required=True,
        default=True)

    update_existing = schema.Bool(
        title=_(u"update_existing"),
        description=_(
            u"help_update_existing",
            default=u"Flag to control whether existing subscribers should be "
            u"updated instead of throwing an error, defaults to false"),
        required=True,
        default=False)

    replace_interests = schema.Bool(
        title=_(u"replace_interests"),
        description=_(
            u"help_replace_interests",
            default=u"Flag to determine whether we replace the interest "
            u"groups with the groups provided or we add the provided"
            u"groups to the member's interest groups (optional, "
            u"defaults to true)"),
        required=True,
        default=True)

    send_welcome = schema.Bool(
        title=_(u"send_welcome"),
        description=_(
            u"help_send_welcome",
            default=u"If your double_optin is false and this is true, we "
            u"will send your lists Welcome Email if this subscribe "
            u"succeeds - this will *not* fire if we end up updating "
            u"an existing subscriber. If double_optin is true, this "
            u"has no effect. defaults to false."),
        required=True,
        default=False)

    @invariant
    def valid_api_key(data):
        if len(data.api_key) == 0:
            return
        mailchimp = PostMonkey(data.api_key)
        try:
            return mailchimp.ping()
        except:
            raise Invalid(u"Your MailChimp API key is not valid. Please go " +
                          u"to mailchimp.com and check your API key.")
示例#20
0
class NotAnEmailAddress(schema.ValidationError):
    __doc__ = _(u"Invalid email address")
    def handleApply(self, action):
        data, errors = self.extractData()
        if 'email' in data:
            mailchimp = getUtility(IMailchimpLocator)

            # Retrieve list_id either from a hidden field in the form or fetch
            # the first list from mailchimp.
            if 'list_id' in data:
                list_id = data['list_id']
            else:
                list_id = mailchimp.default_list_id()

            # Groupings
            if 'interest_groups' in data:
                interest_grouping = mailchimp.groups(list_id=list_id)
                if interest_grouping and data['interest_groups']:
                    data['groupings'] = [
                        {
                            'id': interest_grouping['id'],
                            'groups': ",".join(data['interest_groups']),
                        }
                    ]

            # Use email_type if one is provided by the form, if not choose the
            # default email type from the control panel settings.
            if 'email_type' in data:
                email_type = data['email_type']
            else:
                email_type = None
            # Subscribe to MailChimp list
            try:
                mailchimp.subscribe(
                    list_id=list_id,
                    email_address=data['email'],
                    merge_vars=data,
                    email_type=email_type,
                )
            except MailChimpException, error:
                if error.code == 214:
                    error_msg = _(
                        u"mailchimp_error_msg_already_subscribed",
                        default=u"Could not subscribe to newsletter. "
                                u"The email '${email}' is already subscribed.",
                        mapping={
                            u"email": data['email']
                        }
                    )
                    translated_error_msg = self.context.translate(error_msg)
                    raise WidgetActionExecutionError(
                        'email',
                        Invalid(translated_error_msg)
                    )
                elif error.code == 220:
                    error_msg = _(
                        u"mailchimp_error_msg_banned",
                        default=u"Could not subscribe to newsletter. "
                                u"The email '${email}' has been banned.",
                        mapping={
                            u"email": data['email']
                        }
                    )
                    translated_error_msg = self.context.translate(error_msg)
                    raise WidgetActionExecutionError(
                        'email',
                        Invalid(translated_error_msg)
                    )
                else:
                    error_msg = _(
                        u"mailchimp_error_msg",
                        default=u"Could not subscribe to newsletter. "
                                u"Please contact the site administrator: "
                                u"'${error}'",
                        mapping={
                            u"error": error
                        }
                    )
                    translated_error_msg = self.context.translate(error_msg)
                    raise ActionExecutionError(
                        Invalid(translated_error_msg)
                    )

            IStatusMessage(self.context.REQUEST).addStatusMessage(_(
                u"We have to confirm your email address. In order to " +
                u"finish the newsletter subscription, click on the link " +
                u"inside the email we just send you."),
                type="info"
            )
            portal = getSite()
            self.request.response.redirect(portal.absolute_url())
示例#22
0
import re

from postmonkey import PostMonkey

from zope import schema
from zope.interface import Interface
from zope.interface import invariant
from zope.interface import Invalid
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm

from collective.mailchimp import _

available_fields = SimpleVocabulary([
    SimpleTerm(value=u'subscriber_list', title=_(u'Subscriber list')),
    SimpleTerm(value=u'email', title=_(u'E-Mail'))
])


class ICollectiveMailchimp(Interface):
    """Marker interface that defines a ZTK browser layer. We can reference
    this in the 'layer' attribute of ZCML <browser:* /> directives to ensure
    the relevant registration only takes effect when this theme is installed.

    The browser layer is installed via the browserlayer.xml GenericSetup
    import step.
    """


class NotAnEmailAddress(schema.ValidationError):
    __doc__ = _(u"Invalid email address")
class UnsubscribeNewsletterForm(extensible.ExtensibleForm, form.Form):

    fields = field.Fields(INewsletterUnsubscribe)
    ignoreContext = True
    id = "newsletter-unsubscriber-form"
    label = _(
        u'mailchimp_unsubscribe_newsletter_form_title',
        default=u"Unsubscribe from newsletter",
    )

    description = _(u'mailchimp_unsubscribe_newsletter_form_description',
                    default='')

    def updateFields(self):
        super(UnsubscribeNewsletterForm, self).updateFields()
        self.fields['interest_groups'].widgetFactory = CheckBoxFieldWidget

    def updateWidgets(self):
        super(UnsubscribeNewsletterForm, self).updateWidgets()
        registry = getUtility(IRegistry)
        self.mailchimp_settings = registry.forInterface(IMailchimpSettings)
        self.mailchimp = getUtility(IMailchimpLocator)

        # Set a given email address
        if self.request.get('email'):
            self.widgets['email'].value = self.request['email']

        # Retrieve the list id either from the request/form or fall back to
        # the default_list setting.
        list_id = self.context.REQUEST.get('list_id')
        list_id = list_id or self.request.form.get('form.widgets.list_id')
        list_id = list_id or self.mailchimp_settings.default_list
        self.widgets['list_id'].mode = HIDDEN_MODE
        self.widgets['list_id'].value = list_id

        # Show/hide interest_groups widget
        self.available_interest_groups = self.mailchimp.groups(list_id=list_id)
        if not self.available_interest_groups:
            self.widgets['interest_groups'].mode = HIDDEN_MODE

    @button.buttonAndHandler(
        _(u"unsubscribe_newsletter_button", default=u"Unsubscribe"),
        name='unsubscribe',
    )
    def handle_unsubscribe(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        list_id = data.get('list_id') or self.mailchimp.default_list_id()
        email = data['email']

        update_data = {}
        if data.get('unsubscribe'):
            update_data['status'] = 'unsubscribed'
        else:
            interest_groups = {}
            if data.get('interest_groups'):
                for group in data.get('interest_groups', []):
                    interest_groups[group] = False
                update_data['interests'] = interest_groups

        try:
            self.mailchimp.update_subscriber(list_id,
                                             email_address=email,
                                             **update_data)
        except MailChimpException as error:
            if error.code != 404:
                # If a subscriber did not exist we don't want to announce
                # it. Treat only != 404 as an error.
                IStatusMessage(self.request).addStatusMessage(
                    _(
                        u'mailchimp_unsubscribe_error_msg',
                        default=u'We could not unsubscribe you from '
                        u'the newsletter. '
                        u"Please contact the site administrator: "
                        u"'${error}'",
                        mapping={u"error": error},
                    ),
                    type="info",
                )

        IStatusMessage(self.request).addStatusMessage(
            _(
                u'mailchimp_unsubscribed_msg',
                default=(u'Thank you. You have been unsubscribed from '
                         u'the Newsletter.'),
            ),
            type="info",
        )

        portal = getSite()
        self.request.response.redirect(portal.absolute_url())
# -*- coding: utf-8 -*-
from collective.mailchimp import _
from zope import schema
from zope.interface import Interface
from zope.interface import Invalid
from zope.interface import invariant
from zope.schema.vocabulary import SimpleTerm
from zope.schema.vocabulary import SimpleVocabulary

import re


available_fields = SimpleVocabulary(
    [
        SimpleTerm(value=u'subscriber_list', title=_(u'Subscriber list')),
        SimpleTerm(value=u'email', title=_(u'E-Mail')),
    ]
)


class ICollectiveMailchimp(Interface):
    """Marker interface that defines a ZTK browser layer. We can reference
    this in the 'layer' attribute of ZCML <browser:* /> directives to ensure
    the relevant registration only takes effect when this theme is installed.

    The browser layer is installed via the browserlayer.xml GenericSetup
    import step.
    """


class NotAnEmailAddress(schema.ValidationError):
import re

from zope import schema
from zope.interface import Interface
from zope.interface import invariant
from zope.interface import Invalid
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm

from collective.mailchimp import _

available_fields = SimpleVocabulary(
    [SimpleTerm(value=u"subscriber_list", title=_(u"Subscriber list")), SimpleTerm(value=u"email", title=_(u"E-Mail"))]
)


class ICollectiveMailchimp(Interface):
    """Marker interface that defines a ZTK browser layer. We can reference
    this in the 'layer' attribute of ZCML <browser:* /> directives to ensure
    the relevant registration only takes effect when this theme is installed.

    The browser layer is installed via the browserlayer.xml GenericSetup
    import step.
    """


class NotAnEmailAddress(schema.ValidationError):
    __doc__ = _(u"Invalid email address")


check_email = re.compile(r"[a-zA-Z0-9._%-]+@([a-zA-Z0-9-]+.)*[a-zA-Z]{2,4}").match
示例#26
0
    def handleApply(self, action):
        data, errors = self.extractData()
        if 'email' in data:
            mailchimp = getUtility(IMailchimpLocator)

            # Retrieve list_id either from a hidden field in the form or fetch
            # the first list from mailchimp.
            if 'list_id' in data:
                list_id = data['list_id']
            else:
                list_id = mailchimp.default_list_id()

            # Groupings
            if 'interest_groups' in data:
                interest_grouping = mailchimp.groups(list_id=list_id)
                if interest_grouping and data['interest_groups']:
                    data['groupings'] = [{
                        'id':
                        interest_grouping['id'],
                        'groups':
                        ",".join(data['interest_groups']),
                    }]

            # Use email_type if one is provided by the form, if not choose the
            # default email type from the control panel settings.
            if 'email_type' in data:
                email_type = data['email_type']
            else:
                email_type = None
            # Subscribe to MailChimp list
            try:
                mailchimp.subscribe(
                    list_id=list_id,
                    email_address=data['email'],
                    merge_vars=data,
                    email_type=email_type,
                )
            except MailChimpException, error:
                if error.code == 214:
                    error_msg = _(
                        u"mailchimp_error_msg_already_subscribed",
                        default=u"Could not subscribe to newsletter. "
                        u"The email '${email}' is already subscribed.",
                        mapping={u"email": data['email']})
                    translated_error_msg = self.context.translate(error_msg)
                    raise WidgetActionExecutionError(
                        'email', Invalid(translated_error_msg))
                elif error.code == 220:
                    error_msg = _(
                        u"mailchimp_error_msg_banned",
                        default=u"Could not subscribe to newsletter. "
                        u"The email '${email}' has been banned.",
                        mapping={u"email": data['email']})
                    translated_error_msg = self.context.translate(error_msg)
                    raise WidgetActionExecutionError(
                        'email', Invalid(translated_error_msg))
                else:
                    error_msg = _(
                        u"mailchimp_error_msg",
                        default=u"Could not subscribe to newsletter. "
                        u"Please contact the site administrator: "
                        u"'${error}'",
                        mapping={u"error": error})
                    translated_error_msg = self.context.translate(error_msg)
                    raise ActionExecutionError(Invalid(translated_error_msg))

            IStatusMessage(self.context.REQUEST).addStatusMessage(
                _(u"We have to confirm your email address. In order to " +
                  u"finish the newsletter subscription, click on the link " +
                  u"inside the email we just send you."),
                type="info")
            portal = getSite()
            self.request.response.redirect(portal.absolute_url())
示例#27
0
class NewsletterSubscriberForm(extensible.ExtensibleForm, form.Form):
    fields = field.Fields(INewsletterSubscribe)
    ignoreContext = True
    id = "newsletter-subscriber-form"
    label = _(u"Subscribe to newsletter")

    def updateActions(self):
        super(NewsletterSubscriberForm, self).updateActions()
        self.actions['subscribe'].addClass('context')

    def updateFields(self):
        super(NewsletterSubscriberForm, self).updateFields()
        self.fields['interest_groups'].widgetFactory = \
            CheckBoxFieldWidget
        self.fields['email_type'].widgetFactory = \
            RadioFieldWidget

    def updateWidgets(self):
        super(NewsletterSubscriberForm, self).updateWidgets()
        # Show/hide mail format option widget
        registry = getUtility(IRegistry)
        mailchimp_settings = registry.forInterface(IMailchimpSettings)
        if not mailchimp_settings.email_type_is_optional:
            self.widgets['email_type'].mode = HIDDEN_MODE
        # Retrieve the list id either from the request/form or fall back to
        # the default_list setting.
        if 'list_id' in self.context.REQUEST:
            list_id = self.context.REQUEST['list_id']
        elif 'form.widgets.list_id' in self.request.form:
            list_id = self.request.form['form.widgets.list_id']
        else:
            list_id = mailchimp_settings.default_list
        self.widgets['list_id'].mode = HIDDEN_MODE
        self.widgets['list_id'].value = list_id
        # Show/hide interest_groups widget
        mailchimp = getUtility(IMailchimpLocator)
        groups = mailchimp.groups(list_id=list_id)
        if not groups:
            self.widgets['interest_groups'].mode = HIDDEN_MODE
        if 'preselect_group' in self.context.REQUEST:
            for group_index in self.request['preselect_group']:
                group_index = int(group_index)
                self.widgets['interest_groups']\
                    .items[group_index]['checked'] = True

    @button.buttonAndHandler(_(u"subscribe_to_newsletter_button",
                               default=u"Subscribe"),
                             name='subscribe')
    def handleApply(self, action):
        data, errors = self.extractData()
        if 'email' not in data:
            return
        mailchimp = getUtility(IMailchimpLocator)
        # Retrieve list_id either from a hidden field in the form or fetch
        # the first list from mailchimp.
        if 'list_id' in data and data['list_id'] is not None:
            list_id = data['list_id']
        else:
            list_id = mailchimp.default_list_id()

        # Groupings
        interests = {}
        if 'interest_groups' in data and data['interest_groups'] is not None:
            interest_grouping = mailchimp.groups(list_id=list_id)
            if interest_grouping and data['interest_groups']:
                # Create dictionary with as keys the interest groups, and as
                # values always True.
                interests = dict.fromkeys(data['interest_groups'], True)

        # Use email_type if one is provided by the form, if not choose the
        # default email type from the control panel settings.
        if 'email_type' in data:
            email_type = data['email_type']
        else:
            email_type = 'HTML'
        # Subscribe to MailChimp list
        try:
            mailchimp.subscribe(
                list_id=list_id,
                email_address=data['email'],
                email_type=email_type,
                interests=interests
            )
        except MailChimpException as error:
            return self.handle_error(error, data)
        registry = getUtility(IRegistry)
        mailchimp_settings = registry.forInterface(IMailchimpSettings)
        if mailchimp_settings.double_optin:
            message = _(
                u"We have to confirm your email address. In order to " +
                u"finish the newsletter subscription, click on the link " +
                u"inside the email we just send you.")
        else:
            message = _(
                u"You have been subscribed to our newsletter succesfully.")
        IStatusMessage(self.context.REQUEST).addStatusMessage(
            message, type="info")
        portal = getSite()
        self.request.response.redirect(portal.absolute_url())

    def handle_error(self, error, data):
        # Current api v3 documentation only lists errors in the 400 and 500
        # range.  The 400 code can mean a lot of things...
        if error.code == 400:
            error_msg = _(
                u"mailchimp_error_msg_already_subscribed",
                default=u"Could not subscribe to newsletter. "
                        u"Either the email '${email}' is already subscribed "
                        u"or something else is wrong. Try again later.",
                mapping={u"email": data['email']})
            translated_error_msg = self.context.translate(error_msg)
            raise WidgetActionExecutionError(
                'email',
                Invalid(translated_error_msg)
            )
        elif error.code == 220:
            error_msg = _(
                u"mailchimp_error_msg_banned",
                default=u"Could not subscribe to newsletter. "
                        u"The email '${email}' has been banned.",
                mapping={u"email": data['email']})
            translated_error_msg = self.context.translate(error_msg)
            raise WidgetActionExecutionError(
                'email',
                Invalid(translated_error_msg)
            )
        else:
            error_msg = _(
                u"mailchimp_error_msg",
                default=u"Could not subscribe to newsletter. "
                        u"Please contact the site administrator: "
                        u"'${error}'",
                mapping={u"error": error})
            translated_error_msg = self.context.translate(error_msg)
            raise ActionExecutionError(
                Invalid(translated_error_msg)
            )