Commit 2e9041f2 authored by Jack Otto's avatar Jack Otto
Browse files

Merge branch 'master' of https://gitlab.bucknell.edu/tjs030/bucknellscheduler

 Conflicts:
	webserver.py
parents b8b47acc a92e42cf
from ortools.sat.python import cp_model
from ortools.sat.python.cp_model import CpModel
from ..calendar.cal_setup import get_calendar_service
from datetime import datetime, timedelta
from googleapiclient import errors
from .schedule_objects import Course, Room, Professor
class Schedule:
def __init__(self, model, courses, rooms, profs, days, hours):
self.model = model
def __init__(self, courses, rooms, profs, days, hours):
self.model = cp_model.CpModel()
self.solver = cp_model.CpSolver()
self.courses = courses
self.rooms = rooms
self.profs = profs
......@@ -10,12 +20,14 @@ class Schedule:
for n in self.courses:
for day in self.days:
for hour in self.hours:
for hour in ['10', '11', '12', '14', '15', '09', '08', '16', '13']: ## This is the ideal arrangement of hours
for c in self.rooms:
for p in self.profs:
self.scheduled_classes[(n, c, p, day, hour)] = self.model.NewBoolVar(
f'{n}_{c}_{p}_{day}_{hour}')
self.initialize_constraints()
def initialize_constraints(self):
print("Adding Class must be taught constraint...")
## The class must be taught
......@@ -201,5 +213,98 @@ class Schedule:
except:
print("Error adding previous hard constraint")
def generate_schedule(self):
self.delete_events()
status = self.solver.Solve(self.model)
self.solver.Solve(self.model)
print(status)
for n in self.courses:
for d in self.days:
for h in self.hours:
for c in self.rooms:
for p in self.profs:
if self.solver.Value(self.scheduled_classes[(n, c, p, d, h)]) == 1:
print(f'{n} is taught with {p} in {c} on {d} at {h}')
self.create_event(n,c,p,d,h) # Create GCAL events
## TODO Manually add these events
#final_schedule.append(ScheduleObject(Course("MECH 402C 10", 20, "", 2, ["Th"], 4), Room("DANA115", 20, "", []), Professor("Senior Design Profs", 0, []), "Th", "13"))
#final_schedule.append(ScheduleObject(Course("MECH 402C 11", 20, "", 2, ["Th"], 4), Room("DANA137", 20, "", []), Professor("Senior Design Profs", 0, []), "Th", "13"))
def create_event(self, n, c, p, d, h):
# creates an event that lasts the length of the class
service = get_calendar_service()
dt_now = datetime.now().date()
dayOffset=0
if d == "Mo":
dayOffset = 0
elif d == "Tu":
dayOffset = 1
elif d == "We":
dayOffset = 2
elif d == "Th":
dayOffset = 3
else:
dayOffset = 4
# using 11/1/21 as the date to start the calendar on because 11/1/21 is a monday and thus can use the days the class is taught on to determine the day offset
setTime = datetime(dt_now.year, 11, 1+dayOffset, int(h))
start = setTime.isoformat()
end = (setTime + timedelta(hours=n.length)).isoformat()
event_result = service.events().insert(calendarId='jlitoptimization@gmail.com',
body={
"summary": n.name,
"description": 'Taught in ' + c.name + ' by Professor ' + p.name,
"start": {"dateTime": start, "timeZone": 'America/New_York'},
"end": {"dateTime": end, "timeZone": 'America/New_York'},
"colorId": n.color,
}
).execute()
#write the id to a file to save it
with open("./backend/scheduler/eventID.txt", 'a') as file:
file.write(event_result['id'])
file.write("\n")
print("created event")
print("id: ", event_result['id'])
print("summary: ", event_result['summary'])
print("starts at: ", event_result['start']['dateTime'])
print("ends at: ", event_result['end']['dateTime'])
def delete_events(self):
service = get_calendar_service()
file = open("./backend/scheduler/eventID.txt")
for line in file:
removed_id = line.strip()
try:
service.events().delete(
calendarId='jlitoptimization@gmail.com',
eventId=str(removed_id),
).execute()
print("Event deleted")
except errors.HttpError:
print("Failed to delete event")
file.close()
file = open("./backend/scheduler/eventID.txt", "w")
file.close()
def find_object(self, name):
for n in self.courses:
if n.name == name:
return n
for c in self.rooms:
if c.name == name:
return c
for p in self.profs:
if p.name == name:
return p
\ No newline at end of file
from flask import Flask, redirect, url_for, request
from flask.templating import render_template
from backend.scheduler.scheduler_class import Schedule
from backend.scheduler.schedule_objects import Course, Room, Professor
from backend.inputs.spring_2022_inputs import classes, classrooms, professors
profs = []
courses = []
rooms = []
day_names = ['Mo', 'Tu', 'We', 'Th', 'Fr']
hours = ['08', '09', '10', '11', '12', '13', '14', '15', '16']
for name, length, size, req, days, color in classes:
courses.append(Course(name, size, req, length, days, color))
for room, capacity, feature, unavailable in classrooms:
rooms.append(Room(room, capacity, feature, unavailable))
for name, load, teachable in professors:
profs.append(Professor(name, load, teachable))
scheduler = Schedule(courses, rooms, profs, day_names, hours)
## TODO Only run the scheduler init once!!!!
running = False
app = Flask(__name__)
......@@ -12,20 +37,6 @@ def home():
def index():
return render_template("index.html")
@app.route('/table', methods = ['GET', 'POST'])
def table():
if request.method == 'GET':
return render_template("table.html")
else: ## POST
generate_schedule()
## Generate schedule.html
return render_template("table.html") ## return render_template("schedule.html")
@app.route("/constraints_form", methods=['GET', 'POST'])
def constraint_form():
return render_template("/constraints_form.html")
@app.route("/calendar", methods = ['GET', 'POST'])
def calendar():
global running
......@@ -34,7 +45,7 @@ def calendar():
else: ## POST
if not running:
running = True
generate_schedule()
scheduler.generate_schedule()
running = False
else:
return "Please Wait while another computer generates a schedule :)"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment