Skip to content

Commit 421e4b4

Browse files
authored
Merge pull request #316 from smoors/mail
add support for CC and BCC in sendTextMail and sendHTMLMail
2 parents dab54b3 + 1696c91 commit 421e4b4

File tree

2 files changed

+61
-11
lines changed

2 files changed

+61
-11
lines changed

lib/vsc/utils/mail.py

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from email.mime.multipart import MIMEMultipart
3939
from email.mime.text import MIMEText
4040
from email.mime.image import MIMEImage
41+
from future.utils import string_types
4142

4243
class VscMailError(Exception):
4344
"""Raised if the sending of an email fails for some reason."""
@@ -46,7 +47,7 @@ def __init__(self, mail_host=None, mail_to=None, mail_from=None, mail_subject=No
4647
"""Initialisation.
4748
4849
@type mail_host: string
49-
@type mail_to: string
50+
@type mail_to: list of strings (or string, but deprecated)
5051
@type mail_from: string
5152
@type mail_subject: string
5253
@type err: Exception subclass
@@ -107,7 +108,7 @@ def _send(self, mail_from, mail_to, mail_subject, msg):
107108
"""Actually send the mail.
108109
109110
@type mail_from: string representing the sender.
110-
@type mail_to: string representing the recipient.
111+
@type mail_to: list of strings (or string, but deprecated) representing the recipient.
111112
@type mail_subject: string representing the subject.
112113
@type msg: MIME message.
113114
"""
@@ -148,27 +149,54 @@ def _send(self, mail_from, mail_to, mail_subject, msg):
148149
else:
149150
s.quit()
150151

151-
def sendTextMail(self, mail_to, mail_from, reply_to, mail_subject, message):
152+
def sendTextMail(
153+
self,
154+
mail_to,
155+
mail_from,
156+
reply_to,
157+
mail_subject,
158+
message,
159+
cc=None,
160+
bcc=None):
152161
"""Send out the given message by mail to the given recipient(s).
153162
154-
@type mail_to: string or list of strings
163+
@type mail_to: list
155164
@type mail_from: string
156165
@type reply_to: string
157166
@type mail_subject: string
158167
@type message: string
168+
@type cc: list
169+
@type bcc: list
159170
160-
@param mail_to: a valid recipient email address
171+
@param mail_to: a list of valid email addresses
161172
@param mail_from: a valid sender email address.
162173
@param reply_to: a valid email address for the (potential) replies.
163174
@param mail_subject: the subject of the email.
164175
@param message: the body of the mail.
176+
@param cc: a list of valid CC email addresses
177+
@param bcc: a list of valid BCC email addresses
165178
"""
179+
180+
# deprecated: single email as string
181+
if isinstance(mail_to, string_types):
182+
mail_to = [mail_to]
183+
166184
logging.info("Sending mail [%s] to %s.", mail_subject, mail_to)
167185

168186
msg = MIMEText(message)
169187
msg['Subject'] = mail_subject
170188
msg['From'] = mail_from
171-
msg['To'] = mail_to
189+
msg['To'] = ','.join(mail_to)
190+
191+
if cc:
192+
logging.info("Sending mail [%s] in CC to %s.", mail_subject, cc)
193+
msg['Cc'] = cc
194+
mail_to.extend(cc)
195+
196+
if bcc:
197+
logging.info("Sending mail [%s] in BCC to %s.", mail_subject, bcc)
198+
# do *not* set msg['Bcc'] to avoid leaking the BCC email address to all recipients
199+
mail_to.extend(bcc)
172200

173201
if reply_to is None:
174202
reply_to = mail_from
@@ -206,36 +234,58 @@ def sendHTMLMail(
206234
html_message,
207235
text_alternative,
208236
images=None,
209-
css=None):
237+
css=None,
238+
cc=None,
239+
bcc=None):
210240
"""
211241
Send an HTML email message, encoded in a MIME/multipart message.
212242
213243
The images and css are included in the message, and should be provided separately.
214244
215-
@type mail_to: string or list of strings
245+
@type mail_to: list
216246
@type mail_from: string
217247
@type reply_to: string
218248
@type mail_subject: string
219249
@type html_message: string
220250
@type text_alternative: string
221251
@type images: list of strings
222252
@type css: string
253+
@type cc: list
254+
@type bcc: list
223255
224-
@param mail_to: a valid recipient email addresses.
256+
@param mail_to: a list of valid email addresses
225257
@param mail_from: a valid sender email address.
226258
@param reply_to: a valid email address for the (potential) replies.
227259
@param html_message: the actual payload, body of the mail
228260
@param text_alternative: plain-text version of the mail body
229261
@param images: the images that are referenced in the HTML body. These should be available as files on the
230262
filesystem in the directory where the script runs. Caveat: assume jpeg image type.
231263
@param css: CSS definitions
264+
@param cc: a list of valid CC email addresses
265+
@param bcc: a list of valid BCC email addresses
232266
"""
233267

268+
# deprecated: single email as string
269+
if isinstance(mail_to, string_types):
270+
mail_to = [mail_to]
271+
272+
logging.info("Sending mail [%s] to %s.", mail_subject, mail_to)
273+
234274
# Create message container - the correct MIME type is multipart/alternative.
235275
msg_root = MIMEMultipart('alternative')
236276
msg_root['Subject'] = mail_subject
237277
msg_root['From'] = mail_from
238-
msg_root['To'] = mail_to
278+
msg_root['To'] = ','.join(mail_to)
279+
280+
if cc:
281+
logging.info("Sending mail [%s] in CC to %s.", mail_subject, cc)
282+
msg_root['Cc'] = cc
283+
mail_to.extend(cc)
284+
285+
if bcc:
286+
logging.info("Sending mail [%s] in BCC to %s.", mail_subject, bcc)
287+
# do *not* set msg_root['Bcc'] to avoid leaking the BCC email address to all recipients
288+
mail_to.extend(bcc)
239289

240290
if reply_to is None:
241291
reply_to = mail_from

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
]
4545

4646
PACKAGE = {
47-
'version': '3.3.0',
47+
'version': '3.3.1',
4848
'author': [sdw, jt, ag, kh],
4949
'maintainer': [sdw, jt, ag, kh],
5050
# as long as 1.0.0 is not out, vsc-base should still provide vsc.fancylogger

0 commit comments

Comments
 (0)