Ejemplo n.º 1
0
 def get_regdate(self, ordering='startdate'):
     reg_verb = GetNode('V/Flags/Registration/Enrolled')
     reg_node_parent = self.program.anchor['Classes']
     bits = UserBit.valid_objects().filter(
         user=self.user,
         verb=reg_verb).filter(QTree(qsc__below=reg_node_parent))
     if bits.exists():
         return bits.order_by(ordering).values_list(
             'startdate', flat=True)[0].strftime("%Y-%m-%d %H:%M:%S")
Ejemplo n.º 2
0
    def extraform(self, request, tl, one, two, module, extra, prog):

        custom_form_id = Tag.getProgramTag('%s_extraform_id' % tl, prog, None)
        if custom_form_id:
            cf = Form.objects.get(id=int(custom_form_id))
        else:
            raise ESPError(
                False
            ), 'Cannot find an appropriate form for the quiz.  Please ask your administrator to create a form and set the %s_extraform_id Tag.' % tl

        form_wizard = FormHandler(cf, request, request.user).get_wizard()
        form_wizard.curr_request = request

        if request.method == 'POST':
            form = form_wizard.get_form(0, request.POST, request.FILES)
            if form.is_valid():
                #   Delete previous responses from this user
                dmh = DynamicModelHandler(cf)
                form_model = dmh.createDynModel()
                form_model.objects.filter(user=request.user).delete()
                form_wizard.done([form])
                bit, created = UserBit.valid_objects().get_or_create(
                    user=request.user,
                    qsc=self.program.anchor,
                    verb=self.reg_verb)
                return self.goToCore(tl)
        else:
            #   If the user already filled out the form, use their earlier response for the initial values
            if self.isCompleted():
                dmh = DynamicModelHandler(cf)
                form_model = dmh.createDynModel()
                prev_results = form_model.objects.filter(
                    user=request.user).order_by('-id')
                if prev_results.exists():
                    prev_result_data = {}
                    plain_form = form_wizard.get_form(0)
                    #   Load previous results, with a hack for multiple choice questions.
                    for field in plain_form.fields:
                        if isinstance(plain_form.fields[field],
                                      forms.MultipleChoiceField):
                            prev_result_data[field] = getattr(
                                prev_results[0], field).split(';')
                        else:
                            prev_result_data[field] = getattr(
                                prev_results[0], field)
                    form_wizard = FormHandler(
                        cf, request, request.user).get_wizard(
                            initial_data={0: prev_result_data})

            form = form_wizard.get_form(0)

        return render_to_response(self.baseDir() + 'custom_form.html', request,
                                  (prog, tl), {
                                      'prog': prog,
                                      'form': form,
                                      'tl': tl
                                  })
Ejemplo n.º 3
0
    def _checkStudent(moduleObj, request, *args, **kwargs):
        if not_logged_in(request):
            return HttpResponseRedirect('%s?%s=%s' % (LOGIN_URL, REDIRECT_FIELD_NAME, quote(request.get_full_path())))

        if not request.user.isStudent() and not request.user.isAdmin(moduleObj.program):
            allowed_student_types = Tag.getTag("allowed_student_types", moduleObj.program, default='')
            matching_user_types = UserBit.valid_objects().filter(user=request.user, verb__parent=GetNode("V/Flags/UserRole"), verb__name__in=allowed_student_types.split(","))
            if not matching_user_types:
                return render_to_response('errors/program/notastudent.html', request, (moduleObj.program, 'learn'), {})
        return method(moduleObj, request, *args, **kwargs)
Ejemplo n.º 4
0
 def undoCheckIn(self, teacher, prog):
     """Undo what checkIn does"""
     userbits = UserBit.valid_objects().filter(user=teacher,
                                             qsc=prog.anchor,
                                             verb=GetNode('V/Flags/Registration/Teacher/Arrived'))
     if userbits:
         userbits.update(enddate=datetime.now())
         UserBit.updateCache(teacher.id)
         return '%s is no longer checked in.' % teacher.name()
     else:
         return '%s was not checked in for %s.' % (teacher.name(), prog.niceName())
Ejemplo n.º 5
0
    def select_lunch(self, request, tl, one, two, module, extra, prog):
        context = {'prog': self.program}
        user = request.user
        dates = prog.dates()

        if request.method == 'POST':
            forms = [
                StudentLunchSelectionForm(prog,
                                          user,
                                          dates[i],
                                          request.POST,
                                          prefix='day%d' % i)
                for i in range(len(dates))
            ]
            all_valid = True
            success = True
            for form in forms:
                if not form.is_valid():
                    all_valid = False
            if all_valid:
                context['messages'] = []
                for form in forms:
                    (result, msg) = form.save_data()
                    if not result:
                        success = False
                    context['messages'] += [msg]
                if success:
                    bit, created = UserBit.valid_objects().get_or_create(
                        user=user,
                        qsc=prog.anchor,
                        verb=GetNode('V/Flags/Registration/LunchSelected'))
                    return self.goToCore(tl)
            else:
                context['errors'] = True
        else:
            forms = [
                StudentLunchSelectionForm(prog,
                                          user,
                                          dates[i],
                                          prefix='day%d' % i)
                for i in range(len(dates))
            ]
            for i in range(len(forms)):
                forms[i].load_data()

        if 'messages' in context:
            print context['messages']

        context['forms'] = forms

        return render_to_response(self.baseDir() + 'select_lunch.html',
                                  context)
