feat(InterviewBooking): almost preped for merge into one repo

This commit is contained in:
2024-12-21 22:52:36 -07:00
parent 0de072a5ad
commit 9eae4153ad
31 changed files with 12 additions and 136 deletions

View File

@ -1,128 +0,0 @@
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from NoSheet import NoSheet
import datetime
import os
year_donation = int(str(datetime.datetime.now().year)[2:]) + 1 # gets the last two digits of the current year then adds 1 for the current season
# name based off the 2025 naming system
# Define the path to the Excel file and the lock file
file_name = f"/Interviews/OR{year_donation}-L-Interview Data.xlsx"
if not os.path.isfile(file_name):
os.makedirs(os.path.dirname(file_name), exist_ok=True)
NoSheet(file_name)
app = FastAPI()
@app.get("/")
def get_root():
"""
This does nothing, allows for pings to check for life
``REQUIRES``: ```None`` Nothing
``PROMISES``: ``JSON`` returns a short message in the body
``Develop in part by``: Brock
``Contact``: darkicewolf50@gmail.com
"""
res = {"message": "Hello I am alive, this does nothing"}
# Return the response with the custom header
return JSONResponse(
headers={
"isBase64Encoded": "false", # Header Modification
},
content={
"body": res # Ensure res is a dict or do json.dumps to enusre it is stringified
},
# status_code=200 commented out just to show how to change it if you wanted
)
from interviewPackagers import getSchedulePackager
@app.get("/getAppointments")
async def getAppointments():
"""
checks for all available slots in the database
``REQUIRES``: ``None`` Nothing
``PROMISES``: ``JSON`` returns all of the avaialbe slots by date then time
``Develop in part by``: Brock
``Contact``: darkicewolf50@gmail.com
"""
res = getSchedulePackager(file_name)
return JSONResponse(
headers={
"isBase64Encoded": "false", # Header Modification
},
content={
"body": res # Ensure res is a dict or do json.dumps to enusre it is stringified
},
# status_code=200 commented out just to show how to change it if you wanted
)
from interviewPackagers import SelectAppointment
class Appointment(BaseModel):
"""
The formatted
``REQUIRES``: Correct Format
``PROMISES``: Formatted class, needs to be converted into dict os that it can be used in another file
``Develop in part by``: Brock
``Contact``: darkicewolf50@gmail.com
"""
intervieweeName: str
date: str
startTime: str
intervieweeEmail: str
@app.post("/SelectInterview")
async def postSelectInterview(rawRequest: Appointment):
"""
Books an interview, first checks if the slot is valid
``REQUIRES``: ``Appointment`` A specifically formatted request
``PROMISES``: ``JSON`` returns if the booking was successful or not
``Develop in part by``: Brock
``Contact``: darkicewolf50@gmail.com
"""
requestDict = {key: str(value) for key, value in rawRequest.dict().items()}
res = SelectAppointment(file_name, requestDict)
return JSONResponse(
headers={
"isBase64Encoded": "false", # Header Modification
},
content={
"body": res # Ensure res is a dict or do json.dumps to enusre it is stringified
},
# status_code=200 commented out just to show how to change it if you wanted
)

View File

@ -1,5 +0,0 @@
fastapi[standard]
pandas
openpyxl
PyYAML
filelock

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,44 +0,0 @@
import pandas as pd
import yaml
# Load the YAML file
with open("./interview_database.yaml", 'r') as file:
interview_data = yaml.safe_load(file)
# Access the nested structure within 'Data'
flattened_data = []
for date, date_info in interview_data['Data'].items():
meeting_duration = date_info.get('Meeting Duration')
for start_time_info in date_info.get('Meeting Start Times', []):
for start_time, meeting_info in start_time_info.items():
interviewer_name = meeting_info['Interviewer'][0].get('Name')
interviewer_email = meeting_info['Interviewer'][1].get('Email')
interviewee_name = meeting_info['Interviewee'][0].get('Name')
interviewee_email = meeting_info['Interviewee'][1].get('Email')
category = meeting_info.get('Category')
status = meeting_info.get('Status')
slot = meeting_info.get('Slot')
# Add flattened row to list
flattened_data.append({
'Date': date,
'Meeting Duration': meeting_duration,
'Start Time': start_time,
'Interviewer Name': interviewer_name,
'Interviewer Email': interviewer_email,
'Interviewee Name': interviewee_name,
'Interviewee Email': interviewee_email,
'Category': category,
'Status': status,
'Slot': slot
})
# Convert to DataFrame if flattened data is not empty
if flattened_data:
df = pd.DataFrame(flattened_data)
# Write the DataFrame to an Excel file
df.to_excel("interview_database.xlsx", index=False)
print("Data has been written to interview_database.xlsx")
else:
print("No data found to write.")

