Example #1
0
 def all_transfers_Q(self, **kwargs):
     """
     Returns a Q object that applies all wanted constraints on the related
     line_item objects.
     """
     q_object = self.get_lineitemtypes_Q(**kwargs)
     return nest_Q(q_object, 'line_item')
Example #2
0
    def students(self, QObject=False):

        Enrolled = Q(studentregistration__relationship__name='Enrolled')
        Par = Q(studentregistration__section__parent_class__parent_program=self
                .program)
        Unexpired = nest_Q(StudentRegistration.is_valid_qobject(),
                           'studentregistration')

        # Force Django to generate two subqueries without joining SRs to SSIs,
        # as efficiently as possible since it's still a big query.
        sr_ids = StudentRegistration.valid_objects().filter(
            section__parent_class__parent_program=self.program).values(
                'user').distinct()
        ssi_ids = StudentSubjectInterest.valid_objects().filter(
            subject__parent_program=self.program).values('user').distinct()
        any_reg_q = Q(id__in=sr_ids) | Q(id__in=ssi_ids)

        qobjects = {
            'enrolled': Enrolled & Par & Unexpired,
            'classreg': any_reg_q,
        }

        if QObject:
            return qobjects
        else:
            return {
                k: ESPUser.objects.filter(v).distinct()
                for k, v in qobjects.iteritems()
            }
    def students(self, QObject = False):

        Enrolled = Q(studentregistration__relationship__name='Enrolled')
        Par = Q(studentregistration__section__parent_class__parent_program=self.program)
        Unexpired = nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration')

        # Force Django to generate two subqueries without joining SRs to SSIs,
        # as efficiently as possible since it's still a big query.
        sr_ids = StudentRegistration.valid_objects().filter(
            section__parent_class__parent_program=self.program
        ).values('user').distinct()
        ssi_ids = StudentSubjectInterest.valid_objects().filter(
            subject__parent_program=self.program).values('user').distinct()
        any_reg_q = Q(id__in = sr_ids) | Q(id__in = ssi_ids)

        qobjects = {
            'enrolled': Enrolled & Par & Unexpired,
            'classreg': any_reg_q,
        }

        if QObject:
            return qobjects
        else:
            return {k: ESPUser.objects.filter(v).distinct()
                    for k, v in qobjects.iteritems()}
 def students(self, QObject=False):
     q = Q(studentregistration__section__parent_class__parent_program=self.
           program) & nest_Q(StudentRegistration.is_valid_qobject(),
                             'studentregistration')
     if QObject:
         return {'lotteried_students': q}
     else:
         return {'lotteried_students': ESPUser.objects.filter(q).distinct()}
    def classchangerequest(self, request, tl, one, two, module, extra, prog):
        timeslots = prog.getTimeSlots()
        sections = prog.sections().filter(status=10, meeting_times__isnull=False).distinct()

        enrollments = {}
        for timeslot in timeslots:
            try:
                enrollments[timeslot] = ClassSubject.objects.get(nest_Q(StudentRegistration.is_valid_qobject(), 'sections__studentregistration'), sections__studentregistration__relationship__name="Enrolled", sections__studentregistration__user=request.user, sections__meeting_times=timeslot, parent_program=prog)
            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.valid_objects().filter(user=context['user'], section=section, relationship__name="Request").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 ESPUser.getRankInClass(request.user, section.parent_class) 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.valid_objects().filter(user=context['user'], section__parent_class__parent_program=prog, relationship__name="Request")
            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.valid_objects().get_or_create(user=context['user'], section=section, relationship=RegistrationType.objects.get_or_create(name="Request", category="student")[0])[0]
                    r.save()

                return HttpResponseRedirect(request.path.rstrip('/')+'/?success')
        else:
            return render_to_response(self.baseDir() + 'classchangerequest.html', request, context)