Ejemplo n.º 6
0
 def barcodecheckin(self, request, tl, one, two, module, extra, prog):
     context = {}
     attended_verb = GetNode('V/Flags/Registration/Attended')
     prog_anchor = prog.anchor
     if request.method == 'POST':
         results = {
             'not_found': [],
             'existing': [],
             'new': [],
             'not_student': []
         }
         form = OnsiteBarcodeCheckinForm(request.POST)
         if form.is_valid():
             codes = form.cleaned_data['uids'].split()
             for code in codes:
                 try:
                     result = ESPUser.objects.filter(id=code)
                 except ValueError:
                     results['not_found'].append(code)
                 if len(result) > 1:
                     raise ESPError(
                         False
                     ), "Something weird happened, there are two students with ID %s." % code
                 elif len(result) == 0:
                     results['not_found'].append(code)
                 else:
                     student = result[0]
                     if student.isStudent():
                         existing = UserBit.valid_objects().filter(
                             user=student,
                             qsc=prog_anchor,
                             verb=attended_verb)
                         if existing:
                             results['existing'].append(code)
                         else:
                             new = UserBit(user=student,
                                           qsc=prog_anchor,
                                           verb=attended_verb)
                             new.save()
                             results['new'].append(code)
                     else:
                         results['not_student'].append(code)
     else:
         results = {}
         form = OnsiteBarcodeCheckinForm()
     context['module'] = self
     context['form'] = form
     context['results'] = results
     return render_to_response(self.baseDir() + 'barcodecheckin.html',
                               request, (prog, tl), context)
Ejemplo n.º 7
0
def startreg(form, programs, students, profiles, result_dict={}):

    #   Get first class registration bit and confirmation bit for each student and bin by day
    reg_dict = {}
    confirm_dict = {}
    for program in programs:
        reg_dict[program] = {}
        confirm_dict[program] = {}

    reg_verb = GetNode('V/Flags/Registration')
    confirm_verb = GetNode('V/Flags/Public')

    for student in students:
        for program in programs:
            reg_node = GetNode(program.anchor.uri + '/Classes')
            confirm_node = GetNode(program.anchor.uri + '/Confirmation')

            reg_bits = UserBit.objects.filter(user=student).filter(
                QTree(verb__below=reg_verb)).filter(
                    QTree(qsc__below=reg_node)).order_by('startdate')
            if reg_bits.exists():
                if reg_bits[0].startdate.date() not in reg_dict[program]:
                    reg_dict[program][reg_bits[0].startdate.date()] = 0
                reg_dict[program][reg_bits[0].startdate.date()] += 1

            confirm_bits = UserBit.valid_objects().filter(
                user=student, verb=confirm_verb,
                qsc=confirm_node).order_by('-startdate')
            if confirm_bits.exists():
                if confirm_bits[0].startdate.date(
                ) not in confirm_dict[program]:
                    confirm_dict[program][confirm_bits[0].startdate.date()] = 0
                confirm_dict[program][confirm_bits[0].startdate.date()] += 1

    #   Compile and render
    startreg_list = []
    confirm_list = []
    for program in programs:
        reg_dates = reg_dict[program].keys()
        reg_dates.sort()
        reg_counts = [reg_dict[program][key] for key in reg_dates]
        startreg_list.append(zip(reg_dates, reg_counts))
        confirm_dates = confirm_dict[program].keys()
        confirm_dates.sort()
        confirm_counts = [confirm_dict[program][key] for key in confirm_dates]
        confirm_list.append(zip(confirm_dates, confirm_counts))
    result_dict['program_data'] = zip(programs, startreg_list, confirm_list)

    return render_to_string('program/statistics/startreg.html', result_dict)
