Quellcode durchsuchen

Revert "make email message comply with RFC 5322"

This reverts commit 1a7ec23747fda06a4d6c1b7ab78698528228e0b6.
roy vor 3 Jahren
Ursprung
Commit
b4ba01f780
1 geänderte Dateien mit 41 neuen und 45 gelöschten Zeilen
  1. 41 45
      redmail/email/sender.py

+ 41 - 45
redmail/email/sender.py

@@ -1,6 +1,5 @@
 
 
 from copy import copy
 from copy import copy
-import email.policy
 from email.message import EmailMessage
 from email.message import EmailMessage
 from email.utils import make_msgid, formatdate
 from email.utils import make_msgid, formatdate
 from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
 from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
@@ -41,16 +40,16 @@ class EmailSender:
     password : str, optional
     password : str, optional
         User password to authenticate on the server.
         User password to authenticate on the server.
     cls_smtp : smtplib.SMTP
     cls_smtp : smtplib.SMTP
-        SMTP class to use for connection. See options
+        SMTP class to use for connection. See options 
         from :stdlib:`Python smtplib docs <smtplib.html>`.
         from :stdlib:`Python smtplib docs <smtplib.html>`.
     use_starttls : bool
     use_starttls : bool
-        Whether to use `STARTTLS <https://en.wikipedia.org/wiki/Opportunistic_TLS>`_
+        Whether to use `STARTTLS <https://en.wikipedia.org/wiki/Opportunistic_TLS>`_ 
         when connecting to the SMTP server.
         when connecting to the SMTP server.
     user_name : str, optional
     user_name : str, optional
         Deprecated alias for username. Please use username instead.
         Deprecated alias for username. Please use username instead.
     domain : str, optional
     domain : str, optional
         Portion of the generated IDs after "@" which strengthens the uniqueness
         Portion of the generated IDs after "@" which strengthens the uniqueness
-        of the generated IDs. Used in the Message-ID header and in the Content-IDs
+        of the generated IDs. Used in the Message-ID header and in the Content-IDs 
         of the embedded imaged in the HTML body. Usually not needed to be set.
         of the embedded imaged in the HTML body. Usually not needed to be set.
         Defaults to the fully qualified domain name.
         Defaults to the fully qualified domain name.
     **kwargs : dict
     **kwargs : dict
@@ -81,10 +80,10 @@ class EmailSender:
         HTML body of emails if not specified
         HTML body of emails if not specified
         in the send method.
         in the send method.
     text_template : str
     text_template : str
-        Name of the template to use as the text body of emails
-        if not specified in the send method.
+        Name of the template to use as the text body of emails 
+        if not specified in the send method. 
     html_template : str
     html_template : str
-        Name of the template to use as the HTML body of emails
+        Name of the template to use as the HTML body of emails 
         if not specified in the send method.
         if not specified in the send method.
     use_jinja : bool
     use_jinja : bool
         Use Jinja to render text/HTML. If Jinja is disabled,
         Use Jinja to render text/HTML. If Jinja is disabled,
@@ -117,7 +116,7 @@ class EmailSender:
         when connecting to the SMTP server.
         when connecting to the SMTP server.
     connection : smtplib.SMTP, None
     connection : smtplib.SMTP, None
         Connection to the SMTP server. Created and closed
         Connection to the SMTP server. Created and closed
-        before and after sending each email unless there
+        before and after sending each email unless there 
         is an existing connection.
         is an existing connection.
 
 
     Examples
     Examples
@@ -131,7 +130,7 @@ class EmailSender:
             receivers=["you@example.com"],
             receivers=["you@example.com"],
         )
         )
     """
     """
-
+    
     default_html_theme = "modest.html"
     default_html_theme = "modest.html"
     default_text_theme = "pandas.txt"
     default_text_theme = "pandas.txt"
 
 
