]> git.ipfire.org Git - ipfire.org.git/commitdiff
messages: Automatically inline any CSS
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 26 Oct 2023 08:13:57 +0000 (08:13 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 26 Oct 2023 08:13:57 +0000 (08:13 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
configure.ac
src/backend/messages.py

index bbd7abdf820188e129d302b06ffd587dcb97a9fe..ae6a9af11894bbe25eb705674d755abf4b842b50 100644 (file)
@@ -40,6 +40,7 @@ AX_PYTHON_MODULE([panoramisk], [fatal])
 AX_PYTHON_MODULE([phonenumbers], [fatal])
 AX_PYTHON_MODULE([psycopg], [fatal])
 AX_PYTHON_MODULE([pycares], [fatal])
+AX_PYTHON_MODULE([pynliner], [fatal])
 AX_PYTHON_MODULE([redis.asyncio], [fatal])
 AX_PYTHON_MODULE([tornado], [fatal])
 AX_PYTHON_MODULE([zxcvbn], [fatal])
index 0aea14e8a38cbf98b7b0d0459c569be86279f17b..53f62baa33bda857dc0beaaee4f1aca3c36ea954 100644 (file)
@@ -8,6 +8,7 @@ import email.utils
 import logging
 import mimetypes
 import os.path
+import pynliner
 import random
 import smtplib
 import socket
@@ -148,6 +149,10 @@ class Messages(misc.Object):
                                except KeyError:
                                        message.add_header(header, value)
 
+                       # Inline any CSS
+                       if extension == "html":
+                               message_part = self._inline_css(message_part)
+
                        # Create a MIMEText object out of it
                        message_part = email.mime.text.MIMEText(
                                message_part.get_payload(), mimetype)
@@ -164,6 +169,24 @@ class Messages(misc.Object):
                if self.backend.debug:
                        self.template_loader.reset()
 
+       def _inline_css(self, part):
+               """
+                       Inlines any CSS into style attributes
+               """
+               # Fetch the payload
+               payload = part.get_payload()
+
+               # Setup Pynliner
+               p = pynliner.Pynliner().from_string(payload)
+
+               # Run the inlining
+               payload = p.run()
+
+               # Set the payload again
+               part.set_payload(payload)
+
+               return part
+
        def embed_image(self, path):
                static_dir = self.backend.config.get("global", "static_dir")
                assert static_dir