Skip to content

Commit 06f630f

Browse files
committed
more functional frontend
1 parent 2c73c7e commit 06f630f

21 files changed

Lines changed: 786 additions & 114 deletions

api/database/idb_queue.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ def __init__(self):
1010
def enqueue_student(self, student):
1111
raise NotImplementedError()
1212

13+
@abstractmethod
14+
def enqueue_student_front(self, student):
15+
raise NotImplementedError()
16+
1317
@abstractmethod
1418
def dequeue_student(self):
1519
raise NotImplementedError()
@@ -19,5 +23,9 @@ def get_queue(self):
1923
raise NotImplementedError()
2024

2125
@abstractmethod
22-
def remove_student(self, student, reason):
23-
raise NotImplementedError()
26+
def remove_student(self, student):
27+
raise NotImplementedError()
28+
29+
@abstractmethod
30+
def clear_queue(self):
31+
raise NotImplementedError()

api/database/idb_visits.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ def create_visit(self, student, ta, enqueue_time) -> int:
2222
raise NotImplementedError()
2323

2424
@abstractmethod
25-
def end_visit(self, visit_id):
25+
def end_visit(self, visit_id, reason):
2626
"""Mark in the database that the specified visit
2727
has ended.
2828
2929
:param visit_id: The numeric ID representing the specific visit
30+
:param reason: The resolution of the visit
3031
"""
3132
raise NotImplementedError()

api/database/relational_db/relational_db.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def initialize(self):
2424
(
2525
user_id INTEGER PRIMARY KEY,
2626
preferred_name VARCHAR(64),
27-
last_name VARCHAR (64),
27+
last_name VARCHAR(64),
2828
ubit VARCHAR(16) UNIQUE,
2929
person_num INTEGER UNIQUE,
3030
course_role VARCHAR(16)
@@ -37,7 +37,8 @@ def initialize(self):
3737
CREATE TABLE IF NOT EXISTS queue
3838
(
3939
user_id INTEGER UNIQUE,
40-
joined TEXT DEFAULT (datetime('now', 'localtime'))
40+
joined TEXT DEFAULT (datetime('now', 'localtime')),
41+
priority INTEGER
4142
);
4243
"""
4344
)
@@ -63,6 +64,7 @@ def initialize(self):
6364
ta_id INTEGER,
6465
session_start TEXT DEFAULT (datetime('now','localtime')),
6566
session_end TEXT,
67+
session_end_reason TEXT,
6668
enqueue_time TEXT
6769
);
6870
"""

api/database/relational_db/relational_db_queue.py

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,27 @@ def enqueue_student(self, student):
77
with self.cursor() as cursor:
88
cursor.execute(
99
"""
10-
INSERT OR IGNORE INTO queue (user_id) VALUES (?)
10+
INSERT OR IGNORE INTO queue (user_id, priority) VALUES (?, 0)
1111
""",
1212
(student,),
1313
)
1414

15+
def enqueue_student_front(self, student):
16+
with self.cursor() as cursor:
17+
priority = cursor.execute("SELECT MAX(priority) FROM queue").fetchone()[0]
18+
if priority is None:
19+
priority = 0
20+
else:
21+
priority += 1
22+
23+
cursor.execute(
24+
"""
25+
INSERT OR IGNORE INTO queue (user_id, priority)
26+
VALUES (?, ?)
27+
""",
28+
(student, priority),
29+
)
30+
1531
def dequeue_student(self):
1632
with self.cursor() as cursor:
1733
rows = cursor.execute("SELECT COUNT(*) from queue").fetchone()[0]
@@ -20,10 +36,10 @@ def dequeue_student(self):
2036

2137
user = cursor.execute(
2238
"""
23-
SELECT users.user_id, preferred_name, ubit, person_num
39+
SELECT users.user_id, preferred_name, ubit, person_num, joined
2440
FROM queue
2541
INNER JOIN users ON queue.user_id = users.user_id
26-
ORDER BY joined
42+
ORDER BY priority DESC, joined
2743
"""
2844
).fetchone()
2945
cursor.execute("DELETE FROM queue WHERE user_id = ?", (user[0],))
@@ -33,6 +49,31 @@ def dequeue_student(self):
3349
"preferred_name": user[1],
3450
"ubit": user[2],
3551
"person_num": str(user[3]),
52+
"enqueue_time": user[4]
53+
}
54+
55+
def dequeue_specified_student(self, student_id):
56+
with self.cursor() as cursor:
57+
user = cursor.execute(
58+
"""
59+
SELECT users.user_id, preferred_name, ubit, person_num, joined
60+
FROM queue
61+
INNER JOIN users ON queue.user_id = users.user_id
62+
WHERE users.user_id = ?
63+
""", (student_id,)
64+
).fetchone()
65+
66+
if user is None:
67+
return None
68+
69+
cursor.execute("DELETE FROM queue WHERE user_id = ?", (user[0],))
70+
71+
return {
72+
"user_id": user[0],
73+
"preferred_name": user[1],
74+
"ubit": user[2],
75+
"person_num": str(user[3]),
76+
"enqueue_time": user[4]
3677
}
3778

