示例#1
0
    def post(self, request):
        """Generate best timetables given the user's selected courses"""
        school = request.subdomain
        params = request.data
        student = get_student(request)
        course_ids = list(params["courseSections"].keys())
        courses = [Course.objects.get(id=cid) for cid in course_ids]
        locked_sections = params["courseSections"]

        self.set_params_semester(params)
        save_analytics_timetable(courses, params["semester"], school,
                                 get_student(request))
        self.update_courses_and_locked_sections(params, course_ids, courses,
                                                locked_sections)
        opt_course_ids = params.get("optionCourses", [])
        max_optional = params.get("numOptionCourses", len(opt_course_ids))
        optional_courses = [
            Course.objects.get(id=cid) for cid in opt_course_ids
        ]
        optional_course_subsets = [
            subset for subset_size in range(max_optional, -1, -1)
            for subset in itertools.combinations(optional_courses, subset_size)
        ]
        custom_events = params.get("customSlots", [])
        preferences = params["preferences"]
        with_conflicts = preferences.get("try_with_conflicts", False)
        sort_metrics = [(m["metric"], m["order"])
                        for m in preferences.get("sort_metrics", [])
                        if m["selected"]]

        timetables = [
            timetable for opt_courses in optional_course_subsets
            for timetable in courses_to_timetables(
                courses + list(opt_courses),
                locked_sections,
                params["semester"],
                sort_metrics,
                params["school"],
                custom_events,
                with_conflicts,
                opt_course_ids,
            )
        ]

        context = self.create_context(request, params, student)
        courses = list(courses + optional_courses)
        response = self.create_response(courses, locked_sections, timetables,
                                        context)
        return Response(response, status=status.HTTP_200_OK)
示例#2
0
    def post(self, request):
        """
        Creates a :obj:`SharedTimetable` and returns the hashed database id
        as the slug for the url which students then share and access.
        """
        school = request.subdomain
        timetable = request.data['timetable']
        has_conflict = timetable.get('has_conflict', False)
        semester, _ = Semester.objects.get_or_create(**request.data['semester'])
        student = get_student(request)
        shared_timetable = SharedTimetable.objects.create(
            student=student, school=school, semester=semester,
            has_conflict=has_conflict)
        shared_timetable.save()

        added_courses = set()
        for slot in timetable['slots']:
            course_id, section_id = slot['course'], slot['section']
            if course_id not in added_courses:
                course_obj = Course.objects.get(id=course_id)
                shared_timetable.courses.add(course_obj)
                added_courses.add(course_id)

            section_obj = Section.objects.get(id=section_id)
            shared_timetable.sections.add(section_obj)
            if section_obj.course.id not in added_courses:
                return Response(status=status.HTTP_400_BAD_REQUEST)
        shared_timetable.save()

        response = {'slug': hashids.encrypt(shared_timetable.id)}
        return Response(response, status=status.HTTP_200_OK)
示例#3
0
    def get(self, request, query, sem_name, year):
        """ Return vectorized search results. """
        school = request.subdomain
        sem = Semester.objects.get_or_create(name=sem_name, year=year)[0]
        # TODO: use vectorized search after completion.
        # Use vectorized_search if and only if a valid Searcher object is created, otherwise use baseline_search
        # if apps.get_app_config('searches').searcher:
        #     course_match_objs = apps.get_app_config('searches').searcher.vectorized_search(request.subdomain, query, sem)[:4]
        # else:
        #     course_match_objs = baseline_search(request.subdomain, query, sem)[:4]

        # sorts queries by course number through a comparator
        def course_comparator(course1, course2):
            #isolate course number from XX0000
            c1=int(str(course1)[2:6])
            c2=int(str(course2)[2:6])
            if c1 < c2:
                return -1
            elif c1 > c2:
                return 1
            else:
                return 0
        course_match_objs = baseline_search(request.subdomain, query, sem).distinct()
        #only sort if results is less than 100 for efficiency sake
        if len(course_match_objs) < 100:
            course_match_objs = sorted(course_match_objs, key=cmp_to_key(course_comparator))
        #display only 12 courses to avoid displaying too many.
        course_match_objs = course_match_objs[:12]
        save_analytics_course_search(query[:200], course_match_objs[:2], sem, request.subdomain,
                                     get_student(request))
        course_matches = [CourseSerializer(course, context={'semester': sem, 'school': school}).data
                          for course in course_match_objs]
        return Response(course_matches, status=status.HTTP_200_OK)