View File

@ -1,17 +0,0 @@
# Use an official Python runtime as a parent image
FROM python:3.10-slim
# Set the working directory inside the container
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY ./mock /app
# Install any necessary dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Expose port 8080 for the container to listen on
EXPOSE 8080
# Command to run the Python server when the container starts
CMD ["python", "server.py"]

View File

@ -1,10 +0,0 @@
services:
test-http-container:
container_name: test-http-container
ports:
- 8080:8080
volumes:
- ./mock:/app
build: .
# networks:
# - testnet

View File

@ -1,49 +0,0 @@
import json
import signal
import sys
from http.server import BaseHTTPRequestHandler, HTTPServer
from django.http import HttpResponse
# Function to generate the response
def send_funct():
ymlschedule = {"message": False}
to_send = {
"statusCode": 200,
"isBase64ENcoded": "false",
"body": json.dumps(ymlschedule)
}
return json.dumps(to_send)
# Define request handler
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
# Send response headers
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
# Send the response body (the JSON data)
self.wfile.write(send_funct().encode('utf-8'))
# Graceful shutdown handler
def signal_handler(sig, frame):
print("\nShutting down server gracefully...")
sys.exit(0)
# Set up and start the server
if __name__ == "__main__":
# Register signal handler for graceful shutdown (e.g., Ctrl+C)
signal.signal(signal.SIGINT, signal_handler)
# Set the server address (localhost) and port (8080)
server_address = ('', 8080)
httpd = HTTPServer(server_address, RequestHandler)
print("Server started on port 8080")
try:
# Start the server and listen for requests
httpd.serve_forever()
except KeyboardInterrupt:
# Server shutdown is handled in signal_handler
pass

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1 +0,0 @@
# Interview-Backend

View File

@ -1,11 +0,0 @@
from WriteDB import AppendAppointment
def TestBookAppointment():
date_1 = "2024-09-16"
start_time_1 = "10:30:00"
interviewee_name_1 = "Alice Johnson"
interviewee_email_1 = "ahmadmuhammadofficial@gmail.com"
print(f"\nTest Case 1: Trying to book {date_1} at {start_time_1} for {interviewee_name_1} ({interviewee_email_1})")
AppendAppointment(date_1, start_time_1, interviewee_name_1, interviewee_email_1)
TestBookAppointment()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,8 +0,0 @@
# syntax=docker/dockerfile:1
FROM python:3.10-slim
WORKDIR /code
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["python", "app.py"]

View File

@ -1,32 +0,0 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
hit_count = 0 # In-memory counter
def get_hit_count():
global hit_count
hit_count += 1
return hit_count
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
count = get_hit_count()
response = f'Hello World! I have been seen {count} times.\n'
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(response.encode('utf-8'))
else:
self.send_response(404)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(b'Not Found\n')
def run(server_class=HTTPServer, handler_class=RequestHandler, port=8000):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print(f'Starting server on port {port}...')
httpd.serve_forever()
if __name__ == '__main__':
run()

View File

@ -1,8 +0,0 @@
services:
web:
container_name: test
build: .
ports:
- "8000:8000"
volumes:
- ./:/code

View File

@ -1,64 +0,0 @@
Data:
September 16:
Meeting Duration: 30 min
Meeting Start Times:
- 10:00 AM:
Interviewer:
- Name: John
- Email: john@example.com
Interviewee:
- Name: Jane
- Email: jane@example.com
Category: PowerDrive
Status: Done
Slot: 2
- 10:30 AM:
Interviewer:
- Name: Jay
- Email: jay@example.com
Interviewee:
- Name: Zoz
- Email: Zoz@example.com
Category: PowerTrain
Status: Pending
Slot: 3
- 11:00 AM:
Interviewer:
- Name: Ali
- Email: Ali@example.com
Interviewee:
- Name: Bob
- Email: Bob@example.com
Category: Software
Status: Rescheduled
Slot: 1
- 11:30 AM:
Interviewer:
- Name:
- Email:
Interviewee:
- Name:
- Email:
Category:
Status:
Slot: 1
- 12:00 PM:
Interviewer:
- Name: Ali, John
- Email: Ali@example.com, Jhon@example.com
Interviewee:
- Name: Bob
- Email: Bob@example.com
Category: Software
Status: Cancelled
Slot: 1
- 12:30 PM:
Interviewer:
- Name: Ali
- Email: Ali@example.com
Interviewee:
- Name: Bob, Jish
- Email: Bob@example.com, jish@example.com
Category: Software
Status: Cancelled
Slot: 2

View File

@ -1,17 +0,0 @@
import requests
import json
if __name__ == "__main__":
getres = requests.get("http://bajacloud.ddnsking.com:43443/getAppointments")
print(getres)
print(json.dumps(json.loads(getres.text), indent=4))
# example of a request
# postdata = {
# "intervieweeName": "Brock",
# "date": "2024-09-16",
# "startTime": "11:00:00",
# "intervieweeEmail": "darkicewolf50@gmail.com"
# }
# res = requests.post("http://bajacloud.ddnsking.com:43443/SelectInterview", json.dumps(postdata))
# print(res)
# print(res.text)

View File

@ -1,25 +0,0 @@
import json
import requests
import timeit
def BenchMarkServer():
rawRes = requests.get("http://localhost:8080/getAppointments")
res = json.loads(rawRes.text)
print(json.dumps(res, indent=1))
def BenchMarkDjango():
rawRes = requests.get("http://127.0.0.1:8000/getAppointments")
res = json.loads(rawRes.text)
print(json.dumps(res, indent=1))
if __name__ == "__main__":
test = 1
if test:
djangoTime = timeit.timeit(stmt=BenchMarkDjango, number=1000)
# pythonTime = timeit.timeit(stmt=BenchMarkServer, number=10)
print(f"FastAPI: {djangoTime}\nPython: ")
# reqbody = {
# "body": {"message": "hello"}
# }
# rawRes = requests.post("http://localhost:8000/SelectInterview", reqbody)

View File

@ -1,29 +0,0 @@
<html lang="en-US">
<head>
<title>Interview Invitation</title>
</head>
<body>
<p>Dear {interviewee_name},</p>
<p>Your interview has been scheduled on {date} at {start_time}</p>
<p>Please ensure to be available at the designated time.</p>
<a
href="https://calendar.google.com/calendar/render?action=TEMPLATE&text=Interview+with+{interviewee_name}&dates=20241130T100000Z/20241130T110000Z&details=Interview+with+UCalgary+Baja+Team&location=ENC37"
target="_blank"
>
<button type="button" class="AddtoCal">Add to Google Calendar</button>
</a>
<a
href="https://outlook.live.com/calendar/0/deeplink/compose?subject=Interview+with+{interviewee_name}&body=Interview+with+UCalgary+Baja+Team&location=ENC37&startdt=2024-11-30T10:00:00&enddt=2024-11-30T11:00:00"
target="_blank"
>
<button type="button" class="AddtoCal">Add to Outlook Calendar</button>
</a>
<p>Best regards,</p>
<p>UCalgary Baja Interview Team</p>
<img
src="https://res.cloudinary.com/dpgrgsh7g/image/upload/v1733003224/UCalgaryBAJA_Logo-2024_mpmljh.png"
alt="UCalgary Baja Team"
height="120svh"
/>
</body>
</html>

View File

@ -1,12 +1,11 @@
import pandas as pd
import json
from openpyxl import load_workbook
from send_email import send_email
from .send_email import send_email
from filelock import FileLock
"""
TODO make it work with the new template
TODO update names to be more clear
TODO try to remove pandas
"""

View File

@ -1,4 +1,4 @@
from ReadDB import ReadDatabase
from .ReadDB import ReadDatabase
def getSchedulePackager(file_name):
@ -18,7 +18,7 @@ def getSchedulePackager(file_name):
"interviewDates": ReadDatabase(file_path=file_name)
}
from WriteDB import AppendAppointment
from .WriteDB import AppendAppointment
from email_validator import validate_email, EmailNotValidError