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')
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')
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')
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')
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))
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))
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)