Example #6
0
 def all_students_Q(self, **kwargs):
     """
     The students we want to query have registered for this program and have
     a transfer object that has the constraints we want.
     """
     q_object = self.all_transfers_Q(**kwargs)
     return Q(
         studentregistration__section__parent_class__parent_program=self.
         program) & nest_Q(q_object, 'transfer')
 def students(self, QObject = False):
     q_sr = Q(studentregistration__section__parent_class__parent_program=self.program) & nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration')
     q_ssi = Q(studentsubjectinterest__subject__parent_program=self.program) & nest_Q(StudentSubjectInterest.is_valid_qobject(), 'studentsubjectinterest')
     if QObject:
         return {'twophase_star_students': q_ssi,
                 'twophase_priority_students' : q_sr}
     else:
         return {'twophase_star_students': ESPUser.objects.filter(q_ssi).distinct(),
                 'twophase_priority_students': ESPUser.objects.filter(q_sr).distinct()}
Example #8
0
 def students(self, QObject=False):
     q_sr = Q(
         studentregistration__section__parent_class__parent_program=self.
         program) & nest_Q(StudentRegistration.is_valid_qobject(),
                           'studentregistration')
     q_ssi = Q(studentsubjectinterest__subject__parent_program=self.program
               ) & nest_Q(StudentSubjectInterest.is_valid_qobject(),
                          'studentsubjectinterest')
     if QObject:
         return {
             'twophase_star_students': q_ssi,
             'twophase_priority_students': q_sr
         }
     else:
         return {
             'twophase_star_students':
             ESPUser.objects.filter(q_ssi).distinct(),
             'twophase_priority_students':
             ESPUser.objects.filter(q_sr).distinct()
         }
 def get_schedule_json(self, request, tl, one, two, module, extra, prog):
     resp = HttpResponse(content_type='application/json')
     result = {'user': None, 'user_grade': 0, 'sections': [], 'messages': []}
     try:
         result['user'] = int(request.GET['user'])
     except:
         result['messages'].append('Error: no user specified.')
     if result['user']:
         result['user_grade'] = ESPUser.objects.get(id=result['user']).getGrade(program=prog)
         result['sections'] = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=result['user']).values_list('id', flat=True).distinct())
     json.dump(result, resp)
     return resp
Example #10
0
 def get_schedule_json(self, request, tl, one, two, module, extra, prog):
     resp = HttpResponse(content_type='application/json')
     result = {'user': None, 'user_grade': 0, 'sections': [], 'messages': []}
     try:
         result['user'] = int(request.GET['user'])
     except:
         result['messages'].append('Error: no user specified.')
     if result['user']:
         result['user_grade'] = ESPUser.objects.get(id=result['user']).getGrade(program=prog)
         result['sections'] = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=result['user']).values_list('id', flat=True).distinct())
     json.dump(result, resp)
     return resp
