class AbstractLetterProcessor(object): discard_tag = '' def make_letter(self, email): """ Make 1 letter without mailgun headers """ body = self.letter_body(email) params = self.letter_params() return GlobalEmailStack(email=email, body=body, **params) def create_letters(self): params = self.letter_params() params['headers'].update(self.mailgun_headers()) with Transaction() as tx: for email in self.get_emails(): body = self.letter_body(email) GlobalEmailStack.objects.create(email=email, body=body, **params) self.post_create() tx.commit() def get_emails(self): raise NotImplementedError def letter_body(self, email): raise NotImplementedError def letter_params(self): assert self.discard_tag return {'mimetype': 'text/html', 'headers': {'Precedence': 'bulk'}, 'tag': self.discard_tag} def mailgun_headers(self): return {'X-Mailgun-Tag': self.discard_tag, 'List-Unsubscribe': '<%unsubscribe_email%>'} def post_create(self): pass class DispatchLetterProcessor(AbstractLetterProcessor): discard_tag = 'dispatch' def __init__(self, dispatch): self.dispatch = dispatch def get_emails(self): return self.dispatch.condition.emails_list() def letter_body(self, email): context = {'dispatch': self.dispatch, 'discard': DiscardedRecipient.get_by_email(email)} with override(self.dispatch.signature_lang): return render_to_string('mailing/letter-dispatch.html', context) def letter_params(self): params = super(DispatchLetterProcessor, self).letter_params() params['account'] = 'dispatch' params['subject'] = self.dispatch.subject params['attachments'] = self._attachments() params['headers']['Reply-To'] = self.dispatch.owner.email return params def _attachments(self): files = [] for fl in self.dispatch.attachments: assert fl['file_name'], 'empty attachment filename Dispatch #%s' % self.dispatch.pk files.append({'filename': fl['file_name'], 'content': TranioFile(fl['file_path']).read()}) return files def mailgun_headers(self): headers = super(DispatchLetterProcessor, self).mailgun_headers() headers['List-id'] = '<%s>' % self.dispatch.mailgun_id headers['X-Mailgun-Campaign-Id'] = self.dispatch.mailgun_id headers['X-Postmaster-Msgtype'] = self.dispatch.mailgun_id.replace('-', '_') return headers def post_create(self): self.dispatch.condition.sent_to = u' '.join(self.get_emails()) self.dispatch.condition.save() self.dispatch.status = Dispatch.STATUS_DONE self.dispatch.save() # insides copy self.make_letter('[email protected]').save() self.make_letter('[email protected]').save() self.make_letter('[email protected]').save() class SmiLetterProcessor(AbstractLetterProcessor): discard_tag = 'smi' def __init__(self, smi_delivery): self.sd = smi_delivery self.shipments = None def get_emails(self): self.sd.smi_expand_emails() self.shipments = self.sd.shipments.filter(sended_at=None, rejected=False) return filter(bool, self.shipments.values_list('email', flat=True)) def letter_body(self, email): context = {'delivery': self.sd, 'discard': DiscardedRecipient.get_by_email(email)} template = self.sd.template_map[self.sd.lang] with override(self.sd.lang): return render_to_string(template, context) def letter_params(self): params = super(SmiLetterProcessor, self).letter_params() params['account'] = self.sd.get_accounts()[0]['name'] params['subject'] = self.sd.subject params['attachments'] = self._attachments() params['headers']['Reply-To'] = u'<[email protected]>' return params def _attachments(self): files = [] for fl in self.sd.smi_files.all(): if os.path.isfile(fl.file.path): files.append({'filename': os.path.basename(fl.file.path), 'content': fl.file.read()}) return files def mailgun_headers(self): today = datetime.date.today() headers = super(SmiLetterProcessor, self).mailgun_headers() headers['List-id'] = '<smi-newsletter_%s>' % today.strftime('%Y-%m') headers['X-Mailgun-Campaign-Id'] = 'pr_tranio_ru_from_smi-newsletter' headers['X-Postmaster-Msgtype'] = 'smi_newsletter_%s' % today.strftime('%Y_%m') return headers def post_create(self): self.shipments.update(sended_at=datetime.datetime.now(), send_error=None) self.sd.completed = True self.sd.save()