示例#4
0
def student_info(request):
    if request.method == 'POST':
        return redirect('pilot:pilotcourses')
    else:
        student = get_student(request)
        context = {'student': student}
        return render(request, 'pilot/student_info.html/', context=context)
示例#5
0
def meetings(request, courseList):
    student = get_student(request)
    semester = Semester.objects.filter(name='Spring', year='2020')
    course_list = courseList.split("_")
    if request.method == 'POST':
        sections = ""
        for course in course_list:
            section = request.POST.getlist(course)
            sections += str(section[0]) + "_"
        sections = sections[0:-1]
        return redirect('pilot:offerings', sectionList=sections)
    else:
        decoded_list = {}
        for course in course_list:
            course_decode = Course.objects.get(id=int(course))
            sections = list(
                Section.objects.filter(course=course_decode,
                                       semester=semester))
            sections_offerings = {}
            for section in sections:
                offerings = list(
                    PilotOffering.objects.filter(sections=section))
                sections_offerings[section] = offerings
            decoded_list[course_decode] = sections_offerings
        context = {
            'courses': decoded_list,
            'courseList': courseList,
            'student': student,
            'id': student.id
        }
        return render(request, 'pilot/meetings.html/', context=context)
示例#6
0
 def get_feature_flow(self, request, slug):
     """
     Overrides :obj:`FeatureFlowView` *get_feature_flow* method. Takes the slug,
     decrypts the hashed database id, and either retrieves the corresponding
     timetable or hits a 404.
     """
     timetable_id = hashids.decrypt(slug)[0]
     shared_timetable = get_object_or_404(SharedTimetable,
                                          id=timetable_id,
                                          school=request.subdomain)
     context = {
         "semester": shared_timetable.semester,
         "school": request.subdomain,
         "student": get_student(request),
     }
     return {
         "semester":
         shared_timetable.semester,
         "courses":
         CourseSerializer(shared_timetable.courses,
                          context=context,
                          many=True).data,
         "sharedTimetable":
         DisplayTimetableSerializer.from_model(shared_timetable).data,
     }
示例#7
0
    def post(self, request):
        new_link = FinalExamShare.objects.create(school=request.subdomain,
                                                 student=get_student(request),
                                                 exam_json=request.data)
        new_link.save()

        response = {'slug': hashids.encrypt(new_link.id)}
        return Response(response, status.HTTP_200_OK)
示例#8
0
 def save_analytic(self, request, query, course_matches, sem, advanced=False):
     save_analytics_course_search(
         query[:200],
         course_matches[:2],
         sem,
         request.subdomain,
         get_student(request),
         advanced,
     )
示例#9
0
    def post(self, request):
        new_link = FinalExamShare.objects.create(
            school=request.subdomain,
            student=get_student(request),
            exam_json=request.data
        )
        new_link.save()

        response = {'slug': hashids.encrypt(new_link.id)}
        return Response(response, status.HTTP_200_OK)
示例#10
0
    def get(self, request, *args, **kwargs):
        if not self.allow_unauthenticated and not request.user.is_authenticated:
            return HttpResponseRedirect("/")
        self.school = request.subdomain
        self.student = get_student(request)

        feature_flow = self.get_feature_flow(request, *args, **kwargs)

        # take semester provided by feature flow if available, otherwise the first available sem
        all_semesters = get_current_semesters(self.school)
        if "semester" in feature_flow:
            sem = feature_flow.pop("semester")
            sem_dict = {"name": sem.name, "year": sem.year}
            if sem_dict not in all_semesters:
                all_semesters.append(sem_dict)
            curr_sem_index = all_semesters.index(sem_dict)
        else:
            curr_sem_index = 0
            sem = Semester.objects.get(**all_semesters[curr_sem_index])

        integrations = []
        if self.student and self.student.user.is_authenticated:
            self.student.school = self.school
            self.student.save()
            for i in self.student.integrations.all():
                integrations.append(i.name)

        final_exams = []
        if SCHOOLS_MAP[self.school].final_exams is None:
            final_exams = []
        else:
            for year, terms in SCHOOLS_MAP[self.school].final_exams.items():
                for term in terms:
                    final_exams.append({"name": term, "year": str(year)})

        init_data = {
            "school": self.school,
            "currentUser": get_student_dict(self.school, self.student, sem),
            "currentSemester": curr_sem_index,
            "allSemesters": all_semesters,
            # 'oldSemesters': get_old_semesters(self.school),
            "uses12HrTime": SCHOOLS_MAP[self.school].ampm,
            "studentIntegrations": integrations,
            "latestAgreement":
            AgreementSerializer(Agreement.objects.latest()).data,
            "registrar": SCHOOLS_MAP[self.school].registrar,
            "examSupportedSemesters":
            list(map(all_semesters.index, final_exams)),
            "timeUpdatedTos":
            Agreement.objects.latest().last_updated.isoformat(),
            "featureFlow": dict(feature_flow, name=self.feature_name),
        }

        return render(request, "timetable.html",
                      {"init_data": json.dumps(init_data)})
