Esempio n. 1
0
def given_review_dict(context, pr, lang):
    tfd = UserDownload.objects.filter(user=pr.reviewer.student.user, assignment=pr.assignment)
    if tfd:
        tfd = tfd.first().time_downloaded
    else:
        tfd = DEFAULT_DATE
    r = {
        'object': pr,
        'lang': lang,
        'time_first_download': lang.ftime(tfd),
        'time_submitted': lang.ftime(pr.time_submitted),
        'rev_items': pr.item_list(),
        'pred_hex': encode(pr.assignment.id, context['user_session'].encoder)
    }
    # if predecessor has responded, additional fields must be added
    if pr.time_appraised != DEFAULT_DATE:
        r['time_appraised'] = lang.ftime(pr.time_appraised)
        r['app_icon'] = FACES[pr.appraisal]
        r['app_header'] = lang.phrase('Appraisal_header') % lang.phrase(['ERROR',
            'Quite_happy', 'Mixed_feelings', 'Unhappy'][pr.appraisal])
        r['imp_opinion'] = lang.phrase('Opinion_on_sucessor_version') % lang.phrase(['Pass',
            'No_improvement', 'Minor_changes', 'Good_job'][pr.improvement_appraisal])
    # also indicate whether student has acknowledged
    if pr.time_acknowledged != DEFAULT_DATE:
        r['time_acknowledged'] = lang.ftime(pr.time_acknowledged)
    # in case of an appeal, report the appeal status
    if pr.is_appeal:
        if pr.time_appeal_assigned != DEFAULT_DATE:
            r['time_assigned'] = lang.ftime(pr.time_appeal_assigned)
            ap = Appeal.objects.filter(review=pr).first()
            if ap:
                r['referee'] = prefixed_user_name(ap.referee.user)
                if ap.time_first_viewed != DEFAULT_DATE:
                    r['time_first_viewed'] = lang.ftime(ap.time_first_viewed)
                if ap.time_decided != DEFAULT_DATE:
                    r['time_decided'] = lang.ftime(ap.time_decided)
                    r['ref_rat'] = ap.grade
                    r['ref_motiv'] = ap.grade_motivation
                    r['penalties'] = lang.penalties_as_text(
                        ap.predecessor_penalty, ap.successor_penalty)
                # NOTE: in this case, the student ("you") is the successor ...
                if ap.time_acknowledged_by_successor != DEFAULT_DATE:
                    r['time_your_appr'] = lang.ftime(ap.time_acknowledged_by_successor)
                    r['your_appr_icon'] = FACES[ap.successor_appraisal]
                    r['your_motiv'] = ap.successor_motivation
                    r['you_objected'] = ap.is_contested_by_successor
                # ... and hence the other party the predecessor
                if ap.time_acknowledged_by_predecessor != DEFAULT_DATE:
                    r['time_other_appr'] = lang.ftime(ap.time_acknowledged_by_predecessor)
                    r['other_appr_icon'] = FACES[ap.predecessor_appraisal]
                    r['other_motiv'] = ap.predecessor_motivation
                    r['other_objected'] = ap.is_contested_by_predecessor
    return r
Esempio n. 2
0
def set_course_json(c, jd):
    jd['c'] = c.code
    jd['n'] = c.name
    jd['m'] = prefixed_user_name(c.manager)
    jd['d'] = c.description
    jd['lc'] = c.language.code
    jd['sd'] = c.language.fdate(c.start_date)
    jd['ed'] = c.language.fdate(c.end_date)
    jd['sdi'] = c.start_date.strftime('%Y-%m-%d')
    jd['edi'] = c.end_date.strftime('%Y-%m-%d')
    jd['sn'] = c.staff_name
    jd['sp'] = c.staff_position
    jd['bc'] = c.badge_color
    jd['edx'] = c.is_edX
    jd['hide'] = c.is_hidden
