Add support to the mailing profiles for specifying a "from" address. Closes GitLab issue #522. This commit adds a new backend class property "class_fields" which differs from the normal "fields" property. The "class_fields" property specifies which of the backend fields will be used to initialize a backend's driver class. This is to avoid passing fields that the driver doesn't expect and getting an error. When sending emails, the "send" method will attempt to get a "from" key from the backend data and use that when sending emails. If no "from" key is found a None is passes. Django's behavior in this situation dictates that the "from" value will then be taken from the DEFAULT_FROM_EMAIL setting. Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
from __future__ import unicode_literals
|
|
|
|
from importlib import import_module
|
|
import logging
|
|
|
|
from django.apps import apps
|
|
from django.utils import six
|
|
from django.utils.encoding import force_text
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
__all__ = ('MailerBackend',)
|
|
|
|
|
|
class MailerBackendMetaclass(type):
|
|
_registry = {}
|
|
|
|
def __new__(mcs, name, bases, attrs):
|
|
new_class = super(MailerBackendMetaclass, mcs).__new__(
|
|
mcs, name, bases, attrs
|
|
)
|
|
if not new_class.__module__ == 'mailer.classes':
|
|
mcs._registry[
|
|
'{}.{}'.format(new_class.__module__, name)
|
|
] = new_class
|
|
|
|
return new_class
|
|
|
|
|
|
class MailerBackendBase(object):
|
|
"""
|
|
Base class for the mailing backends. This class is mainly a wrapper
|
|
for other Django backends that adds a few metadata to specify the
|
|
fields it needs to be instanciated at runtime.
|
|
|
|
The fields attribute is a list of dictionaries with the format:
|
|
{
|
|
'name': '' # Field internal name
|
|
'label': '' # Label to show to users
|
|
'class': '' # Field class to use. Field classes are Python dot
|
|
paths to Django's form fields.
|
|
'initial': '' # Field initial value
|
|
'default': '' # Default value.
|
|
}
|
|
|
|
"""
|
|
class_path = '' # Dot path to the actual class that will handle the mail
|
|
fields = {}
|
|
|
|
@classmethod
|
|
def get_class_fields(cls):
|
|
backend_field_list = getattr(cls, 'fields', {}).keys()
|
|
return getattr(cls, 'class_fields', backend_field_list)
|
|
|
|
|
|
class MailerBackend(six.with_metaclass(MailerBackendMetaclass, MailerBackendBase)):
|
|
@classmethod
|
|
def get(cls, name):
|
|
return cls._registry[name]
|
|
|
|
@classmethod
|
|
def get_all(cls):
|
|
return cls._registry
|
|
|
|
@staticmethod
|
|
def initialize():
|
|
for app in apps.get_app_configs():
|
|
try:
|
|
import_module('{}.mailers'.format(app.name))
|
|
except ImportError as exception:
|
|
if force_text(exception) not in ('No module named mailers', 'No module named \'{}.mailers\''.format(app.name)):
|
|
logger.error(
|
|
'Error importing %s mailers.py file; %s', app.name,
|
|
exception
|
|
)
|