Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
path("task-list/<subject_abbr>", default_view.tasks_list_all),
path("student-list", default_view.student_list),
path("submits/<int:task_assignment>", default_view.create_submit),
path("info", default_view.info),
path("info", default_view.info, name="api_info"),
path("classes", default_view.class_detail_list),
path("classes/all", default_view.all_classes),
path("classes/<int:class_id>/add_students", default_view.add_student_to_class),
Expand Down
21 changes: 14 additions & 7 deletions quiz/middleware.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from django.http import HttpResponseRedirect
from django.urls import reverse, resolve, Resolver404
from enum import Enum
from quiz.models import EnrolledQuiz
from kelvin.settings import DEBUG
from debug_toolbar.toolbar import DebugToolbar
from quiz.quiz_utils import quiz_running_for_user


class SubmitType(Enum):
Expand All @@ -19,28 +21,33 @@ def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
try:
enrolled_quiz = EnrolledQuiz.objects.get(student=request.user.id, submitted=False)
enrolled_quiz = quiz_running_for_user(request.user)

if enrolled_quiz is not None:
fill_url = reverse("quiz_fill")

allowed_urls = [
fill_url,
reverse("api_quiz_results", args=[enrolled_quiz.id, SubmitType.PERIODIC.value]),
reverse("api_quiz_results", args=[enrolled_quiz.id, SubmitType.MANUAL.value]),
reverse("api_info"),
reverse("notification_all"),
reverse("notification_mark_as_read_all"),
reverse("cas_ng_logout"),
]

try:
if resolve(request.path_info).url_name == "quiz_asset":
resolved_path = resolve(request.path_info).url_name
if resolved_path == "quiz_asset":
allowed_urls.append(request.path_info)
elif resolved_path == "notification_mark_as_read_single":
allowed_urls.append(request.path_info)
except Resolver404:
pass

if request.path_info not in allowed_urls:
debug_toolbar = DEBUG and DebugToolbar.is_toolbar_request(request)
if not debug_toolbar and request.path_info not in allowed_urls:
return HttpResponseRedirect(fill_url)
except EnrolledQuiz.DoesNotExist:
pass

response = self.get_response(request)

Expand Down
12 changes: 12 additions & 0 deletions quiz/quiz_utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.contrib.auth.models import User

from typing import Optional
from common.models import Class
from quiz.models import Quiz, AssignedQuiz, EnrolledQuiz
from web.markdown_utils import process_markdown
Expand All @@ -13,6 +14,17 @@ class QuizException(Exception):
pass


def quiz_running_for_user(user: User) -> Optional[EnrolledQuiz]:
"""
Returns currently running quiz for given user.
If user is not running a quiz at the moment, None is returned.
"""
try:
return EnrolledQuiz.objects.get(student=user.id, submitted=False)
except EnrolledQuiz.DoesNotExist:
return None


def quiz_assigned_classes(quiz: Quiz, requested_by: int):
"""
Function that returns a list of classes that are/can be assigned to the quiz.
Expand Down
14 changes: 11 additions & 3 deletions web/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,17 @@
),
path("submit/<int:submit_id>/pipeline", student_view.pipeline_status),
# notifications
path("notification/all", notification_view.all_notifications),
path("notification/mark_as_read", notification_view.mark_as_read),
path("notification/mark_as_read/<int:notification_id>", notification_view.mark_as_read),
path("notification/all", notification_view.all_notifications, name="notification_all"),
path(
"notification/mark_as_read",
notification_view.mark_as_read,
name="notification_mark_as_read_all",
),
path(
"notification/mark_as_read/<int:notification_id>",
notification_view.mark_as_read,
name="notification_mark_as_read_single",
),
# teacher
path("teacher/task/<int:task_id>", teacher_view.teacher_task, name="teacher_task"),
path("teacher/task/<int:task_id>.tar", student_view.teacher_task_tar, name="teacher_task_tar"),
Expand Down
Loading