示例#11
0
    def get(self, request, *args, **kwargs):
        if not self.allow_unauthenticated and not request.user.is_authenticated:
            return HttpResponseRedirect('/')
        self.school = request.subdomain
        self.student = get_student(request)

        feature_flow = self.get_feature_flow(request, *args, **kwargs)

        # take semester provided by feature flow if available, otherwise the first available sem
        all_semesters = get_current_semesters(self.school)
        if 'semester' in feature_flow:
            sem = feature_flow.pop('semester')
            sem_dict = {'name': sem.name, 'year': sem.year}
            if sem_dict not in all_semesters:
                all_semesters.append(sem_dict)
            curr_sem_index = all_semesters.index(sem_dict)
        else:
            curr_sem_index = 0
            sem = Semester.objects.get(**all_semesters[curr_sem_index])

        integrations = []
        if self.student and self.student.user.is_authenticated:
            self.student.school = self.school
            self.student.save()
            for i in self.student.integrations.all():
                integrations.append(i.name)

        final_exams = []
        if SCHOOLS_MAP[self.school].final_exams is None:
            final_exams = []
        else:
            for year, terms in SCHOOLS_MAP[self.school].final_exams.items():
                for term in terms:
                    final_exams.append({'name': term, 'year': str(year)})

        init_data = {
            'school': self.school,
            'currentUser': get_student_dict(self.school, self.student, sem),
            'currentSemester': curr_sem_index,
            'allSemesters': all_semesters,
            # 'oldSemesters': get_old_semesters(self.school),
            'uses12HrTime': SCHOOLS_MAP[self.school].ampm,
            'studentIntegrations': integrations,
            'latestAgreement':
            AgreementSerializer(Agreement.objects.latest()).data,
            'registrar': SCHOOLS_MAP[self.school].registrar,
            'examSupportedSemesters':
            list(map(all_semesters.index, final_exams)),
            'timeUpdatedTos':
            Agreement.objects.latest().last_updated.isoformat(),
            'featureFlow': dict(feature_flow, name=self.feature_name)
        }

        return render(request, 'timetable.html',
                      {'init_data': json.dumps(init_data)})
示例#12
0
    def get(self, request, *args, **kwargs):
        self.school = request.subdomain
        self.student = get_student(request)

        feature_flow = self.get_feature_flow(request, *args, **kwargs)

        # take semester provided by feature flow if available, otherwise the first available sem
        all_semesters = get_current_semesters(self.school)
        if 'semester' in feature_flow:
            sem = feature_flow.pop('semester')
            sem_dict = {'name': sem.name, 'year': sem.year}
            if sem_dict not in all_semesters:
                all_semesters.append(sem_dict)
            curr_sem_index = all_semesters.index(sem_dict)
        else:
            curr_sem_index = 0
            sem = Semester.objects.get(**all_semesters[curr_sem_index])

        integrations = []
        if self.student and self.student.user.is_authenticated():
            self.student.school = self.school
            self.student.save()
            for i in self.student.integrations.all():
                integrations.append(i.name)

        final_exams = []
        if SCHOOLS_MAP[self.school].final_exams is None:
            final_exams = []
        else:
            for year, terms in SCHOOLS_MAP[self.school].final_exams.items():
                for term in terms:
                    final_exams.append({
                        'name': term,
                        'year': str(year)
                    })

        init_data = {
            'school': self.school,
            'currentUser': get_student_dict(self.school, self.student, sem),
            'currentSemester': curr_sem_index,
            'allSemesters': all_semesters,
            # 'oldSemesters': get_old_semesters(self.school),
            'uses12HrTime': SCHOOLS_MAP[self.school].ampm,
            'studentIntegrations': integrations,
            'examSupportedSemesters': map(all_semesters.index,
                                          final_exams),
            'timeUpdatedTos': Agreement.objects.latest().last_updated.isoformat(),

            'featureFlow': dict(feature_flow, name=self.feature_name)
        }

        return render(request, 'timetable.html', {'init_data': json.dumps(init_data)})
