예제 #1
0
    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)
예제 #2
0
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
    })
예제 #3
0
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
예제 #4
0
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
예제 #5
0
    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)
예제 #6
0
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)
예제 #7
0
    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'
        })
예제 #8
0
 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]
예제 #9
0
 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
예제 #10
0
    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()
예제 #11
0
 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')
예제 #12
0
 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)
예제 #13
0
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())
예제 #14
0
    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}")
예제 #15
0
 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)
     )
예제 #16
0
 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)
     )
예제 #17
0
 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
예제 #18
0
    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)
예제 #19
0
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
예제 #20
0
    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
예제 #21
0
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)
예제 #22
0
    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
예제 #23
0
    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()
예제 #24
0
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
예제 #25
0
    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())
예제 #26
0
    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')
예제 #27
0
    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())
예제 #29
0
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)
예제 #30
0
    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)