diff --git a/mylib/email.py b/mylib/email.py index 5673dc3..ee81a2c 100644 --- a/mylib/email.py +++ b/mylib/email.py @@ -1,5 +1,6 @@ """ Email client to forge and send emails """ +import base64 import email.utils import logging import os @@ -9,6 +10,7 @@ from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText +import magic from mako.template import Template as MakoTemplate from mylib.config import ( @@ -22,6 +24,14 @@ from mylib.config import ( log = logging.getLogger(__name__) +def load_image_as_base64(path): + """Load image file as base64""" + log.debug("Load image file '%s'", path) + with open(path, "rb") as file_desc: + data = file_desc.read() + return f"data:{magic.from_buffer(data, mime=True)};base64, {base64.b64encode(data).decode()}" + + class EmailClient( ConfigurableObject ): # pylint: disable=useless-object-inheritance,too-many-instance-attributes @@ -165,7 +175,7 @@ class EmailClient( continue template_type = "text" if template_type == ".txt" else template_type[1:] if template_name not in self.templates: - self.templates[template_name] = {} + self.templates[template_name] = {"path": templates_path} log.debug("Load email template %s %s from %s", template_name, template_type, filepath) with open(filepath, encoding="utf8") as file_desc: self.templates[template_name][template_type] = MakoTemplate( @@ -239,6 +249,7 @@ class EmailClient( msg["Date"] = email.utils.formatdate(None, True) encoding = encoding if encoding else self._get_option("encoding") if template: + log.debug("Forge email from template %s", template) assert template in self.templates, f"Unknown template {template}" # Handle subject from template if not subject: @@ -264,6 +275,9 @@ class EmailClient( ) if self.templates[template].get("html"): if isinstance(self.templates[template]["html"], MakoTemplate): + template_vars["load_image_as_base64"] = self.template_image_loader( + self.templates[template].get("path") + ) parts.append((self.templates[template]["html"].render(**template_vars), "html")) else: parts.append((self.templates[template]["html"].format(**template_vars), "html")) @@ -296,6 +310,19 @@ class EmailClient( msg.attach(part) return msg + @staticmethod + def template_image_loader(directory_path): + """Return wrapper for the load_image_as_base64 function bind on the template directory""" + + def _load_image_as_base64(path): + return load_image_as_base64( + os.path.join(directory_path, path) + if directory_path and not os.path.isabs(path) + else path + ) + + return _load_image_as_base64 + def send( self, recipients, msg=None, subject=None, just_try=None, cc=None, bcc=None, **forge_args ): diff --git a/mylib/scripts/email_templates/header.svg b/mylib/scripts/email_templates/header.svg new file mode 100644 index 0000000..bb086b8 --- /dev/null +++ b/mylib/scripts/email_templates/header.svg @@ -0,0 +1,62 @@ + + + + + + + + + Header + + diff --git a/mylib/scripts/email_templates/test.html b/mylib/scripts/email_templates/test.html index f9ba261..280638c 100644 --- a/mylib/scripts/email_templates/test.html +++ b/mylib/scripts/email_templates/test.html @@ -1 +1,2 @@ -Just a test email. (sent at ${sent_date}) + +

Just a test email. (sent at ${sent_date})

diff --git a/mylib/scripts/email_test.py b/mylib/scripts/email_test.py index a5419f9..ed036b4 100644 --- a/mylib/scripts/email_test.py +++ b/mylib/scripts/email_test.py @@ -38,19 +38,10 @@ def main(argv=None): # pylint: disable=too-many-locals,too-many-statements "-T", "--template", action="store_true", - dest="template", help="Template name to send (default: test)", default="test", ) - test_opts.add_argument( - "-m", - "--mako", - action="store_true", - dest="test_mako", - help="Test mako templating", - ) - test_opts.add_argument( "--cc", action="store", @@ -93,7 +84,7 @@ def main(argv=None): # pylint: disable=too-many-locals,too-many-statements options.test_to, cc=options.test_cc, bcc=options.test_bcc, - template="test", + template=options.template, sent_date=datetime.datetime.now(), ): log.info("Test email sent") diff --git a/setup.py b/setup.py index 75b1a50..e5e5cd3 100644 --- a/setup.py +++ b/setup.py @@ -22,6 +22,7 @@ extras_require = { "pytz", ], "email": [ + "python-magic", "mako", ], "pgsql": [