def calculateDues(book_id, token=None, uid=None): ''' Function to calculate the dues for a student given the student token/ USN and the book id We take both token and USN because if the admin makes the request when viewing a students page then we need to be able to handle that as well params: book_id : <str> The books ID token : <str> Default None , The token of the user making the request uid : <str> The USN of the student to calculate the due for returns: <str> --- if theres no due <int> The amount due if books are due ''' # get the token from the tokencollection userData = tokenCollection.find_one({"token": token}) # if the token belongs to an admin then the borrow data needs to come from the student ie students user id if userData['_id'] == "Admin": userData = {"_id": uid} # get the borrow object borrowObj = borrowsCollection.find_one({ "User": userData['_id'], "BookID": book_id }) # get the number of days overdue daysDue = ( datetime.now().replace(minute=0, second=0, hour=0, microsecond=0) - borrowObj['DueDate'].replace( minute=0, second=0, hour=0, microsecond=0)).days if daysDue <= 0: return "--" else: return format_price(5 * daysDue)
def decorated_function(*args, **kwargs): ''' Function to wrap the passed function params: *args: <args> The arguments **kwargs : <kwargs> The Kwargs returns: <f::returnType> The Return of the passed function ''' # If the token isnt available, redirect to login if "token" not in session or not session['token']: return redirect(url_for("loginHandler")) token = session['token'] # If the tokendata is not present redirect to login tokenData = tokenCollection.find_one({"token": token}, {"token": 0}) if not tokenData: return redirect(url_for("loginHandler")) # If the user data does not exist, redirect to login userData = usersCollection.find_one({"_id": tokenData['_id']}, {"Type": 1}) if not userData: return redirect(url_for("index")) # If the type is Stuent we redirect to index ie home page if userData['Type'] == "Student": return redirect(url_for("index")) return f(*args, **kwargs)
def userLogin(userData): ''' Function to check the users credentials and login. params: userData : <dict> Dict containing the user details ie password and usn returns: <dict> {status:True,message:True,token:<str:token string>} if success {status:False,message:Error Message} if failure ''' # Check if USN and password fields are non-empty # if empty return the error if not userData['USN']: return {'status':False,'message':"Please Enter USN"} if not userData['password']: return {'status':False,'message':"Please Enter password"} # Check if the user token exists or not in the token collection # if it exists it means the user is already logged in userToken = tokenCollection.find_one({"_id":userData['USN']}) if userToken: return {'status':True,'message':"User logged in","token":userToken['token']} try: # Fetch the users auth data userAuth = authCollection.find_one({"_id":userData['USN']}) # handle connection failure except ConnectionFailure: return {'status':False,'message':"Could not connect to database"} # if the auth data does not exist , error out if not userAuth: return {'status':False,'message':"User does not exist"} # calculate the the hash of the given password + the salt passHash = sha256((userData['password']+userAuth['salt']).encode()).hexdigest() # if it matches , login successfully if passHash == userAuth['passHash']: token = str(uuid4()) # insert the token and the id into the token collection try: tokenCollection.insert_one({ "_id":userData['USN'], "token":token }) except DuplicateKeyError: return {"status":True,'message':"User already logged in","token":token} return {"status":True,'message':"User Logged in","token":token} # if the hash does not match we error out else: return {'status':False,'message':"Incorrect USN or password"}
def checkIfReserved(token, book_id): ''' Function to check if the book has been reserved by the current user params: token: <str> The token of the current user book_id : <str> The ID of the book returns: <bool> True, if reserved False if not reserved ''' tokenObj = tokenCollection.find_one({"token": token}) borrowObj = borrowsCollection.find_one({ "User": tokenObj['_id'], "BookID": book_id }) if not borrowObj: return False else: return True
def getDueDate(token, book_id, uid=None): ''' Function to get the due date for the given book for the given user params: token : <str> The token of the user making the request book_id : <str> The ID of the book returns: <str> Date in yyyy-mm-dd format ''' # get the token from the tokencollection tokenObj = tokenCollection.find_one({"token": token}) # if the token belongs to an admin then the borrow data needs to come from the student ie students user id if tokenObj['_id'] == "Admin": tokenObj = {"_id": uid} borrowObj = borrowsCollection.find_one({ "User": tokenObj['_id'], "BookID": book_id }) duedate = borrowObj['DueDate'].strftime("%Y-%m-%d") return duedate
def getUserFromToken(token): ''' Function to get the user data for a particular user based on the token params: token : <str> The Users token returns: <dict> {status:True,message:<dict: User data>,borrows:<List(dict): list of all borrowed books >} if success {status:False,message:Error Message} if failure ''' try: # get the token object from the token collection tokenData = tokenCollection.find_one({"token":token}) # handle connection failure except ConnectionFailure: return {'status':False,'message':"Unable to connnect to database"} # if the token obj does not exist, then return an error if not tokenData: return {'status':False,'message':"Token does not exist, please refresh/logout and log back in"} # get the user associated with that token userId = tokenData['_id'] try: # get the userdata based on that token userData = usersCollection.find_one({"_id":userId}) # handle connection faliure except ConnectionFailure: return {'status':False,'message':"Unable to connnect to database"} # if user obj does not exist throw an error if not userData: return {'status':False,'message':"User data does not exist"} borrowData = getUsersBorrowedBooks(userId) if not borrowData['status']: return {'status':False,'message':"Unable to fetch user data"} borrowData = borrowData['message'] # return the user object return {'status':True,'message':userData,'borrows':borrowData}
def isAdmin(token): ''' Function to check if the token of the user is an admin token or not params: token :<str> The token of the user making the request returns: <bool> True if admin False if not admin ''' tokenData = tokenCollection.find_one({"token": token}, {"token": 0}) if not tokenData: return False userData = usersCollection.find_one({"_id": tokenData['_id']}, {"Type": 1}) if not userData: return False if userData['Type'] == "Student": return False else: return True
def reserveBook(book_id,book_name,token): ''' Function to reserve a book params: book_id : <str> The book id for the book being borrowed book_name : <str> The book Name token : <str> The token of the user making the request ''' tokenObj = tokenCollection.find_one({"token":token}) if not tokenObj: return {'status':False,'message':"Unable to find token, please logout and log back in"} # generate the book borrow object borrowObj = { "BookName":book_name, "BorrowedOn":datetime.now(), "DueDate":(datetime.now() + timedelta(days=10)), "ReturnedOn":None, "User":tokenObj['_id'], "BookID":book_id } # find if the book is in stock before inserting the borrow data into the database book_stock = booksCollection.find_one({"_id":book_id},{"Stock":1}) # if not in stock throw an error if book_stock['Stock']<=0: return {'status':False,'message':"Book is out Stock"} # if in stock then update the count of that book and insert the borrow obj booksCollection.update_one({"_id":book_id},{"$inc":{"Stock":-1}}) # insert the object try: borrowsCollection.insert_one(borrowObj) except ConnectionFailure: booksCollection.update_one({"_id":book_id},{"$inc":{"Stock":1}}) return {'status':False,'message':"Unable to connect to database"} return {'status':True,'message':"Book reserved"}