parent
8e592f3adc
commit
6ed3c35554
@ -0,0 +1,148 @@ |
||||
#Import smtp for the email sending function |
||||
import smtplib |
||||
|
||||
#Import argparse to parse command line args |
||||
import argparse |
||||
|
||||
#Import sys so that we can exit when given bad command line args |
||||
import sys |
||||
|
||||
#Import datetime and time to check dates |
||||
from datetime import date |
||||
import time |
||||
|
||||
#Import getpass for password input |
||||
import getpass |
||||
|
||||
#Import subprocess for validation of if a user is in a group |
||||
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, catch_error_with, error_form |
||||
|
||||
#Constants |
||||
DEFAULT_DAY_VALUE = 21 |
||||
MAX_LOGIN_ATTEMPTS = 3 |
||||
|
||||
class DaysForm(FormWindow): |
||||
caption = "Enter the max number of days a book can be signed out for" |
||||
blabel = "Enter" |
||||
labels = ["Days"] |
||||
|
||||
def _return_values(self): |
||||
return self.entries[0].value |
||||
|
||||
|
||||
class NameForm(FormWindow): |
||||
caption = "Enter the name you want in the signature line for the email" |
||||
blabel = "Enter" |
||||
labels = ["Name"] |
||||
|
||||
def _return_values(self): |
||||
if self.entries[0].value is "": |
||||
return "Librarian" |
||||
else: |
||||
return self.entries[0].value |
||||
|
||||
#Private functions |
||||
def _send_email(quest_id: str, signed_out_date: str, max_days_can_be_signed_out:int, librarianName: str, book_name_list) -> None: |
||||
"""Sends an email to quest_id@csclub.uwaterloo.ca if the date the book |
||||
was signed out exceeds the days it is supposed to be signed out for""" |
||||
|
||||
email_address = quest_id + "@csclub.uwaterloo.ca" |
||||
book_name = "".join(book_name_list) |
||||
|
||||
#Determine the days the book has been signed out |
||||
date_tokens = signed_out_date.split("-") |
||||
date_signed_out = date(int(date_tokens[0]), int(date_tokens[1]), int(date_tokens[2])) |
||||
days_signed_out = date.fromtimestamp(time.time()) - date_signed_out |
||||
|
||||
if days_signed_out.days > max_days_can_be_signed_out: |
||||
email_message_body = ("Hi " + quest_id + ",\n\n" + "Our records indicate that you " |
||||
"have had the book " + book_name + " signed out for " + str(str(days_signed_out).split(" ")[:1])[2:-2] + |
||||
" days.\n\n" + "Please return the book to the CS Club office " |
||||
"(MC 3036) at your earliest convenience.\n\n" + "Thanks,\n\n" + |
||||
librarianName + "\n" + "Computer Science Club | University of Waterloo\n" |
||||
"librarian@csclub.uwaterloo.ca") |
||||
|
||||
email_message_subject = "Overdue book: {}".format(book_name) |
||||
email_message = "Subject: {}\n\n{}".format(email_message_subject, email_message_body) |
||||
|
||||
server.sendmail("librarian@csclub.uwaterloo.ca", email_address, email_message) |
||||
|
||||
#Public functions |
||||
@permissions.check_permissions(permissions.PERMISSION_LIBCOM) |
||||
@catch_error_with(lambda w, hb, *args : (w, hb, None)) |
||||
def sendemails_procedure(w, hb, cy, cx, mx): |
||||
"""Procedure to send emails to those with overdue books |
||||
|
||||
w: ncurses window for the routine |
||||
cy,cx: centre coordinates of the screen |
||||
mx: max width of screen |
||||
""" |
||||
|
||||
#Get the max days a book can be signed out for |
||||
step1 = DaysForm(w,hb,width=mx-20) |
||||
(r,c)=w.getmaxyx() |
||||
w.mvwin(cy-r//2,cx-c//2) |
||||
days = step1.event_loop() |
||||
step1.clear() |
||||
|
||||
#Set the days to a default value if the value given is less than 0 |
||||
if not isinstance(days, int) or days < 0: |
||||
days = DEFAULT_DAY_VALUE |
||||
|
||||
#Get the name of the librarain |
||||
step2 = NameForm(w,hb,width=mx-20) |
||||
(r,c)=w.getmaxyx() |
||||
w.mvwin(cy-r//2,cx-c//2) |
||||
librarianName = step2.event_loop() |
||||
step2.clear() |
||||
|
||||
#Set up email |
||||
global server |
||||
server = smtplib.SMTP_SSL("mail.csclub.uwaterloo.ca", 465) |
||||
|
||||
#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] |
||||
|
||||
try: |
||||
server.login(csclubID, csclubPwd) |
||||
break |
||||
except smtplib.SMTPAuthenticationError: |
||||
loginAttempts += 1 |
||||
|
||||
#Check to see if login failed |
||||
if loginAttempts >= MAX_LOGIN_ATTEMPTS: |
||||
return "" |
||||
|
||||
#Get the books that are signed out |
||||
signed_out_books = db.get_checkedout_books() |
||||
|
||||
for data in signed_out_books: |
||||
quest_id = data["uwid"] |
||||
date = str(data["date"]).split(" ")[0] |
||||
book_name_with_spaces = data["title"] |
||||
|
||||
_send_email(str(quest_id), str(date), days, str(librarianName), book_name_with_spaces) |
||||
|
||||
#Exit from the email server |
||||
server.quit() |
||||
|
||||
return "" |
||||
|
||||
|
Loading…
Reference in new issue