Ejemplo n.º 8
0
    def printschedules(self, request, tl, one, two, module, extra, prog):
        " A link to print a schedule. "
        if not request.GET.has_key('sure') and not request.GET.has_key(
                'gen_img'):
            printers = [x.name for x in GetNode('V/Publish/Print').children()]

            return render_to_response(self.baseDir() + 'instructions.html',
                                      request, (prog, tl),
                                      {'printers': printers})

        if request.GET.has_key('sure'):
            return render_to_response(
                self.baseDir() + 'studentschedulesrenderer.html', request,
                (prog, tl), {})

        verb_path = 'V/Publish/Print'
        if extra and extra != '':
            verb_path = "%s/%s" % (verb_path, extra)

        verb = GetNode(verb_path)
        qsc = self.program_anchor_cached().tree_create(['Schedule'])

        Q_qsc = Q(qsc=qsc.id)
        Q_verb = Q(verb__in=[verb.id] + list(verb.children()))

        ubits = UserBit.valid_objects().filter(Q_qsc & Q_verb).order_by(
            'startdate')[:1]

        for ubit in ubits:
            ubit.enddate = datetime.now()
            ubit.save()

        # get students
        old_students = set([ESPUser(ubit.user) for ubit in ubits])

        if len(old_students) > 0:
            response = ProgramPrintables.get_student_schedules(
                request, list(old_students), prog, onsite=True)
            # set the refresh rate
            #response['Refresh'] = '2'
            return response
        else:
            # No response if no users
            return HttpResponse('')
Ejemplo n.º 9
0
def edit_profile(request, module):

    curUser = ESPUser(request.user)

    if curUser.isStudent():
        return profile_editor(request, None, True, 'student')

    elif curUser.isTeacher():
        return profile_editor(request, None, True, 'teacher')

    elif curUser.isGuardian():
        return profile_editor(request, None, True, 'guardian')

    elif curUser.isEducator():
        return profile_editor(request, None, True, 'educator')	

    else:
        user_types = UserBit.valid_objects().filter(verb__parent=GetNode("V/Flags/UserRole")).select_related().order_by('-id')
        return profile_editor(request, None, True, user_types[0].verb.name if user_types else '')
Ejemplo n.º 10
0
    def ajax_sections_cached(self, prog):
        sections = prog.sections().select_related()

        rrequests = ResourceRequest.objects.filter(target__in = sections)

        rrequest_dict = defaultdict(list)
        for r in rrequests:
            rrequest_dict[r.target_id].append((r.res_type_id, r.desired_value))


        teacher_bits = UserBit.valid_objects().filter(verb=GetNode('V/Flags/Registration/Teacher'), qsc__in = (s.parent_class.anchor_id for s in sections), user__isnull=False).values("qsc_id", "user_id").distinct()

        teacher_dict = defaultdict(list)
        for b in teacher_bits:
            teacher_dict[b["qsc_id"]].append(b["user_id"])
        
        sections_dicts = [
            {   'id': s.id,
                'class_id': s.parent_class_id,
                'emailcode': s.emailcode(),
                'text': s.title(),
                'category': s.category.category,
                'length': float(s.duration),
                'teachers': teacher_dict[s.parent_class.anchor_id],
                'resource_requests': rrequest_dict[s.id],
                'max_class_capacity': s.max_class_capacity,
                'capacity': s.capacity,
                'class_size_max': s.parent_class.class_size_max,
                'optimal_class_size': s.parent_class.class_size_optimal,
                'optimal_class_size_range': s.parent_class.optimal_class_size_range.range_str() if s.parent_class.optimal_class_size_range else None,
                'allowable_class_size_ranges': [ cr.range_str() for cr in s.parent_class.get_allowable_class_size_ranges() ],
                'status': s.status,
                'parent_status': s.parent_class.status,
                'grades': [s.parent_class.grade_min, s.parent_class.grade_max],
                'prereqs': s.parent_class.prereqs,
                'comments': s.parent_class.message_for_directors,
            } for s in sections ]

        response = HttpResponse(content_type="application/json")
        simplejson.dump(sections_dicts, response)
        return response
Ejemplo n.º 11
0
def repeats(form, programs, students, profiles, result_dict={}):

    confirm_verb = GetNode('V/Flags/Public')

    #   For each student, find out what other programs they registered for and bin by quantity in each program type
    repeat_count = {}
    for student in students:
        bits = UserBit.valid_objects().filter(user=student,
                                              verb=confirm_verb,
                                              qsc__name='Confirmation')
        anchors = DataTree.objects.filter(
            id__in=bits.values_list('qsc__parent', flat=True))
        indiv_count = {}
        for anchor in anchors:
            if anchor.parent.name not in indiv_count:
                indiv_count[anchor.parent.name] = 0
            indiv_count[anchor.parent.name] += 1
        program_types = indiv_count.keys()
        program_types.sort()
        id_pair = tuple([
            tuple([program_type, indiv_count[program_type]])
            for program_type in program_types
        ])
        if id_pair not in repeat_count:
            repeat_count[id_pair] = 0
        repeat_count[id_pair] += 1

    #   Compile and render
    key_map = {}
    repeat_labels = []
    for key in repeat_count:
        if len(key) > 0:
            repeat_labels.append(', '.join(
                ['%dx %s' % (x[1], x[0]) for x in key]))
            key_map[repeat_labels[-1]] = key
    repeat_labels.sort()
    repeat_counts = []
    for label in repeat_labels:
        repeat_counts.append(repeat_count[key_map[label]])
    result_dict['repeat_data'] = zip(repeat_labels, repeat_counts)
    return render_to_string('program/statistics/repeats.html', result_dict)
Ejemplo n.º 12
0
    def rapidcheckin(self, request, tl, one, two, module, extra, prog):
        context = {}
        if request.method == 'POST':
            #   Handle submission of student
            form = OnSiteRapidCheckinForm(request.POST)
            if form.is_valid():
                student = ESPUser(form.cleaned_data['user'])
                #   Check that this is a student user who is not also teaching (e.g. an admin)
                if student.isStudent(
                ) and student not in self.program.teachers()['class_approved']:
                    existing_bits = UserBit.valid_objects().filter(
                        user=student,
                        qsc=prog.anchor,
                        verb=GetNode('V/Flags/Registration/Attended'))
                    if not existing_bits.exists():
                        new_bit, created = UserBit.objects.get_or_create(
                            user=student,
                            qsc=prog.anchor,
                            verb=GetNode('V/Flags/Registration/Attended'))
                    context['message'] = '%s %s marked as attended.' % (
                        student.first_name, student.last_name)
                    if request.is_ajax():
                        return self.ajax_status(request, tl, one, two, module,
                                                extra, prog, context)
                else:
                    context[
                        'message'] = '%s %s is not a student and has not been checked in' % (
                            student.first_name, student.last_name)
                    if request.is_ajax():
                        return self.ajax_status(request, tl, one, two, module,
                                                extra, prog, context)
        else:
            form = OnSiteRapidCheckinForm()

        context['module'] = self
        context['form'] = form
        return render_to_response(self.baseDir() + 'ajaxcheckin.html', request,
                                  (prog, tl), context)
Ejemplo n.º 13
0
    def satprep_schedulestud(self, request, tl, one, two, module, extra, prog):
        """ An interface for scheduling all the students, provided the classes have already
        been generated. """
        from esp.program.modules.module_ext import SATPrepTeacherModuleInfo
        import string
        import random
        import copy

        #   Get confirmation and a list of users first.
        if not request.method == 'POST' and not request.POST.has_key(
                'schedule_confirm'):
            return render_to_response(self.baseDir() + 'schedule_confirm.html',
                                      request, (prog, tl), {})

        filterObj, found = get_user_list(request, self.program.getLists(True))
        if not found:
            return filterObj

        #   Find the user's scores and put them in a python list.
        users = list(filterObj.getList(User).distinct())
        subjects = ['math', 'verb', 'writ']

        #   Expire existing enrollments
        reg_bits = UserBit.valid_objects().filter(
            verb=DataTree.get_by_uri('V/Flags/Registration/Enrolled')).filter(
                QTree(qsc__below=prog.anchor))
        """
        print 'Expiring %d enrollment bits' % reg_bits.count()
        """
        for bit in reg_bits:
            bit.expire()

        #   Add scores to each user
        for user in users:
            satprepreginfo = SATPrepRegInfo.getLastForProgram(
                user, self.program)
            user.scores = {}
            for subject in subjects:
                user.scores[subject] = SATPrepAdminSchedule.getScore(
                    satprepreginfo, subject)

        #   Get an independently sorted list for each subject
        sorted_lists = {}
        for subject in subjects:
            sorted_lists[subject] = copy.deepcopy(users)
            sorted_lists[subject].sort(key=lambda x: x.scores[subject])

        #   Generate list of possible orderings
        def combinations(lst):
            if len(lst) == 1:
                return [lst]
            else:
                result = []
                for i in range(len(lst)):
                    other_items = [y for y in lst if y != lst[i]]
                    result += [[lst[i]] + x for x in combinations(other_items)]
                return result

        orderings = combinations(subjects)

        #   Divide students into orderings
        num_orderings = len(orderings)
        num_subjects = len(subjects)
        ordering_index = 0
        subject_index = 0

        def lists_non_empty():
            for subject in subjects:
                if len(sorted_lists[subject]) > 0:
                    return True
            return False

        ordering_lists = [[] for ordering in orderings]
        while lists_non_empty():
            #   Pull a student from the top of the list in the current subject
            new_student = sorted_lists[subjects[subject_index]].pop()
            #   Put them in the list for the current ordering
            ordering_lists[ordering_index].append(new_student)
            #   Remove them from the other lists
            for subject in subjects:
                if subject != subjects[subject_index]:
                    sorted_lists[subject].remove(new_student)

            #   Debug statement:
            #   print 'Took %s (scores: %s) from %s list to ordering %s' % (new_student, new_student.scores, subjects[subject_index], orderings[ordering_index])

            #   Move to the next subject list
            subject_index = (subject_index + 1) % num_subjects
            #   Move to the next ordering list
            ordering_index = (ordering_index + 1) % num_orderings
        """
        #   Debug statements
        print '--------------'
        for i in range(num_orderings):
            print 'Ordering %s: %d students' % (orderings[i], len(ordering_lists[i]))
        """

        #   Retrieve the class sections of the program, keeping track of their subject and level
        #   in the class_list dictionary.
        tmi = SATPrepTeacherModuleInfo.objects.filter(program=prog)
        class_list = {}
        timeslots = prog.getTimeSlots()
        for timeslot in timeslots:
            class_list[timeslot] = {}
            for subject in subjects:
                class_list[timeslot][subject] = {}
        for t in tmi:
            section = t.section
            subject = t.get_subject_display().lower()[:4]
            cl = ESPUser(t.user).getTaughtClasses(prog)
            for c in cl:
                for s in c.get_sections():
                    timeslot = s.start_time()
                    if section not in class_list[timeslot][subject]:
                        class_list[timeslot][subject][section] = []
                    class_list[timeslot][subject][section].append(
                        (s, s.room_capacity()))
        """
        #   Debug statements
        #   print class_list
        """

        #   For each timeslot/subject combination, find the orderings that include it
        for timeslot_index in range(len(timeslots)):
            for subject in subjects:
                valid_orderings = filter(
                    lambda o: o[timeslot_index] == subject, orderings)

                #   Get a list of students in those orderings sorted by their score in the current subject
                #   (Exclude students that have no score)
                timeslot = timeslots[timeslot_index]
                students = []
                for ordering in valid_orderings:
                    students += ordering_lists[orderings.index(ordering)]
                students = filter(lambda s: s.scores[subject] >= 200, students)
                students.sort(key=lambda s: s.scores[subject])
                students.reverse()
                """
                #   Debug statement
                print 'Timeslot %s; subject %s: %d students' % (timeslots[timeslot_index], subject, len(students))
                """

                #   Parcel out the spots in each level proportional to space
                num_students = len(students)
                num_spots = 0
                section_dict = class_list[timeslot][subject]
                level_space = {}
                level_thresholds = {}
                indiv_thresholds = {}
                ordered_sections = section_dict.keys()
                ordered_sections.sort()
                prev_section = None
                for section in ordered_sections:
                    level_space[section] = 0
                    for item in section_dict[section]:
                        num_spots += item[1]
                        level_space[section] += item[1]
                for section in ordered_sections:
                    if prev_section is None:
                        prev_threshold = 0
                    else:
                        prev_threshold = level_thresholds[prev_section]
                    section_size = level_space[section] * float(
                        num_students) / num_spots
                    level_thresholds[section] = prev_threshold + section_size
                    indiv_thresholds[section] = [
                        section_size * item[1] / level_space[section] +
                        prev_threshold for item in section_dict[section]
                    ]
                    prev_section = section
                    """
                    #   Debug statement
                    #   print ' -> Section %s (%d/%d students): threshold = %f, indiv = %s' % (section, level_thresholds[section] - prev_threshold, level_space[section], level_thresholds[section], indiv_thresholds[section])
                    """

                #   Assign students
                num_students_assigned = 0
                section_index = 0
                current_item = 0
                for student in students:
                    if (section_index >= len(ordered_sections)):
                        raise ESPError(False), 'Overran number of sections'
                    current_section = ordered_sections[section_index]
                    if (current_item >= len(
                            indiv_thresholds[current_section])):
                        raise ESPError(
                            False), 'Overran number of sections in section'

                    target_section = section_dict[current_section][
                        current_item][0]

                    if not hasattr(target_section, 'min_score'):
                        target_section.min_score = 800
                    if not hasattr(target_section, 'max_score'):
                        target_section.max_score = 200

                    target_section.preregister_student(student,
                                                       overridefull=True)
                    if student.scores[subject] < target_section.min_score:
                        target_section.min_score = student.scores[subject]
                    if student.scores[subject] > target_section.max_score:
                        target_section.max_score = student.scores[subject]

                    num_students_assigned += 1
                    """
                    #   Debug statements
                    print '  Assigning student %s (scores: %s) to %s' % (student, student.scores, target_section)
                    print '  -> %d assigned (current thresholds are %f, %f)' % (num_students_assigned, indiv_thresholds[current_section][current_item], level_thresholds[current_section])
                    """

                    #   Increment section if necessary
                    if num_students_assigned > level_thresholds[
                            current_section]:
                        section_index += 1
                        current_item = 0
                    #   Increment item if necessary
                    elif num_students_assigned > indiv_thresholds[
                            current_section][current_item]:
                        current_item += 1
                """ 
                #   Check results
                for section in ordered_sections:
                    #   This code assumes multiple sections per level+timeblock+subject
                    print ' -> Section %s' % section
                    for item in section_dict[section]:
                        print '    (%d/%d) %s' % (item[0].num_students(), item[1], item[0])
                    
                    #   This code assumes one section per level+timeblock+subject
                    item = section_dict[section][0]
                    print ' -> Section %s (%d/%d) %s: Scores %d-%d' % (section, item[0].num_students(), item[1], item[0], item[0].min_score, item[0].max_score)
                """

        return HttpResponseRedirect('/manage/%s/schedule_options' %
                                    self.program.getUrlBase())
Ejemplo n.º 14
0
 def isCompleted(self):
     """Return true if user has filled out the teacher quiz."""
     return UserBit.valid_objects().filter(user=get_current_request().user,
                                           qsc=self.program.anchor,
                                           verb=self.reg_verb).exists()
Ejemplo n.º 15
0
    def getMissingTeachers(self, prog, starttime=None, when=None):
        """Return a list of class sections with missing teachers"""
        sections = prog.sections().annotate(begin_time=Min("meeting_times__start")) \
                                  .filter(status=10, parent_class__status=10, begin_time__isnull=False)
        if starttime is not None:
            sections = sections.filter(begin_time=starttime.start)
        teachers = ESPUser.objects.filter(
            userbit__in=UserBit.valid_objects(when),
            userbit__qsc__classsubject__sections__in=sections,
            userbit__verb=GetNode('V/Flags/Registration/Teacher'))
        arrived = teachers.filter(
            userbit__in=UserBit.valid_objects(when),
            userbit__qsc=prog.anchor,
            userbit__verb=GetNode('V/Flags/Registration/Teacher/Arrived'))
        missing = teachers.exclude(id__in=arrived)
        missing_sections = sections.filter(
            parent_class__anchor__userbit_qsc__in=UserBit.valid_objects(when),
            parent_class__anchor__userbit_qsc__user__in=missing,
            parent_class__anchor__userbit_qsc__verb=GetNode(
                'V/Flags/Registration/Teacher'))
        userbits = UserBit.valid_objects(when).filter(qsc__classsubject__sections__in=missing_sections,
                                                  verb=GetNode('V/Flags/Registration/Teacher')) \
                                          .distinct() \
                                          .values_list('user', 'qsc__classsubject', 'qsc__friendly_name') \
                                          .order_by('user__last_name', 'user__first_name')

        teacher_dict = {}
        for teacher in list(arrived) + list(missing):
            contact = teacher.getLastProfile().contact_user
            if contact is None:
                contact = ContactInfo(phone_cell='N/A')
            teacher_dict[teacher.id] = {
                'username': teacher.username,
                'name': teacher.name(),
                'last_name': teacher.last_name,
                'phone': contact.phone_cell or contact.phone_day,
                'arrived': True
            }
        for teacher in missing:
            teacher_dict[teacher.id]['arrived'] = False

        class_dict = {}
        class_arr = []
        for teacher_id, class_id, class_name in userbits:
            if class_id not in class_dict:
                class_dict[class_id] = {
                    'id': ClassSubject.objects.get(id=class_id).emailcode(),
                    'name': class_name,
                    'teachers': [],
                    'any_arrived': False
                }
                class_arr.append(class_dict[class_id])
            class_dict[class_id]['teachers'].append(teacher_dict[teacher_id])

        for sec in missing_sections:
            if sec.parent_class.id in class_dict:
                class_ = class_dict[sec.parent_class.id]
                class_['room'] = (sec.prettyrooms() or [None])[0]
                if 'time' in class_:
                    class_['time'] = min(class_['time'], sec.begin_time)
                else:
                    class_['time'] = sec.begin_time

        #Move sections where at least one teacher showed up to end of list
        for sec in class_arr:
            for teacher in sec['teachers']:
                if teacher['arrived']:
                    sec['any_arrived'] = True
                    break
        class_arr = [sec for sec in class_arr if sec['any_arrived'] == False] + \
                    [sec for sec in class_arr if sec['any_arrived'] == True]

        return class_arr, teacher_dict
Ejemplo n.º 16
0
    def update_schedule_json(self, request, tl, one, two, module, extra, prog):
        resp = HttpResponse(mimetype='application/json')
        result = {'user': None, 'sections': [], 'messages': []}
        try:
            user = ESPUser.objects.get(id=int(request.GET['user']))
        except:
            user = None
            result['messages'].append('Error: could find user %s' %
                                      request.GET.get('user', None))
        try:
            desired_sections = simplejson.loads(request.GET['sections'])
        except:
            result['messages'].append(
                'Error: could not parse requested sections %s' %
                request.GET.get('sections', None))
            desired_sections = None

        #   Check in student, since if they're using this view they must be onsite
        existing_bits = UserBit.valid_objects().filter(
            user=user,
            qsc=prog.anchor,
            verb=GetNode('V/Flags/Registration/Attended'))
        if not existing_bits.exists():
            new_bit, created = UserBit.objects.get_or_create(
                user=user,
                qsc=prog.anchor,
                verb=GetNode('V/Flags/Registration/Attended'))

        if user and desired_sections is not None:
            override_full = (request.GET.get("override", "") == "true")

            current_sections = list(
                ClassSection.objects.filter(
                    status__gt=0,
                    parent_class__status__gt=0,
                    parent_class__parent_program=prog,
                    studentregistration__start_date__lte=datetime.now(),
                    studentregistration__end_date__gte=datetime.now(),
                    studentregistration__relationship__name='Enrolled',
                    studentregistration__user__id=user.id).values_list(
                        'id', flat=True).order_by('id').distinct())
            sections_to_remove = ClassSection.objects.filter(
                id__in=list(set(current_sections) - set(desired_sections)))
            sections_to_add = ClassSection.objects.filter(
                id__in=list(set(desired_sections) - set(current_sections)))

            failed_add_sections = []
            for sec in sections_to_add:
                if sec.isFull() and not override_full:
                    result['messages'].append(
                        'Failed to add %s (%s) to %s: %s (%s).  Error was: %s'
                        % (user.name(), user.id, sec.emailcode(), sec.title(),
                           sec.id, 'Class is currently full.'))
                    failed_add_sections.append(sec.id)

            if len(failed_add_sections) == 0:
                #   Remove sections the student wants out of
                for sec in sections_to_remove:
                    sec.unpreregister_student(user)
                    result['messages'].append(
                        'Removed %s (%s) from %s: %s (%s)' %
                        (user.name(), user.id, sec.emailcode(), sec.title(),
                         sec.id))

                #   Remove sections that conflict with those the student wants into
                sec_times = sections_to_add.select_related(
                    'meeting_times__id').values_list(
                        'id', 'meeting_times__id').order_by(
                            'meeting_times__id').distinct()
                sm = ScheduleMap(user, prog)
                existing_sections = []
                for (sec, ts) in sec_times:
                    if ts and ts in sm.map and len(sm.map[ts]) > 0:
                        #   We found something we need to remove
                        for sm_sec in sm.map[ts]:
                            if sm_sec.id not in sections_to_add:
                                sm_sec.unpreregister_student(user)
                                result['messages'].append(
                                    'Removed %s (%s) from %s: %s (%s)' %
                                    (user.name(), user.id, sm_sec.emailcode(),
                                     sm_sec.title(), sm_sec.id))
                            else:
                                existing_sections.append(sm_sec)

                #   Add the sections the student wants
                for sec in sections_to_add:
                    if sec not in existing_sections and sec.id not in failed_add_sections:
                        error = sec.cannotAdd(user, not override_full)
                        if not error:
                            reg_result = sec.preregister_student(
                                user, overridefull=override_full)
                            if not reg_result:
                                error = 'Class is currently full.'
                        else:
                            reg_result = False
                        if reg_result:
                            result['messages'].append(
                                'Added %s (%s) to %s: %s (%s)' %
                                (user.name(), user.id, sec.emailcode(),
                                 sec.title(), sec.id))
                        else:
                            result['messages'].append(
                                'Failed to add %s (%s) to %s: %s (%s).  Error was: %s'
                                % (user.name(), user.id, sec.emailcode(),
                                   sec.title(), sec.id, error))

            result['user'] = user.id
            result['sections'] = list(
                ClassSection.objects.filter(
                    status__gt=0,
                    parent_class__status__gt=0,
                    parent_class__parent_program=prog,
                    studentregistration__start_date__lte=datetime.now(),
                    studentregistration__end_date__gte=datetime.now(),
                    studentregistration__relationship__name='Enrolled',
                    studentregistration__user__id=result['user']).values_list(
                        'id', flat=True).distinct())

        simplejson.dump(result, resp)
        return resp
Ejemplo n.º 17
0
 def isCompleted(self):
     return UserBit.valid_objects().filter(
         user=get_current_request().user,
         qsc=self.program.anchor,
         verb=GetNode('V/Flags/Registration/LunchSelected')).exists()
Ejemplo n.º 18
0
else:
    print "What? Exiting."
    sys.exit()

# CHECK-IN USERS
prog = Program.objects.all().filter(anchor=PROGRAM_ID)[0]

for i in ids:
    if i.strip() == "":
        continue

    result = ESPUser.objects.all().filter(id=i)

    if len(result) != 1:
        print "%s: Not found (%s results)" % (i, len(result))
        continue
    student = result[0]

    # from onsitecheckinmodule.py:
    existing_bits = UserBit.valid_objects().filter(user=student,
                                                   qsc=prog.anchor,
                                                   verb=attended_verb)
    if not existing_bits.exists():
        new_bit, created = UserBit.objects.get_or_create(user=student,
                                                         qsc=prog.anchor,
                                                         verb=attended_verb)
        print '%s: %s %s marked as attended.' % (i, student.first_name,
                                                 student.last_name)
    else:
        print '%s: already marked as attended' % (i)
Ejemplo n.º 19
0
def classchangerequest(request, tl, one, two):
    from esp.program.models import Program, StudentAppResponse, StudentRegistration, RegistrationType
    from esp.program.models.class_ import *
    from urllib import quote
    try:
        prog = Program.by_prog_inst(one, two)  #DataTree.get_by_uri(treeItem)
    except Program.DoesNotExist:
        raise Http404("Program not found.")

    if tl != "learn":
        raise Http404

    if not request.user or not request.user.is_authenticated():
        return HttpResponseRedirect(
            '%s?%s=%s' %
            (LOGIN_URL, REDIRECT_FIELD_NAME, quote(request.get_full_path())))

    if not request.user.isStudent() and not request.user.isAdmin(prog):
        allowed_student_types = Tag.getTag("allowed_student_types",
                                           prog,
                                           default='')
        matching_user_types = UserBit.valid_objects().filter(
            user=request.user,
            verb__parent=GetNode("V/Flags/UserRole"),
            verb__name__in=allowed_student_types.split(","))
        if not matching_user_types:
            return render_to_response('errors/program/notastudent.html',
                                      request, (prog, 'learn'), {})

    errorpage = 'errors/program/wronggrade.html'

    verb_override = GetNode('V/Flags/Registration/GradeOverride')
    cur_grade = request.user.getGrade(prog)
    if (not UserBit.UserHasPerms(user = request.user, qsc  = prog.anchor_id, verb = verb_override)) and (cur_grade != 0 and (cur_grade < prog.grade_min or \
                           cur_grade > prog.grade_max)):
        return render_to_response(errorpage, request, (prog, tl), {})

    setattr(request, "program", prog)
    setattr(request, "tl", tl)
    setattr(request, "module", "classchangerequest")

    from django import forms
    from datetime import datetime
    from esp.utils.scheduling import getRankInClass

    timeslots = prog.getTimeSlots()
    sections = prog.sections().filter(status=10)

    enrollments = {}
    for timeslot in timeslots:
        try:
            enrollments[timeslot] = ClassSubject.objects.get(
                sections__studentregistration__relationship__name="Enrolled",
                sections__studentregistration__user=request.user,
                sections__meeting_times=timeslot,
                parent_program=prog,
                sections__studentregistration__end_date__gte=datetime.now())
        except ClassSubject.DoesNotExist:
            enrollments[timeslot] = None

    context = {}
    context['timeslots'] = timeslots
    context['enrollments'] = enrollments
    context['user'] = request.user
    if 'success' in request.GET:
        context['success'] = True
    else:
        context['success'] = False

    if request.user.isStudent():
        sections_by_slot = dict([(timeslot, [
            (section, 1 == StudentRegistration.objects.filter(
                user=context['user'],
                section=section,
                relationship__name="Request",
                end_date__gte=datetime.now()).count()) for section in sections
            if section.get_meeting_times()[0] == timeslot
            and section.parent_class.grade_min <= request.user.getGrade(
                prog) <= section.parent_class.grade_max
            and section.parent_class not in enrollments.values()
            and getRankInClass(request.user, section) in (5, 10)
        ]) for timeslot in timeslots])
    else:
        sections_by_slot = dict([(timeslot, [
            (section, False) for section in sections
            if section.get_meeting_times()[0] == timeslot
        ]) for timeslot in timeslots])

    fields = {}
    for i, timeslot in enumerate(sections_by_slot.keys()):
        choices = [('0', "I'm happy with my current enrollment.")]
        initial = '0'
        for section in sections_by_slot[timeslot]:
            choices.append(
                (section[0].emailcode(),
                 section[0].emailcode() + ": " + section[0].title()))
            if section[1]:
                initial = section[0].emailcode()
        fields['timeslot_' + str(i + 1)] = forms.ChoiceField(
            label="Timeslot " + str(i + 1) + " (" + timeslot.pretty_time() +
            ")",
            choices=choices,
            initial=initial)

    form = type('ClassChangeRequestForm', (forms.Form, ), fields)
    context['form'] = form()
    if request.method == "POST":
        old_requests = StudentRegistration.objects.filter(
            user=context['user'],
            section__parent_class__parent_program=prog,
            relationship__name="Request",
            end_date__gte=datetime.now())
        for r in old_requests:
            r.expire()
        form = form(request.POST)
        if form.is_valid():
            for value in form.cleaned_data.values():
                section = None
                for s in sections:
                    if s.emailcode() == value:
                        section = s
                        break
                if not section:
                    continue
                r = StudentRegistration.objects.get_or_create(
                    user=context['user'],
                    section=section,
                    relationship=RegistrationType.objects.get_or_create(
                        name="Request", category="student")[0])[0]
                r.end_date = datetime(9999, 1, 1, 0, 0, 0, 0)
                r.save()

            return HttpResponseRedirect(request.path.rstrip('/') + '/?success')
    else:
        return render_to_response('program/classchangerequest.html', request,
                                  (prog, tl), context)