def test_get_correct_semester(self): winter_semester = Semester.get_semester(datetime(2015, 12, 25)) self.assertEqual(winter_semester.type, Semester.TYPE_WINTER) summer_semester = Semester.get_semester(datetime(2016, 5, 20)) self.assertEqual(summer_semester.type, Semester.TYPE_SUMMER) some_semester = Semester.get_semester(winter_semester.semester_ending + timedelta(days=1)) self.assertEqual(some_semester.type, Semester.TYPE_SUMMER)
def session(request, semester=None): from apps.enrollment.courses.models.semester import Semester exams_filter = ExamFilter(request.GET, queryset=Term.get_exams()) if semester: semester = Semester.get_by_id(semester) else: semester = Semester.get_current_semester() return TemplateResponse(request, 'schedule/session.html', { "semester": semester, "exams": exams_filter.qs })
def export_as_csv(modeladmin: admin.ModelAdmin, request: HttpRequest, queryset: QuerySet) -> HttpResponse: semester = Semester.get_current_semester() records = Record.objects.filter( student__in=queryset, group__course__semester=semester, status=1).select_related( 'student', 'student__user', 'group', 'group__course') opts = modeladmin.model._meta response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=%s.csv' % str(opts).replace('.', '_') writer = csv.writer(response) for record in records: writer.writerow([record.student.matricula, record.student.user.first_name, record.student.user.last_name, record.group.course.name, record.group.get_type_display(), record.group.get_terms_as_string()]) return response
def prepare_data_for_create_poll(request, group_id=0): data = pop_template_from_session(request) if group_id > 0: group = Group.objects.get(pk=group_id) data['group'] = group.pk data['type'] = group.type data['course_id'] = group.course.pk data['semester'] = group.course.semester.pk data['groups'] = Group.objects.filter( type=group.type, course=group.course).order_by('teacher') if data['semester']: data['courses'] = get_courses_for_user(request, data['semester']) else: semester_id = Semester.get_current_semester() data['semester'] = semester_id data['courses'] = get_courses_for_user(request, semester_id) data['studies_types'] = Program.objects.all() data['semesters'] = Semester.objects.all() data['sections'] = Section.objects.filter(deleted=False) data['types'] = GROUP_TYPE_CHOICES return data
def test_count_changed_days_in_winter_semester(self): semester = Semester.get_semester(datetime(2015, 11, 10)) self.assertNotEqual(semester, None) changed_days = ChangedDay.get_added_days_of_week(semester.semester_beginning, semester.semester_ending) self.assertEqual(len(changed_days), 3)
def change_desiderata(request): """ This view is to change desiderata for semester in which the desiderata is currently open. """ user = request.user employee = user.employee semester = Semester.get_default_semester() desiderata = Desiderata.get_desiderata(employee, semester) other = DesiderataOther.get_desiderata_other(employee, semester) desiderata_formset_initial = Desiderata.get_desiderata_to_formset( desiderata) if request.method == 'POST': formset = DesiderataFormSet(request.POST) other_form = DesiderataOtherForm(request.POST, instance=other) if formset.is_valid(): formset.save(desiderata, employee, semester) desiderata = Desiderata.get_desiderata(employee, semester) desiderata_formset_initial = Desiderata.get_desiderata_to_formset( desiderata) if other_form.is_valid(): other_form.save() messages.success(request, 'Zmiany zapisano pomyślnie') else: other_form = DesiderataOtherForm(instance=other) formset = DesiderataFormSet(initial=desiderata_formset_initial) data = {'formset': formset, 'other_form': other_form, 'semester': semester} return render(request, 'offer/desiderata/change_desiderata.html', data)
def __init__(self, user, data=None, **kwargs): if data: data = deepcopy(data) if 'type' not in data: data['type'] = Event.TYPE_GENERIC super(EventForm, self).__init__(data, **kwargs) if not self.instance.pk: self.instance.author = user if BaseUser.is_employee(user): self.fields['type'].choices = Event.TYPES_FOR_TEACHER else: self.fields['type'].choices = Event.TYPES_FOR_STUDENT if not BaseUser.is_employee(user): self.fields['course'].queryset = CourseInstance.objects.none() else: semester = Semester.get_current_semester() previous_semester = Semester.get_semester(datetime.now().date() - timedelta(days=30)) queryset = CourseInstance.objects.filter(semester__in=[semester, previous_semester]). \ select_related('semester'). \ order_by('semester') if not user.has_perm('schedule.manage_events'): queryset = CourseInstance.objects.filter( groups__type='1', groups__teacher=user.employee, semester__in=[semester, previous_semester]) self.fields['course'].queryset = queryset self.fields['title'].widget.attrs.update({'class': 'form-control'}) self.fields['type'].widget.attrs.update({'class': 'form-control'}) self.fields['course'].widget.attrs.update({'class': 'form-control'}) self.fields['description'].widget.attrs.update( {'class': 'form-control'}) self.fields['visible'].widget.attrs.update({ 'checked': '', 'class': 'custom-control-input' })
def get_groups_without_poll(): semester = Semester.get_current_semester() polls = Poll.objects.filter(semester=semester, group__isnull=False, deleted=False).order_by('pk') polls = [p.group_id for p in polls] groups = Group.objects.filter(course__semester=semester).order_by('pk') return [g for g in groups if g.pk not in polls]
def winter_semester_2015_16(): """Records opening and closing dates are made up""" semester = Semester( visible=True, type=Semester.TYPE_WINTER, year='2015/16', records_opening=datetime(2015, 9, 20), records_closing=datetime(2015, 10, 14), lectures_beginning=datetime(2015, 10, 1), lectures_ending=datetime(2016, 2, 3), semester_beginning=datetime(2015, 10, 1), semester_ending=datetime(2016, 2, 21), records_ects_limit_abolition=datetime(2015, 10, 1), is_grade_active=False ) semester.full_clean() return semester
def count_current_semester_polls_without_keys(): from apps.grade.ticket_create.models.public_key import PublicKey semester = Semester.get_current_semester() polls_with_keys = PublicKey.objects.all().values('poll') return Poll.objects.filter( semester=semester, deleted=False).exclude(pk__in=polls_with_keys).count()
def get_polls_for_semester(semester=None): if not semester: semester = Semester.get_current_semester() return Poll.objects.filter(semester=semester, deleted=False).select_related( 'group', 'group__course', 'group__teacher', 'group__teacher__user')
def test_get_all_sundays_in_winter_semester(self): winter_semester = Semester.get_semester(datetime(2015, 12, 1)) sundays = winter_semester.get_all_days_of_week(common.SUNDAY) self.assertTrue(sundays) # a sunday in winter semester a_sunday = date(2015, 12, 6) another_sunday = date(2015, 11, 22) self.assertTrue(a_sunday in sundays) self.assertTrue(another_sunday in sundays)
def statistics(request): from apps.enrollment.courses.models import CourseInstance from apps.enrollment.courses.models.semester import Semester semester_id = request.GET.get('semester_id', None) semester = Semester.get_by_id_or_default(semester_id) exams = CourseInstance.objects.filter(semester=semester, has_exam=True) return TemplateResponse(request, 'schedule/statistics.html', locals())
def handle(self, *args, **kwargs): semester_id = kwargs["semester"] created, skipped = 0, 0 if semester_id: semester = Semester.objects.get(id=semester_id) else: semester = Semester.get_current_semester() self.stdout.write(f"Selected semester: `{semester}` with id {semester.id}") # Check whether poll exists for a selected semester self.stdout.write(f"\n{HEADER}Semester polls") semester_poll = Poll.objects.filter(semester=semester).count() > 0 if semester_poll: self.stdout.write(f"{MARGIN}Poll for a selected semester already exists") skipped += 1 else: new_poll = Poll(group=None, course=None, semester=semester) new_poll.save() self.stdout.write( f"{CREATED}Poll for a selected semester does not exist, creating" ) created += 1 # Check whether poll exists for courses held in a selected semester self.stdout.write(f"\n{HEADER}Course/group polls") courses = CourseInstance.objects.filter(semester=semester) for course in courses: course_poll = Poll.objects.filter(course=course).count() > 0 if not course.has_exam or course_poll: self.stdout.write(f"{MARGIN}{course}") skipped += 1 else: new_poll = Poll(group=None, course=course, semester=None) new_poll.save() self.stdout.write(f"{CREATED}{course}") created += 1 groups = Group.objects.filter(course=course) for group in groups: group_poll = Poll.objects.filter(group=group).count() > 0 if group_poll: self.stdout.write(f"{MARGIN}{MARGIN}{group}") skipped += 1 else: new_poll = Poll(group=group, course=None, semester=None) new_poll.save() self.stdout.write(f"{CREATED}{MARGIN}{group}") created += 1 self.stdout.write(f"\n{HEADER}Summary") self.stdout.write(f"{MARGIN}Created: {created}, skipped: {skipped}")
def test_clean_on_overlapping_reservation_where_both_are_same(self): semester = Semester.get_semester(date(2016, 5, 12)) # summer20152016 room = Classroom.get_by_number('110') reservation = SpecialReservation( semester=semester, title='overlapping', classroom=room, dayOfWeek=common.WEDNESDAY, start_time=time(15), end_time=time(16) )
def test_try_clean_on_overlapping_reservation(self): semester = Semester.get_semester(date(2016, 5, 12)) room = Classroom.get_by_number('110') reservation = SpecialReservation( semester=semester, title='overlapping', classroom=room, dayOfWeek=common.THURSDAY, start_time=time(14), end_time=time(16) )
def semester_year(self): start_year = datetime.now().year end_year = start_year + SEMESTER_YEAR_RANGE f = Faker() while True: year = f.random_int(start_year, end_year) try: semester_year = Semester.get_semester_year_from_raw_year(year) Semester.objects.get(year=semester_year) except Semester.DoesNotExist: return year
def changelist_view(self, request, extra_context=None): if 'course__semester__id__exact' not in request.GET: q = request.GET.copy() semester = Semester.get_current_semester() q['course__semester__id__exact'] = semester.id request.GET = q request.META['QUERY_STRING'] = request.GET.urlencode() return super(GroupAdmin, self).changelist_view(request, extra_context=extra_context)
def make_template_variables(request): """ parse POST for template datas @author mjablonski @param request @return dictionary - templates option """ var = {} if request.POST.get('title', '') == '': raise NoTitleException type = int(request.POST.get('type', 0)) if not type: type = None studies_type = int(request.POST.get('studies-type', -1)) if studies_type > -1: studies_type = Program.objects.get(pk=studies_type) else: studies_type = None course = int(request.POST.get('course', 0)) if course > 0: course = CourseInstance.objects.get(pk=course) elif not course: course = None else: course = -1 group = int(request.POST.get('group', 0)) if group > 0: group = Group.objects.filter(pk=group) else: group = None semester = int(request.POST.get('semester', 0)) if semester > 0: semester = Semester.objects.get(pk=semester) else: semester = Semester.get_current_semester() var['type'] = type var['studies_type'] = studies_type var['course'] = course var['title'] = request.POST.get('title', '') var['semester'] = semester var['description'] = request.POST.get('description', '') var['groups_without'] = request.POST.get('poll-only-without', 'off') var['group'] = group var['exam'] = request.POST.get('exam', False) return var
def get_all_polls_for_student(student: Student, semester: Semester = None) -> List: """Checks the eligibility of a student and returns a list of polls. :param student: a valid instance of `Student` class. :param semester: if no semester is given, assumes a current one. :returns: a list of all available polls for a given student. """ if not student.is_active: return [] current_semester = semester if current_semester is None: current_semester = Semester.get_current_semester() if current_semester is None: return [] if not current_semester.is_grade_active: return [] polls = [] poll_for_semester = Poll.objects.filter( semester=current_semester).first() if poll_for_semester: polls.append(poll_for_semester) # Retrieves only the groups that the Student is enrolled in records = records_models.Record.objects.filter( student=student, status=records_models.RecordStatus.ENROLLED, group__course__semester=current_semester, ).select_related('group') for record in records: group = record.group course = group.course semester = course.semester if semester == current_semester: if course.has_exam: poll_for_course = Poll.objects.get(course=course) if poll_for_course and poll_for_course not in polls: polls.append(poll_for_course) poll_for_group = Poll.objects.get(group=group) if poll_for_group: polls.append(poll_for_group) return polls
def tickets_generate(request): """Renders tickets_generate page and lists Polls student is entitled to.""" semester = Semester.get_current_semester() is_grade_active = semester.is_grade_active if not is_grade_active: messages.error( request, "Ocena zajęć jest w tej chwili zamknięta; nie można pobrać biletów" ) return redirect('grade-main') polls = get_grouped_polls(request.user.student) data = { 'polls': polls, 'is_grade_active': is_grade_active, } return render(request, 'ticket_create/tickets_generate.html', data)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) classrooms = Classroom.objects.filter(can_reserve=True) by_floor = defaultdict(list) floor_names = dict(floors) for r in classrooms: by_floor[floor_names[r.floor]].append((r.pk, r.number)) self.fields['rooms'].choices = by_floor.items() semester = Semester.get_current_semester() next_sem = Semester.objects.get_next() weeks = [(week[0], f"{week[0]} - {week[1]}") for week in semester.get_all_weeks()] if semester != next_sem: weeks.insert(0, ('nextsem', f"Generuj z planu zajęć dla semestru '{next_sem}'")) weeks.insert(0, ('currsem', f"Generuj z planu zajęć dla semestru '{semester}'")) self.fields['week'].widget.choices = weeks
def setUpTestData(cls) -> None: s = StudentFactory() s.matricula = str(randint(100000, 200000)) cls.student_user = s.user Semester.objects.all().delete() cls.semester = Semester( visible=True, type=Semester.TYPE_WINTER, records_opening=datetime.now() - timedelta(days=15), records_closing=datetime.now() + timedelta(days=15), records_ects_limit_abolition=datetime.now() + timedelta(days=5), semester_beginning=datetime.now() + timedelta(days=20), semester_ending=datetime.now() + timedelta(days=100)) cls.semester.full_clean() cls.semester.save()
def generate_keys_for_polls(semester=None): from apps.enrollment.courses.models.semester import Semester if not semester: semester = Semester.get_current_semester() poll_list = Poll.get_polls_without_keys(semester) pub_list = [] priv_list = [] i = 1 for el in poll_list: (pub, priv) = generate_rsa_key() pub_list.append(pub) priv_list.append(priv) i = i + 1 save_public_keys(list(zip(poll_list, pub_list))) save_private_keys(list(zip(poll_list, priv_list))) print(i - 1) return
def handle(self, *args, **options): semester = Semester.get_default_semester() if options['person']: students = Student.objects.filter(status=0) for student in students: records = Record.enrolled.filter( student=student, group__course__semester=semester) for r in records: print(str(student.id) + ' ' + str(r.group_id)) #print str(student.id) + ' ' + str(r.id) if options['group']: groups = Group.objects.filter(course__semester=semester) for g in groups: for t in g.term.all(): print(str(g.id) + ' ' + str(t)) if options['type']: groups = Group.objects.filter(course__semester=semester) for g in groups: print(str(g.id) + ' ' + g.get_type_display())
def validate_against_course_terms(self): assert (self.room is not None) semester = Semester.get_semester(self.day) if not semester: return if semester.lectures_beginning <= self.day and self.day <= semester.lectures_ending: course_terms = CourseTerm.get_terms_for_semester( semester=semester, day=self.day, classrooms=[self.room], start_time=self.start, end_time=self.end) if course_terms: raise ValidationError(message={ '__all__': [ 'W tym samym czasie w tej sali odbywają się zajęcia: ' + course_terms[0].group.course.name + ' ' + str(course_terms[0]) ] }, code='overlap')
def get_all_polls_for_semester(user, semester: Semester = None) -> List['Poll']: """Returns all polls that user may see the submissions for. The polls will be annotated with submission counts. """ current_semester = semester if current_semester is None: current_semester = Semester.get_current_semester() is_superuser = user.is_superuser is_employee = user.employee if not is_superuser and not is_employee: return Poll.objects.none() poll_for_semester = Poll.objects.filter(semester=current_semester) if is_superuser: polls_for_courses = Poll.objects.filter( course__semester=current_semester) polls_for_groups = Poll.objects.filter( group__course__semester=current_semester) elif is_employee: polls_for_courses = Poll.objects.filter( course__semester=current_semester, course__owner=user.employee, ) | Poll.objects.filter(group__course__semester=current_semester, group__course__owner=user.employee) polls_for_groups = Poll.objects.filter( group__course__semester=current_semester, group__teacher=user.employee, ) qs = poll_for_semester | polls_for_courses | polls_for_groups sub_count_ann = models.Count( 'submission', filter=models.Q(submission__submitted=True)) return list(qs.annotate(number_of_submissions=sub_count_ann))
def this_semester(self): return self.filter(semester=Semester.get_current_semester())
def sign_tickets(request): """Signs the tickets sent by a student and returns list of signatures. The student must request to sign all the tickets he is entitled to. The signing may only be performed once in a semester. Request must be a dict of objects: { "signing_requests": [ # An object for every poll. { # Id of the poll. "id": 123, # A blinded ticket. "ticket": 12345..., }, ] } Returns: A list of signed tickets, each being a dict like below. { # Id of the poll. 'id': 123, # The ticket from the request signed using a private key # corresponding to the poll. 'signature': 1234... } Errors: 400 BadRequest: When JSON request could not be parsed. 403 Forbidden: When the student tries to sign a ticket for a poll he is not entitled to, fails to request a ticket he is entitled to, or has already been signing this semester. """ try: signing_requests_dict = json.loads(request.body.decode('utf-8')) except json.decoder.JSONDecodeError: return HttpResponseBadRequest("Couldn't parse JSON") signing_requests = signing_requests_dict['signing_requests'] semester = Semester.get_current_semester() student_polls = { poll.pk for poll in Poll.get_all_polls_for_student(request.user.student, semester) } request_polls = {int(req['id']) for req in signing_requests} if request_polls - student_polls: return HttpResponseForbidden( f"Student nie jest upoważniony do tych ankiet: {request_polls - student_polls}." ) if student_polls - request_polls: return HttpResponseForbidden( f"Student powinien również wygenerować bilety dla tych " "ankiet: {student_polls - request_polls}.") if len(request_polls) != len(signing_requests): return HttpResponseForbidden( f"Próbowano podpisać wiele biletów do jednej ankiety.") # Now we made sure that student_polls == request_polls # We obtain a lock on RSA keys. keys = RSAKeys.objects.filter(poll__in=request_polls).select_for_update() keys_by_poll = {key.poll_id: key for key in keys} _, created = StudentGraded.objects.get_or_create( student=request.user.student, semester=semester) if not created: return HttpResponseForbidden( f"Student już podpisywał bilety w tym semestrze.") response = [] for signing_request in signing_requests: key = keys_by_poll[int(signing_request['id'])] signed_ticket = key.sign_ticket(signing_request['ticket']) signing_response = { 'id': signing_request['id'], 'signature': str(signed_ticket), } response.append(signing_response) return JsonResponse(response, safe=False)
def __init__(self, data=None, *args, **kwargs): if not data: semester = Semester.get_current_semester() data = {'event__course__semester': semester.id} super(ExamFilter, self).__init__(data, *args, **kwargs)