示例#1
0
def all_news(request):
    """
        Latest news, result of query search or given page with focused news
    """
    if BaseUser.is_student(request.user):
        student = request.user.student
        student.last_news_view = datetime.datetime.now()
        student.save()

    elif BaseUser.is_employee(request.user):
        employee = request.user.employee
        employee.last_news_view = datetime.datetime.now()
        employee.save()

    query = request.GET.get('q')
    if query:
        query = query.strip()
        items = News.objects.get_published().filter(
            Q(title__icontains=query) | Q(body__icontains=query))
    else:
        items = News.objects.exclude(category='-')

    paginator = Paginator(items, settings.NEWS_PER_PAGE)
    page = request.GET.get('page')
    try:
        news = paginator.page(page)
    except (PageNotAnInteger, EmptyPage):
        news = paginator.page(1)

    data = {'items': news, 'page_range': paginator.page_range, 'query': query}

    return render(request, 'news/list_all.html', data)
示例#2
0
def can_set_advisor(user: User, advisor: Optional[Employee]) -> bool:
    """Is the specified user permitted to set the given advisor (may be None)?

    Only called if the user is permitted to modify the thesis in general
    (that is, `can_modify_thesis` returns True)
    """
    return is_thesis_staff(user) or (BaseUser.is_employee(user) and user.employee == advisor)
示例#3
0
def is_theses_regular_employee(user: User):
    """Is the specified user a regular university employee?

    Those have permissions to create theses and can be set as advisors,
    but otherwise have no administrative privileges
    """
    return BaseUser.is_employee(user) and not user.is_staff
示例#4
0
 def filter_only_mine(self: QuerySet, user: User):
     if BaseUser.is_student(user):
         return self.filter(students__in=[user.student])
     elif BaseUser.is_employee(user):
         return self.filter(Q(advisor=user.employee) | Q(supporting_advisor=user.employee))
     # this is an error situation, one of the conditions above should have caught it
     return self
示例#5
0
def student_profile(request: HttpRequest, user_id: int) -> HttpResponse:
    """student profile"""
    try:
        student: Student = Student.objects.select_related(
            'user', 'consent').get(user_id=user_id)
    except Student.DoesNotExist:
        raise Http404

    # We will not show the student profile if he decides to hide it.
    if not BaseUser.is_employee(
            request.user) and not student.consent_granted():
        return HttpResponseRedirect(reverse('students-list'))

    semester = Semester.objects.get_next()

    records = Record.objects.filter(
        student=student,
        group__course__semester=semester,
        status=RecordStatus.ENROLLED).select_related(
            'group__teacher', 'group__teacher__user',
            'group__course').prefetch_related('group__term',
                                              'group__term__classrooms')
    groups = [r.group for r in records]

    # Highlight groups shared with the viewer in green.
    viewer_groups = Record.common_groups(request.user, groups)
    for g in groups:
        g.is_enrolled = g.pk in viewer_groups

    group_dicts = build_group_list(groups)
    data = {
        'student': student,
        'groups_json': json.dumps(group_dicts, cls=DjangoJSONEncoder),
    }

    if request.is_ajax():
        return render(request, 'users/student_profile_contents.html', data)

    active_students = Student.get_list(
        begin='All',
        restrict_list_consent=not BaseUser.is_employee(request.user))
    data.update({
        'students': active_students,
        'char': "All",
    })
    return render(request, 'users/student_profile.html', data)
def roles(request):
    """Merge user's group membership info into template context."""
    return {
        'is_employee': BaseUser.is_employee(request.user),
        'is_external_contractor':
        BaseUser.is_external_contractor(request.user),
        'is_student': BaseUser.is_student(request.user),
    }
示例#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 can_user_view_students_list_for_group(user: BaseUser,
                                          group: Group) -> bool:
    """Tell whether the user is authorized to see students' names
    and surnames in the given group.
    """
    is_user_proper_employee = (BaseUser.is_employee(user)
                               and not BaseUser.is_external_contractor(user))
    is_user_group_teacher = user == group.teacher.user
    return is_user_proper_employee or is_user_group_teacher