Example #11
0
    def __init__(self, program, **kwargs):
        """ Set constant parameters for class changes. """

        assert isinstance(program,(Program,int))
        self.program = program
        if isinstance(program,int):
            self.program = Program.objects.get(id=program)
        print self.program
        iscorrect = raw_input("Is this the correct program (y/[n])? ")
        assert (iscorrect.lower() == 'y' or iscorrect.lower() == 'yes')
        self.now = datetime.now()
        self.options = ClassChangeController.default_options.copy()
        self.options.update(kwargs)
        self.students_not_checked_in = []
        self.deadline = self.now
        if 'deadline' in self.options.keys():
            self.deadline = self.options['deadline']

        self.Q_SR_NOW = nest_Q(StudentRegistration.is_valid_qobject(self.now), 'studentregistration')
        self.Q_SR_PROG = Q(studentregistration__section__parent_class__parent_program=self.program, studentregistration__section__meeting_times__isnull=False) & self.Q_SR_NOW
        self.Q_SR_REQ = Q(studentregistration__relationship__name="Request") & self.Q_SR_PROG
        self.Q_NOW = StudentRegistration.is_valid_qobject(self.now)
        self.Q_PROG = Q(section__parent_class__parent_program=self.program, section__meeting_times__isnull=False) & self.Q_NOW
        self.Q_REQ = Q(relationship__name="Request") & self.Q_PROG

        self.students = ESPUser.objects.filter(self.Q_SR_REQ).order_by('id').distinct()
        if 'students_not_checked_in' in self.options.keys() and isinstance(self.options['students_not_checked_in'],QuerySet):
            self.students_not_checked_in = list(self.options['students_not_checked_in'].values_list('id',flat=True).distinct())
        else:
            self.students_not_checked_in = list(self.students.exclude(id__in=self.program.students()['attended']).values_list('id',flat=True).distinct())

        self.priority_limit = self.program.priorityLimit()
        self._init_Q_objects()
        self.sections = self.program.sections().filter(status__gt=0, parent_class__status__gt=0, meeting_times__isnull=False).order_by('id').select_related('parent_class','parent_class__parent_program').distinct()
        if not self.options['use_closed_classes']:
            self.sections = self.sections.filter(registration_status=0).distinct()
        self.timeslots = self.program.getTimeSlots().order_by('id').distinct()
        self.num_timeslots = len(self.timeslots)
        self.num_students = len(self.students)
        self.num_sections = len(self.sections)






        numpy.random.seed(self.now.microsecond)

        self.initialize()

        if self.options['stats_display']:
            logger.info('Initialized lottery assignment for %d students, %d sections, %d timeslots', self.num_students, self.num_sections, self.num_timeslots)
    def __init__(self, program, **kwargs):
        """ Set constant parameters for class changes. """

        assert isinstance(program,(Program,int))
        self.program = program
        if isinstance(program,int):
            self.program = Program.objects.get(id=program)
        print self.program
        iscorrect = raw_input("Is this the correct program (y/[n])? ")
        assert (iscorrect.lower() == 'y' or iscorrect.lower() == 'yes')
        self.now = datetime.now()
        self.options = ClassChangeController.default_options.copy()
        self.options.update(kwargs)
        self.students_not_checked_in = []
        self.deadline = self.now
        if 'deadline' in self.options.keys():
            self.deadline = self.options['deadline']
        self.Q_SR_NOW = nest_Q(StudentRegistration.is_valid_qobject(self.now), 'studentregistration')
        self.Q_SR_PROG = Q(studentregistration__section__parent_class__parent_program=self.program, studentregistration__section__meeting_times__isnull=False) & self.Q_SR_NOW
        self.Q_SR_REQ = Q(studentregistration__relationship__name="Request") & self.Q_SR_PROG
        self.Q_NOW = StudentRegistration.is_valid_qobject(self.now)
        self.Q_PROG = Q(section__parent_class__parent_program=self.program, section__meeting_times__isnull=False) & self.Q_NOW
        self.Q_REQ = Q(relationship__name="Request") & self.Q_PROG
        self.students = ESPUser.objects.filter(self.Q_SR_REQ).order_by('id').distinct()
        if 'students_not_checked_in' in self.options.keys() and isinstance(self.options['students_not_checked_in'],QuerySet):
            self.students_not_checked_in = list(self.options['students_not_checked_in'].values_list('id',flat=True).distinct())
        else:
            self.students_not_checked_in = list(self.students.exclude(id__in=self.program.students()['attended']).values_list('id',flat=True).distinct())
        self.priority_limit = self.program.priorityLimit()
        self._init_Q_objects()
        self.sections = self.program.sections().filter(status__gt=0, parent_class__status__gt=0, meeting_times__isnull=False).order_by('id').select_related('parent_class','parent_class__parent_program','meeting_times').distinct()
        if not self.options['use_closed_classes']:
            self.sections = self.sections.filter(registration_status=0).distinct()
        self.timeslots = self.program.getTimeSlots().order_by('id').distinct()
        self.num_timeslots = len(self.timeslots)
        self.num_students = len(self.students)
        self.num_sections = len(self.sections)






        numpy.random.seed(self.now.microsecond)

        self.initialize()

        if self.options['stats_display']:
            logger.info('Initialized lottery assignment for %d students, %d sections, %d timeslots', self.num_students, self.num_sections, self.num_timeslots)
    def students(self, QObject=False):
        from django.db.models import Q

        Enrolled = Q(studentregistration__relationship__name='Enrolled')
        Par = Q(studentregistration__section__parent_class__parent_program=self
                .program)
        Unexpired = nest_Q(StudentRegistration.is_valid_qobject(),
                           'studentregistration')

        if QObject:
            retVal = {
                'enrolled': self.getQForUser(Enrolled & Par & Unexpired),
                'classreg': self.getQForUser(Par & Unexpired)
            }
        else:
            retVal = {
                'enrolled':
                ESPUser.objects.filter(Enrolled & Par & Unexpired).distinct(),
                'classreg':
                ESPUser.objects.filter(Par & Unexpired).distinct()
            }

        allowed_student_types = Tag.getTag("allowed_student_types",
                                           target=self.program)
        if allowed_student_types:
            allowed_student_types = allowed_student_types.split(",")
            for stutype in allowed_student_types:
                GroupName = Q(groups__name=stutype)
                if QObject:
                    retVal[stutype] = self.getQForUser(Par & Unexpired & Reg
                                                       & VerbName & VerbParent)
                else:
                    retVal[stutype] = ESPUser.objects.filter(
                        Par & Unexpired & Reg & GroupName).distinct()

        return retVal