示例#13
0
文件: views.py 项目: rbiz4/semesterly
    def post(self, request, query, sem_name, year):
        """ Return advanced search results. """
        school = request.subdomain
        page = int(request.query_params.get('page', 1))
        sem, _ = Semester.objects.get_or_create(name=sem_name, year=year)
        # Filter first by the user's search query.
        # TODO : use vectorized search (change returned obj to be filterable)
        course_match_objs = baseline_search(school, query, sem)

        # Filter now by departments, areas, levels, or times if provided.
        filters = request.data.get('filters', {})
        if filters.get('areas'):
            course_match_objs = course_match_objs.filter(areas__contains=filters.get('areas'))
        if filters.get('departments'):
            course_match_objs = course_match_objs.filter(department__in=filters.get('departments'))
        if filters.get('levels'):
            course_match_objs = course_match_objs.filter(level__in=filters.get('levels'))
        if filters.get('times'):
            day_map = {"Monday": "M", "Tuesday": "T", "Wednesday": "W", "Thursday": "R",
                       "Friday": "F"}
            course_match_objs = course_match_objs.filter(
                reduce(operator.or_,
                       (Q(section__offering__time_start__gte="{0:0=2d}:00".format(min_max['min']),
                          section__offering__time_end__lte="{0:0=2d}:00".format(min_max['max']),
                          section__offering__day=day_map[min_max['day']],
                          section__semester=sem,
                          section__section_type="L") for min_max in filters.get('times'))
                       )
            )
        course_match_objs = course_match_objs.order_by('id')
        try:
            paginator = Paginator(course_match_objs.distinct(), 20)
            course_match_objs = paginator.page(page)
        except EmptyPage:
            return Response([])

        save_analytics_course_search(query[:200], course_match_objs[:2], sem, school,
                                     get_student(request),
                                     advanced=True)
        student = None
        logged = request.user.is_authenticated()
        if logged and Student.objects.filter(user=request.user).exists():
            student = Student.objects.get(user=request.user)
        serializer_context = {'semester': sem, 'student': student, 'school': request.subdomain}
        json_data = [CourseSerializer(course, context=serializer_context).data
                     for course in course_match_objs]

        return Response(json_data, status=status.HTTP_200_OK)
示例#14
0
文件: views.py 项目: rbiz4/semesterly
 def get(self, request, query, sem_name, year):
     """ Return vectorized search results. """
     school = request.subdomain
     sem = Semester.objects.get_or_create(name=sem_name, year=year)[0]
     # TODO: use vectorized search after completion.
     # Use vectorized_search if and only if a valid Searcher object is created, otherwise use baseline_search
     # if apps.get_app_config('searches').searcher:
     #     course_match_objs = apps.get_app_config('searches').searcher.vectorized_search(request.subdomain, query, sem)[:4]
     # else:
     #     course_match_objs = baseline_search(request.subdomain, query, sem)[:4]
     course_match_objs = baseline_search(request.subdomain, query, sem).distinct()[:4]
     save_analytics_course_search(query[:200], course_match_objs[:2], sem, request.subdomain,
                                  get_student(request))
     course_matches = [CourseSerializer(course, context={'semester': sem, 'school': school}).data
                       for course in course_match_objs]
     return Response(course_matches, status=status.HTTP_200_OK)
示例#15
0
 def get(self, request, query, sem_name, year):
     """ Return vectorized search results. """
     school = request.subdomain
     sem = Semester.objects.get_or_create(name=sem_name, year=year)[0]
     # TODO: use vectorized search after completion.
     # Use vectorized_search if and only if a valid Searcher object is created, otherwise use baseline_search
     # if apps.get_app_config('searches').searcher:
     #     course_match_objs = apps.get_app_config('searches').searcher.vectorized_search(request.subdomain, query, sem)[:4]
     # else:
     #     course_match_objs = baseline_search(request.subdomain, query, sem)[:4]
     course_match_objs = baseline_search(request.subdomain, query, sem).distinct()[:4]
     save_analytics_course_search(query[:200], course_match_objs[:2], sem, request.subdomain,
                                  get_student(request))
     course_matches = [CourseSerializer(course, context={'semester': sem, 'school': school}).data
                       for course in course_match_objs]
     return Response(course_matches, status=status.HTTP_200_OK)
