Skip to content

Commit

Permalink
specific routing
Browse files Browse the repository at this point in the history
  • Loading branch information
chrissdelaney committed Apr 23, 2024
1 parent f67b1dd commit ade7d9c
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 101 deletions.
40 changes: 23 additions & 17 deletions app/spreadsheet_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,28 @@ def get_sheet(self, sheet_name):

def get_courses(self, email:str) -> list:
self.set_active_document(GOOGLE_SHEETS_MASTER_DOCUMENT_ID)
students_sheet = self.get_sheet("roster")
all_student_course_ids = students_sheet.get_all_records()
student_course_ids = [course["COURSE_ID"] for course in all_student_course_ids if course["EMAIL"] == email]
roster_sheet = self.get_sheet("roster")
all_course_ids = roster_sheet.get_all_records()
user_courses = [course_info for course_info in all_course_ids if course_info["EMAIL"] == email]

courses_sheet = self.get_sheet("courses")
all_courses = courses_sheet.get_all_records()

student_courses_info = [course_info for course_info in all_courses if course_info["COURSE_ID"] in student_course_ids]
for i in range(len(user_courses)):
course = user_courses[i]
general_course_info = [c for c in all_courses if c.get('COURSE_ID') == course.get('COURSE_ID')]
if len(general_course_info) == 0:
continue #in case generic info row not created
general_course_info = general_course_info[0]

print(student_courses_info)
if general_course_info.get('SHEETS_DOCUMENT_ID'):
del general_course_info['SHEETS_DOCUMENT_ID']

user_courses[i] = {**course, **general_course_info}

print(user_courses)

return student_courses_info
return user_courses


def get_course_assignments(self, student_email:str, course_id:str) -> list:
Expand Down Expand Up @@ -140,7 +150,6 @@ def get_course_roster(self, course_id:str):

self.set_active_document(course_document_id_list[0])

#get student_grade
gradebook_sheet = self.get_sheet("GRADEBOOK")
all_grades = gradebook_sheet.get_all_records()