示例#9
0
def create_ical_file(request: HttpRequest) -> HttpResponse:
    user = request.user
    semester = Semester.get_default_semester()

    cal = iCalendar()
    cal.add('x-wr-timezone').value = 'Europe/Warsaw'
    cal.add('version').value = '2.0'
    cal.add('prodid').value = 'Fereol'
    cal.add('calscale').value = 'GREGORIAN'
    cal.add('calname').value = "{} - schedule".format(user.get_full_name())
    cal.add('method').value = 'PUBLISH'

    if BaseUser.is_student(user):
        student = user.student
        records = Record.objects.filter(
            student_id=student.pk,
            group__course__semester_id=semester.pk,
            status=RecordStatus.ENROLLED).select_related(
                'group', 'group__course')
        groups = [r.group for r in records]
    elif BaseUser.is_employee(user):
        groups = list(
            Group.objects.filter(course__semester=semester,
                                 teacher=user.employee))
    else:
        raise InvalidUserException()
    for group in groups:
        course_name = group.course.name
        group_type = group.human_readable_type().lower()
        try:
            terms = group.get_all_terms_for_export()
        except IndexError:
            continue
        for term in terms:
            start_datetime = datetime.datetime.combine(term.day, term.start)
            start_datetime += BREAK_DURATION
            end_datetime = datetime.datetime.combine(term.day, term.end)
            event = cal.add('vevent')
            event.add('summary').value = "{} - {}".format(
                course_name, group_type)
            if term.room:
                event.add('location').value = 'sala ' + term.room.number \
                    + ', Instytut Informatyki Uniwersytetu Wrocławskiego'

            event.add('description').value = 'prowadzący: ' \
                + group.get_teacher_full_name()
            event.add('dtstart').value = start_datetime
            event.add('dtend').value = end_datetime

    cal_str = cal.serialize()
    response = HttpResponse(cal_str, content_type='application/calendar')
    ical_file_name = get_ical_filename(user, semester)
    response['Content-Disposition'] = "attachment; filename={}".format(
        ical_file_name)
    return response
示例#10
0
 def get_serializer_context(self):
     """When serializing votes for a thesis, we need to know the user type
     determining it for every thesis would be expensive as it requires
     a DB hit, so it's a good idea to do it here and pass it to the serializer
     """
     result = super().get_serializer_context()
     user = self.request.user
     result["user"] = user
     result["is_staff"] = is_thesis_staff(user)
     result["is_employee"] = BaseUser.is_employee(user)
     return result
示例#11
0
def create_form(request):
    """It is not a view itself, just factory for preferences and preferences_save"""
    if BaseUser.is_employee(request.user):
        instance, created = NotificationPreferencesTeacher.objects.get_or_create(
            user=request.user)
        if request.method == 'POST':
            return PreferencesFormTeacher(request.POST, instance=instance)
        return PreferencesFormTeacher(instance=instance)

    instance, created = NotificationPreferencesStudent.objects.get_or_create(
        user=request.user)
    if request.method == 'POST':
        return PreferencesFormStudent(request.POST, instance=instance)
    return PreferencesFormStudent(instance=instance)
示例#12
0
def dispatch_notifications_task(user):
    """Dispatch all pending notifications for the given user by email.

    We batch all the e-mails for the user together and send them using one SMTP
    connection. We also wait for THROTTLE_SECONDS until we let the next task in
    the work queue to send emails. This rate limiting is introduced for Gmail to
    accept our queries.
    """
    if BaseUser.is_employee(user):
        model, created = NotificationPreferencesTeacher.objects.get_or_create(user=user)
    elif BaseUser.is_student(user):
        model, created = NotificationPreferencesStudent.objects.get_or_create(user=user)
    else:
        return

    repo = get_notifications_repository()
    pending_notifications = repo.get_unsent_for_user(user)
    if not pending_notifications:
        return

    messages = []
    for pn in pending_notifications:
        # User controls in account settings
        # what notifications will be send
        if not getattr(model, pn.description_id, None):
            continue

        ctx = {
            'content': render_description(
                pn.description_id, pn.description_args),
            'greeting': f'Dzień dobry, {user.first_name}',
        }

        message_contents = render_to_string('notifications/email_base.html', ctx)
        messages.append((
            'Wiadomość od Systemu Zapisów IIUWr',
            strip_tags(message_contents),
            settings.MASS_MAIL_FROM,
            [user.email],
        ))
    send_mass_mail(messages, fail_silently=False)

    # Only mark the notifications as sent if the e-mails went out successfully.
    for pn in pending_notifications:
        repo.mark_as_sent(user, pn)

    time.sleep(settings.EMAIL_THROTTLE_SECONDS)
