Compare commits

...

1 Commits

Author SHA1 Message Date
Patrick Melanson 73bbf6bb33 Use currently-logged-in user to authenticate for mass email sending.
Basically, this commit removes email sending code that asked the
user for a CSC username and email to authenticate to an SMTP server
to send a mass email. Now, we just use the system utility 'sendmail'
to do it, which means you don't have to enter in your email creds
to send a mass email once you're already logged in.

Magic!
2017-08-28 16:51:14 -04:00
2 changed files with 25 additions and 56 deletions

View File

@ -1,3 +1,5 @@
from email.mime.text import MIMEText
def format_reminder_email(quest_id: str,
days_signed_out: int,
librarian_name: str,
@ -6,7 +8,7 @@ def format_reminder_email(quest_id: str,
Formats an email as a plain string for sending out email reminders
for signed out books.
Example: _send_email("s455wang", "2017-02-04", 30, "csfmurph", "How to Design Programs")
Example: format_reminder_email("s455wang", 30, "Connor Murphy", "How to Design Programs")
"""
assert len(quest_id) <= 8
assert quest_id.isalnum()
@ -14,7 +16,7 @@ def format_reminder_email(quest_id: str,
assert librarian_name != ""
assert book_name != ""
email_message_body = \
email_message = MIMEText(
"""Hi {},
Our records indicate that you have had the book {} signed out for {} days.
@ -32,16 +34,11 @@ librarian@csclub.uwaterloo.ca""".format(
book_name,
days_signed_out,
librarian_name
)
))
email_message_subject = "Overdue book: {}".format(book_name)
email_message = (
"To: \"{0}@csclub.uwaterloo.ca\" <{0}@csclub.uwaterloo.ca>\n".format(quest_id) +
"Subject: {}\n".format(email_message_subject) +
"\n" +
email_message_body
)
assert email_message.replace("\n", "").isprintable(), \
email_message["Subject"] = "Overdue book: {}".format(book_name)
email_message["To"] = "\"{0}@csclub.uwaterloo.ca\" <{0}@csclub.uwaterloo.ca>\n".format(quest_id)
assert email_message.as_string().replace("\n", "").isprintable(), \
"Our email should not have characters apart from normal characters and newline"
return email_message
return email_message.as_string()

View File

@ -14,14 +14,15 @@ import time
#Import getpass for password input
import getpass
#Import subprocess for validation of if a user is in a group
#Import subprocess for validation of if a user is in a group, and running
#a sendmail process
import subprocess
#Import librarian permissions
from library import permissions
from library.exceptions import *
import library.database as db
from library.interface.form import FormWindow, BookForm, LoginForm, SuccessForm, catch_error_with, error_form
from library.interface.form import FormWindow, BookForm, SuccessForm, catch_error_with, error_form
from library.emails import format_reminder_email
# email testing folder creation
@ -91,11 +92,15 @@ def _send_email(quest_id: str,
os.makedirs("test_emails", exist_ok=True)
#Know that book titles such as "FORTRAN/77" exist, sanitize slashes.
filename = ("test_emails/{}_{}.txt"
.format(quest_id, book_name.replace('/', '-')))
with open(filename, 'w') as f:
.format(quest_id, book_name.replace("/", "-")))
with open(filename, "w") as f:
print(email_message, file=f)
else:
server.sendmail("librarian@csclub.uwaterloo.ca", email_addresses, email_message)
#Equivalent to:
#echo <email_message> | sendmail questid@csclub.uwaterloo.ca
sendmail_process = subprocess.Popen(["sendmail"] + email_addresses,
stdin=subprocess.PIPE)
sendmail_process.communicate(input=email_message.encode("utf-8"))
return True
return False
@ -129,40 +134,10 @@ def sendemails_procedure(w, hb, cy, cx, mx):
if librarianName == {}:
return "" #User cancelled the dialog box
#Set up email
global server
server = smtplib.SMTP_SSL("mail.csclub.uwaterloo.ca", 465)
# don't send out emails if this is true
#Don't send out emails if this gets set to True
testing = False
#Attempt to login 3 times
loginAttempts = 0
while loginAttempts < MAX_LOGIN_ATTEMPTS:
#Get the user's login info to login to the mail server
step3 = LoginForm(w, hb, width=mx - 20)
(r, c) = w.getmaxyx()
w.mvwin(cy - r // 2, cx - c // 2)
loginInfo = step3.event_loop()
step3.clear()
csclubID = loginInfo[0]
csclubPwd = loginInfo[1]
if csclubID == "TESTING12345":
testing = True
break
try:
server.login(csclubID, csclubPwd)
break
except smtplib.SMTPAuthenticationError:
loginAttempts += 1
#Check to see if login failed
if loginAttempts >= MAX_LOGIN_ATTEMPTS:
return ""
if librarianName == "TESTING12345":
testing = True
#Get the books that are signed out
signed_out_books = db.get_checkedout_books()
@ -182,20 +157,17 @@ def sendemails_procedure(w, hb, cy, cx, mx):
earliest_checkout = min(earliest_checkout,
datetime.strptime(date, "%Y-%m-%d"))
#Exit from the email server
server.quit()
#A success message about what emails we just sent
assert earliest_checkout > datetime(2010,1,1)
time_since_earliest_checkout = ''
time_since_earliest_checkout = ""
days_since_earliest_checkout = (datetime.now().toordinal()
- earliest_checkout.toordinal())
assert days >= 0
month_length = 30 #It's wrong because it's an approximation
if days_since_earliest_checkout < month_length:
time_since_earliest_checkout = '{} days ago'.format(days_since_earliest_checkout)
time_since_earliest_checkout = "{} days ago".format(days_since_earliest_checkout)
else:
time_since_earliest_checkout = '{:0.1f} months ago'.format(days_since_earliest_checkout / month_length)
time_since_earliest_checkout = "{:0.1f} months ago".format(days_since_earliest_checkout / month_length)
if emails_sent == 0:
success_text = """