@ -8,7 +8,7 @@ import argparse
import sys
#Import datetime and time to check dates
from datetime import date
from datetime import datetime
import time
#Import getpass for password input
@ -21,128 +21,146 @@ import subprocess
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
from library . interface . form import FormWindow , BookForm , LoginForm , catch_error_with , error_form
from library . emails import format_reminder_email
# email testing folder creation
import os
#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 " ]
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
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
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 :
def _send_email ( quest_id : str ,
signed_out_date : str ,
max_days_can_be_signed_out : int ,
librarian_name : str ,
book_name_list ,
testing = False ) - > 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
was signed out exceeds the days it is supposed to be signed out for .
Set testing to true to output emails to the current directory , instead
of actually sending them .
"""
# Determine the days the book has been signed out
d = datetime . strptime ( signed_out_date , " % Y- % m- %d " )
days_signed_out = ( d . today ( ) - d ) . days
if days_signed_out > max_days_can_be_signed_out :
email_address = quest_id + " @csclub.uwaterloo.ca "
book_name = " " . join ( book_name_list )
email_message = format_reminder_email ( quest_id , days_signed_out , librarian_name , book_name )
if testing :
os . makedirs ( " test_emails " , exist_ok = True )
with open ( " test_emails/ {} _ {} .txt " . format ( quest_id , book_name ) , ' w ' ) as f :
print ( email_message , file = f )
else :
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 ) )
@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
""" 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 " "
#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 )
# don't send out emails if this is 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 " "
#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 ,
testing )
#Exit from the email server
server . quit ( )
return " "