示例#13
0
    def common_groups(cls, user: User, groups: List[Group]) -> Set[int]:
        """Returns ids of those of groups that user is involved in.

        User may be an employee — we then return groups he is teaching. If user
        is a student, we return those of the groups, he is enrolled into. If
        user is neither a student nor an employee, an empty set is returned.
        """
        common_groups = set()
        if BaseUser.is_student(user):
            student_records = Record.objects.filter(
                group__in=groups, student=user.student, status=RecordStatus.ENROLLED)
            common_groups = {r.group_id for r in student_records}
        if BaseUser.is_employee(user):
            common_groups = set(
                Group.objects.filter(pk__in=[g.pk for g in groups],
                                     teacher=user.employee).values_list('pk', flat=True))
        return common_groups
示例#14
0
def students_list(request: HttpRequest,
                  begin: str = 'All',
                  query: Optional[str] = None) -> HttpResponse:
    students = Student.get_list(begin, not BaseUser.is_employee(request.user))

    if request.is_ajax():
        students = prepare_ajax_students_list(students)
        return AjaxSuccessMessage(message="ok", data=students)
    else:
        data = {
            "students": students,
            "char": begin,
            "query": query,
            'mailto_group': mailto(request.user, students),
            'mailto_group_bcc': mailto(request.user, students, True)
        }
        return render(request, 'users/students_list.html', data)
示例#15
0
    def get_queryset(self):
        from apps.enrollment.courses.models.group import Group

        query = []

        if BaseUser.is_student(self.request.user):
            query.append(Q(record__student=self.request.user.student) & Q(record__status='1'))

        if BaseUser.is_employee(self.request.user):
            query.append(Q(teacher=self.request.user.employee))

        queryset = super(MyScheduleAjaxView, self).get_queryset()
        groups = Group.objects.filter(reduce(operator.or_, query))

        return queryset.filter(Q(event__group__in=groups) |
                               Q(event__interested=self.request.user) |
                               Q(event__author=self.request.user)).select_related('event', 'event__group',
                                                                                  'event__group__teacher')
示例#16
0
def is_owner_of_thesis(user: User, thesis: Thesis) -> bool:
    """Is the specified user the advisor of the specified thesis?"""
    return BaseUser.is_employee(user) and thesis.advisor == user.employee
示例#17
0
 def _to_base_person(user: User):
     if BaseUser.is_employee(user):
         return user.employee
     elif BaseUser.is_student(user):
         return user.student
     raise exceptions.NotFound()
示例#18
0
def my_profile(request):
    """User profile page.

    The profile page displays user settings (e-mail address, notifications). If
    he is a student, his opening times will be displayed. If the user is an
    employee, the page allows him to modify his public information (office,
    consultations).
    """
    semester = Semester.objects.get_next()

    data = {
        'semester': semester,
    }

    if BaseUser.is_employee(request.user):
        data.update({
            'consultations': request.user.employee.consultations,
            'room': request.user.employee.room,
            'homepage': request.user.employee.homepage,
            'title': request.user.employee.title,
        })

    if semester and BaseUser.is_student(request.user):
        student: Student = request.user.student
        groups_opening_times = GroupOpeningTimes.objects.filter(
            student_id=student.pk,
            group__course__semester_id=semester.pk).select_related(
                'group', 'group__course', 'group__teacher',
                'group__teacher__user').prefetch_related(
                    'group__term', 'group__term__classrooms')
        groups_times = []
        got: GroupOpeningTimes
        for got in groups_opening_times:
            group: Group = got.group
            group.opening_time = got.time
            groups_times.append(group)
        t0_time_obj = T0Times.objects.filter(student_id=student.pk,
                                             semester_id=semester.pk)
        try:
            t0_time = t0_time_obj.get().time
        except T0Times.DoesNotExist:
            t0_time = None
        grade_info = StudentGraded.objects.filter(
            student=student).select_related('semester').order_by(
                '-semester__records_opening')
        semesters_participated_in_grade = [x.semester for x in grade_info]
        current_semester_ects = Record.student_points_in_semester(
            student, semester)
        data.update({
            't0_time': t0_time,
            'groups_times': groups_times,
            'semesters_participated_in_grade': semesters_participated_in_grade,
            'current_semester_ects': current_semester_ects,
        })

    notifications_form = create_form(request)
    data.update({
        'form': notifications_form,
    })

    return render(request, 'users/my_profile.html', data)