Skip to content

Commit

Permalink
Emailer allows cc and bcc
Browse files Browse the repository at this point in the history
  • Loading branch information
mcarans committed Nov 14, 2019
1 parent 64720f5 commit f034faa
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 13 deletions.
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ html5lib==1.0.1
psycopg2-binary==2.8.4
pyaml==19.4.1
ratelimit==2.2.1
six==1.12.0
six==1.13.0
sshtunnel==0.1.5
tabulator==1.28.0
tabulator==1.29.0
typing==3.7.4.1
yamlloader==0.5.5
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
'psycopg2-binary',
'pyaml',
'ratelimit',
'six>=1.12.0',
'six>=1.13.0',
'sshtunnel',
'tabulator>=1.28.0',
'tabulator>=1.29.0',
'typing',
'yamlloader'
]
Expand Down
40 changes: 34 additions & 6 deletions src/hdx/utilities/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,27 @@ def close(self):
"""
self.server.quit()

def send(self, recipients, subject, text_body, html_body=None, sender=None, **kwargs):
# type: (List[str], str, str, Optional[str], Optional[str], Any) -> None
@staticmethod
def get_normalised_emails(recipients):
# type: (List[str]) -> List[str]
"""
Get list of normalised emails
Args:
recipients (List[str]): Email recipient
Returns:
List[str]: Normalised emails
"""
normalised_recipients = list()
for recipient in recipients:
v = validate_email(recipient, check_deliverability=True) # validate and get info
normalised_recipients.append(v['email']) # replace with normalized form
return normalised_recipients

def send(self, recipients, subject, text_body, html_body=None, sender=None, cc=None, bcc=None, **kwargs):
# type: (List[str], str, str, Optional[str], Optional[str], Optional[List[str]], Optional[List[str]], Any) -> None
"""
Send email
Expand All @@ -145,6 +164,8 @@ def send(self, recipients, subject, text_body, html_body=None, sender=None, **kw
text_body (str): Plain text email body
html_body (Optional[str]): HTML email body
sender (Optional[str]): Email sender. Defaults to global sender.
cc (Optional[List[str]]): Email cc. Defaults to None.
bcc (Optional[List[str]]): Email cc. Defaults to None.
**kwargs: See below
mail_options (list): Mail options (see smtplib documentation)
rcpt_options (list): Recipient options (see smtplib documentation)
Expand All @@ -157,10 +178,6 @@ def send(self, recipients, subject, text_body, html_body=None, sender=None, **kw
sender = self.sender
v = validate_email(sender, check_deliverability=False) # validate and get info
sender = v['email'] # replace with normalized form
normalised_recipients = list()
for recipient in recipients:
v = validate_email(recipient, check_deliverability=True) # validate and get info
normalised_recipients.append(v['email']) # replace with normalized form

if html_body is not None:
msg = MIMEMultipart('alternative')
Expand All @@ -172,8 +189,19 @@ def send(self, recipients, subject, text_body, html_body=None, sender=None, **kw
msg = MIMEText(text_body)
msg['Subject'] = subject
msg['From'] = sender

normalised_recipients = self.get_normalised_emails(recipients)
msg['To'] = ', '.join(normalised_recipients)

if cc is not None:
normalised_cc = self.get_normalised_emails(cc)
msg['Cc'] = ', '.join(normalised_cc)
normalised_recipients.extend(normalised_cc)

if bcc is not None:
normalised_bcc = self.get_normalised_emails(bcc)
normalised_recipients.extend(normalised_bcc)

# Perform operations via server
self.connect()
self.server.sendmail(sender, normalised_recipients, msg.as_string(), **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion src/hdx/utilities/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.8.6
1.8.7
7 changes: 5 additions & 2 deletions tests/hdx/utilities/test_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def test_mail(self, mocksmtp):
email_config_dict.update(smtp_initargs)

recipients = ['larry@gmail.com', 'moe@gmail.com', 'curly@gmail.com']
cc = ['tweedledum@gmail.com', 'tweedledee@gmail.com']
bcc = ['theinvisibleman@gmail.com', 'ghost@gmail.com']
subject = 'hello'
text_body = 'hello there'
html_body = """\
Expand All @@ -52,20 +54,21 @@ def test_mail(self, mocksmtp):
rcpt_options = [1, 2]

with Email(email_config_dict=email_config_dict) as email:
email.send(recipients, subject, text_body, sender=sender, mail_options=mail_options,
email.send(recipients, subject, text_body, sender=sender, cc=cc, bcc=bcc, mail_options=mail_options,
rcpt_options=rcpt_options)
assert email.server.type == 'smtpssl'
assert email.server.initargs == smtp_initargs
assert email.server.username == username
assert email.server.password == password
assert email.server.sender == sender
assert email.server.recipients == recipients
assert email.server.recipients == recipients + cc + bcc
assert email.server.msg == '''Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: hello
From: me@gmail.com
To: larry@gmail.com, moe@gmail.com, curly@gmail.com
Cc: tweedledum@gmail.com, tweedledee@gmail.com
hello there'''
assert email.server.send_args == {'mail_options': ['a', 'b'], 'rcpt_options': [1, 2]}
Expand Down

0 comments on commit f034faa

Please sign in to comment.