@@ -144,7 +143,7 @@ class EmailSender:
     # Set globals
     # Set globals
     templates_html_table.globals["get_span"] = get_span
     templates_html_table.globals["get_span"] = get_span
     templates_text_table.globals["get_span"] = get_span
     templates_text_table.globals["get_span"] = get_span
-
+    
     templates_html_table.globals["is_last_group_row"] = is_last_group_row
     templates_html_table.globals["is_last_group_row"] = is_last_group_row
     templates_text_table.globals["is_last_group_row"] = is_last_group_row
     templates_text_table.globals["is_last_group_row"] = is_last_group_row
 
 
@@ -188,7 +187,7 @@ class EmailSender:
         self.use_starttls = use_starttls
         self.use_starttls = use_starttls
         self.cls_smtp = cls_smtp
         self.cls_smtp = cls_smtp
         self.kws_smtp = kwargs
         self.kws_smtp = kwargs
-
+        
         self.connection = None
         self.connection = None
 
 
     def send(self,
     def send(self,
@@ -202,8 +201,8 @@ class EmailSender:
              text:Optional[str]=None,
              text:Optional[str]=None,
              html_template:Optional[str]=None,
              html_template:Optional[str]=None,
              text_template:Optional[str]=None,
              text_template:Optional[str]=None,
-             body_images:Optional[Dict[str, Union[str, bytes, 'plt.Figure', 'Image']]]=None,
-             body_tables:Optional[Dict[str, 'pd.DataFrame']]=None,
+             body_images:Optional[Dict[str, Union[str, bytes, 'plt.Figure', 'Image']]]=None, 
+             body_tables:Optional[Dict[str, 'pd.DataFrame']]=None, 
              body_params:Optional[Dict[str, Any]]=None,
              body_params:Optional[Dict[str, Any]]=None,
              attachments:Optional[Dict[str, Union[str, os.PathLike, 'pd.DataFrame', bytes]]]=None) -> EmailMessage:
              attachments:Optional[Dict[str, Union[str, os.PathLike, 'pd.DataFrame', bytes]]]=None) -> EmailMessage:
         """Send an email.
         """Send an email.
@@ -214,8 +213,8 @@ class EmailSender:
             Subject of the email.
             Subject of the email.
         sender : str, optional
         sender : str, optional
             Email address the email is sent from.
             Email address the email is sent from.
-            Note that some email services might not
-            respect changing sender address
+            Note that some email services might not 
+            respect changing sender address 
             (for example Gmail).
             (for example Gmail).
         receivers : list, optional
         receivers : list, optional
             Receivers of the email.
             Receivers of the email.
@@ -245,27 +244,27 @@ class EmailSender:
             Name of the text template loaded using Jinja environment specified
             Name of the text template loaded using Jinja environment specified
             in ``templates_text`` attribute. Specify either ``text`` or ``text_template``.
             in ``templates_text`` attribute. Specify either ``text`` or ``text_template``.
         body_images : dict of bytes, dict of path-like, dict of plt Figure, dict of PIL Image, optional
         body_images : dict of bytes, dict of path-like, dict of plt Figure, dict of PIL Image, optional
-            HTML images to embed with the html. The key should be
+            HTML images to embed with the html. The key should be 
             as Jinja variables in the html and the values represent
             as Jinja variables in the html and the values represent
             images (path to an image, bytes of an image or image object).
             images (path to an image, bytes of an image or image object).
         body_tables : dict of Pandas dataframes, optional
         body_tables : dict of Pandas dataframes, optional
-            HTML tables to embed with the html. The key should be
+            HTML tables to embed with the html. The key should be 
             as Jinja variables in the html and the values are Pandas
             as Jinja variables in the html and the values are Pandas
             DataFrames.
             DataFrames.
         body_params : dict, optional
         body_params : dict, optional
             Extra Jinja parameters passed to the HTML and text bodies.
             Extra Jinja parameters passed to the HTML and text bodies.
         use_jinja : bool
         use_jinja : bool
