Ejemplo n.º 1
0
 def test_choices_enum(self):
     choices_num = ChoicesEnum(
         ('A', 'a'),
         ('B', 'b'),
     )
     assert_equal(choices_num.A, 'A')
     assert_equal(choices_num.B, 'B')
     assert_equal(list(choices_num.choices), [('A', 'a'), ('B', 'b')])
     assert_equal(tuple(choices_num.all), ('A', 'B'))
     assert_equal(choices_num.get_label('A'), 'a')
     assert_equal(choices_num.get_label('B'), 'b')
Ejemplo n.º 2
0
 def test_choices_enum_with_distinct_key_and_value_should_return_right_values_and_choices(self):
     choices_num = ChoicesEnum(
         ('A', 'label a', 'c'),
         ('B', 'label b', 'd'),
     )
     assert_equal(choices_num.A, 'c')
     assert_equal(choices_num.B, 'd')
     assert_equal(list(choices_num.choices), [('c', 'label a'), ('d', 'label b')])
     assert_equal(choices_num.all, ('c', 'd'))
     assert_equal(choices_num.get_label('c'), 'label a')
     assert_equal(choices_num.get_label('d'), 'label b')
Ejemplo n.º 3
0
 def test_choices_enum_should_return_right_values_and_choices(self):
     choices_num = ChoicesEnum(
         ('A', 'label a'),
         ('B', 'label b'),
     )
     assert_equal(choices_num.A, 'A')
     assert_equal(choices_num.B, 'B')
     assert_equal(list(choices_num.choices), [('A', 'label a'), ('B', 'label b')])
     assert_equal(choices_num.all, ('A', 'B'))
     assert_equal(choices_num.get_label('A'), 'label a')
     assert_equal(choices_num.get_label('B'), 'label b')
Ejemplo n.º 4
0
 def test_choices_enum_should_return_right_values_and_choices(self):
     choices_num = ChoicesEnum(
         ('A', 'label a'),
         ('B', 'label b'),
     )
     assert_equal(choices_num.A, 'A')
     assert_equal(choices_num.B, 'B')
     assert_equal(list(choices_num.choices), [('A', 'label a'),
                                              ('B', 'label b')])
     assert_equal(choices_num.all, ('A', 'B'))
     assert_equal(choices_num.get_label('A'), 'label a')
     assert_equal(choices_num.get_label('B'), 'label b')
Ejemplo n.º 5
0
 def test_choices_enum_with_distinct_key_and_value_should_return_right_values_and_choices(
         self):
     choices_num = ChoicesEnum(
         ('A', 'label a', 'c'),
         ('B', 'label b', 'd'),
     )
     assert_equal(choices_num.A, 'c')
     assert_equal(choices_num.B, 'd')
     assert_equal(list(choices_num.choices), [('c', 'label a'),
                                              ('d', 'label b')])
     assert_equal(choices_num.all, ('c', 'd'))
     assert_equal(choices_num.get_label('c'), 'label a')
     assert_equal(choices_num.get_label('d'), 'label b')
Ejemplo n.º 6
0
class TwilioSMSBackend(SMSBackend):
    """
    SMS backend implementing twilio service https://www.twilio.com/
    """

    twilio_client = None

    STATE = ChoicesEnum(
        ('ACCEPTED', _l('accepted'), 'accepted'),
        ('QUEUED', _l('queued'), 'queued'),
        ('SENDING', _l('sending'), 'sending'),
        ('SENT', _l('sent'), 'sent'),
        ('DELIVERED', _l('delivered'),
         'delivered'),  # TODO implement checking delivery status
        ('RECEIVED', _l('received'), 'received'),
        ('FAILED', _l('failed'), 'failed'),
        ('UNDELIVERED', _l('undelivered'), 'undelivered'),
    )

    STATES_MAPPING = {
        STATE.ACCEPTED: OutputSMSMessage.STATE.SENT,
        STATE.QUEUED: OutputSMSMessage.STATE.SENT,
        STATE.SENDING: OutputSMSMessage.STATE.SENT,
        STATE.SENT: OutputSMSMessage.STATE.SENT,
        STATE.DELIVERED: OutputSMSMessage.STATE.DELIVERED,
        STATE.RECEIVED: OutputSMSMessage.STATE.DELIVERED,
        STATE.FAILED: OutputSMSMessage.STATE.ERROR,
        STATE.UNDELIVERED: OutputSMSMessage.STATE.ERROR,
    }

    def _get_twilio_client(self):
        """
        Connect to the twilio service
        """
        if not self.twilio_client:
            self.twilio_client = TwilioRestClient(settings.TWILIO_ACCOUNT_SID,
                                                  settings.TWILIO_AUTH_TOKEN)
        return self.twilio_client

    def publish_message(self, message):
        """
        Method uses twilio REST client for sending SMS message
        :param message: SMS message
        """
        client = self._get_twilio_client()
        try:
            result = client.messages.create(from_=settings.TWILIO_SENDER,
                                            to=force_text(message.recipient),
                                            body=message.content)
            self.update_message(
                message,
                state=self.STATES_MAPPING[result.status],
                error=result.error_message if result.error_message else None,
                sent_at=timezone.now())
        except Exception as ex:
            self.update_message(message,
                                state=OutputSMSMessage.STATE.ERROR,
                                error=force_text(ex))
