]> git.ipfire.org Git - ipfire.org.git/blobdiff - src/backend/messages.py
Support sending HTML emails
[ipfire.org.git] / src / backend / messages.py
index 28b717c07f2be70f9b40ee6196a7ee3906071061..8063ce399ede36ebe042ea8ddf49468fb29fcbaa 100644 (file)
@@ -1,8 +1,8 @@
 #!/usr/bin/python3
 
 import email
-import email.charset
-import email.mime.nonmultipart
+import email.mime.multipart
+import email.mime.text
 import email.utils
 import logging
 import subprocess
@@ -104,37 +104,46 @@ class Messages(misc.Object):
                }
                namespace.update(kwargs)
 
-               # Create a non-multipart message
-               message = email.mime.nonmultipart.MIMENonMultipart(
-                       "text", "plain", charset="utf-8",
-               )
+               # Create an alternating multipart message to show HTML or text
+               message = email.mime.multipart.MIMEMultipart("alternative")
 
-               # Load template
-               t = self.template_loader.load("%s.txt" % template_name)
-
-               # Render the message
-               try:
-                       message_part = t.generate(**namespace)
+               for extension, mimetype in (("txt", "plain"), ("html", "html")):
+                       try:
+                               t = self.template_loader.load("%s.%s" % (template_name, extension))
+                       except IOError as e:
+                               # Ignore if the HTML template does not exist
+                               if extension == "html":
+                                       continue
 
-               # Reset the rendered template when it could not be rendered
-               except:
-                       self.template_loader.reset()
-                       raise
+                               # Raise all other exceptions
+                               raise e
 
-               # Parse the message and extract the header
-               message_part = email.message_from_string(message_part.decode())
-               for k, v in list(message_part.items()):
+                       # Render the message
                        try:
-                               message.replace_header(k, v)
-                       except KeyError:
-                               message.add_header(k, v)
+                               message_part = t.generate(**namespace)
+
+                       # Reset the rendered template when it could not be rendered
+                       except:
+                               self.template_loader.reset()
+                               raise
+
+                       # Parse the message and extract the header
+                       message_part = email.message_from_string(message_part.decode())
+
+                       for header in message_part:
+                               try:
+                                       message.replace_header(header, message_part[header])
+                               except KeyError:
+                                       message.add_header(header, message_part[header])
 
-               # Do not encode emails in base64
-               charset = email.charset.Charset("utf-8")
-               charset.body_encoding = email.charset.QP
+                       # Create a MIMEText object out of it
+                       message_part = email.mime.text.MIMEText(
+                               message_part.get_payload(), mimetype)
 
-               # Set payload
-               message.set_payload(message_part.get_payload(), charset=charset)
+                       # Attach the parts to the mime container.
+                       # According to RFC2046, the last part of a multipart message
+                       # is preferred.
+                       message.attach(message_part)
 
                # Send the message
                self.send(recipients, message, priority=priority, headers=headers)
@@ -143,6 +152,15 @@ class Messages(misc.Object):
                if self.backend.debug:
                        self.template_loader.reset()
 
+       async def send_cli(self, template, recipient):
+               """
+                       Send a test message from the CLI
+               """
+               account = self.backend.accounts.get_by_mail(recipient)
+
+               return self.send_template(template, recipients=[recipient,],
+                       account=account)
+
 
 class Queue(misc.Object):
        @property