mirror of
https://github.com/UofCBaja/Interview-Backend.git
synced 2025-06-15 13:24:19 -06:00
feat(Send_Email): Added feature to send emails
This commit is contained in:
commit
58f913d3ed
44
ConversionToExcel.py
Normal file
44
ConversionToExcel.py
Normal file
@ -0,0 +1,44 @@
|
||||
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.")
|
134
WriteDB.py
Normal file
134
WriteDB.py
Normal file
@ -0,0 +1,134 @@
|
||||
import pandas as pd
|
||||
import json
|
||||
from openpyxl import load_workbook
|
||||
from send_email import send_email
|
||||
|
||||
# Define the path to the Excel file
|
||||
file_path = "./interview_database.xlsx"
|
||||
|
||||
def ReadDatabase():
|
||||
"""
|
||||
Reads the Database to retrieve available interview slots.
|
||||
|
||||
``REQUIRES``: None
|
||||
|
||||
``PROMISES``: JSON (Available interview slots)
|
||||
|
||||
``Developed by``: Ahmad
|
||||
|
||||
``Contact``: ahmad.ahmad1@ucalgary.ca
|
||||
"""
|
||||
# Load the Excel file into a pandas DataFrame with specific columns
|
||||
df = pd.read_excel(file_path, usecols=['Date', 'Start Time', 'Slot', 'Interviewee Name', 'Interviewee Email', 'Meeting Duration'])
|
||||
|
||||
# Initialize the dictionary to store structured data for available slots
|
||||
interview_data = {}
|
||||
|
||||
# Process each row in the DataFrame to structure data by date and time
|
||||
for _, row in df.iterrows():
|
||||
# Convert Date and Start Time to string format for easier comparison
|
||||
date = str(row['Date']).split(" ")[0] # Format date to YYYY-MM-DD
|
||||
start_time = str(row['Start Time'])
|
||||
|
||||
# Calculate the slot capacity and current number of interviewees
|
||||
slot_capacity = int(row['Slot']) if not pd.isna(row['Slot']) else 0
|
||||
interviewee_names = [name.strip() for name in str(row['Interviewee Name']).split(',') if name.strip()]
|
||||
interviewee_count = len(interviewee_names) if interviewee_names != ["nan"] else 0
|
||||
|
||||
# Check if there are available slots for more interviewees
|
||||
if interviewee_count < slot_capacity:
|
||||
# Organize data by date and time, keeping track of available slots and meeting duration
|
||||
if date not in interview_data:
|
||||
interview_data[date] = {}
|
||||
interview_data[date][start_time] = {
|
||||
'Meeting Duration': row['Meeting Duration'],
|
||||
'Available Slots': slot_capacity - interviewee_count
|
||||
}
|
||||
|
||||
return interview_data
|
||||
|
||||
def AppendAppointment(date, start_time, interviewee_name, interviewee_email):
|
||||
"""
|
||||
Appends a new appointment with the interviewee's name and email if the slot is available.
|
||||
|
||||
``REQUIRES``: date (str), start_time (str), interviewee_name (str), interviewee_email (str)
|
||||
|
||||
``PROMISES``: Updates the Excel file with the new interviewee's name and email if there is an available slot. Returns Bool.
|
||||
|
||||
``Developed by``: Ahmad
|
||||
|
||||
``Contact``: ahmad.ahmad1@ucalgary.ca
|
||||
"""
|
||||
available_slots = ReadDatabase()
|
||||
|
||||
# Check if the requested slot is available in the `available_slots` structure
|
||||
if date in available_slots and start_time in available_slots[date]:
|
||||
# Load workbook and select "Sheet1" for updating appointments
|
||||
workbook = load_workbook(file_path)
|
||||
sheet = workbook["Sheet1"]
|
||||
df = pd.read_excel(file_path)
|
||||
|
||||
# Find and update the row that matches the provided date and start time
|
||||
for index, row in df.iterrows():
|
||||
row_date = str(row['Date']).split(" ")[0]
|
||||
row_start_time = str(row['Start Time'])
|
||||
|
||||
if row_date == date and row_start_time == start_time:
|
||||
# Current entries for names and emails, and append new data with comma and space
|
||||
current_names = str(row['Interviewee Name']).strip()
|
||||
current_emails = str(row['Interviewee Email']).strip()
|
||||
|
||||
updated_names = f"{current_names}, {interviewee_name}" if current_names != "nan" else interviewee_name
|
||||
updated_emails = f"{current_emails}, {interviewee_email}" if current_emails != "nan" else interviewee_email
|
||||
|
||||
# Update the cells with new names and emails
|
||||
name_cell = sheet.cell(row=index + 2, column=df.columns.get_loc('Interviewee Name') + 1)
|
||||
email_cell = sheet.cell(row=index + 2, column=df.columns.get_loc('Interviewee Email') + 1)
|
||||
name_cell.value = updated_names
|
||||
email_cell.value = updated_emails
|
||||
|
||||
workbook.save(file_path)
|
||||
send_email(interviewee_email, interviewee_name, date, start_time)
|
||||
return True
|
||||
|
||||
# If no slots available, return that the slot is unavailable
|
||||
return False
|
||||
|
||||
def run_tests():
|
||||
"""
|
||||
Executes test cases to verify appointment scheduling and slot availability.
|
||||
|
||||
``REQUIRES``: None
|
||||
|
||||
``PROMISES``: Prints test outcomes to validate successful booking or slot unavailability.
|
||||
"""
|
||||
print("Available Slots:")
|
||||
available_slots = ReadDatabase()
|
||||
print(json.dumps(available_slots, indent=4))
|
||||
|
||||
# Test Case 1: Append to an available slot on 2024-09-16 at 10:30:00
|
||||
date_1 = "2024-09-16"
|
||||
start_time_1 = "10:30:00"
|
||||
interviewee_name_1 = "Alice Johnson"
|
||||
interviewee_email_1 = "alice.johnson@example.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)
|
||||
|
||||
# Test Case 2: Append to an available slot on 2024-09-17 at 13:30:00
|
||||
date_2 = "2024-09-17"
|
||||
start_time_2 = "13:30:00"
|
||||
interviewee_name_2 = "Bob Smith"
|
||||
interviewee_email_2 = "bob.smith@example.com"
|
||||
print(f"\nTest Case 2: Trying to book {date_2} at {start_time_2} for {interviewee_name_2} ({interviewee_email_2})")
|
||||
AppendAppointment(date_2, start_time_2, interviewee_name_2, interviewee_email_2)
|
||||
|
||||
# Test Case 3: Attempting to book at 10:30:00 on 2024-09-16 for a different interviewee
|
||||
date_3 = "2024-09-16"
|
||||
start_time_3 = "10:30:00"
|
||||
interviewee_name_3 = "Charlie Brown"
|
||||
interviewee_email_3 = "charlie.brown@example.com"
|
||||
print(f"\nTest Case 3: Trying to book {date_3} at {start_time_3} for {interviewee_name_3} ({interviewee_email_3})")
|
||||
AppendAppointment(date_3, start_time_3, interviewee_name_3, interviewee_email_3)
|
||||
|
||||
# Run tests
|
||||
run_tests()
|
BIN
__pycache__/send_email.cpython-312.pyc
Normal file
BIN
__pycache__/send_email.cpython-312.pyc
Normal file
Binary file not shown.
BIN
interview_database.xlsx
Normal file
BIN
interview_database.xlsx
Normal file
Binary file not shown.
64
interview_database.yaml
Normal file
64
interview_database.yaml
Normal file
@ -0,0 +1,64 @@
|
||||
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
|
41
send_email.py
Normal file
41
send_email.py
Normal file
@ -0,0 +1,41 @@
|
||||
import smtplib
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
def send_email(interviewee_email="darkicewolf50@gmail.com", interviewee_name="brock", date="y", start_time="x"):
|
||||
"""
|
||||
Sends an email notification to the interviewee and a static Gmail 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.
|
||||
"""
|
||||
# Define static email for notifications and Gmail credentials
|
||||
static_email = "uofcbaja.noreply@gmail.com"
|
||||
gmail_user = "uofcbaja.noreply@gmail.com"
|
||||
gmail_apppassword = "pver lpnt upjd zvld"
|
||||
|
||||
# Create message object
|
||||
msg = MIMEMultipart()
|
||||
msg['From'] = gmail_user
|
||||
msg['To'] = f"{interviewee_email}, {static_email}"
|
||||
msg['Subject'] = "Interview Appointment Confirmation"
|
||||
|
||||
# Message body
|
||||
body = (f"Dear {interviewee_name},\n\n"
|
||||
f"Your interview has been scheduled on {date} at {start_time}.\n"
|
||||
"Please ensure to be available at the designated time.\n\n"
|
||||
"Best regards,\nYour Interview Team")
|
||||
msg.attach(MIMEText(body, 'plain'))
|
||||
|
||||
try:
|
||||
# Setup the server and send the email
|
||||
server = smtplib.SMTP('smtp.gmail.com', 587)
|
||||
server.starttls()
|
||||
server.login(gmail_user, gmail_apppassword)
|
||||
server.sendmail(gmail_user, [interviewee_email, static_email], msg.as_string())
|
||||
server.quit()
|
||||
print(f"Email sent successfully to {interviewee_email} and {static_email}.")
|
||||
except Exception as e:
|
||||
print(f"Failed to send email: {e}")
|
||||
|
||||
send_email()
|
Loading…
x
Reference in New Issue
Block a user