From a9460dc6928e3e68eb8c6b4b7e7c454b52f498c9 Mon Sep 17 00:00:00 2001 From: darkicewolf50 Date: Sat, 7 Dec 2024 19:48:55 -0700 Subject: [PATCH] feat(Packagers): combined get and post into a file, added condition of no excel file to read and write --- GetSchedulePackager.py | 25 ----- MockDB/schedule.yaml | 11 -- NoSheet.py | 48 +++++---- OR25-L-Interview Data.xlsx | Bin 6733 -> 6776 bytes ReadDB.py | 106 ++++++++++--------- WriteDB.py | 159 ++++++++++++++++------------ __pycache__/NoSheet.cpython-313.pyc | Bin 0 -> 4705 bytes interviewPackagers.py | 0 main.py | 4 +- postSelectAppointment.py | 44 -------- send_email.py | 16 ++- temp.yml | 37 ------- 12 files changed, 192 insertions(+), 258 deletions(-) delete mode 100644 GetSchedulePackager.py delete mode 100644 MockDB/schedule.yaml create mode 100644 __pycache__/NoSheet.cpython-313.pyc create mode 100644 interviewPackagers.py delete mode 100644 postSelectAppointment.py delete mode 100644 temp.yml diff --git a/GetSchedulePackager.py b/GetSchedulePackager.py deleted file mode 100644 index 6e85fd7..0000000 --- a/GetSchedulePackager.py +++ /dev/null @@ -1,25 +0,0 @@ -import yaml -import json - -from ReadDB import ReadDatabase - -with open("./MockDB/schedule.yaml", "r") as scheduleyml: - ymlschedule = yaml.safe_load(scheduleyml) - -def getSchedulePackager(): - """ - Formats and allows for the - - ``REQUIRES``: None - - ``PROMISES``: ``JSON`` http response ready - - ``Develop in part by``: Brock T - - ``Contact``: darkicewolf50@gmail.ocm - - """ - return { - "interviewDates": ReadDatabase() - } - diff --git a/MockDB/schedule.yaml b/MockDB/schedule.yaml deleted file mode 100644 index 2a85139..0000000 --- a/MockDB/schedule.yaml +++ /dev/null @@ -1,11 +0,0 @@ -Date: - Sept 16: - Meeting Duration: 30 min - Meeting Start Times: - - 10:00 am - - 10:30 am - - 11:00 am - - 11:30 am - - 1:00 pm - - 1:30 pm - - 2:00 pm diff --git a/NoSheet.py b/NoSheet.py index e5d9aab..f8fd33b 100644 --- a/NoSheet.py +++ b/NoSheet.py @@ -1,13 +1,24 @@ import openpyxl import yaml -import json import datetime from openpyxl.styles import Font, Border, Side, PatternFill from openpyxl.formatting.rule import FormulaRule def NoSheet(): - # sheet with an example properites + """ + Creates the Template for more data to be added + + ``REQUIRES``: ``None`` Ensure no other sheets are present, will overwrite them + + ``PROMISES``: ``XLSX File`` give the template for recuitment for the year + + ``Develop in part by``: Brock + + ``Contact``: darkicewolf50@gmail.com + + """ + yamlraw = """ Recruitment Responses: - Frist Name (What we should call them): Steve @@ -39,21 +50,20 @@ Interview TimeTable: - Category (if not general): Test - Interviewer(s) Name(s): Example - Status: Dropdown (Options in datahelp) #default is Unknown -Data Helper: +Data Helper And Info: - Status Dropdown: - Unknown - Done - No Show - Cancelled/Moved + - First time Startup: Call getschedule for the year - How to Add Dropdown: Go into data, click data validation, select list then select the area you want to get values from in the formula spot """ - + # uses the base above "yaml file" to create the base template yamlsheet = yaml.safe_load(yamlraw) - # print(json.dumps(yamlsheet, indent=4)) - year_donation = int(str(datetime.datetime.now().year)[2:]) # gets the last two digits of the current year then adds 1 for the current season - file_name = f"OR{year_donation + 1}-L-Interview Data.xlsx" # name based off the 2025 naming system + file_name = f"./OR{year_donation + 1}-L-Interview Data.xlsx" # name based off the 2025 naming system # border style border = Border( # defualt behaviour is thin @@ -63,9 +73,6 @@ Data Helper: bottom=Side(style='thin') ) - # for conditional formatting - red_fill = PatternFill(start_color="FF0000", end_color="FF0000", fill_type="solid") - # create workbook in memory work_book = openpyxl.Workbook() @@ -73,45 +80,50 @@ Data Helper: default_sheet = work_book.active work_book.remove(default_sheet) + # decomposes the yaml file at the top and convertss it into a standard template + # does one sheet at a time for sheet_name, title_list in yamlsheet.items(): - # add standard sheets + # add 1 standard sheet, by the outermost name sheet = work_book.create_sheet(sheet_name) + # gets header titles for each sheet, from the inner list titles = [list(title.keys())[0] for title in title_list] + # makes the header titles to bold, have a border and have text for col_num, title in enumerate(titles, start=1): cell = sheet.cell(row=1, column=col_num) cell.value = title - cell.font = Font(bold=True) cell.border = border - + # example data to show on what it will look like or to copy formatting down example_data = [list(data.values())[0] for data in title_list] for col_num, data in enumerate(example_data, start=1): + # for special case Data Helper where there a list in a dictionary if isinstance(data, list): row_num = 2 for item in data: cell = sheet.cell(row=row_num, column=col_num) cell.value = item row_num += 1 + # adds data to the cells else: cell = sheet.cell(row=2, column=col_num) - cell.value = data + # changes the Dropdown data in status to unknown instead of the other option, only there for prep for a dropdown if data == "Dropdown (Options in datahelp)": cell.value = "Unknown" + else: + cell.value = data + if sheet.title == "Recruitment Responses": sheet.conditional_formatting.add("A2:I2", FormulaRule(formula=['=$I2="No"'], fill=PatternFill(start_color="FF0000", end_color="FF0000", fill_type="solid"))) - - - - # save to storage work_book.save(file_name) + print(f"Created {file_name} for {year_donation}") if __name__ == "__main__": NoSheet() \ No newline at end of file diff --git a/OR25-L-Interview Data.xlsx b/OR25-L-Interview Data.xlsx index cfa75ffdf1c0e40745315517b036a3d2174c615a..6d0e3f3dc831da1b7b693df12e0e6091125a4328 100644 GIT binary patch delta 1467 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 an6)F`v$4KwZ~rS__xk)HEKkx!IQDP2DbXna literal 0 HcmV?d00001 diff --git a/interviewPackagers.py b/interviewPackagers.py new file mode 100644 index 0000000..e69de29 diff --git a/main.py b/main.py index f052938..307f85c 100644 --- a/main.py +++ b/main.py @@ -35,7 +35,7 @@ def get_root(): ) -from GetSchedulePackager import getSchedulePackager +from interviewPackagers import getSchedulePackager @app.get("/getAppointments") async def getAppointments(): @@ -65,7 +65,7 @@ async def getAppointments(): # status_code=200 commented out just to show how to change it if you wanted ) -from postSelectAppointment import SelectAppointment +from interviewPackagers import SelectAppointment class Appointment(BaseModel): """ diff --git a/postSelectAppointment.py b/postSelectAppointment.py deleted file mode 100644 index f48b30b..0000000 --- a/postSelectAppointment.py +++ /dev/null @@ -1,44 +0,0 @@ -from WriteDB import AppendAppointment -from email_validator import validate_email, EmailNotValidError - - -def SelectAppointment (appointmentJson): - """ - packages up a response for a http request - - ``appointmentJSON``: ``JSON`` - The appointment date and time details - - ``returns``: ``json`` - Returns the status of the booking confirmation - - ``Develop in part by``: Brock T - - ``Contact``: darkicewolf50@gmail.com - """ - """ - { - "intervieweeName": "Alice Johnson", - "date": "2024-09-16", - "startTime": "10:30:00", - "intervieweeEmail": "darkicewolf50@gmail.com" - } - """ - try: - validEmail = validate_email(appointmentJson["intervieweeEmail"], check_deliverability=True) - if validEmail: - status = AppendAppointment(date=appointmentJson["date"], start_time=appointmentJson["startTime"], interviewee_name=appointmentJson["intervieweeName"], interviewee_email=appointmentJson["intervieweeEmail"]) - - if status: - resBody = {"Success": True, "validEmail": "true"} - else: - resBody = {"Success": False, "validEmail": "true"} - - # resBody["message"] = appointmentJson for testing - return resBody - - except EmailNotValidError as e: - return {"Success": False, "validEmail": "false"} - -if __name__ == "__main__": - print(SelectAppointment("10:00 AM")) diff --git a/send_email.py b/send_email.py index 888ce36..a506b71 100644 --- a/send_email.py +++ b/send_email.py @@ -4,12 +4,20 @@ from email.mime.text import MIMEText from datetime import datetime, timedelta import pytz # For timezone handling -def send_email(interviewee_email="darkicewolf50@gmail.com", interviewee_name="brock", date="10-1-2024", start_time="10:00 AM", location ="ENC25"): +""" +TODO add +""" +def send_email(interviewee_email="darkicewolf50@gmail.com", interviewee_name="brock", date="2024-1-10", start_time="10:00:00", location ="ENC25"): """ - Sends an email notification to the interviewee and a static Gmail account. + Sends an email notification to the interviewee and to the uofcbaja account - ``REQUIRES``: interviewee_email (str), interviewee_name (str), date (str), start_time (str) - ``PROMISES``: Sends an email to interviewee and static email on successful appointment booking. + ``REQUIRES``: ``str`` interviewee_email, ``str`` interviewee_name, ``str`` date, ``str`` start_time + + ``PROMISES``: ``EMAIL`` Sends an email to interviewee and static email on successful appointment booking. + + ``Developed by``: Ahmad + + ``Contact``: ahmad.ahmad1@ucalgary.ca """ # Define static email for notifications and Gmail credentials static_email = "uofcbaja.noreply@gmail.com" diff --git a/temp.yml b/temp.yml deleted file mode 100644 index a4d7d76..0000000 --- a/temp.yml +++ /dev/null @@ -1,37 +0,0 @@ -Recruitment Responses: - - Frist Name (What we should call them): Steve - - Last Name: the Bug - - Ucalgary Email: steve.the.bug@ucalgary.ca - - What Subsystem/SubTeam are you interested in?: | - Chassis - Ergonomics - Suspension - Steering - Powertrain - Final Drive - Any Mechanical - Business - Content Creation - Business - Business Relations - Software - - Major: General (1st Year) - - Academic Year: 1st - - Why are you interested in joining UCalgary BAJA?: Example Interest - - Where did you hear about us?: Testing - - Are you available for team meetings/work days? Saturdays 10 am - 4 pm: "Yes" #add condiftional formatting for no to make whole line red -Interview TimeTable: - - Date: 9/16/2024 - - Meeting Duration: 30 min - - Start Time Slot: 10:00:00 AM - - Slot: 1 - - Interviewee Name (What to call them): Steve - - Interviewee Email: steve.the.bug@ucalgary.ca - - Category (if not general): Test - - Interviewer(s) Name(s): Example - - Status: Dropdown (Options in datahelp) #default is Unknown -Data Helper: - - Status Dropdown: - - Unknown - - Done - - No Show - - Cancelled/Moved - - How to Add Dropdown: Go into data, click data validation, select list then select the area you want to get values from in the formula spot