diff --git a/codeGrader/backend/api/handlers/Score.py b/codeGrader/backend/api/handlers/Score.py index f25e3ac..36bd71b 100644 --- a/codeGrader/backend/api/handlers/Score.py +++ b/codeGrader/backend/api/handlers/Score.py @@ -85,8 +85,9 @@ def get_scores(self, view: str, arguments: dict = {}): db_object = self.sql_session.get_object(self.dbClass, object_id) print(db_object.id) score = db_object.user_score(user_id) + user = self.sql_session.get(User, user_id) - user_data_dict = {"user_id": user_id, "score": score} + user_data_dict = {"user_id": user_id, "username": user.username, "score": score} output_data_list.append(user_data_dict) output[str(self.dbClass.__table__)] = [{object_id: output_data_list}] @@ -94,10 +95,11 @@ def get_scores(self, view: str, arguments: dict = {}): else: # the object_id is not given, so we need to query all objects db_objects = self.sql_session.get_all(self.dbClass) + user = self.sql_session.get(User, user_id) for db_object in db_objects: score = db_object.user_score(user_id) print(score) - user_data_dict = {"user_id": user_id, "score": score} + user_data_dict = {"user_id": user_id, "username": user.username, "score": score} object_list.append({db_object.id: user_data_dict}) output[str(self.dbClass.__table__)] = object_list @@ -113,7 +115,7 @@ def get_scores(self, view: str, arguments: dict = {}): for user in users: score = db_object.user_score(user.id) - user_data_dict = {"user_id": user.id, "score": score} + user_data_dict = {"user_id": user.id, "username": user.username, "score": score} output_data_list.append(user_data_dict) object_list.append({object_id: output_data_list}) @@ -125,7 +127,7 @@ def get_scores(self, view: str, arguments: dict = {}): for db_object in db_objects: for user in users: score = db_object.user_score(user.id) - user_data_dict = {"user_id": user.id, "score": score} + user_data_dict = {"user_id": user.id, "username": user.username, "score": score} output_data_list.append(user_data_dict) object_list.append({db_object.id: output_data_list}) output_data_list = [] diff --git a/codeGrader/frontend/admin/app.py b/codeGrader/frontend/admin/app.py index dffe470..d36dd4b 100644 --- a/codeGrader/frontend/admin/app.py +++ b/codeGrader/frontend/admin/app.py @@ -35,7 +35,8 @@ DeleteExerciseHandler, DeleteProfileHandler, AddTaskAttachmentHandler, DeleteTaskAttachmentHandler, \ AddTaskInstructionHandler, DeleteTaskInstructionHandler, TaskInstructionHandler, TaskAttachmentHandler, \ SubmissionFileHandler, TestCaseInputFileHandler, TestCaseOutputFileHandler, AddTestCaseHandler, \ - DeleteTestCaseHandler, AddMembershipHandler, DeleteMembershipHandler, PasswordResetHandler, AddUserListHandler + DeleteTestCaseHandler, AddMembershipHandler, DeleteMembershipHandler, PasswordResetHandler, AddUserListHandler, \ + ErrorHandler from gevent.pywsgi import WSGIServer import datetime @@ -70,7 +71,7 @@ def app_index(): method = route.methods rule = route.rule endpoint = route.endpoint - output_data.append({rule:{"methods": method, "endpoint": endpoint} }) + output_data.append({rule: {"methods": method, "endpoint": endpoint}}) output["routes"] = output_data return output @@ -89,6 +90,17 @@ def adminUser_login(admin_id): return user +@app.errorhandler(Exception) +def error(err: Exception): + """ + Error Handler for a when a error occurs. + @param err: The Exception that has been raised + @type err: Exception + @return: Rendered Error Page with Information for the user + """ + return ErrorHandler(request).get(err, err.code) + + @app.route("/login", methods=['GET', 'POST']) def login() -> Union[Response, str]: """ diff --git a/codeGrader/frontend/admin/handlers/Error.py b/codeGrader/frontend/admin/handlers/Error.py new file mode 100644 index 0000000..8d6d5a1 --- /dev/null +++ b/codeGrader/frontend/admin/handlers/Error.py @@ -0,0 +1,74 @@ +# CodeGrader - https://github.com/ooemperor/CodeGrader +# Copyright © 2023, 2024 Michael Kaiser +# +# This file is part of CodeGrader. +# +# CodeGrader is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# CodeGrader is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with CodeGrader. If not, see . + +""" +Handler Classes for the Error Sites of the CodeGrader +""" +import flask +import flask_login +from flask import request, render_template, redirect +from .Base import BaseHandler +import datetime +from codeGrader.frontend.config import config + + +class ErrorHandler(BaseHandler): + """ + Handles Rendering of the Error Site + """ + + def __init__(self, request: flask.Request): + """ + Constructor of the Error Handler + @param request: The request from the app route of flask + @type request: flask.request + """ + super().__init__(request) + + def get(self, error: Exception, error_code: int) -> (str, int): + """ + Renders the template of the Error Site of the user frontend + @param error: The Exception of the site + @type error: Exception + @param error_code: The Error Code of the site + @type error_code: int + @return: str + """ + request_data = dict() + request_data["path"] = self.request.path + request_data["method"] = self.request.method + request_data["time"] = datetime.datetime.now() + request_data["error"] = error + + if error_code == 404: + request_data["title"] = "Page not found" + request_data["error_text"] = "It looks like the page you are looking for does not exist" + request_data["gif"] = config.gif_404 + return render_template("error.html", **request_data), error_code + + elif error_code == 500: + request_data["title"] = f"{config.userAppName} not found" + request_data["error_text"] = "An Error occured on the server while processing your request. Please Try Again!" + request_data["gif"] = config.gif_500 + return render_template("error.html", **request_data), error_code + + else: + request_data["title"] = f"{config.userAppName} Error" + request_data["error_text"] = "Something went wrong. Please Try Again!" + request_data["gif"] = config.gif_500 + return render_template("error.html", **request_data), error_code diff --git a/codeGrader/frontend/admin/handlers/Exercise.py b/codeGrader/frontend/admin/handlers/Exercise.py index e8ef4dd..3102a2d 100644 --- a/codeGrader/frontend/admin/handlers/Exercise.py +++ b/codeGrader/frontend/admin/handlers/Exercise.py @@ -70,6 +70,9 @@ def get(self, id_: int) -> Union[str, Response]: editable = self.admin.check_permission('w', exercise["profile"]["id"]) subjects = self.api.get("/subjects", profile=self.admin.get_filter_profile()) + scores = self.api.get(f"/scores/exercise", object_id=id_) + scores = scores["exercise"][0][str(id_)] + exercise["scores"] = scores exercise["subjects"] = subjects["subject"] diff --git a/codeGrader/frontend/admin/handlers/Subject.py b/codeGrader/frontend/admin/handlers/Subject.py index 1888d96..589d033 100644 --- a/codeGrader/frontend/admin/handlers/Subject.py +++ b/codeGrader/frontend/admin/handlers/Subject.py @@ -73,6 +73,10 @@ def get(self, id_: int) -> Union[str, Response]: subject["profiles"] = profiles["profile"] subject["memberships"] = memberships["membership"] + scores = self.api.get(f"/scores/subject", object_id=id_) + scores = scores["subject"][0][str(id_)] + subject["scores"] = scores + editable = self.admin.check_permission('w', subject["profile"]["id"]) subject["editable"] = editable diff --git a/codeGrader/frontend/admin/handlers/Task.py b/codeGrader/frontend/admin/handlers/Task.py index 90ec785..c1fc565 100644 --- a/codeGrader/frontend/admin/handlers/Task.py +++ b/codeGrader/frontend/admin/handlers/Task.py @@ -72,6 +72,9 @@ def get(self, id_: int) -> Union[str, Response]: exercises = self.api.get("/exercises", profile=self.admin.get_filter_profile()) submissions = self.api.get("/submissions", profile=self.admin.get_filter_profile(), task_id=id_) testcases = self.api.get("/testcases", task_id=id_) + scores = self.api.get(f"/scores/task", object_id=id_) + scores = scores["task"][0][str(id_)] + task["scores"] = scores task["exercises"] = exercises["exercise"] if "submission" in submissions.keys(): # handles the case that there are no submissions yet task["submissions"] = submissions["submission"] diff --git a/codeGrader/frontend/admin/handlers/__init__.py b/codeGrader/frontend/admin/handlers/__init__.py index 45b9114..840e986 100644 --- a/codeGrader/frontend/admin/handlers/__init__.py +++ b/codeGrader/frontend/admin/handlers/__init__.py @@ -36,6 +36,7 @@ from .TestCase import TestCaseInputFileHandler, TestCaseOutputFileHandler, AddTestCaseHandler, DeleteTestCaseHandler from .Membership import AddMembershipHandler, DeleteMembershipHandler from .PasswordReset import PasswordResetHandler +from .Error import ErrorHandler __all__ = ["AdminUserLoginHandler", "AdminSessionHandler", "SessionAdmin", "UserListHandler", "UserHandler", "HomeHandler", "AdminHandler", "AdminListHandler", "ProfileListHandler", "ProfileHandler", @@ -46,4 +47,5 @@ "AddTaskAttachmentHandler", "AddTaskInstructionHandler", "DeleteTaskAttachmentHandler", "DeleteTaskInstructionHandler", "TaskInstructionHandler", "TaskAttachmentHandler", "SubmissionFileHandler", "TestCaseInputFileHandler", "TestCaseOutputFileHandler", "AddTestCaseHandler", "DeleteTestCaseHandler", - "AddMembershipHandler", "DeleteMembershipHandler", "PasswordResetHandler", "AddUserListHandler"] + "AddMembershipHandler", "DeleteMembershipHandler", "PasswordResetHandler", "AddUserListHandler", + "ErrorHandler"] diff --git a/codeGrader/frontend/admin/templates/error.html b/codeGrader/frontend/admin/templates/error.html new file mode 100644 index 0000000..857de28 --- /dev/null +++ b/codeGrader/frontend/admin/templates/error.html @@ -0,0 +1,60 @@ + + + + + + + + + {{ appname}} Error + + + + +
+
+
+

+ {{ title }} +

+
+
+ {{ error_text }} +
+ If you think this should not happen, please contact your administrator and provide the Information below. +
+
+ {{ gif|safe }} +
+
+ Path: {{path}} +
+ Method: {{method}} +
+ Time: {{time}} +
+ Exception: {{error}} +
+
+
+ + + \ No newline at end of file diff --git a/codeGrader/frontend/admin/templates/exercise.html b/codeGrader/frontend/admin/templates/exercise.html index 1c46749..a950176 100644 --- a/codeGrader/frontend/admin/templates/exercise.html +++ b/codeGrader/frontend/admin/templates/exercise.html @@ -121,6 +121,50 @@