Source code for student.utils

# Copyright (C) 2017 Semester.ly Technologies, LLC
#
# Semester.ly is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Semester.ly is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

from django.db.models import Q
from django.forms import model_to_dict

from student.models import Student, PersonalTimetable
from timetable.models import Course
from timetable.serializers import DisplayTimetableSerializer


[docs]def get_student(request): """ Returns: (:obj:`Student`): the student belonging to the authenticated user """ logged = request.user.is_authenticated if logged and Student.objects.filter(user=request.user).exists(): return Student.objects.get(user=request.user) else: return None
[docs]def get_classmates_from_course_id( school, student, course_id, semester, friends=None, include_same_as=False ): """ Get's current and past classmates (students with timetables containing the provided course ID). Classmates must have social_courses enabled to be included. If social_sections is enabled, info about what section they are in is also passed. Args: school (:obj:`str`): the school code (e.g. 'jhu') student (:obj:`Student`): the student for whom to find classmates course_id (:obj:`int`): the database id for the course semester (:obj:`Semester`): the semester that is current (to check for) friends (:obj:`list` of :obj:`Students`): if provided, does not re-query for friends list, uses provided list. include_same_as (:obj:`bool`): If provided as true, searches for classmates in any courses marked as "same as" in the database. """ if not friends: friends = student.friends.filter(social_courses=True) past_ids = [course_id] if include_same_as: c = Course.objects.get(id=course_id) if c.same_as: past_ids.append(c.same_as.id) curr_ptts = ( PersonalTimetable.objects.filter( student__in=friends, courses__id__exact=course_id ) .filter(Q(semester=semester)) .order_by("student", "last_updated") .distinct("student") ) past_ptts = ( PersonalTimetable.objects.filter(student__in=friends, courses__id__in=past_ids) .exclude(student__in=curr_ptts.values_list("student", flat=True)) .filter(~Q(semester=semester)) .order_by("student", "last_updated") .distinct("student") ) return { "current": get_classmates_from_tts(student, course_id, curr_ptts), "past": get_classmates_from_tts(student, course_id, past_ptts), }
[docs]def get_classmates_from_tts(student, course_id, tts): """ Returns a list of classmates a student has from a list of other user's timetables. This utility does the leg work for :meth:`get_classmates_from_course_id` by taking either a list of current or past timetables and finding classmates relevant to that list. If both students have social_offerings enabled, adds information about what sections the student is enrolled in on each classmate. """ classmates = [] for tt in tts: friend = tt.student classmate = model_to_dict( friend, exclude=["user", "id", "fbook_uid", "friends", "time_accepted_tos"] ) classmate["first_name"] = friend.user.first_name classmate["last_name"] = friend.user.last_name if student.social_offerings and friend.social_offerings: friend_sections = tt.sections.filter(course__id=course_id) sections = list( friend_sections.values_list("meeting_section", flat=True).distinct() ) classmate["sections"] = sections else: classmate["sections"] = [] classmates.append(classmate) return classmates
[docs]def get_friend_count_from_course_id(student, course_id, semester): """ Computes the number of friends a user has in a given course for a given semester. Ignores whether or not those friends have social courses enabled. Never exposes those user's names or infromation. This count is used purely to upsell user's to enable social courses. """ return ( PersonalTimetable.objects.filter( student__in=student.friends.all(), courses__id__exact=course_id ) .filter(Q(semester=semester)) .distinct("student") .count() )
[docs]def get_student_tts(student, school, semester): """ Returns serialized list of a student's :obj:`PersonalTimetable` objects ordered by last updated for passing to the frontend. """ timetables = student.personaltimetable_set.filter( school=school, semester=semester ).order_by("-last_updated") return DisplayTimetableSerializer.from_model(timetables, many=True).data