Ejemplo n.º 7
0
class MandrillEmailBackend(EmailBackend):
    """
    E-mail backend implementing Mandrill service (https://mandrillapp.com/api/docs/index.python.html).
    """

    MANDRILL_STATES = ChoicesEnum(
        ('SENT', _('sent')),
        ('QUEUED', _('queued')),
        ('SCHEDULED', _('scheduled')),
        ('REJECTED', _('rejected')),
        ('INVALID', _('invalid')),
    )

    MANDRILL_STATES_MAPPING = {
        MANDRILL_STATES.SENT: EmailMessage.STATE.SENT,
        MANDRILL_STATES.QUEUED: EmailMessage.STATE.SENT,
        MANDRILL_STATES.SCHEDULED: EmailMessage.STATE.SENT,
        MANDRILL_STATES.REJECTED: EmailMessage.STATE.ERROR,
        MANDRILL_STATES.INVALID: EmailMessage.STATE.ERROR,
    }

    def _serialize_attachments(self, message):
        return [{
            'type':
            attachment.content_type,
            'name':
            os.path.basename(attachment.file.name),
            'content':
            base64.b64encode(attachment.file.read()).decode('utf-8')
        } for attachment in message.attachments.all()]

    def publish_message(self, message):
        mandrill_client = mandrill.Mandrill(settings.EMAIL_MANDRILL.KEY)
        mandrill_client.session = generate_session(
            slug='pymess - Mandrill',
            related_objects=(message, ),
            timeout=settings.EMAIL_MANDRILL.TIMEOUT)
        try:
            result = mandrill_client.messages.send(message={
                'to': [{
                    'email': message.recipient
                }],
                'from_email':
                message.sender,
                'from_name':
                message.sender_name,
                'html':
                message.content,
                'subject':
                message.subject,
                'headers':
                settings.EMAIL_MANDRILL.HEADERS,
                'track_opens':
                settings.EMAIL_MANDRILL.TRACK_OPENS,
                'auto_text':
                settings.EMAIL_MANDRILL.AUTO_TEXT,
                'inline_css':
                settings.EMAIL_MANDRILL.INLINE_CSS,
                'url_strip_qs':
                settings.EMAIL_MANDRILL.URL_STRIP_QS,
                'preserve_recipients':
                settings.EMAIL_MANDRILL.PRESERVE_RECIPIENTS,
                'view_content_link':
                settings.EMAIL_MANDRILL.VIEW_CONTENT_LINK,
                'async':
                settings.EMAIL_MANDRILL.ASYNC,
                'attachments':
                self._serialize_attachments(message)
            }, )[0]
            mandrill_state = result['status'].upper()
            state = self.MANDRILL_STATES_MAPPING.get(mandrill_state)
            error = self.MANDRILL_STATES.get_label(
                mandrill_state) if state == EmailMessage.STATE.ERROR else None
            if mandrill_state == self.MANDRILL_STATES.REJECTED:
                error += ', mandrill message: "{}"'.format(
                    result['reject_reason'])

            extra_sender_data = message.extra_sender_data or {}
            extra_sender_data['result'] = result
            self.update_message(message,
                                state=state,
                                sent_at=timezone.now(),
                                extra_sender_data=extra_sender_data,
                                error=error)
        except (mandrill.Error, JSONDecodeError,
                requests.exceptions.RequestException) as ex:
            self.update_message(message,
                                state=EmailMessage.STATE.ERROR,
                                error=force_text(ex))
