Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ wittymail_ve/

# VS Code
.vscode/
.idea/

# WittyMail log file
wittymail_log.txt
wittymail_log.txt
28 changes: 28 additions & 0 deletions backend/EmailProviderTest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from mailer.Email import Email
from mailer.EmailProvider import EmailProvider
import sys

'''
Basic Test1
-----------
1. Get username and password from CLI
2. Login using SMTP
3. Send a basic email
4. Logout
'''
def basic_test1(username, password):
e = Email([username], [username], 'Subject', 'Body')
eP = EmailProvider()
selected_eP = eP.choose_email_provider("SMTP")
seP = selected_eP(username, 'smtp.gmail.com', 587, username, password)
seP.login()
seP.send_email(e)
seP.logout()

if __name__ == '__main__':
if len(sys.argv) != 3:
print("EmailProviderTest.py <username> <password>")

username = sys.argv[1]
password = sys.argv[2]
basic_test1(username, password)
32 changes: 32 additions & 0 deletions backend/mailer/Email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env python
# coding=utf-8

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import os
import util.logger as logger

log = logger.get_logger(__name__)

class Email():
subject_template = None
body_template = None

def __init__(self, to, cc, subject, body, status = None):
assert to is not None and \
cc is not None, \
log.error('Incorrect value provided to=%s cc=%s' % (to, cc))
self.to = to
self.cc = cc
self.subject = subject
self.body = body
self.status = status
self.attachment = None

def __del__(self):
self.to = None
Email.subject_template = None
Email.body_template = None
19 changes: 19 additions & 0 deletions backend/mailer/EmailProvider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import importlib
import pdb
#from mailer.SMTPEmailProvider import SMTPEmailProvider

class EmailProvider:
def __init__(self):
pass

def choose_email_provider(self, name):
from mailer.SMTPEmailProvider import SMTPEmailProvider
return SMTPEmailProvider

def login(self):
raise NotImplementedError()
def send_email(self):
raise NotImplementedError()
def logout(self):
raise NotImplementedError()

95 changes: 95 additions & 0 deletions backend/mailer/SMTPEmailProvider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env python
# coding=utf-8

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import os
import util.logger as logger
from mailer.EmailProvider import EmailProvider

log = logger.get_logger(__name__)

class SMTPEmailProvider(EmailProvider):
def __init__(self, frm, server, port, username, password):
EmailProvider.__init__(self)
assert server is not None and port is not None and username is not None and password is not None,\
log.error('server, port number, username or password is None')

self.frm = frm
self.server = server
self.port = port
self.username = username
self.password = password
self.s = None

def logout(self):
self.s.quit()
log.debug('emailapi teardown successful')

# TODO Can you check if SMTPlib has different types of Exception (*Error) classes and write an except block for each?
def login(self):
# Connect to the SMTP server and login
try:
self.s = smtplib.SMTP(self.server, self.port)
self.s.ehlo()
self.s.starttls()
self.s.login(self.username, self.password)

except:
log.exception('Incorrect server/user information provided')
return [-1, 'Incorrect server/user information provided']

log.debug('Login successful')
return [0, 'Login successful']

def send_email(self, e):
try:
# Extra <p> tags show up as multiple line breaks in the resulting email, so replace them
# with single line breaks
body = e.body.replace('</p><p>', '<br />')

log.debug("Cleaned body: %s", body)

msg = MIMEMultipart()
msg['From'] = self.frm
msg['To'] = ", ".join(e.to)

ccs_to_send = []
if e.cc is not None and e.cc[0] != 'None':
msg['Cc'] = ", ".join(e.cc)
for cc in e.cc:
ccs_to_send.append(cc.strip())
else:
log.debug('No cc mailer provided')

msg['Subject'] = e.subject
msg.attach(MIMEText(e.body, 'html'))

if (e.attachment is not None):
for attachment in e.attachment:
if not os.path.isfile(attachment):
return [-1, 'Attachment not found']
try:
a = open(attachment, "rb")
except:
log.exception("Failed to open attachment: %s", attachment)
raise
p = MIMEBase('application', 'octet-stream')
p.set_payload((a).read())
encoders.encode_base64(p)
p.add_header('Content-Disposition', "attachment; filename= %s" % os.path.basename(attachment))
msg.attach(p)

msg_str = msg.as_string()
log.debug("ccs_to_send: %s", ccs_to_send)
if ccs_to_send:
self.s.sendmail(msg['From'], e.to + ccs_to_send, msg_str)
else:
self.s.sendmail(msg['From'], e.to, msg_str)
log.info('Email sent by %s to %s' % (msg['From'], msg['To']))
return [0, 'Email sent successfully']
except:
log.exception("Failed to send test email")
136 changes: 0 additions & 136 deletions backend/mailer/emailapi.py

This file was deleted.

Loading