# -*- coding: utf-8 -*-
-# Copyright (C) 2012 W. Trevor King <wking@drexel.edu>
+# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
#
# This file is part of pygrader.
#
from . import ENCODING as _ENCODING
from . import LOG as _LOG
-from .color import standard_colors as _standard_colors
-from .color import color_string as _color_string
-from .color import write_color as _write_color
from .model.person import Person as _Person
smtp.send_message(msg=msg)
test_smtp.__test__ = False # not a test for nose
-def send_emails(emails, smtp=None, use_color=None, debug_target=None,
- dry_run=False):
+def send_emails(emails, smtp=None, debug_target=None, dry_run=False):
"""Iterate through `emails` and mail them off one-by-one
>>> from email.mime.text import MIMEText
... emails.append(
... (msg,
... lambda status: stdout.write('SUCCESS: {}\\n'.format(status))))
- >>> send_emails(emails, use_color=False, dry_run=True)
+ >>> send_emails(emails, dry_run=True)
... # doctest: +REPORT_UDIFF, +NORMALIZE_WHITESPACE
- sending message to ['Moneypenny <mp@sis.gov.uk>', 'James Bond <007@sis.gov.uk>']...\tDRY-RUN
SUCCESS: None
- sending message to ['M <m@sis.gov.uk>', 'James Bond <007@sis.gov.uk>']...\tDRY-RUN
SUCCESS: None
"""
local_smtp = smtp is None
- highlight,lowlight,good,bad = _standard_colors(use_color=use_color)
for msg,callback in emails:
sources = [
_email_utils.formataddr(a) for a in _pgp_mime.email_sources(msg)]
# TODO: remove convert_content_transfer_encoding?
#if msg.get('content-transfer-encoding', None) == 'base64':
# convert_content_transfer_encoding(msg, '8bit')
- _LOG.debug(_color_string(
- '\n{}\n'.format(msg.as_string()), color=lowlight))
- _write_color('sending message to {}...'.format(targets),
- color=highlight)
+ _LOG.debug('\n{}\n'.format(msg.as_string()))
+ _LOG.info('sending message to {}...'.format(targets))
if not dry_run:
try:
if local_smtp:
if local_smtp:
smtp.quit()
except:
- _write_color('\tFAILED\n', bad)
+ _LOG.warning('failed to send message to {}'.format(targets))
if callback:
callback(False)
raise
else:
- _write_color('\tOK\n', good)
+ _LOG.info('sent message to {}'.format(targets))
if callback:
callback(True)
else:
- _write_color('\tDRY-RUN\n', good)
+ _LOG.info('dry run, so no message sent to {}'.format(targets))
if callback:
callback(None)
send_emails([(message, None)], *self.args, **self.kwargs)
-def get_address(person, header=False):
+def get_address(person):
r"""
>>> from pygrader.model.person import Person as Person
>>> p = Person(name='Jack', emails=['a@b.net'])
>>> get_address(p)
'Jack <a@b.net>'
- Here's a simple unicode example.
+ Here's a simple unicode example. The name portion of the address
+ is encoded following RFC 2047.
>>> p.name = '✉'
>>> get_address(p)
- '✉ <a@b.net>'
-
- When you encode addresses that you intend to place in an email
- header, you should set the `header` option to `True`. This
- encodes the name portion of the address without encoding the email
- portion.
-
- >>> get_address(p, header=True)
'=?utf-8?b?4pyJ?= <a@b.net>'
- Note that the address is in the clear. Without the `header`
- option you'd have to rely on something like:
-
- >>> from email.header import Header
- >>> Header(get_address(p), 'utf-8').encode()
- '=?utf-8?b?4pyJIDxhQGIubmV0Pg==?='
-
- This can cause trouble when your mailer tries to decode the name
- following :RFC:`2822`, which limits the locations in which encoded
- words may appear.
+ Note that the address is in the clear. Otherwise you can have
+ trouble when your mailer tries to decode the name following
+ :RFC:`2822`, which limits the locations in which encoded words may
+ appear.
"""
- if header:
- encoding = _pgp_mime.guess_encoding(person.name)
- if encoding == 'us-ascii':
- name = person.name
- else:
- name = _Header(person.name, encoding).encode()
- return _email_utils.formataddr((name, person.emails[0]))
- return _email_utils.formataddr((person.name, person.emails[0]))
+ encoding = _pgp_mime.guess_encoding(person.name)
+ return _email_utils.formataddr(
+ (person.name, person.emails[0]), charset=encoding)
-def _construct_email(author, targets, subject, message, cc=None):
+def construct_email(author, targets, subject, message, cc=None):
if author.pgp_key:
signers = [author.pgp_key]
else:
message = _pgp_mime.encrypt(message=message, recipients=recipients)
message['Date'] = _email_utils.formatdate()
- message['From'] = get_address(author, header=True)
+ message['From'] = get_address(author)
message['Reply-to'] = message['From']
message['To'] = ', '.join(
- get_address(target, header=True) for target in targets)
+ get_address(target) for target in targets)
if cc:
message['Cc'] = ', '.join(
- get_address(target, header=True) for target in cc)
+ get_address(target) for target in cc)
subject_encoding = _pgp_mime.guess_encoding(subject)
if subject_encoding == 'us-ascii':
message['Subject'] = subject
return message
-def construct_email(author, targets, subject, text, cc=None):
+def construct_text_email(author, targets, subject, text, cc=None):
r"""Build a text/plain email using `Person` instances
>>> from pygrader.model.person import Person as Person
>>> author = Person(name='Джон Доу', emails=['jdoe@a.gov.ru'])
>>> targets = [Person(name='Jill', emails=['c@d.net'])]
>>> cc = [Person(name='H.D.', emails=['hd@wall.net'])]
- >>> msg = construct_email(author, targets, cc=cc,
+ >>> msg = construct_text_email(author, targets, cc=cc,
... subject='Once upon a time', text='Bla bla bla...')
>>> print(msg.as_string()) # doctest: +REPORT_UDIFF, +ELLIPSIS
Content-Type: text/plain; charset="us-ascii"
With unicode text:
- >>> msg = construct_email(author, targets, cc=cc,
+ >>> msg = construct_text_email(author, targets, cc=cc,
... subject='Once upon a time', text='Funky ✉.')
>>> print(msg.as_string()) # doctest: +REPORT_UDIFF, +ELLIPSIS
Content-Type: text/plain; charset="utf-8"
<BLANKLINE>
"""
message = _pgp_mime.encodedMIMEText(text)
- return _construct_email(
+ return construct_email(
author=author, targets=targets, subject=subject, message=message,
cc=cc)
>>> student = Person(name='Джон Доу', emails=['jdoe@a.gov.ru'])
>>> assistant = Person(name='Jill', emails=['c@d.net'])
>>> cc = [assistant]
- >>> msg = construct_email(author=student, targets=[assistant],
+ >>> msg = construct_text_email(author=student, targets=[assistant],
... subject='Assignment 1 submission', text='Bla bla bla...')
>>> rsp = construct_response(author=assistant, targets=[student],
... subject='Received assignment 1 submission', text='3 hours late',
message = _MIMEMultipart('mixed')
message.attach(_pgp_mime.encodedMIMEText(text))
message.attach(_MIMEMessage(original))
- return _construct_email(
+ return construct_email(
author=author, targets=targets, subject=subject, message=message,
cc=cc)