Esempio n. 3
0
def set_leg_json(el, jd):
    jd['n'] = el.name
    jd['r'] = el.rejectable
    jd['d'] = el.description.replace('<img ', '<img class="ui large image" ')
    jd['lo'] = el.learning_objectives
    jd['ui'] = el.upload_instruction.replace('<img ', '<img class="ui large image" ')
    jd['uits'] = [ui.to_dict() for ui in el.upload_items.all()]
    jd['f'] = el.required_files
    jd['ff'] = el.file_list()
    jd['s'] = el.required_section_title
    jd['l'] = el.required_section_length
    jd['k'] = el.required_keywords
    jd['ut'] = el.min_upload_minutes
    jd['ri'] = el.review_instruction.replace('<img ', '<img class="ui large image" ')
    jd['rits'] = [ri.to_dict() for ri in el.review_items.all()]
    jd['w'] = el.word_count
    jd['rt'] = el.min_review_minutes
    jd['se'] = EDIT_STRING % (prefixed_user_name(el.last_editor),
        timezone.localtime(el.time_last_edit).strftime(DATE_TIME_FORMAT))
    # also pass number of assignments for this leg (leg cannot be deleted if acnt > 0)
    jd['acnt'] = Assignment.objects.filter(leg=el).count()
Esempio n. 4
0
                        log_message('FAILURE -- error message: ' + str(e), context['user'])
        # close mailbox connection -- marked messages will now be deleted
        mailbox.quit()
    except Exception, e:
        warn_user(context, 'Error while retrieving mail', 'System message: ' + str(e))

    # add picture queue mail address
    context['pq_mail'] = settings.PICTURE_QUEUE_MAIL
    
    # add course data to context
    context['course'] = {
        'object': c,
        'hex':  encode(c.id, context['user_session'].encoder),
        'start': c.language.fdate(c.start_date),
        'end': c.language.fdate(c.end_date),
        'manager': prefixed_user_name(c.manager),                         
        'instructors': ', '.join([prefixed_user_name(i) for i in c.instructors.all()])
    }

    # add list of queue pictures for this course
    context['pictures'] = [{
        'object': qp,
        'hex': encode(qp.id, day_code(PQ_DAY_CODE), True), # NOTE: deterministic encoding!
        'time_received': qp.time_received.strftime('%H:%M'),
        'sender': qp.mail_from_name if qp.mail_from_name else qp.mail_from_address
        } for qp in QueuePicture.objects.filter(course=c).order_by('time_received', 'id')
    ]
    context['page_title'] = 'Presto Picture Queue' 
    return render(request, 'presto/picture_queue.html', context)

