Skip to content

Commit

Permalink
Allow mail to be sent to multiple recipients
Browse files Browse the repository at this point in the history
Now the recipients argument must be a list, but everywhere
that we use this it already was.

Add some additional error checking to ensure that configuration is good
before sending the message
  • Loading branch information
alastair authored and amCap1712 committed Apr 28, 2022
1 parent b831e38 commit 105c46f
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 10 deletions.
18 changes: 13 additions & 5 deletions brainzutils/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from flask import current_app

from typing import List
import smtplib
import socket

def send_mail(subject, text, recipients, attachments=None,
from flask import current_app


def send_mail(subject: str, text: str, recipients: List[str], attachments=None,
from_name="MetaBrainz Notifications",
from_addr=None, boundary=None):
"""This function can be used as a foundation for sending email.
Expand All @@ -21,6 +23,12 @@ def send_mail(subject, text, recipients, attachments=None,
from_name: Name of the sender.
from_addr: Email address of the sender.
"""
if not isinstance(recipients, list):
raise ValueError("recipients must be a list of email addresses")

if 'SMTP_SERVER' not in current_app.config or 'SMTP_PORT' not in current_app.config:
raise ValueError("Flask current_app requires config items SMTP_SERVER and SMTP_PORT to be set")

if attachments is None:
attachments = []
if from_addr is None:
Expand All @@ -32,12 +40,12 @@ def send_mail(subject, text, recipients, attachments=None,
if not recipients:
return

message =MIMEMultipart()
message = MIMEMultipart()

if boundary is not None:
message = MIMEMultipart(boundary=boundary)

message['To']="<%s>" %(recipients)
message['To'] = ", ".join(recipients)
message['Subject'] = subject
message['From'] = "%s <%s>" % (from_name, from_addr)
message.attach(MIMEText(text, _charset='utf-8'))
Expand Down
39 changes: 34 additions & 5 deletions brainzutils/test/test_mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,66 @@
import smtplib
from unittest import mock

from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from brainzutils import flask
from brainzutils import mail

class MailTestCase(unittest.TestCase):

def test_send_email_missing_config(self):
app = flask.CustomFlask(__name__)
with app.app_context():
with self.assertRaises(ValueError) as err:
mail.send_mail(
subject='ListenBrainz Spotify Importer Error',
text='It is a test mail',
recipients=[],
attachments=None,
from_name='ListenBrainz',
from_addr='noreply@metabrainz.org',
boundary='b'
)
assert "Flask current_app requires config items" in str(err.exception)

def test_send_email_string_recipients(self):
app = flask.CustomFlask(__name__)
with app.app_context():
with self.assertRaises(ValueError) as err:
mail.send_mail(
subject='ListenBrainz Spotify Importer Error',
text='It is a test mail',
recipients='wrongemail@metabrainz.org',
attachments=None,
from_name='ListenBrainz',
from_addr='noreply@metabrainz.org',
boundary='b'
)
assert str(err.exception) == "recipients must be a list of email addresses"

@mock.patch('smtplib.SMTP')
def test_send_email(self, mock_smtp):
app = flask.CustomFlask(__name__)
app.config['SMTP_SERVER'] = 'localhost'
app.config['SMTP_PORT'] = 8080
app.config['SMTP_PORT'] = 25

with app.app_context():
from_address = 'noreply@metabrainz.org'
recipients = 'sarthak2907@gmail.com'
recipients = ['musicbrainz@metabrainz.org', 'listenbrainz@metabrainz.org']
text = 'It is a test mail'
from_name = 'ListenBrainz'
subject = 'ListenBrainz Spotify Importer Error'
boundary = '===============2220963697271485568=='
message = MIMEMultipart(boundary=boundary)
message['To'] = '<%s>' % (recipients)
message['To'] = "musicbrainz@metabrainz.org, listenbrainz@metabrainz.org"
message['Subject'] = subject
message['From'] = '%s <%s>' % (from_name, from_address)
message.attach(MIMEText(text, _charset='utf-8'))

mail.send_mail(
subject='ListenBrainz Spotify Importer Error',
text='It is a test mail',
recipients='sarthak2907@gmail.com',
recipients=recipients,
attachments=None,
from_name='ListenBrainz',
from_addr='noreply@metabrainz.org',
Expand Down

0 comments on commit 105c46f

Please sign in to comment.