Ejemplo n.º 8
0
class MandrillEmailBackend(EmailBackend):
    """
    E-mail backend implementing Mandrill service (https://mandrillapp.com/api/docs/index.python.html).
    """

    MANDRILL_STATES = ChoicesEnum(
        ('SENT', _('sent')),
        ('QUEUED', _('queued')),
        ('SCHEDULED', _('scheduled')),
        ('REJECTED', _('rejected')),
        ('INVALID', _('invalid')),
    )

    MANDRILL_STATES_MAPPING = {
        MANDRILL_STATES.SENT: EmailMessage.STATE.SENT,
        MANDRILL_STATES.QUEUED: EmailMessage.STATE.SENT,
        MANDRILL_STATES.SCHEDULED: EmailMessage.STATE.SENT,
        MANDRILL_STATES.REJECTED: EmailMessage.STATE.ERROR,
        MANDRILL_STATES.INVALID: EmailMessage.STATE.ERROR,
    }

    config = AttrDict({
        'HEADERS': None,
        'TRACK_OPENS': False,
        'TRACK_CLICKS': False,
        'AUTO_TEXT': False,
        'INLINE_CSS': False,
        'URL_STRIP_QS': False,
        'PRESERVE_RECIPIENTS': False,
        'VIEW_CONTENT_LINK': True,
        'ASYNC': False,
        'TIMEOUT': 5,  # 5s
    })

    def _serialize_attachments(self, message):
        return [{
            'type':
            attachment.content_type,
            'name':
            os.path.basename(attachment.file.name),
            'content':
            base64.b64encode(attachment.file.read()).decode('utf-8')
        } for attachment in message.attachments.all()]

    def _create_client(self, message):
        mandrill_client = mandrill.Mandrill(self.config.KEY)
        mandrill_client.session = generate_session(slug='pymess - Mandrill',
                                                   related_objects=(message, ),
                                                   timeout=self.config.TIMEOUT)
        return mandrill_client

    def publish_message(self, message):
        mandrill_client = self._create_client(message)
        try:
            result = mandrill_client.messages.send(message={
                'to': [{
                    'email': message.recipient
                }],
                'from_email':
                message.sender,
                'from_name':
                message.sender_name,
                'html':
                message.content,
                'subject':
                message.subject,
                'headers':
                self.config.HEADERS,
                'track_opens':
                self.config.TRACK_OPENS,
                'auto_text':
                self.config.AUTO_TEXT,
                'inline_css':
                self.config.INLINE_CSS,
                'url_strip_qs':
                self.config.URL_STRIP_QS,
                'preserve_recipients':
                self.config.PRESERVE_RECIPIENTS,
                'view_content_link':
                self.config.VIEW_CONTENT_LINK,
                'async':
                self.config.ASYNC,
                'attachments':
                self._serialize_attachments(message)
            }, )[0]
            mandrill_state = result['status'].upper()
            state = self.MANDRILL_STATES_MAPPING.get(mandrill_state)
            error = (self.MANDRILL_STATES.get_label(mandrill_state)
                     if state == EmailMessage.STATE.ERROR else None)
            if mandrill_state == self.MANDRILL_STATES.REJECTED:
                error += ', mandrill message: "{}"'.format(
                    result['reject_reason'])

            extra_sender_data = message.extra_sender_data or {}
            extra_sender_data['result'] = result
            self._update_message_after_sending(
                message,
                state=state,
                sent_at=timezone.now(),
                extra_sender_data=extra_sender_data,
                error=error,
                external_id=result.get('_id'))
        except (mandrill.Error, JSONDecodeError,
                requests.exceptions.RequestException) as ex:
            self._update_message_after_sending_error(message, error=str(ex))
            # Do not re-raise caught exception. Re-raise exception causes transaction rollback (lost of information
            # about exception).

    def pull_message_info(self, message):
        if message.external_id:
            mandrill_client = self._create_client(message)
            try:
                info = mandrill_client.messages.info(message.external_id)
                self._update_message(
                    message,
                    extra_sender_data={
                        **message.extra_sender_data, 'info': info
                    },
                    info_changed_at=timezone.now(),
                    update_only_changed_fields=True,
                )
            except mandrill.UnknownMessageError:
                self._update_message(message,
                                     info_changed_at=timezone.now(),
                                     update_only_changed_fields=True)
        else:
            self._update_message(message,
                                 info_changed_at=timezone.now(),
                                 update_only_changed_fields=True)