Is it possible to add a custom EMAIL_BACKEND?

I need to set a custom (generated) Envelope-From for outgoing mails in order to properly handle bounces. The best way would be a configurable script that has FROM: and TO: as arguments and gets the mail via stdin.

Something like this:

/usr/local/bin/mailscript <from> <to> [to]…

Is it possible to provide my own EmailBackend class in a way that it survives an upgrade of seafile?

Cheers

Can anybody help me with this, please? I want to avoid writing a milter for this.

It should be possible to create something that you just put somewhere in the PYTHONPATH and refer to it in seahub_settings.py.
But you need to consult the Django documentation for any specific instructions.

thank you schlarbm.

here is my EmailBackend class for anyone that is interested

  • put it somewhere in the PYTHONPATH
  • add EMAIL_BACKEND and EMAIL_SENDPROG to seahub_settings.py
  • EMAIL_HOST also has to be present for it to work

this will call EMAIL_SENDPROG with sender and recipient as arguments and pass the mail via stdin

import subprocess
import threading
import os

from django.conf import settings
from django.core.mail.backends.base import BaseEmailBackend
from django.core.mail.message import sanitize_address


class EmailBackend(BaseEmailBackend):
    def __init__(self, fail_silently=False, sendprog=None, **kwargs):
        super(EmailBackend, self).__init__(fail_silently = fail_silently)
        self.sendprog = sendprog or settings.EMAIL_SENDPROG
        self._lock = threading.RLock()


    def send_messages(self, email_messages):
        """
        Sends one or more EmailMessage objects and returns the number of email
        messages sent.
        """
        if not email_messages:
            return

        num_sent = 0

        with self._lock:

            for message in email_messages:

                if self._send(message):
                    num_sent += 1

        return num_sent


    def _send(self, email_message):
        """A helper method that does the actual sending."""

        if not email_message.recipients():
            return False

        from_email = sanitize_address(email_message.from_email, email_message.encoding)
        recipients = [sanitize_address(addr, email_message.encoding)
                      for addr in email_message.recipients()]
        message = email_message.message()

        args = [ self.sendprog, from_email ] + recipients

        try:

            with open(os.devnull, 'wb') as DEVNULL:
                proc = subprocess.Popen(args, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=DEVNULL, close_fds=True)

            errorout = proc.communicate(input=message.as_bytes(linesep='\r\n'))[1]

            proc.wait()
            if proc.returncode != 0:
                return False
                #FIXME: raise appropriate exception

        except OSError as e:
            if not self.fail_silently:
                raise

            return False

        return True

i have to do some more testing but it seems to work