-            Use Jinja to render text/HTML. If Jinja is disabled, body content cannot be
+            Use Jinja to render text/HTML. If Jinja is disabled, body content cannot be 
             embedded, templates have no effect and body parameters do nothing.
             embedded, templates have no effect and body parameters do nothing.
         attachments : dict, optional
         attachments : dict, optional
             Attachments of the email. If dict value is string, the attachment content
             Attachments of the email. If dict value is string, the attachment content
             is the string itself. If path, the attachment is the content of the path's file.
             is the string itself. If path, the attachment is the content of the path's file.
-            If dataframe, the dataframe is turned to bytes or text according to the
+            If dataframe, the dataframe is turned to bytes or text according to the 
             file extension in dict key.
             file extension in dict key.
 
 
         Examples
         Examples
         --------
         --------
-
+        
             Simple example:
             Simple example:
 
 
             .. code-block:: python
             .. code-block:: python
@@ -273,9 +272,9 @@ class EmailSender:
                 from redmail import EmailSender
                 from redmail import EmailSender
 
 
                 email = EmailSender(
                 email = EmailSender(
-                    host='localhost',
-                    port=0,
-                    username='me@example.com',
+                    host='localhost', 
+                    port=0, 
+                    username='me@example.com', 
                     password='<PASSWORD>'
                     password='<PASSWORD>'
                 )
                 )
                 email.send(
                 email.send(
@@ -296,7 +295,7 @@ class EmailSender:
         Notes
         Notes
         -----
         -----
             See also `Jinja documentation <https://jinja.palletsprojects.com>`_
             See also `Jinja documentation <https://jinja.palletsprojects.com>`_
-            for utilizing Jinja in ``html`` and ``text`` arguments or for using
+            for utilizing Jinja in ``html`` and ``text`` arguments or for using 
             Jinja templates with  ``html_template`` and ``text_template`` arguments.
             Jinja templates with  ``html_template`` and ``text_template`` arguments.
         """
         """
         msg = self.get_message(
         msg = self.get_message(
@@ -317,8 +316,8 @@ class EmailSender:
         )
         )
         self.send_message(msg)
         self.send_message(msg)
         return msg
         return msg
-
-    def get_message(self,
+        
+    def get_message(self, 
                   subject:Optional[str]=None,
                   subject:Optional[str]=None,
                   sender:Optional[str]=None,
                   sender:Optional[str]=None,
                   receivers:Union[List[str], str, None]=None,
                   receivers:Union[List[str], str, None]=None,
@@ -328,8 +327,8 @@ class EmailSender:
                   text:Optional[str]=None,
                   text:Optional[str]=None,
                   html_template:Optional[str]=None,
                   html_template:Optional[str]=None,
                   text_template:Optional[str]=None,
                   text_template:Optional[str]=None,
-                  body_images:Optional[Dict[str, Union[str, bytes, 'plt.Figure', 'Image']]]=None,
-                  body_tables:Optional[Dict[str, 'pd.DataFrame']]=None,
+                  body_images:Optional[Dict[str, Union[str, bytes, 'plt.Figure', 'Image']]]=None, 
+                  body_tables:Optional[Dict[str, 'pd.DataFrame']]=None, 
                   body_params:Optional[Dict[str, Any]]=None,
                   body_params:Optional[Dict[str, Any]]=None,
                   attachments:Optional[Dict[str, Union[str, os.PathLike, 'pd.DataFrame', bytes]]]=None,
                   attachments:Optional[Dict[str, Union[str, os.PathLike, 'pd.DataFrame', bytes]]]=None,
                   headers:Optional[Dict[str, str]]=None,
                   headers:Optional[Dict[str, str]]=None,
@@ -354,12 +353,12 @@ class EmailSender:
             raise ValueError("Email must have a subject")
             raise ValueError("Email must have a subject")
 
 
         msg = self._create_body(
         msg = self._create_body(
-            subject=subject,
-            sender=sender,
+            subject=subject, 
+            sender=sender, 
             receivers=receivers,
             receivers=receivers,
             cc=cc,
             cc=cc,
             bcc=bcc,
             bcc=bcc,
-            headers=headers
+            headers=headers 
         )
         )
         has_text = text is not None or text_template is not None
         has_text = text is not None or text_template is not None
         has_html = html is not None or html_template is not None
         has_html = html is not None or html_template is not None
@@ -372,8 +371,8 @@ class EmailSender:
                 use_jinja=use_jinja
                 use_jinja=use_jinja
             )
             )
             body.attach(
             body.attach(
-                msg,
-                text,
+                msg, 
+                text, 
                 tables=body_tables,
                 tables=body_tables,
                 jinja_params=self.get_text_params(extra=body_params, sender=sender),
                 jinja_params=self.get_text_params(extra=body_params, sender=sender),
             )
             )
@@ -393,7 +392,7 @@ class EmailSender:
                 tables=body_tables,
                 tables=body_tables,
                 jinja_params=self.get_html_params(extra=body_params, sender=sender)
                 jinja_params=self.get_html_params(extra=body_params, sender=sender)
             )
             )