示例#16
0
def pilotcourses(request):
    student = get_student(request)
    if request.method == 'POST':
        course_list = request.POST.getlist('course_list')
        courses_selected = ""
        for course in course_list:
            courses_selected += str(course) + "_"
        courses_selected = courses_selected[0:-1]
        return redirect('pilot:meetings', courseList=courses_selected)
    else:
        COURSE_LIST = []
        for courseint in CourseIntegration.objects.filter(integration_id=3):
            if Course.objects.filter(id=courseint.course_id).exists():
                COURSE_LIST.append(Course.objects.get(id=courseint.course_id))
        context = {'courses': COURSE_LIST, 'student': student}
        return render(request, 'pilot/courses.html/', context=context)
示例#17
0
    def post(self, request, query, sem_name, year):
        """ Return advanced search results. """
        school = request.subdomain
        page = int(request.query_params.get('page', 1))
        sem, _ = Semester.objects.get_or_create(name=sem_name, year=year)
        # Filter first by the user's search query.
        # TODO : use vectorized search (change returned obj to be filterable)
        course_match_objs = baseline_search(school, query, sem)

        # Filter now by departments, areas, levels, or times if provided.
        filters = request.data.get('filters', {})
        if filters.get('areas'):
            course_match_objs = course_match_objs.filter(areas__in=filters.get('areas'))
        if filters.get('departments'):
            course_match_objs = course_match_objs.filter(department__in=filters.get('departments'))
        if filters.get('levels'):
            course_match_objs = course_match_objs.filter(level__in=filters.get('levels'))
        if filters.get('times'):
            day_map = {"Monday": "M", "Tuesday": "T", "Wednesday": "W", "Thursday": "R",
                       "Friday": "F"}
            course_match_objs = course_match_objs.filter(
                reduce(operator.or_,
                       (Q(section__offering__time_start__gte="{0:0=2d}:00".format(min_max['min']),
                          section__offering__time_end__lte="{0:0=2d}:00".format(min_max['max']),
                          section__offering__day=day_map[min_max['day']],
                          section__semester=sem,
                          section__section_type="L") for min_max in filters.get('times'))
                       )
            )
        try:
            paginator = Paginator(course_match_objs.distinct(), 20)
            course_match_objs = paginator.page(page)
        except EmptyPage:
            return Response([])

        save_analytics_course_search(query[:200], course_match_objs[:2], sem, school,
                                     get_student(request),
                                     advanced=True)
        student = None
        logged = request.user.is_authenticated()
        if logged and Student.objects.filter(user=request.user).exists():
            student = Student.objects.get(user=request.user)
        serializer_context = {'semester': sem, 'student': student, 'school': request.subdomain}
        json_data = [CourseSerializer(course, context=serializer_context).data
                     for course in course_match_objs]

        return Response(json_data, status=status.HTTP_200_OK)
示例#18
0
    def put(self, request):
        """
        Creates a notification token for the user.
        """
        token = request.data
        school = request.subdomain
        student = get_student(request)
        token, _ = RegistrationToken.objects.update_or_create(auth=token['auth'],
                                                              p256dh=token['p256dh'],
                                                              endpoint=token['endpoint'])
        if student:
            token.student = student
            token.save()
            student.school = school
            student.save()

        return Response(model_to_dict(token), status=status.HTTP_201_CREATED)
示例#19
0
 def get_feature_flow(self, request, slug):
     """
     Overrides :obj:`FeatureFlowView` *get_feature_flow* method. Takes the slug,
     decrypts the hashed database id, and either retrieves the corresponding
     timetable or hits a 404.
     """
     timetable_id = hashids.decrypt(slug)[0]
     shared_timetable = get_object_or_404(SharedTimetable,
                                          id=timetable_id,
                                          school=request.subdomain)
     context = {'semester': shared_timetable.semester, 'school': request.subdomain,
                'student': get_student(request)}
     return {
         'semester': shared_timetable.semester,
         'courses': CourseSerializer(shared_timetable.courses, context=context, many=True).data,
         'sharedTimetable': DisplayTimetableSerializer.from_model(shared_timetable).data
     }
