diff --git a/courses/models.py b/courses/models.py index 400d75a..a01298d 100644 --- a/courses/models.py +++ b/courses/models.py @@ -1,6 +1,5 @@ from django.contrib.auth.models import User from django.db import models -from django.db.models import Q from django.urls import reverse from courses.utils import get_canvas_course, get_canvas_object @@ -53,7 +52,7 @@ def __str__(self): return f"{self.name} ({self.term})" def get_absolute_url(self): - return reverse("courses:detail", kwargs={"pk": self.id}) + return reverse("courses:detail", kwargs={"pk": self.pk}) def get_students(self, section_pk=None): students = [] diff --git a/courses/utils.py b/courses/utils.py index 05f0ca5..2658ff0 100644 --- a/courses/utils.py +++ b/courses/utils.py @@ -30,6 +30,8 @@ def get_canvas_url(): load_dotenv() if os.getenv("API_URL") is not None: api_url = os.getenv("API_URL") + if not api_url: + raise ValueError("API_URL is empty") else: api_url = "https://ufl.instructure.com/" @@ -69,8 +71,8 @@ def get_canvas_course(course_code=None, term_name=None, canvas_id=None): if (canvas_course.course_code == course_code and canvas_course.term["name"] == term_name): return canvas_course - except: - pass + except Exception as e: + print(e) return None def get_course_from_UFSOC_apix( diff --git a/courses/views.py b/courses/views.py index 5da1a63..46c0097 100644 --- a/courses/views.py +++ b/courses/views.py @@ -782,50 +782,51 @@ def grading_scheme_update_view(request, course_pk): """ status = 'success' course = get_object_or_404(Course, pk=course_pk) - if request.method == 'POST': - data = json.loads(request.body.decode("utf-8")) + if request.method != 'POST': + return JsonResponse({'message': 'Only POST requests are allowed.'}) + data = json.loads(request.body.decode("utf-8")) - num_questions = int(data.get('num_questions')) - equal_grades = data.get('equal_grades') - max_grades = data.get('max_grades') - apply_to_all = data.get('apply_to_all') - assignment_id = data.get('assignment_id') + num_questions = int(data.get('num_questions')) + equal_grades = data.get('equal_grades') + max_grades = data.get('max_grades') + apply_to_all = data.get('apply_to_all') + assignment_id = data.get('assignment_id') - assignment_of_request = course.assignments.get(pk=assignment_id) - assignment_group = assignment_of_request.assignment_group_object + assignment_of_request = course.assignments.get(pk=assignment_id) + assignment_group = assignment_of_request.assignment_group_object - if equal_grades: - max_grades = [assignment_of_request.max_score / num_questions] * num_questions - max_grades = ",".join(map(str, max_grades)) - else: - max_grades = max_grades + if equal_grades: + max_grades = [assignment_of_request.max_score / num_questions] * num_questions + max_grades = ",".join(map(str, max_grades)) + else: + max_grades = max_grades - if apply_to_all: - assignments_to_update = course.assignments.filter( - assignment_group_object=assignment_group - ) - else: - assignments_to_update = [assignment_of_request] + if apply_to_all: + assignments_to_update = course.assignments.filter( + assignment_group_object=assignment_group + ) + else: + assignments_to_update = [assignment_of_request] - for assignment in assignments_to_update: - # check if the assignment has graded submissions - # if it does, do not update the grading scheme - num_subs_with_grader = assignment.get_all_submissions().filter(graded_by__isnull=False).count() - num_subs_with_question_grades = assignment.get_all_submissions().filter(question_grades__isnull=False).count() - if num_subs_with_grader == 0 and num_subs_with_question_grades == 0: - print(f"Updating to grading scheme {max_grades} for assignment {assignment.name}") - assignment.max_question_scores = max_grades - assignment.save() - else: - print(f"Assignment {assignment.name} has (partially or fully) graded submissions. Not updating grading scheme.") - status = 'warning' + for assignment in assignments_to_update: + # check if the assignment has graded submissions + # if it does, do not update the grading scheme + num_subs_with_grader = assignment.get_all_submissions().filter(graded_by__isnull=False).count() + num_subs_with_question_grades = assignment.get_all_submissions().filter(question_grades__isnull=False).count() + if num_subs_with_grader == 0 and num_subs_with_question_grades == 0: + print(f"Updating to grading scheme {max_grades} for assignment {assignment.name}") + assignment.max_question_scores = max_grades + assignment.save() + else: + print(f"Assignment {assignment.name} has (partially or fully) graded submissions. Not updating grading scheme.") + status = 'warning' - response = { - 'message': 'Grading scheme updated!', - 'status': status - } - return JsonResponse(response) + response = { + 'message': 'Grading scheme updated!', + 'status': status + } + return JsonResponse(response) @login_required def api_canvas_courses_get_view(request): diff --git a/profiles/models.py b/profiles/models.py index ab373f4..c7bbcc0 100644 --- a/profiles/models.py +++ b/profiles/models.py @@ -24,7 +24,7 @@ class BaseProfile(models.Model): auto_now=True ) def __str__(self): - return f"Profile {self.id}" + return f"Profile {self.pk}" class Meta: abstract = True diff --git a/profiles/views.py b/profiles/views.py index f5e9b85..add8843 100644 --- a/profiles/views.py +++ b/profiles/views.py @@ -58,7 +58,7 @@ def profile_preferences_edit_view(request): # } # }; - if not request.method in ["POST", "PUT"]: + if request.method not in ["POST", "PUT"]: return HttpResponseNotFound() import json data = json.loads(request.body.decode("utf-8")) @@ -134,7 +134,8 @@ def profile_update_view(request): # get the user user = request.user # get the user profile - profile = user.profile + # profile = user.profile + # the data we get from the form contains the following fields: # first_name, last_name, email # we get the data from the request diff --git a/sections/models.py b/sections/models.py index 667ab57..4f7bbff 100644 --- a/sections/models.py +++ b/sections/models.py @@ -1,9 +1,5 @@ -import re -from datetime import datetime - from django.contrib.auth.models import User from django.db import models -from django.db.models import Q from django.urls import reverse from courses.models import Course diff --git a/sections/utils.py b/sections/utils.py index b194311..9f9f400 100644 --- a/sections/utils.py +++ b/sections/utils.py @@ -4,7 +4,7 @@ from students.models import Student -def import_students_to_sections(csv_fpath): +def import_students_to_sections(csv_fpath: str): """ Import students to sections. """ @@ -12,14 +12,18 @@ def import_students_to_sections(csv_fpath): for i, row in df.iterrows(): try: import re - match = re.match('.*\((\d{5})\)',row['Section']) + match = re.match(r'.*\((\d{5})\)',row['Section']) + if match is None: + raise ValueError("No 5 digit match in section") print(f"{match.group(1)}") section = Section.objects.get(name=str(match.group(1))) except Section.DoesNotExist: print("section does not exist") section = None - match = re.match("(.*),\s(.*)",row['Student']) + match = re.match(r"(.*),\s(.*)",row['Student']) + if match is None: + raise ValueError("Student name should be in the format 'Last, First'") print(f"{match.group(1)} {match.group(2)}") print(row['SIS User ID']) print(row['SIS Login ID']) @@ -29,11 +33,12 @@ def import_students_to_sections(csv_fpath): uni_id=row['SIS User ID'], email=row['SIS Login ID']) - student.sections.add(section) print(created) print("Student:", student.__dict__) - section.save() - print(f"Added {student.first_name} {student.last_name}" + if section is not None: + student.sections.add(section) + section.save() + print(f"Added {student.first_name} {student.last_name}" f" ({student.uni_id}) to {section.name}") print("Done.") return df \ No newline at end of file diff --git a/students/models.py b/students/models.py index e773385..3314081 100644 --- a/students/models.py +++ b/students/models.py @@ -35,8 +35,6 @@ def __str__(self): return f"{self.first_name} {self.last_name}" def get_section_in_course(self, course): - # if the student is enrolled in multiple sections in the same course - # raise an error student_sections = self.sections.filter(course=course) if len(student_sections) > 1: @@ -83,7 +81,7 @@ async def main(profiles): async with aiohttp.ClientSession() as session: tasks = [ download_avatar(session, profile) for profile in profiles ] finished = 0 - print(f"Downloading avatars...") + print("Downloading avatars...") results = [] for task in asyncio.as_completed(tasks): result = await task @@ -116,7 +114,7 @@ async def main(profiles): print("Avatar is the same. Not updating.") continue except Exception as e: - pass + print(e) print("New avatar. Updating ...") student_profile.avatar.save( basename, diff --git a/students/views.py b/students/views.py index 7af024a..283b18c 100644 --- a/students/views.py +++ b/students/views.py @@ -1,12 +1,11 @@ import json +from typing import Optional from django.apps import apps from django.contrib.auth.decorators import login_required from django.db.models import Q from django.http import JsonResponse from django.shortcuts import get_object_or_404, render - -from students.models import Student from rest_framework import viewsets from rest_framework import permissions @@ -14,6 +13,10 @@ # from students.permissions import IsTA from students.serializers import StudentSerializer +Course = apps.get_model("courses", "Course") +Section = apps.get_model("sections", "Section") +Student = apps.get_model("students", "Student") +PaperSubmission = apps.get_model("submissions", "PaperSubmission") class StudentInSectionViewSet(viewsets.ModelViewSet): """ @@ -49,10 +52,9 @@ def get_queryset(self): return Student.objects.filter(sections__course=course_id) -def get_serialized_students(course_pk, section_pk=None): +def get_serialized_students(course_pk: int, section_pk: Optional[int] = None): """returns a list of serialized students in a course or section""" - Course = apps.get_model("courses", "Course") - Section = apps.get_model("sections", "Section") + if section_pk: section = get_object_or_404(Section, pk=section_pk) if course_pk != str(section.course.pk): @@ -82,9 +84,7 @@ def get_serialized_students(course_pk, section_pk=None): def get_serialized_submissions(student_pk, course_pk, assignment_group=None): """returns a list of serialized submissions for a student in a course""" - Student = apps.get_model("students", "Student") - Course = apps.get_model("courses", "Course") - PaperSubmission = apps.get_model("submissions", "PaperSubmission") + student = get_object_or_404(Student, pk=student_pk) course = get_object_or_404(Course, pk=course_pk) @@ -136,7 +136,6 @@ def get_serialized_submissions(student_pk, course_pk, assignment_group=None): def course_list_view(request, course_pk): """create a view that returns a serialized list of students in a course""" print(request.user) - Course = apps.get_model("courses", "Course") course = get_object_or_404(Course, pk=course_pk) serialized_students = get_serialized_students(course_pk) @@ -154,7 +153,6 @@ def course_list_view(request, course_pk): @login_required def api_course_enrollments_create(request, course_pk): """create a view that creates a student in a course""" - Course = apps.get_model("courses", "Course") if request.method != "POST": return JsonResponse({"message": "Only POST requests are allowed."}) @@ -162,8 +160,6 @@ def api_course_enrollments_create(request, course_pk): students_data_str = data.get("students") students_data = json.loads(students_data_str) course = Course.objects.get(pk=course_pk) - Student = apps.get_model("students", "Student") - Section = apps.get_model("sections", "Section") profiles = [] print(f"lenght of students_data: {len(students_data)}") @@ -255,7 +251,6 @@ def course_students_view(request, course_pk): @login_required def section_list_view(request, course_pk, section_pk): """create a view that returns a serialized list of students in a course""" - Section = apps.get_model("sections", "Section") section = get_object_or_404(Section, pk=section_pk) if course_pk != str(section.course.pk): raise ValueError("Course pk does not match section's course pk") @@ -276,8 +271,6 @@ def section_list_view(request, course_pk, section_pk): @login_required def detail_view(request, course_pk, student_pk): """create a view that returns information about a student""" - Student = apps.get_model("students", "Student") - Course = apps.get_model("courses", "Course") student = get_object_or_404(Student, pk=student_pk) course = get_object_or_404(Course, pk=course_pk) section = student.sections.filter(course=course).first()