-
+        
         self._set_content_type(
         self._set_content_type(
             msg,
             msg,
             has_text=has_text,
             has_text=has_text,
@@ -430,10 +429,7 @@ class EmailSender:
         return make_msgid(domain=self.domain)
         return make_msgid(domain=self.domain)
 
 
     def _create_body(self, subject, sender, receivers=None, cc=None, bcc=None, headers=None) -> EmailMessage:
     def _create_body(self, subject, sender, receivers=None, cc=None, bcc=None, headers=None) -> EmailMessage:
-        # Python's default email policy follows the Internet mail standards (RFC 5322) EXCEPT for line endings.
-        # For line endings the default policy  uses python's default LF instead of CRLF as mandated by RFC 5322.
-        # So we can manually edit this to to comply with the internet standards.
-        msg = EmailMessage(email.policy.default.clone(linesep="\r\n"))
+        msg = EmailMessage()
 
 
         email_headers = {
         email_headers = {
             "From": sender,
             "From": sender,
@@ -485,7 +481,7 @@ class EmailSender:
             # thus it is also closed with this message
             # thus it is also closed with this message
             with self:
             with self:
                 self.connection.send_message(msg)
                 self.connection.send_message(msg)
-
+    
     def __enter__(self):
     def __enter__(self):
         self.connect()
         self.connect()
 
 
@@ -506,7 +502,7 @@ class EmailSender:
         "Connect and get the SMTP Server"
         "Connect and get the SMTP Server"
         user = self.username
         user = self.username
         password = self.password
         password = self.password
-
+        
         server = self.cls_smtp(self.host, self.port, **self.kws_smtp)
         server = self.cls_smtp(self.host, self.port, **self.kws_smtp)
         if self.use_starttls:
         if self.use_starttls:
             server.starttls()
             server.starttls()
@@ -576,13 +572,13 @@ class EmailSender:
             return None
             return None
         return self.templates_text.get_template(layout)
         return self.templates_text.get_template(layout)
 
 
-    def set_template_paths(self,
-                           html:Union[str, os.PathLike, None]=None,
-                           text:Union[str, os.PathLike, None]=None,
-                           html_table:Union[str, os.PathLike, None]=None,
+    def set_template_paths(self, 
+                           html:Union[str, os.PathLike, None]=None, 
+                           text:Union[str, os.PathLike, None]=None, 
+                           html_table:Union[str, os.PathLike, None]=None, 
                            text_table:Union[str, os.PathLike, None]=None):
                            text_table:Union[str, os.PathLike, None]=None):
         """Create Jinja envs for body templates using given paths
         """Create Jinja envs for body templates using given paths
-
+        
         This is a shortcut for manually setting them:
         This is a shortcut for manually setting them:
 
 
         .. code-block:: python
         .. code-block:: python