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)
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)
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
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
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), }
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 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
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
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
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)
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)
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
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)
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')
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
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()
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)