Hi, I'm Mike


© Nike Borzov
I’m just a little horsie but I’m an expensive one
Because I pull this massive cart from this to that river bank.
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()