import collections
import csv
import os

from django.conf import settings

from esp.users.models import ESPUser
from esp.program.models import ProgramModule
from esp.utils.query_utils import nest_Q

filename = os.path.join(settings.PROJECT_ROOT, 'zip_data.csv')

student_sets = [
    ('All users', ESPUser.objects.all()),
    ('Signed up for a class', ESPUser.objects.filter(
        nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'),
        studentregistration__isnull=False)),
]

for program in Program.objects.all():
    try:
        s = program.students()
    except ProgramModule.CannotGetClassException:
        # If there are modules that don't exist (either because they're too
        # old, or on a dev server because they're too new for your version of
        # the code), just skip the program.  Depending whether things are
        # cached, this could be one of two different errors.
        continue
    except ImportError:
        continue
    if 'attended' in s:
Example #15
0
    def classchangerequest(self, request, tl, one, two, module, extra, prog):
        timeslots = prog.getTimeSlots()
        sections = prog.sections().filter(
            status=10, meeting_times__isnull=False).distinct()

        enrollments = {}
        for timeslot in timeslots:
            try:
                enrollments[timeslot] = ClassSubject.objects.get(
                    nest_Q(StudentRegistration.is_valid_qobject(),
                           'sections__studentregistration'),
                    sections__studentregistration__relationship__name=
                    "Enrolled",
                    sections__studentregistration__user=request.user,
                    sections__meeting_times=timeslot,
                    parent_program=prog)
            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.valid_objects().filter(
                    user=context['user'],
                    section=section,
                    relationship__name="Request").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 ESPUser.
                getRankInClass(request.user, section.parent_class) 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.valid_objects().filter(
                user=context['user'],
                section__parent_class__parent_program=prog,
                relationship__name="Request")
            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.valid_objects().get_or_create(
                        user=context['user'],
                        section=section,
                        relationship=RegistrationType.objects.get_or_create(
                            name="Request", category="student")[0])[0]
                    r.save()

                return HttpResponseRedirect(
                    request.path.rstrip('/') + '/?success')
        else:
            return render_to_response(
                self.baseDir() + 'classchangerequest.html', request, context)
Example #16
0
def main():

    global priorityLimit, SR_PROG, SR_REQ, SR_WAIT, SR_EN, PROG, REQ, WAIT, EN, p, students, sections, timeslots, timeslot, all_students
    global en, req, loc, en_new, cap, score, req_num, wait, changed, unchanged, student

    save_enrollments = False
    send_emails = False

    if "-h" in sys.argv or "--help" in sys.argv:
        print "Help."
        return

    if "--save-enrollments" in sys.argv or "-se" in sys.argv:
        save_enrollments = True

    if "--send-emails" in sys.argv:
        send_emails = True

    p = None

    for arg in sys.argv:
        if arg.startswith("--pk="):
            p = Program.objects.get(pk=int(arg[5:]))
            break
    if not p:
        return
    else:
        print p

    iscorrect = raw_input("Is this the correct program (y/[n])? ")
    if not (iscorrect.lower() == 'y' or iscorrect.lower() == 'yes'):
        return

    if save_enrollments:
        iscorrect = raw_input(
            "Are you sure you want to save the results in the database (y/[n])? "
        )
        if not (iscorrect.lower() == 'y' or iscorrect.lower() == 'yes'):
            return

    studentregmodule = p.getModuleExtension('StudentClassRegModuleInfo')
    if studentregmodule and studentregmodule.priority_limit > 0:
        priorityLimit = studentregmodule.priority_limit
    SR_PROG = Q(
        studentregistration__section__parent_class__parent_program=p) & nest_Q(
            StudentRegistration.is_valid_qobject(), 'studentregistration')
    SR_REQ = Q(studentregistration__relationship__name="Request") & SR_PROG
    SR_WAIT = [
        Q(studentregistration__relationship=("Waitlist/%s" % str(i + 1)))
        & SR_PROG for i in range(priorityLimit)
    ]
    SR_WAIT.append(
        Q(studentregistration__relationship__contains="Waitlist") & SR_PROG)
    SR_EN = Q(studentregistration__relationship__name="Enrolled") & SR_PROG
    PROG = Q(section__parent_class__parent_program=p
             ) & StudentRegistration.is_valid_qobject()
    REQ = Q(relationship__name="Request") & PROG
    WAIT = [Q(relationship__name__contains="Waitlist") & PROG]
    WAIT += [
        Q(relationship__name=("Waitlist/%s" % str(i + 1))) & PROG
        for i in range(priorityLimit)
    ]
    EN = Q(relationship__name="Enrolled") & PROG
    timeslots = p.getTimeSlots()

    for timeslot in timeslots:
        print "Setup for", timeslot, "....",
        sys.stdout.flush()
        en = {}
        req = {}
        loc = {}
        en_new = {}
        cap = {}
        score = {}
        req_num = {}
        wait = {}
        sections = list(p.sections().filter(status=10, meeting_times=timeslot))

        class ClassSectionNull:
            def __init__(self):
                self.limbo = []

            def __repr__(self):
                return "<NullSection>"

        NullSection = ClassSectionNull()
        en[NullSection] = [[]]
        cap[NullSection] = 0
        score[NullSection] = 0
        for i in range(len(sections)):
            en[sections[i]] = [[] for j in range(priorityLimit + 2)]
            req[sections[i]] = [[] for j in range(priorityLimit + 2)]
            en_new[sections[i]] = []
            cap[sections[i]] = sections[i].capacity - sections[i].num_students(
            )
            req_num[sections[i]] = 0
            score[sections[i]] = -cap[sections[i]]
        students = ESPUser.objects.filter(
            SR_REQ, studentregistration__section__meeting_times=timeslot)
        all_students |= set(students)
        for i in range(students.count()):
            req[students[i]] = StudentRegistration.objects.get(
                REQ, user=students[i], section__meeting_times=timeslot).section
            loc[students[i]] = StudentRegistration.objects.get(
                REQ, user=students[i], section__meeting_times=timeslot).section
            req[req[students[i]]][0].append(students[i])
            req_num[req[students[i]]] += 1
            score[req[students[i]]] += 1
            try:
                en[students[i]] = StudentRegistration.objects.get(
                    EN, user=students[i],
                    section__meeting_times=timeslot).section
            except Exception:
                en[students[i]] = NullSection
            en[en[students[i]]][0].append(students[i])
            cap[en[students[i]]] += 1
            score[en[students[i]]] -= 1
            try:
                wait[students[i]] = int(
                    StudentRegistration.objects.get(
                        WAIT[0],
                        user=students[i],
                        section__meeting_times=timeslot,
                        section=req[students[i]]).relationship.name.partition(
                            "/")[2])
            except Exception:
                wait[students[i]] = priorityLimit + 1
            req[req[students[i]]][wait[students[i]]].append(students[i])
            en[req[students[i]]][wait[students[i]]].append(students[i])
        cap[NullSection] = 0
        score[NullSection] = 0
        print " done!"
        print "Randomly assigning students to classes by priority ....",
        sys.stdout.flush()
        for i in range(len(sections)):
            for j in range(1, priorityLimit + 2):
                if len(en[sections[i]][j]) > cap[sections[i]]:
                    random.shuffle(en[sections[i]][j])
                    for k in range(cap[sections[i]], len(en[sections[i]][j])):
                        NullSection.limbo.append(en[sections[i]][j][k])
                        loc[en[sections[i]][j][k]] = NullSection
                    en[sections[i]][j] = en[sections[i]][j][:(
                        cap[sections[i]])]
                    for k in range(j + 1, priorityLimit + 2):
                        for l in range(len(en[sections[i]][k])):
                            NullSection.limbo.append(en[sections[i]][k][l])
                            loc[en[sections[i]][k][l]] = NullSection
                        en[sections[i]][k] = []
                cap[sections[i]] -= len(en[sections[i]][j])
                en_new[sections[i]] += en[sections[i]][j]
                if not cap[sections[i]]:
                    break
        print " done!"
        print "Pushing students back to original classes...",
        sys.stdout.flush()
        a = 0
        limbo_orig = NullSection.limbo[:]
        limbo_all = [set()]

        while len(NullSection.limbo):
            a += 1
            limbo_all.append(set())
            limbo_old = NullSection.limbo[:]
            NullSection.limbo = []
            for i in range(len(limbo_old)):
                limbo_all[0].add(limbo_old[i])
                limbo_all[a].add(limbo_old[i])
                if en[limbo_old[i]] == NullSection:
                    continue
                if isinstance(en_new[en[limbo_old[i]]], list) and len(
                        en_new[en[limbo_old[i]]]):
                    pq = Queue.PriorityQueue()
                    random.shuffle(en_new[en[limbo_old[i]]])
                    b = 0
                    for student in en_new[en[limbo_old[i]]]:
                        pq.put((score[en[student]], student), False)
                        b += 1
                    en_new[en[limbo_old[i]]] = pq
                if not cap[en[limbo_old[i]]]:
                    move = en_new[en[limbo_old[i]]].get(False)[1]
                    sys.stdout.flush()
                    loc[move] = NullSection
                    NullSection.limbo.append(move)
                else:
                    cap[en[limbo_old[i]]] -= 1
                loc[limbo_old[i]] = en[limbo_old[i]]
        print " done!"
        print "Saving enrollments ....",
        sys.stdout.flush()
        for student in students:
            if loc[student] != en[student] and loc[student] != NullSection:
                if save_enrollments:
                    loc[student].preregister_student(student)
                    if en[student] != NullSection:
                        en[student].unpreregister_student(student)
                changed.add(student)
            else:
                unchanged.add(student)
        print " done!\n\n"
        sys.stdout.flush()
    unchanged -= changed

    print "Sending emails...."
    from django.conf import settings
    if hasattr(settings, 'EMAILTIMEOUT') and \
           settings.EMAILTIMEOUT is not None:
        timeout = settings.EMAILTIMEOUT
    else:
        timeout = 2
    f = open("classchanges.txt", 'w')
    from esp.dbmail.models import send_mail, MessageRequest, TextOfEmail
    subject = "[" + p.niceName() + "] Class Change"
    from_email = p.director_email
    bcc = p.getDirectorCCEmail()
    extra_headers = {}
    extra_headers['Reply-To'] = p.director_email
    for student in changed:
        text = "<html>\nHello " + student.first_name + ",<br /><br />\n\n"
        text += "We've processed your class change request, and have updated your schedule. Your new schedule is as follows: <br /><br />\n\n"
        text += get_student_schedule(student) + "\n\n<br /><br />\n\n"
        text += "We hope you enjoy your new schedule. See you soon!<br /><br />"
        text += "The " + p.niceName() + " Directors\n"
        text += "</html>"
        recipient_list = [student.email]
        print text, "\n\nSent to", student.username, "<", student.email, ">\n\n------------------------\n\n"
        f.write(
            text.replace(u'\u2019', "'").replace(u'\u201c', '"').replace(
                u'\u201d', '"') + "\n\nSent to " + student.username +
            "\n\n------------------------\n\n")
        if save_enrollments and send_emails:
            send_mail(subject,
                      text,
                      from_email,
                      recipient_list,
                      bcc=bcc,
                      extra_headers=extra_headers)
            time.sleep(timeout)

    for student in unchanged:
        text = "<html>\nHello " + student.first_name + ",<br /><br />\n\n"
        text += "We've processed your class change request, and unfortunately are unable to update your schedule. Your schedule is still as follows: <br /><br />\n\n"
        text += get_student_schedule(student) + "\n\n<br /><br />\n\n"
        text += "See you soon!<br /><br />"
        text += "The " + p.niceName() + " Directors\n"
        text += "</html>"
        recipient_list = [student.email]
        print text, "\n\nSent to", student.username, "<", student.email, ">\n\n------------------------\n\n"
        f.write(
            text.replace(u'\u2019', "'").replace(u'\u201c', '"').replace(
                u'\u201d', '"') + "\n\nSent to " + student.username +
            "\n\n------------------------\n\n")
        if save_enrollments and send_emails:
            send_mail(subject,
                      text,
                      from_email,
                      recipient_list,
                      bcc=bcc,
                      extra_headers=extra_headers)
            time.sleep(timeout)

    return 0
 def students(self, QObject = False):
     q = Q(studentregistration__section__parent_class__parent_program=self.program) & nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration')
     if QObject:
         return {'lotteried_students': q}
     else:
         return {'lotteried_students': ESPUser.objects.filter(q).distinct()}
Example #18
0
    def update_schedule_json(self, request, tl, one, two, module, extra, prog):
        resp = HttpResponse(content_type='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 = json.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
        q = Record.objects.filter(user=user, program=prog, event='attended')
        if not q.exists():
            new_rec, created = Record.objects.get_or_create(user=user, program=prog, event='attended')

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

            current_sections = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, 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(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=result['user']).values_list('id', flat=True).distinct())

        json.dump(result, resp)
        return resp
    def update_schedule_json(self, request, tl, one, two, module, extra, prog):
        resp = HttpResponse(content_type='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 = json.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
        q = Record.objects.filter(user=user, program=prog, event='attended')
        if not q.exists():
            new_rec, created = Record.objects.get_or_create(user=user, program=prog, event='attended')

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

            current_sections = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, 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(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=result['user']).values_list('id', flat=True).distinct())

        json.dump(result, resp)
        return resp
Example #20
0
def classchangerequest(request, tl, one, two):
    from esp.program.models import Program, StudentAppResponse, StudentRegistration, RegistrationType
    from esp.program.models.class_ import ClassSubject
    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 = any(
            x in request.user.groups.all().values_list("name", flat=True)
            for x in allowed_student_types.split(","))
        if not matching_user_types:
            return render_to_response('errors/program/notastudent.html',
                                      request, {})

    errorpage = 'errors/program/wronggrade.html'

    cur_grade = request.user.getGrade(prog)
    if (not Permission.user_has_perm(
            request.user, 'GradeOverride', program=prog)
            and (cur_grade != 0 and
                 (cur_grade < prog.grade_min or cur_grade > prog.grade_max))):
        return render_to_response(errorpage, request, {})

    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(
                nest_Q(StudentRegistration.is_valid_qobject(),
                       'sections__studentregistration'),
                sections__studentregistration__relationship__name="Enrolled",
                sections__studentregistration__user=request.user,
                sections__meeting_times=timeslot,
                parent_program=prog)
        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.valid_objects().filter(
                user=context['user'],
                section=section,
                relationship__name="Request").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.valid_objects().filter(
            user=context['user'],
            section__parent_class__parent_program=prog,
            relationship__name="Request")
        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,
                                  context)