Exemple #1
0
    def post(self):
        course = self.request.get('course')
        try:
            data = json.loads(self.request.get('data'))
        except ValueError:
            data = None
        if not course or not data:
            return self.response.set_status(202)

        # Create Evals
        if data['instructor']:
            for ta in data['tas']:
                Eval.create(course, ta, data['instructor'])
            data['instructor'] = None

        # Create Invites
        tas = [ta['name'] for ta in data['tas']]
        for student in data['students'][:]:
            try:
                EvalInvite.create(course, student, tas)
            except DeadlineExceededError:
                # Need to test this
                data = json.dumps(data)
                taskqueue.add(url='/admin/init', params={'course': course,
                                                         'data': data})
                return self.response.set_status(200)
            data['students'].remove(student)
        return self.response.set_status(201)
Exemple #2
0
    def get(self, key, ta='', responses=None, success=None, errors=None):
        invite = EvalInvite.get_by_key_name(key)
        if not invite:
            return self.redirect('/')

        settings = Settings.get_by_key_name('settings')
        invite.expired = datetime.datetime.now() > settings.expire_date
        success = success or []
        errors = errors or []

        remaining = invite.remaining_evals()
        if not remaining and not invite.tas:
            if settings.send_completed_email:
                body = const.COMPLETED_EMAIL_TEMPLATE.format(invite.name)
                try:
                    to_email = '{} <{}>'.format(invite.name, invite.email)
                    mail.send_mail(settings.admin_email, to_email,
                                   const.COMPLETED_EMAIL_SUBJECT, body)
                except apiproxy_errors.OverQuotaError as message:
                    logging.error(message)
            completed = Completed(name=invite.name, email=invite.email)
            completed.put()
            invite.delete()
            questions = None
        else:
            if not responses:
                responses = [''] * len(const.QUESTIONS)
            questions = zip(const.QUESTIONS, responses)

        values = {'invite': invite, 'success': success, 'errors': errors,
                  'sel_ta': ta, 'questions': questions, 'remaining': remaining}
        template = jinja_environment.get_template('eval.html')
        self.response.out.write(template.render(values))
Exemple #3
0
 def reset(self):
     if self.request.get('confirm') != '0xDEADBEEF':
         self.get(errors=['Invalid confirmation'])
     else:
         keys = [x for x in EvalInvite.all(keys_only=True)]
         keys.extend([x for x in Eval.all(keys_only=True)])
         keys.extend([x for x in Completed.all(keys_only=True)])
         for i in range(int(math.ceil(len(keys) * 1. / MAX_DELETES))):
             db.delete(keys[i * MAX_DELETES:(i + 1) * MAX_DELETES])
         self.get(successes=['Reset Database'])
Exemple #4
0
    def get(self, successes=None, warnings=None, errors=None):
        courses = {}

        # Remaining Evaluations
        for invite in EvalInvite.all():
            if invite.course not in courses:
                courses[invite.course] = {}

            for ta in invite.tas:
                if ta in courses[invite.course]:
                    courses[invite.course][ta].remaining += 1
                else:
                    courses[invite.course][ta] = helpers.Dummy(
                        remaining=1, completed=0, sent_results=None)

        # Completed Evaluations
        for evaluation in Eval.all():
            completed = sum(evaluation.get_responses()[0])
            tas = courses[evaluation.course]
            if evaluation.ta in tas:
                tas[evaluation.ta].completed = completed
                tas[evaluation.ta].sent_results = evaluation.sent_results
            else:
                tas[evaluation.ta] = helpers.Dummy(
                    completed=completed, remaining=0,
                    sent_results=evaluation.sent_results)

        form_token, cookie = helpers.generate_validation_token()
        self.response.headers.add_header('Set-Cookie', cookie)

        successes = helpers.nsorted(successes) if successes else []
        warnings = helpers.nsorted(warnings) if warnings else []
        errors = helpers.nsorted(errors) if errors else []
        courses = [(x, sorted(courses[x].items())) for x in
                   helpers.nsorted(courses)]

        # Initialize settings if not already set
        user = users.get_current_user()
        admin_email = 'Computer Science Lead TA <{}>'.format(user.email())
        now = datetime.datetime.now()
        expire_date = now + datetime.timedelta(days=5)
        settings = Settings.get_or_insert('settings', admin_email=admin_email,
                                          expire_date=expire_date)
        if settings.expire_date < now:
            remaining_time = str(datetime.timedelta())
        else:
            remaining_time = str(settings.expire_date - now)

        values = {'successes': successes, 'warnings': warnings,
                  'errors': errors, 'courses': courses,
                  'form_token': form_token, 'eval_time': remaining_time}
        template = jinja_environment.get_template('admin.html')
        self.response.out.write(template.render(values))
Exemple #5
0
    def post(self, key):
        invite = EvalInvite.get_by_key_name(key)
        if not invite:
            return self.redirect('/')

        settings = Settings.get_by_key_name('settings')
        if datetime.datetime.now() > settings.expire_date:
            return self.get(key)

        ta = self.request.get('ta')
        if ta not in invite.tas:
            return self.get(key, errors=('Must select a TA to evaluate',))

        if self.request.get('not_applicable'):
            success = 'Not Applicable: {}'.format(ta)
        else:
            errors = []
            responses = self.get_responses()

            for i in range(len(const.QUESTIONS)):
                if i >= len(responses):
                    responses.append('')
                    continue
                if const.QUESTIONS[i][1] in [0, 1]:
                    if responses[i] not in ['0', '1', '2', '3', '4', '5']:
                        responses[i] = ''
                        errors.append('Must provide an answer for {!r}'.format(
                                const.QUESTIONS[i][0]))
            if errors:
                return self.get(key, ta, responses, errors=errors)

            try:
                db.run_in_transaction(Eval.update, invite.course, ta,
                                      responses)
            except apiproxy_errors.RequestTooLargeError:
                return self.get(key, ta, responses,
                                errors=('Your response is too long',))
            success = 'Evaluated: {}'.format(ta)

        # Remove TA from list of TAs student can evaluate
        invite.tas.remove(ta)
        invite.put()
        self.get(key, success=success)