Esempio n. 5
0
def set_history_properties(context, p):
    # switch to the course language
    lang = p.estafette.course.language
    # add the language-sensitive properties to the context
    context['lang'] = lang
    context['last_action'] = lang.ftime(p.student.last_action)
    context['start'] = lang.ftime(p.estafette.start_time)
    context['end'] = lang.ftime(p.estafette.end_time)
    context['desc'] = p.estafette.estafette.description
    context['next_deadline'] = p.estafette.next_deadline()
    context['decisions'] = []
    
    # NOTE: first see whether participant has decided on appeals in this estafette
    ap_list = Appeal.objects.filter(referee__user=p.student.user
        ).filter(review__reviewer__estafette=p.estafette).exclude(time_decided=DEFAULT_DATE)
    if ap_list:
        # create a list of decided appeals for each course estafette
        ap_nr = 0
        for ap in ap_list:
            ap_nr += 1
            # add the appeal that has been decided
            ar = ap.review
            a = ar.assignment
            ap_dict = {
                'nr': ap_nr,
                'appeal': ap,
                'appeal_title': '%s %s%s <span style="margin-left: 1em; font-weight: 500">(%s)</span>' % (
                    lang.phrase('Appeal_case_decision'), a.case.letter, str(a.leg.number),
                    lang.ftime(ap.time_decided)),
                # show names only to instructors
                'show_names': has_role(context, 'Instructor'),
                # add assignment properties
                'case_title': '%s %s: %s' % (lang.phrase('Case'), a.case.letter, a.case.name),
                'case_desc': a.case.description,
                'step_title': '%s %s: %s' % (lang.phrase('Step'), a.leg.number, a.leg.name),
                'step_desc': a.leg.description,
                'author': a.participant.student.dummy_name(),
                'time_uploaded': lang.ftime(a.time_uploaded),
                'pred_file_list': a.leg.file_list,
                'pred_hex': encode(a.id, context['user_session'].encoder),
                # add properties of the review that is appealed against
                'review': ar,
                'rev_items': ar.item_list(),
                'reviewer': ar.reviewer.student.dummy_name(),
                'time_reviewed': lang.ftime(ar.time_submitted),
                'time_appealed': lang.ftime(ar.time_appraised),
                # add properties concerning the appeal (but attributes of the PeerReview object)
                'imp_opinion': lang.phrase('Pred_opinion_succ_work') % lang.phrase(['Pass',
                    'No_improvement', 'Minor_changes', 'Good_job'][ar.improvement_appraisal]),
                'time_assigned': lang.ftime(ar.time_appeal_assigned),
                # add appeal properties
                'time_viewed': lang.ftime(ap.time_first_viewed),
                'penalties_as_text': lang.penalties_as_text(ap.predecessor_penalty, ap.successor_penalty),
                'hex': encode(ap.id, context['user_session'].encoder)
            }
            # pass hex for case if it has a file attached
            if a.case.upload:
                ap_dict['case_hex'] = encode(a.case.id, context['user_session'].encoder)
            # pass predecessor's appreciation of the decision (if submitted)
            if ap.time_acknowledged_by_predecessor != DEFAULT_DATE:
                ap_dict['time_pred_appr'] = lang.ftime(ap.time_acknowledged_by_predecessor)
                ap_dict['pred_appr_icon'] = FACES[ap.predecessor_appraisal]
                ap_dict['pred_appr_color'] = COLORS[ap.predecessor_appraisal]
                ap_dict['pred_motiv'] = ap.predecessor_motivation
                ap_dict['pred_objected'] = ap.is_contested_by_predecessor
            # pass predecessor's appreciation of the decision (if submitted)
            if ap.time_acknowledged_by_successor != DEFAULT_DATE:
                ap_dict['time_succ_appr'] = lang.ftime(ap.time_acknowledged_by_successor)
                ap_dict['succ_appr_icon'] = FACES[ap.successor_appraisal]
                ap_dict['succ_appr_color'] = COLORS[ap.successor_appraisal]
                ap_dict['succ_motiv'] = ap.successor_motivation
                ap_dict['succ_objected'] = ap.is_contested_by_successor
            context['decisions'].append(ap_dict)

    # now compile a consecutive list of all the student's actions in this estafette
    # (1) get list of all assignments for the student so far (except rejections and clones!)
    a_list = Assignment.objects.filter(participant=p).exclude(is_rejected=True
        ).filter(clone_of__isnull=True).order_by('leg__number')
    # from this list, derive a list with only the primary keys of the assignments
    aid_list = [a.id for a in a_list]
    # (2) get list of all reviews the student has written so far
    pr_given = PeerReview.objects.filter(reviewer=p).exclude(time_submitted=DEFAULT_DATE)
    # (3) also get list of all reviews the student has received so far
    pr_received = PeerReview.objects.filter(assignment__id__in=aid_list
        ).exclude(time_submitted=DEFAULT_DATE)
    # (4) also get the "oldest" user download objects for the assignment set
    ud_set = UserDownload.objects.filter(user=p.student.user, assignment__id__in=aid_list
            ).annotate(first_download_at=Min('time_downloaded'))
    # process the assignments in their number sequence
    steps = []
    for a in a_list:
        # show all the student's assignments (i.e., also those without file uploads)
        step_nr = a.leg.number
        step = {
            'step_nr': step_nr,
            'assignment': a,
            'header': lang.phrase('Step_header') % (step_nr, a.leg.name),
            # indicate whether the student did upload this step (or file list should not be shown)
            'uploaded': (a.time_uploaded != DEFAULT_DATE),
            'time': lang.ftime(a.time_uploaded),
            'case_title': '%s %s: %s' % (lang.phrase('Case'), a.case.letter, a.case.name),
            'case': a.case.description,
            'desc': a.leg.description,
            'Assigned_to_you': lang.phrase('Assigned_to_you') % lang.ftime(a.time_assigned),
            'You_uploaded': lang.phrase('You_uploaded') % lang.ftime(a.time_uploaded),
            'upl_items': a.item_list(),
            'own_file_list': a.leg.file_list(),
            'pred_file_list': [],
            'succ_file_list': [],
            'pred_reviews': [],
            'succ_reviews': [],
            'own_hex': encode(a.id, context['user_session'].encoder)
        }
        # pass hex for case if it has a file attached
        if a.case.upload:
            step['case_hex'] = encode(a.case.id, context['user_session'].encoder)
        # add half point bonus statement if such bonus was earned
        if a.on_time_for_bonus():
            step['time_bonus'] = lang.phrase('Half_point_bonus')

        # for all but the first step, also show the review(s) the student has given on preceding steps
        if step_nr > 1:
            # the file list is step-specific, but not review-specific
            step['pred_file_list'] = a.predecessor.leg.file_list()
            step['pred_hex'] = encode(a.predecessor.id, context['user_session'].encoder)
            # get the first user download (if any)
            fud = ud_set.filter(assignment__id=a.id).first()
            if fud:
                step['downloaded'] = lang.ftime(fud.first_download_at)
            # the student may have given several reviews: rejections and second opinions
            prgl = pr_given.filter(assignment__leg__number=step_nr - 1).order_by('time_submitted')
            # add these reviews to this step
            for pr in prgl:
                step['pred_reviews'].append(given_review_dict(context, pr, lang))

        # the student may also have received reviews of own work
        prrl = pr_received.filter(assignment__leg__number=step_nr).order_by('time_submitted')
        for pr in prrl:
            # do not show reviews that have been saved, but for which the successor did NOT
            # upload yet (unless it is a rejection or a FINAL review or a second opinion)
            if not (pr.is_rejection or pr.is_second_opinion or pr.final_review_index):
                # to prevent all error, double-check whether there IS a successor
                # NOTE: if reviewer is "instructor student", then skip the upload check
                if pr.assignment.successor and not (pr.reviewer.student.dummy_index < 0):
                    if pr.assignment.successor.time_uploaded == DEFAULT_DATE:
                        continue  # skip this review, but continue looping
            r = {
                'object': pr,
                'time_submitted': lang.ftime(pr.time_submitted),
                'rev_items': pr.item_list()
                # no 'pred_hex' field, as the reviewed work is the student's own step
            }
            # if student has responded, additional fields must be added
            if pr.time_appraised != DEFAULT_DATE:
                r['time_appraised'] = lang.ftime(pr.time_appraised)
                r['app_icon'] = FACES[pr.appraisal]
                r['app_header'] = lang.phrase('Your_appraisal_header') % lang.phrase(['ERROR',
                    'You_quite_happy', 'Mixed_feelings', 'You_unhappy'][pr.appraisal])
            # student can see reviewer's work only if review is not a rejection,
            # a second opinion, or a final review (which has by definition no successor)
            if not (pr.is_rejection or pr.is_second_opinion or pr.final_review_index):
                # to prevent all error, double-check whether there IS a successor
                if pr.assignment.successor:
                    step['succ_file_list'] = pr.assignment.successor.leg.file_list()
                    step['succ_hex'] = encode(pr.assignment.successor.id, context['user_session'].encoder)
                r['imp_opinion'] = lang.phrase('Your_opinion_on_improvement') % lang.phrase(['Pass',
                    'No_improvement', 'Minor_changes', 'Good_job'][pr.improvement_appraisal])
            # in case of an appeal, report the appeal status
            if pr.is_appeal:
                if pr.time_appeal_assigned != DEFAULT_DATE:
                    r['time_assigned'] = lang.ftime(pr.time_appeal_assigned)
                    ap = Appeal.objects.filter(review=pr).first()
                    if ap:
                        r['referee'] = prefixed_user_name(ap.referee.user)
                        if ap.time_first_viewed != DEFAULT_DATE:
                            r['time_first_viewed'] = lang.ftime(ap.time_first_viewed)
                        if ap.time_decided != DEFAULT_DATE:
                            r['time_decided'] = lang.ftime(ap.time_decided)
                            r['ref_rat'] = ap.grade
                            r['ref_motiv'] = ap.grade_motivation
                            r['penalties'] = lang.penalties_as_text(
                                ap.predecessor_penalty, ap.successor_penalty)
                        # NOTE: in this case, the student ("you") is the predecessor ...
                        if ap.time_acknowledged_by_predecessor != DEFAULT_DATE:
                            r['time_your_appr'] = lang.ftime(ap.time_acknowledged_by_predecessor)
                            r['your_appr_icon'] = FACES[ap.predecessor_appraisal]
                            r['your_motiv'] = ap.predecessor_motivation
                            r['you_objected'] = ap.is_contested_by_predecessor
                        # ... and hence the other party the successor
                        if ap.time_acknowledged_by_successor != DEFAULT_DATE:
                            r['time_other_appr'] = lang.ftime(ap.time_acknowledged_by_successor)
                            r['other_appr_icon'] = FACES[ap.successor_appraisal]
                            r['other_motiv'] = ap.successor_motivation
                            r['other_objected'] = ap.is_contested_by_successor
            # add the review to the list
            step['succ_reviews'].append(r)
        # now all step properties have been set, so the step is added to the list
        steps.append(step)            
    # and finally the step list is added to the context
    context['steps'] = steps

    # the student may also have given final reviews
    context['final_reviews'] = []
    prgl = pr_given.filter(final_review_index__gt=0).order_by('final_review_index')
    # add these reviews to this step
    n = 0
    for pr in prgl:
        r = given_review_dict(context, pr, lang)
        n += 1
        r['nr'] = n
        a = pr.assignment
        r['header'] = lang.phrase('Final_review_header') % (step_nr, a.leg.name)
        r['case_title'] = '%s %s: %s' % (lang.phrase('Case'), a.case.letter, a.case.name)
        r['case'] = a.case.description
        # pass hex for case if it has a file attached
        if a.case.upload:
            r['case_hex'] = encode(a.case.id, context['user_session'].encoder)
        context['final_reviews'].append(r)
