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")
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 })
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)
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())
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)
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)
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)
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('')
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 '')
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
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)
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)
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())
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()
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
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
def isCompleted(self): return UserBit.valid_objects().filter( user=get_current_request().user, qsc=self.program.anchor, verb=GetNode('V/Flags/Registration/LunchSelected')).exists()
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)
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)