3879
def get_queue(self):
@@ -55,5 +96,16 @@ def get_queue(self):
5596

5697
return users_l
5798

58-
def remove_student(self, student, reason):
59-
pass
99+
def clear_queue(self):
100+
with self.cursor() as cursor:
101+
cursor.execute(
102+
"DELETE FROM queue"
103+
)
104+
105+
def remove_student(self, student):
106+
with self.cursor() as cursor:
107+
queue_info = cursor.execute("SELECT * FROM queue WHERE user_id = ?", (student, )).fetchone()
108+
109+
cursor.execute("DELETE FROM queue WHERE user_id = ?", (student, ))
110+
111+
return {"user_id": queue_info[0], "joined": queue_info[1]}

api/database/relational_db/relational_db_visits.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ def create_visit(self, student, ta, enqueue_time) -> int:
2020

2121

2222

23-
def end_visit(self, visit_id):
23+
def end_visit(self, visit_id, reason):
2424
# YYYY-MM-DD HH:MM:SS
2525
now = str(datetime.datetime.now().isoformat(' ', timespec="seconds"))
2626

2727
with self.cursor() as cursor:
2828
cursor.execute("""
2929
UPDATE visits
30-
SET session_end = ?
30+
SET session_end = ?, session_end_reason = ?
3131
WHERE visit_id = ? AND session_end is null
32-
""")
32+
""", (now, reason, visit_id))
3333

api/queue/controller.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,27 @@ def add_to_queue_by_card_swipe(swipe_data):
1717
return False
1818

1919

20-
def add_to_queue_by_ta_override(identifier):
20+
def add_to_queue_by_ta_override(identifier, front=False):
2121
student = db.lookup_identifier(identifier)
2222
if student is not None:
23-
add_to_queue(student)
23+
if front:
24+
add_to_front_of_queue(student)
25+
else:
26+
add_to_queue(student)
2427
return True
2528
return False
2629

2730

2831
def add_to_queue(user_account):
2932
user_id = user_account["user_id"]
3033
db.enqueue_student(user_id)
34+
35+
def add_to_front_of_queue(user_account):
36+
user_id = user_account["user_id"]
37+
db.enqueue_student_front(user_id)
38+
39+
def remove_from_queue_without_visit(student, reason):
40+
queue_info = db.remove_student(student)
41+
visit = db.create_visit(student, None, queue_info["joined"])
42+
db.end_visit(visit, reason)
43+

api/queue/routes.py

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from flask import Blueprint, request
44

55
import api.queue.controller as controller
6+
from api.queue.controller import remove_from_queue_without_visit
67
from api.roster.controller import min_level
78
from api.database.db import db
89

@@ -86,10 +87,18 @@ def dequeue():
8687
"""
8788
role: TA
8889
89-
Remove the first student from the queue and create a Visit in the DB
90+
Remove the specified student from the queue and create a Visit in the DB
9091
9192
Not allowed if TA is already in a visit
9293
94+
Args:
95+
body.id: The ID of the account to dequeue
96+
97+
Body:
98+
{
99+
"id": <string>
100+
}
101+
93102
Returns:
94103
200 OK - Student was dequeued
95104
{
@@ -99,23 +108,34 @@ def dequeue():
99108
"preferred_name: <string>
100109
}
101110
102-
400 Bad Request - The queue is empty
111+
400 Bad Request - The queue is empty or user is not in the queue
103112
403 Unauthorized - Requester does not have TA permissions
104113
{
105114
"message": <string>
106115
}
107116
"""
108117

109-
student = db.dequeue_student()
118+
body = request.get_json()
119+
120+
if not (auth_token := request.cookies.get("auth_token")):
121+
return {"message": "You are not logged in!"}, 403
122+
123+
user = db.get_authenticated_user(auth_token)
124+
user_id = user["user_id"]
125+
126+
student = db.dequeue_specified_student(body["id"])
110127

111128
if student is None:
112129
return {"message": "The queue is empty"}, 400
113130

131+
visit = db.create_visit(body["id"], user_id, student["enqueue_time"])
132+
114133
return {
115134
"id": int(student["user_id"]),
116135
"username": student["ubit"],
117136
"pn": str(student["person_num"]),
118137
"preferred_name": student["preferred_name"],
138+
"visitID": visit
119139
}
120140

121141

@@ -215,7 +235,23 @@ def remove_self():
215235
"message": <string>
216236
}
217237
"""
218-
return f"{request.path} hit 😎, remove method is used."
238+
239+
if not (auth_token := request.cookies.get("auth_token")):
240+
return {"message": "You are not logged in!"}, 403
241+
242+
user = db.get_authenticated_user(auth_token)
243+
244+
if not user:
245+
return {"message": "You are not logged in!"}, 403
246+
247+
user_id = user["user_id"]
248+
body = request.get_json()
249+
250+
remove_from_queue_without_visit(user_id, f"[SELF-REMOVE]: {body["reason"]}")
251+
252+
253+
254+
return {"message":"Removed self from queue."}
219255