Esempio n. 6
0
def instructor(request, **kwargs):
    context = generic_context(request)
    # check whether user can have instructor role
    if not change_role(context, 'Instructor'):
        return render(request, 'presto/forbidden.html', context)

    # create list of courses in which the user is manager/instructor
    context['courses'] = []
    c_set = Course.objects.filter(
        Q(instructors=context['user'])
        | Q(manager=context['user'])).distinct()
    for c in c_set:
        context['courses'].append({
            'object':
            c,
            'start':
            c.start_date.strftime(DATE_FORMAT),
            'end':
            c.end_date.strftime(DATE_FORMAT),
            'manager':
            prefixed_user_name(c.manager),
            'estafette_count':
            CourseEstafette.objects.filter(course=c).count(),
            'hex':
            encode(c.id, context['user_session'].encoder)
        })

    # create list of estafettes of which the user is creator/editor
    context['estafettes'] = [{
        'object':
        e,
        'edits':
        EDIT_STRING %
        (prefixed_user_name(e.last_editor), timezone.localtime(
            e.time_last_edit).strftime(DATE_TIME_FORMAT)),
        'template':
        e.template.name,
        'case_count':
        EstafetteCase.objects.filter(estafette=e).count(),
        'hex':
        encode(e.id, context['user_session'].encoder)
    } for e in Estafette.objects.filter(
        Q(editors=context['user']) | Q(creator=context['user'])).distinct()]

    # create list of active project relays in which the user is instructor
    context['running_relays'] = [{
        'object':
        ce,
        'start_time':
        c.language.ftime(ce.start_time),
        'end_time':
        c.language.ftime(ce.end_time),
        'next_deadline':
        ce.next_deadline(),
        'participant_count':
        Participant.objects.filter(estafette=ce,
                                   student__dummy_index__gt=-1).count(),
        'active_count':
        Participant.objects.filter(estafette=ce,
                                   student__dummy_index__gt=-1).filter(
                                       time_last_action__gte=timezone.now() -
                                       timedelta(days=1)).count(),
        'demo_code':
        ce.demonstration_code(),
        'hex':
        encode(ce.id, context['user_session'].encoder)
    } for ce in CourseEstafette.objects.filter(
        course__in=c_set, is_deleted=False).exclude(
            start_time__gte=timezone.now()).exclude(
                end_time__lte=timezone.now())]

    # create list of estafette templates that the user can choose from
    context['templates'] = [{
        'object':
        et,
        'hex':
        encode(et.id, context['user_session'].encoder)
    } for et in EstafetteTemplate.objects.filter(published=True)]

    context['page_title'] = 'Presto Instructor'
    return render(request, 'presto/instructor.html', context)
Esempio n. 7
0
        try:
            h = kwargs.get('hex', '')
            context = generic_context(request, h)
            etid = decode(h, context['user_session'].decoder)
            et = EstafetteTemplate.objects.get(pk=etid)
            log_message('Deleting template %s' % et.name, context['user'])
            et.delete()
        except Exception, e:
            report_error(request, context, e)
            return render(request, 'presto/error.html', context)

    # pass list of estafette templates that the user is (co-)authoring
    context['templates'] = [{
        'object': t,
        'hex': encode(t.id, context['user_session'].encoder),
        'edits': EDIT_STRING % (prefixed_user_name(t.last_editor),
                 timezone.localtime(t.time_last_edit).strftime(DATE_TIME_FORMAT)),
        'leg_count': EstafetteLeg.objects.filter(template=t).count()
        } for t in EstafetteTemplate.objects.filter(
            Q(editors=context['user']) | Q(creator=context['user'])).distinct()
    ]

    # TO DO: also pass list of questionnaire templates that the user is (co-)authoring
    context['questionnaires'] = [{
        'object': q,
        'hex': encode(q.id, context['user_session'].encoder),
        'edits': EDIT_STRING % (prefixed_user_name(q.last_editor),
                 timezone.localtime(q.time_last_edit).strftime(DATE_TIME_FORMAT)),
        'item_count': 0, # to be changed!!
        } for q in QuestionnaireTemplate.objects.filter(
            Q(editors=context['user']) | Q(creator=context['user'])).distinct()
Esempio n. 8
0
     ap.grade = int(request.POST.get('dr', 0))
     ap.grade_motivation = request.POST.get('dm', '')
     # print ap.grade_motivation
     ap.predecessor_penalty = float(request.POST.get('pp', 0))
     ap.successor_penalty = float(request.POST.get('sp', 0))
     # NOTE: time_decided is not set => saved, but not submitted yet
     ap.save()
     jd['pt'] = ap.review.reviewer.student.course.language.penalties_as_text(
         ap.predecessor_penalty, ap.successor_penalty)
     log_message('Appeal decision saved: ' + unicode(ap), presto_user)
 elif a == 'get estafette':
     eid = decode(request.POST.get('h', ''), user_session.encoder)
     e = Estafette.objects.get(pk=eid)
     jd['n'] = e.name
     jd['d'] = e.description
     jd['e'] = EDIT_STRING % (prefixed_user_name(e.last_editor),
         timezone.localtime(e.time_last_edit).strftime(DATE_TIME_FORMAT))
     # also pass number of estafettes having this template (no deletion if cnt > 0)
     jd['cnt'] = CourseEstafette.objects.filter(estafette=e).count()
 elif a == 'get case':
     ecid = decode(request.POST.get('h', ''), user_session.encoder)
     ec = EstafetteCase.objects.get(pk=ecid)
     jd['n'] = ec.name
     jd['d'] = ec.description
     jd['k'] = ec.required_keywords
     jd['u'] = '' if ec.upload == None else ec.upload.original_name
     jd['e'] = EDIT_STRING % (prefixed_user_name(ec.last_editor),
         timezone.localtime(ec.time_last_edit).strftime(DATE_TIME_FORMAT))
     # also pass number of assignments having this case (case cannot be deleted if acnt > 0)
     jd['acnt'] = Assignment.objects.filter(case=ec).count()
 elif a == 'new estafette':
Esempio n. 9
0
            ce.save()
            log_message('Added new estafette to course', context['user'])
        except Exception, e:
            report_error(context, e)
            return render(request, 'presto/error.html', context)

    # add course properties that need conversion to context
    context['course'] = {
        'object':
        c,
        'start':
        c.language.fdate(c.start_date),
        'end':
        c.language.fdate(c.end_date),
        'manager':
        prefixed_user_name(c.manager),
        'owned':
        c.manager == context['user'],
        'instructors': [{
            'name': prefixed_user_name(i),
            'hex': encode(i.id, context['user_session'].encoder)
        } for i in c.instructors.all()],
        'hex':
        encode(c.id, context['user_session'].encoder),
        'disc': (c.badge_color >> 24) & 15,
        'red': (c.badge_color >> 16) & 255,
        'green': (c.badge_color >> 8) & 255,
        'blue':
        c.badge_color & 255
    }
Esempio n. 10
0
def verify_certified_image(img):
    try:
        # make pixels accessible as pix[x, y]
        pix = img.load()
        w, h = img.size
        # check for approriate dimensions
        if h != BADGE_HEIGHT or w != BADGE_WIDTH:
            raise ValueError('Badge should be 256x256 pixels')
        # get the 256-bit signature
        signature = ''.join([test_bit(pix, i) for i in range(0, 256)])
        # get the length of the "payload" coded in the next 14 bits
        bits = ''.join([test_bit(pix, i) for i in range(256, 270)])
        bit_count = int(bits, 2)
        if bit_count > MAX_DATA_BITS:
            raise ValueError('Invalid data size (%d)' % bit_count)
        # get the actual data
        bits = ''.join([test_bit(pix, i) for i in range(270, 270 + bit_count)])
        # check integrity of bits
        bits_hash = hash_to_binary(hexlify(pbkdf2_hmac("sha256", bits,
                settings.BADGE_SALT, settings.BADGE_ITERATIONS)))
        if bits_hash != signature:
            raise ValueError('Corrupted badge data')
        # decode the bits
        bd = binary_to_dict(bits)
        # see if the standard badge properties exist
        mf = list(set(['ID', 'CC', 'CN', 'AL', 'TI', 'PR', 'FN', 'EM']) - set(bd.keys()))
        if mf:
            raise ValueError('Incomplete data (missing: %s)' % ', '.join(mf))
        # see if the badge exists in the database
        # NOTE: use filter instead of get so that we can generate our own error message
        b = PrestoBadge.objects.filter(pk=bd['ID'])
        if b.count() == 0:
            raise ValueError('Unmatched badge ID')
        # get the first element (should be the only one)
        b = b.first()
        if b.participant:
            u = b.participant.student.user
            pr = b.participant.estafette.estafette.name
        if b.referee:
            u = b.referee.user
            pr = b.referee.estafette_leg.template.name
        # see if badge data match those in database
        if prefixed_user_name(u) != bd['FN']:
            raise ValueError('Holder name (%s) does not match "%s"' %
                (bd['FN'], prefixed_user_name(u)))
        if u.email != bd['EM']:
            raise ValueError('Holder e-mail address (%s) does not match "%s"' %
                (bd['EM'], u.email))
        if b.course.code != bd['CC']:
            raise ValueError('Course code (%s) does not match "%s"' % (bd['CC'], b.course.code))
        if b.course.name != bd['CN']:
            raise ValueError('Course name (%s) does not match "%s"' % (bd['CN'], b.course.name))
        if pr != bd['PR']:
            raise ValueError('Project relay name (%s) does not match "%s"' %
                (bd['PR'], pr))
        if b.attained_level != bd['AL']:
            raise ValueError('Attained level (%d) should have been %d' % (bd['AL'], b.attained_level))
        # update badge verification parameters
        b.time_last_verified = timezone.now()
        b.verification_count += 1
        b.save()
        # return the badge object
        return b
    except Exception, e:
        log_message('Failed to validate badge: ' + str(e))
        return False
Esempio n. 11
0
                                              letter=l,
                                              creator=context['user'],
                                              time_created=timezone.now(),
                                              last_editor=context['user'],
                                              time_last_edit=timezone.now())

    # when no errors, create list of cases in this estafette
    ec_list = EstafetteCase.objects.filter(estafette=e)
    e_cases = []
    for ec in ec_list:
        e_cases.append({
            'object':
            ec,
            'edits':
            EDIT_STRING %
            (prefixed_user_name(ec.last_editor),
             timezone.localtime(ec.time_last_edit).strftime(DATE_TIME_FORMAT)),
            'hex':
            encode(ec.id, context['user_session'].encoder)
        })
    context['estafette'] = {
        'object':
        e,
        'edits':
        EDIT_STRING %
        (prefixed_user_name(e.last_editor), timezone.localtime(
            e.time_last_edit).strftime(DATE_TIME_FORMAT)),
        'hex':
        encode(e.id, context['user_session'].encoder),
        'owner':
        prefixed_user_name(e.creator),