Coverage for .tox/coverage/lib/python3.11/site-packages/wuttjamaican/email/message.py: 100%
45 statements
« prev ^ index » next coverage.py v7.3.2, created at 2024-08-26 14:27 -0500
« prev ^ index » next coverage.py v7.3.2, created at 2024-08-26 14:27 -0500
1# -*- coding: utf-8; -*-
2################################################################################
3#
4# WuttJamaican -- Base package for Wutta Framework
5# Copyright © 2023-2024 Lance Edgar
6#
7# This file is part of Wutta Framework.
8#
9# Wutta Framework is free software: you can redistribute it and/or modify it
10# under the terms of the GNU General Public License as published by the Free
11# Software Foundation, either version 3 of the License, or (at your option) any
12# later version.
13#
14# Wutta Framework is distributed in the hope that it will be useful, but
15# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17# more details.
18#
19# You should have received a copy of the GNU General Public License along with
20# Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
21#
22################################################################################
23"""
24Email Message
25"""
27from email.mime.multipart import MIMEMultipart
28from email.mime.text import MIMEText
31class Message:
32 """
33 Represents an email message to be sent.
35 :param to: Recipient(s) for the message. This may be either a
36 string, or list of strings. If a string, it will be converted
37 to a list since that is how the :attr:`to` attribute tracks it.
38 Similar logic is used for :attr:`cc` and :attr:`bcc`.
40 All attributes shown below may also be specified via constructor.
42 .. attribute:: key
44 Unique key indicating the "type" of message. An "ad-hoc"
45 message created arbitrarily may not have/need a key; however
46 one created via
47 :meth:`~wuttjamaican.email.handler.EmailHandler.make_auto_message()`
48 will always have a key.
50 This key is not used for anything within the ``Message`` class
51 logic. It is used by
52 :meth:`~wuttjamaican.email.handler.EmailHandler.make_auto_message()`
53 when constructing the message, and the key is set on the final
54 message only as a reference.
56 .. attribute:: sender
58 Sender (``From:``) address for the message.
60 .. attribute:: subject
62 Subject text for the message.
64 .. attribute:: to
66 List of ``To:`` recipients for the message.
68 .. attribute:: cc
70 List of ``Cc:`` recipients for the message.
72 .. attribute:: bcc
74 List of ``Bcc:`` recipients for the message.
76 .. attribute:: replyto
78 Optional reply-to (``Reply-To:``) address for the message.
80 .. attribute:: txt_body
82 String with the ``text/plain`` body content.
84 .. attribute:: html_body
86 String with the ``text/html`` body content.
87 """
89 def __init__(
90 self,
91 key=None,
92 sender=None,
93 subject=None,
94 to=None,
95 cc=None,
96 bcc=None,
97 replyto=None,
98 txt_body=None,
99 html_body=None,
100 ):
101 self.key = key
102 self.sender = sender
103 self.subject = subject
104 self.set_recips('to', to)
105 self.set_recips('cc', cc)
106 self.set_recips('bcc', bcc)
107 self.replyto = replyto
108 self.txt_body = txt_body
109 self.html_body = html_body
111 def set_recips(self, name, value):
112 """ """
113 if value:
114 if isinstance(value, str):
115 value = [value]
116 if not isinstance(value, (list, tuple)):
117 raise ValueError("must specify a string, tuple or list value")
118 else:
119 value = []
120 setattr(self, name, list(value))
122 def as_string(self):
123 """
124 Returns the complete message as string. This is called from
125 within
126 :meth:`~wuttjamaican.email.handler.EmailHandler.deliver_message()`
127 to obtain the SMTP payload.
128 """
129 msg = None
131 if self.txt_body and self.html_body:
132 txt = MIMEText(self.txt_body, _charset='utf_8')
133 html = MIMEText(self.html_body, _subtype='html', _charset='utf_8')
134 msg = MIMEMultipart(_subtype='alternative', _subparts=[txt, html])
136 elif self.txt_body:
137 msg = MIMEText(self.txt_body, _charset='utf_8')
139 elif self.html_body:
140 msg = MIMEText(self.html_body, 'html', _charset='utf_8')
142 if not msg:
143 raise ValueError("message has no body parts")
145 msg['Subject'] = self.subject
146 msg['From'] = self.sender
148 for addr in self.to:
149 msg['To'] = addr
150 for addr in self.cc:
151 msg['Cc'] = addr
152 for addr in self.bcc:
153 msg['Bcc'] = addr
155 if self.replyto:
156 msg.add_header('Reply-To', self.replyto)
158 return msg.as_string()