示例#20
0
    def put(self, request):
        """
        Creates a notification token for the user.
        """
        token = request.data
        school = request.subdomain
        student = get_student(request)
        token, _ = RegistrationToken.objects.update_or_create(
            auth=token['auth'],
            p256dh=token['p256dh'],
            endpoint=token['endpoint'])
        if student:
            token.student = student
            token.save()
            student.school = school
            student.save()

        return Response(model_to_dict(token), status=status.HTTP_201_CREATED)
示例#21
0
 def post(self, request, query, sem_name, year):
     """Return advanced search results."""
     school = request.subdomain
     sem, _ = Semester.objects.get_or_create(name=sem_name, year=year)
     filters = request.data.get("filters", {})
     course_matches = search(school, query, sem)
     course_matches = self.filter_course_matches(course_matches, filters, sem)
     course_matches = course_matches.distinct()[:100]  # prevent timeout
     self.save_analytic(request, query, course_matches, sem, True)
     student = get_student(request)
     serializer_context = {
         "semester": sem,
         "student": student,
         "school": request.subdomain,
     }
     course_match_data = [
         CourseSerializer(course, context=serializer_context).data
         for course in course_matches
     ]
     return Response(course_match_data, status=status.HTTP_200_OK)
示例#22
0
 def post(self, request):
     """
     Creates a :obj:`SharedTimetable` and returns the hashed database id
     as the slug for the url which students then share and access.
     """
     school = request.subdomain
     timetable = request.data["timetable"]
     has_conflict = timetable.get("has_conflict", False)
     semester, _ = Semester.objects.get_or_create(
         **request.data["semester"])
     student = get_student(request)
     shared_timetable = SharedTimetable.objects.create(
         student=student,
         school=school,
         semester=semester,
         has_conflict=has_conflict)
     shared_timetable.save()
     self.save_courses(timetable, shared_timetable)
     response = {"slug": hashids.encrypt(shared_timetable.id)}
     return Response(response, status=status.HTTP_200_OK)
示例#23
0
    def get(self, request, *args, **kwargs):
        self.school = request.subdomain
        self.student = get_student(request)

        feature_flow = self.get_feature_flow(request, *args, **kwargs)

        # take semester provided by feature flow if available, otherwise the first available sem
        all_semesters = get_current_semesters(self.school)
        if 'semester' in feature_flow:
            sem = feature_flow.pop('semester')
            sem_dict = {'name': sem.name, 'year': sem.year}
            if sem_dict not in all_semesters:
                all_semesters.append(sem_dict)
            curr_sem_index = all_semesters.index(sem_dict)
        else:
            curr_sem_index = 0
            sem = Semester.objects.get(**all_semesters[curr_sem_index])

        integrations = []
        if self.student and self.student.user.is_authenticated():
            self.student.school = self.school
            self.student.save()
            for i in self.student.integrations.all():
                integrations.append(i.name)

        init_data = {
            'school': self.school,
            'currentUser': get_student_dict(self.school, self.student, sem),
            'currentSemester': curr_sem_index,
            'allSemesters': all_semesters,
            'oldSemesters': get_old_semesters(self.school),
            'uses12HrTime': self.school in AM_PM_SCHOOLS,
            'studentIntegrations': integrations,
            'examSupportedSemesters': map(all_semesters.index,
                                          final_exams_available.get(self.school, [])),
            'timeUpdatedTos': Agreement.objects.latest().last_updated.isoformat(),

            'featureFlow': dict(feature_flow, name=self.feature_name)
        }

        return render(request, 'timetable.html', {'init_data': json.dumps(init_data)})
