mirror of
https://github.com/UofCBaja/BajaCloud.git
synced 2025-07-08 12:07:12 -06:00
feat(InterviewBooking): almost preped for merge into one repo
This commit is contained in:
@ -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
|
||||
)
|
||||
|
@ -1,5 +0,0 @@
|
||||
fastapi[standard]
|
||||
pandas
|
||||
openpyxl
|
||||
PyYAML
|
||||
filelock
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
@ -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.")
|
@ -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"]
|
@ -1,10 +0,0 @@
|
||||
services:
|
||||
test-http-container:
|
||||
container_name: test-http-container
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- ./mock:/app
|
||||
build: .
|
||||
# networks:
|
||||
# - testnet
|
Binary file not shown.
@ -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 |
Binary file not shown.
@ -1 +0,0 @@
|
||||
# Interview-Backend
|
@ -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 |
@ -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"]
|
@ -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()
|
@ -1,8 +0,0 @@
|
||||
services:
|
||||
web:
|
||||
container_name: test
|
||||
build: .
|
||||
ports:
|
||||
- "8000:8000"
|
||||
volumes:
|
||||
- ./:/code
|
@ -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
|
Binary file not shown.
@ -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)
|
@ -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)
|
@ -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>
|
@ -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
|
||||
"""
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user