Expand Down Expand Up @@ -252,7 +261,7 @@ def get_assignment_scores(self, student_email:str, course_id:str, assignment_id:
# AUTH FUNCTIONS #
#####################

def check_user_type(self, email:str) -> str:
def get_user_courses(self, email:str) -> list:
"""
this security is SO BAD and needs to be improved
but it'll work for now...
Expand All @@ -262,20 +271,17 @@ def check_user_type(self, email:str) -> str:
all_records = students_sheet.get_all_records()
courses_list = [row for row in all_records if row["EMAIL"] == email]

if len(courses_list) == 0:
return "user"
elif courses_list[0].get('USER_TYPE').lower() == "student":
return "student"
elif courses_list[0].get('USER_TYPE').lower() == "teacher":
return "teacher"
else:
return "unknown" #TODO: need a better catch here...
return courses_list




if __name__ == "__main__":

ss = SpreadsheetService()

ss.get_courses("[email protected]")

#ss.get_student_courses("[email protected]")

ss.get_assignment_scores("[email protected]", "12345", "onboarding")
#ss.get_assignment_scores("[email protected]", "12345", "onboarding")
10 changes: 6 additions & 4 deletions web_app/routes/auth_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ def google_oauth_callback():
# "locale": user_info["locale"],
#})

session['current_user']["user_type"] = get_user_type(user_info["email"])
session['current_user']["user_courses"] = get_user_courses(user_info["email"])

print("STORED IN SESSION:")
print(session['current_user']['user_courses'])

print(f"{session['current_user']['email']} is a {session['current_user']['user_type']}")


else:
Expand All @@ -82,9 +84,9 @@ def logout():
return redirect("/")


def get_user_type(email:str) -> str:
def get_user_courses(email:str) -> str:
ss = current_app.config["SPREADSHEET_SERVICE"]
return ss.check_user_type(email=email)
return ss.get_user_courses(email=email)
#
# EMAIL / PASSWORD AUTH (NOT IMPLEMENTED)
#
Expand Down
42 changes: 34 additions & 8 deletions web_app/routes/courses_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

courses_routes = Blueprint("courses_routes", __name__)

from web_app.routes.wrappers import authenticated_route, student_route, teacher_route
from web_app.routes.wrappers import authenticated_route, student_route, teacher_route, ta_route

@courses_routes.route("/courses/<course_id>")
@authenticated_route
Expand All @@ -14,19 +14,29 @@ def course(course_id):
#TODO: change hard coded email to "email" fetched from session
email = "[email protected]"
##################################
assignments_list = []

if current_user.get('user_type') == "student":

courses_info = [c for c in current_user.get('user_courses') if int(c['COURSE_ID']) == int(course_id)]

if len(courses_info) == 0:
flash(str(courses_info))
return redirect('/user/courses')

role = courses_info[0].get('USER_TYPE')

if role == "STUDENT":
assignments_list = ss.get_course_assignments(email, course_id)
return render_template("assignments.html", assignments=assignments_list, course_id=course_id)
elif current_user.get('user_type') == "teacher":
elif role == "TEACHER" or role == "TA":
roster_data = ss.get_course_roster(course_id)
return render_template("course_roster.html", roster_data=roster_data)
return render_template("course_roster.html", roster_data=roster_data, course_id=course_id)
return render_template("assignments.html", assignments=assignments_list, course_id=course_id)


@courses_routes.route("/courses/<course_id>/assignments/<assignment_id>")
@authenticated_route
@student_route
@student_route()
def assignment(course_id, assignment_id):
print(f"COURSE {course_id}: ASSIGNMENT {assignment_id}")
ss = current_app.config["SPREADSHEET_SERVICE"]
Expand All @@ -37,8 +47,24 @@ def assignment(course_id, assignment_id):
email = "[email protected]"
#######################

assignment_details = ss.get_assignment_scores(email, course_id, assignment_id)
try:
assignment_details = ss.get_assignment_scores(email, course_id, assignment_id)

print(assignment_details)
except Exception as e:
flash('Error, could not fetch assignment details')
flash(str(e))
return redirect(f'/courses/{course_id}')

return render_template("assignment.html", assignment_details=assignment_details)
return render_template("assignment.html", assignment_details=assignment_details)

@courses_routes.route("/courses/<course_id>/students/<student_info>")
@authenticated_route
@ta_route()
def student_grades(course_id, student_info):
student_info_list = student_info.split("__")
last_name = student_info_list[0]
first_name = student_info_list[1]
student_email = student_info_list[2]
ss = current_app.config["SPREADSHEET_SERVICE"]
assignments_list = ss.get_course_assignments(student_email, course_id)
return render_template("assignments_teacher.html", assignments=assignments_list, course_id=course_id, student_email=student_email, first_name=first_name, last_name=last_name)
4 changes: 2 additions & 2 deletions web_app/routes/user_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ def courses():
ss = current_app.config["SPREADSHEET_SERVICE"]

email = current_user["email"]
email = "[email protected]"

courses = ss.get_courses(email)
print(courses)

return render_template("courses.html", courses=courses)

Expand Down Expand Up @@ -78,4 +78,4 @@ def profile():
print("USER PROFILE...")
current_user = session.get("current_user")
#user = fetch_user(email=current_user["email"])
return render_template("user_profile.html", user=current_user) # user=user
return render_template("user_profile.html", user=current_user) # user=user
136 changes: 109 additions & 27 deletions web_app/routes/wrappers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@

import functools
from flask import session, redirect, flash
from flask import session, redirect, flash, request

STATUS_DICT = {
"USER": 1,
"STUDENT": 2,
"TA": 3,
"TEACHER": 4,
"ADMIN": 5
}

def authenticated_route(view):
"""
Expand All @@ -23,30 +31,104 @@ def wrapped_view(**kwargs):
return redirect("/login")
return wrapped_view

def student_route(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
current_user = session.get("current_user")
if current_user.get("user_type") == "student": #this security is so weak haha
#print("CURRENT USER:", session["current_user"])
return view(**kwargs)
else:
print("UNAUTHENTICATED...")
flash("Unauthenticated!", "warning")
return redirect("/")

return wrapped_view
def student_route():
def decorator(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
course_id = kwargs.get('course_id', request.view_args.get('course_id'))
current_user = session.get("current_user")
if not current_user:
return redirect ("/login")

user_courses = current_user.get('user_courses')

def teacher_route(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
current_user = session.get("current_user")
if current_user.get("user_type") == "teacher": #this security is so weak haha
#print("CURRENT USER:", session["current_user"])
return view(**kwargs)
else:
print("UNAUTHENTICATED...")
flash("Unauthenticated!", "warning")
return redirect("/")

return wrapped_view
if not user_courses:
print("USER COURSES:")
print(user_courses)
print("ERROR...")
flash("ERROR! We could not find this assignment.", "warning")
return redirect("/user/courses")

course_status_list = [c for c in user_courses if int(c.get('COURSE_ID')) == int(course_id)]

if len(course_status_list) == 0:
return redirect("/user/courses") #user not in course

course_status = course_status_list[0].get('USER_TYPE')

if STATUS_DICT.get(course_status) >= STATUS_DICT.get("STUDENT"):
return view(**kwargs)
else:
print("UNAUTHENTICATED...")
flash("Unauthenticated! You are not allowed to access this page.", "warning")
return redirect("/user/courses")
return wrapped_view
return decorator

def ta_route():
def decorator(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
course_id = kwargs.get('course_id', request.view_args.get('course_id'))
current_user = session.get("current_user")
if not current_user:
return redirect ("/login")

user_courses = current_user.get('user_courses')

if not user_courses:
print("USER COURSES:")
print(user_courses)
print("ERROR...")
flash("ERROR! We could not find this assignment.", "warning")
return redirect("/user/courses")

course_status_list = [c for c in user_courses if int(c.get('COURSE_ID')) == int(course_id)]

if len(course_status_list) == 0:
return redirect("/user/courses") #user not in course

course_status = course_status_list[0].get('USER_TYPE')

if STATUS_DICT.get(course_status) >= STATUS_DICT.get("TA"):
return view(**kwargs)
else:
print("UNAUTHENTICATED...")
flash("Unauthenticated! You are not allowed to access this page.", "warning")
return redirect("/user/courses")
return wrapped_view
return decorator

def teacher_route():
def decorator(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
course_id = kwargs.get('course_id', request.view_args.get('course_id'))
current_user = session.get("current_user")
if not current_user:
return redirect ("/login")

user_courses = current_user.get('user_courses')

if not user_courses:
print("USER COURSES:")
print(user_courses)
print("ERROR...")
flash("ERROR! We could not find this assignment.", "warning")
return redirect("/user/courses")

course_status_list = [c for c in user_courses if int(c.get('COURSE_ID')) == int(course_id)]

if len(course_status_list) == 0:
return redirect("/user/courses") #user not in course

course_status = course_status_list[0].get('USER_TYPE')

if STATUS_DICT.get(course_status) >= STATUS_DICT.get("TEACHER"):
return view(**kwargs)
else:
print("UNAUTHENTICATED...")
flash("Unauthenticated! You are not allowed to access this page.", "warning")
return redirect("/user/courses")
return wrapped_view
return decorator
47 changes: 47 additions & 0 deletions web_app/templates/assignments_teacher.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{% extends "bootstrap_5_layout.html" %}
{% set active_page = "assignments" %}

{% block content %}

<h2>Assignments - {{first_name}} {{last_name}}({{student_email}})</h2>

<table class="table table-hover text-center">
<thead>
<tr>
<th scope="col">Assignment</th>
<th scope="col">Due Date</th>
<th scope="col">Points</th>
<th scope="col">Grade</th>
</tr>
</thead>
<tbody>
{% for a in assignments %}
<tr class="clickable-row" data-href="/courses/{{ course_id }}/assignments/{{ a.SHEET_NAME }}">
<td>
{{ a.NAME }}
</td>
<td>
{{ a.DUE_DATE }}
</td>
<td>
{{ a.POINTS }}
</td>
<td>
{{ a.GRADE }}
</td>
</tr>
{% endfor %}
</tbody>
</table>

<script>
document.addEventListener("DOMContentLoaded", function(){
document.querySelectorAll('.clickable-row').forEach(row => {
row.addEventListener('click', function() {
window.location.href = this.dataset.href;
});
});
});
</script>

{% endblock %}
Loading

0 comments on commit ade7d9c

Please sign in to comment.