220256

221257
@blueprint.route("/remove-from-queue", methods=["POST"])
@@ -245,7 +281,59 @@ def remove(user_id):
245281
"""
246282
return f"{request.path} hit 😎, remove method is used."
247283

284+
@blueprint.route("/clear-queue", methods=["DELETE"])
285+
@min_level('ta')
286+
def clear_queue():
287+
db.clear_queue()
288+
return {"message": "Successfully cleared the queue."}
289+
290+
291+
@blueprint.route("/enqueue-override-front")
292+
@min_level('ta')
293+
def enqueue_override_front():
294+
""" Exact same behavior as /enqueue-ta-override, except it sends the student to the front.
295+
296+
Args:
297+
body.identifier: A unique identifier for the student This can either be their UBIT, pn, or the id of their account
298+
299+
Body:
300+
{
301+
"identifier": <string>
302+
}
303+
304+
Returns:
305+
200 OK - Student was added to the queue
306+
403 Unauthorized - Requester does not have TA permissions
307+
404 Not Found - No student matching provided identifier
308+
{
309+
"message": <string>,
310+
}
311+
"""
312+
body = request.get_json()
313+
identifier = body["identifier"]
314+
315+
if controller.add_to_queue_by_ta_override(identifier, True):
316+
return {"message": "Student was added to the front of the queue"}
317+
318+
return {"message": "No student matching provided identifier"}, 404
319+
320+
@blueprint.route("/end-visit", methods=["POST"])
321+
@min_level('ta')
322+
def end_visit():
323+
body = request.get_json()
324+
325+
visit = body.get("id")
326+
reason = body.get("reason")
327+
328+
if visit is None or reason is None:
329+
return {"message": "Malformed request"}, 400
330+
331+
db.end_visit(visit, reason)
332+
333+
return {"message": "Ended the visit"}
334+
335+
248336

249337
# TODO: move to end of queue (Called by TAs to add the students they just saw back to the end of the queue)
250338

251-
# TODO: Clear the queue
339+

0 commit comments

Comments
 (0)