示例#24
0
def offerings(request, sectionList):
    student = get_student(request)
    section_list = sectionList.split("_")
    if request.method == 'POST':
        return redirect('pilot:semlyhome')
    else:
        vacant = []
        full = []
        message = ""
        for section in section_list:
            with transaction.atomic():
                pilot_offering = PilotOffering.objects.get(id=int(section))
                signedup = False
                for person in pilot_offering.students.all():
                    if person == student:
                        signedup = True
                        message = 'You are already enrolled in this course'
                for person in pilot_offering.wait_students.all():
                    if person == student:
                        signedup = True
                        message = 'You are already on the waitlist for this course'
                if not signedup:
                    if pilot_offering.enrolment < pilot_offering.size:
                        vacant.append(pilot_offering)
                        pilot_offering.students.add(student)
                        pilot_offering.enrolment = len(
                            pilot_offering.students.all())
                    else:
                        full.append(pilot_offering)
                        pilot_offering.wait_students.add(student)
                        pilot_offering.waitlist = len(
                            pilot_offering.wait_students.all())
                pilot_offering.save()
        context = {
            'student': student,
            'enrolled': vacant,
            'waitlisted': full,
            'sections': section_list,
            'message': message
        }
        return render(request, 'pilot/offerings.html/', context=context)
示例#25
0
def info(request):
    if request.method == 'POST':
        form = StudentForm(request.POST)
        student_object = get_student(request)
        if form.is_valid():
            student_object.user.first_name = form.cleaned_data['first_name']
            student_object.user.last_name = form.cleaned_data['last_name']
            student_object.hopid = form.cleaned_data['hopid']
            student_object.jhed = form.cleaned_data['jhed']
            student_object.class_year = form.cleaned_data['class_year']
            student_object.major = form.cleaned_data['major']
            pre_h = form.cleaned_data['pre_health']
            pre_h = {'True': True, 'False': False, 'None': None}[pre_h]
            student_object.pre_health = pre_h
            diss = form.cleaned_data['diss']
            diss = {'True': True, 'False': False, 'None': None}[diss]
            student_object.disabilities = diss
            student_object.save()
        return redirect('pilot:studentinfo')
    else:
        return render(request, 'pilot/get_info.html/')
示例#26
0
def view_analytics_dashboard(request):
    student = get_student(request)
    if student and student.user.is_staff:
        # Number of time tables by school
        total_timetables_by_school = {}
        # timetables_per_hour = {}
        # shared_timetables_per_hour = {}
        for school in ACTIVE_SCHOOLS:
            total_timetables_by_school[school] = number_timetables(school=school)
            # timetables_per_hour[school] = number_timetables_per_hour(school=school)
            # shared_timetables_per_hour[school] = number_timetables_per_hour(Timetable=SharedTimetable, school=school)

        # Number of users by permission
        # TODO: Moves this array to somewhere else (like ACTIVE_SCHOOLS)
        total_signups = number_timetables(Timetable=Student)

        permissions = ["social_courses", "social_offerings", "social_all"]
        num_users_by_permission = {}
        for permission in permissions:
            # TODO: hacky way of passing in permission as an identifier for parameter.
            # Also have to use tuple for template to easily access %.
            args = {"Timetable": Student, permission: True}
            num_users = number_timetables(**args)
            percent_users = format(float(num_users) / total_signups * 100, '.2f')
            num_users_by_permission[permission] = (num_users, percent_users)

        total_calendar_exports = number_timetables(Timetable=CalendarExport)
        google_calendar_exports = number_timetables(Timetable=CalendarExport, is_google_calendar=True)
        ics_calendar_exports = total_calendar_exports - google_calendar_exports
        unique_users_calendar_exports = number_timetables(Timetable=CalendarExport, distinct="student")

        total_final_exam_views = number_timetables(Timetable=FinalExamModalView)
        unique_users_final_exam_views = number_timetables(Timetable=FinalExamModalView, distinct="student")
        total_shared_timetable_views = number_timetables(Timetable=SharedTimetableView)
        total_shared_course_views = number_timetables(Timetable=SharedCourseView)

        fb_alert_views = number_timetables(Timetable=FacebookAlertView)
        unique_users_fb_alert_views = number_timetables(Timetable=FacebookAlertView, distinct="student")
        fb_alert_clicks = number_timetables(Timetable=FacebookAlertClick)
        unique_users_fb_alert_clicks = number_timetables(Timetable=FacebookAlertClick, distinct="student")

        return render_to_response('analytics_dashboard.html', {
                "signups_per_hour": number_timetables_per_hour(
                    Timetable=Student,start_delta_days=7, interval_delta_hours=24),
                "total_timetables_by_school": json.dumps(total_timetables_by_school),
                "total_timetables_by_semester": json.dumps(number_timetables_per_semester()),
                "total_timetables": number_timetables(),
                "total_shared_timetables": number_timetables(Timetable=SharedTimetable),
                "total_personal_timetables": number_timetables(Timetable=PersonalTimetable),
                "total_signups": total_signups,
                "num_users_chrome_notifs": number_user_chrome_notifs(),
                "num_users_by_permission": num_users_by_permission,
                "num_users_by_class_year": json.dumps(number_students_by_year()),
                "num_users_by_school": json.dumps(number_students_by_school()),
                "number_of_reactions": json.dumps(number_of_reactions()),
                "total_calendar_exports": total_calendar_exports,
                "google_calendar_exports": google_calendar_exports,
                "ics_calendar_exports": ics_calendar_exports,
                "unique_users_calendar_exports": unique_users_calendar_exports,
                "total_final_exam_views": total_final_exam_views,
                "unique_users_final_exam_views": unique_users_final_exam_views,
                "fb_alert_views": fb_alert_views,
                "unique_users_fb_alert_views": unique_users_fb_alert_views,
                "fb_alert_clicks": fb_alert_clicks,
                "unique_users_fb_alert_clicks": unique_users_fb_alert_clicks,
                "total_shared_timetable_views":total_shared_timetable_views,
                "total_shared_course_views":total_shared_course_views,
                "calendar_exports_by_type": json.dumps({"ics": ics_calendar_exports, "google": google_calendar_exports}),
                "jhu_most_popular_courses": [], # needs to be refactored; was causing timeout on server because too slow
                "uoft_most_popular_courses": [], # needs to be refactored; was causing timeout on server because too slow
                "umd_most_popular_courses": [], # needs to be refactored; was causing timeout on server because too slow
                "itcr_most_popular_courses": []
            },
            context_instance=RequestContext(request))
    else:
        raise Http404
示例#27
0
    def post(self, request):
        """Generate best timetables given the user's selected courses"""
        school = request.subdomain
        params = request.data
        student = get_student(request)

        try:
            params['semester'] = Semester.objects.get_or_create(**params['semester'])[0]
        except TypeError: # handle deprecated cached semesters from frontend
            params['semester'] = Semester.objects.get(name="Fall", year="2016") \
                if params['semester'] == "F" \
                else Semester.objects.get(name="Spring", year="2017")

        course_ids = params['courseSections'].keys()
        courses = [Course.objects.get(id=cid) for cid in course_ids]
        locked_sections = params['courseSections']

        save_analytics_timetable(courses, params['semester'], school, get_student(request))

        for updated_course in params.get('updated_courses', []):
            cid = str(updated_course['course_id'])
            locked_sections[cid] = locked_sections.get(cid, {})
            if cid not in course_ids:
                courses.append(Course.objects.get(id=int(cid)))

            for locked_section in filter(bool, updated_course['section_codes']):
                update_locked_sections(locked_sections, cid, locked_section, params['semester'])

        # temp optional course implementation
        opt_course_ids = params.get('optionCourses', [])
        max_optional = params.get('numOptionCourses', len(opt_course_ids))
        optional_courses = [Course.objects.get(id=cid) for cid in opt_course_ids]
        optional_course_subsets = [subset for subset_size in range(max_optional, -1, -1)
                                   for subset in itertools.combinations(optional_courses,
                                                                        subset_size)]

        custom_events = params.get('customSlots', [])
        preferences = params['preferences']
        with_conflicts = preferences.get('try_with_conflicts', False)
        sort_metrics = [(m['metric'], m['order']) for m in preferences.get('sort_metrics', [])
                        if m['selected']]

        # TODO move sorting to view level so that result is sorted
        timetables = [timetable for opt_courses in optional_course_subsets
                                for timetable in courses_to_timetables(courses + list(opt_courses),
                                                                       locked_sections,
                                                                       params['semester'],
                                                                       sort_metrics,
                                                                       params['school'],
                                                                       custom_events,
                                                                       with_conflicts,
                                                                       opt_course_ids)]

        context = {'semester': params['semester'], 'school': request.subdomain, 'student': student}
        courses = [course for course in courses + optional_courses]
        response = {
            'timetables': DisplayTimetableSerializer(timetables, many=True).data,
            'new_c_to_s': locked_sections,
            'courses': CourseSerializer(courses, context=context, many=True).data
        }
        return Response(response, status=status.HTTP_200_OK)