def show_input(self): """ Show multiple choice problems """ choices = [] limit = self._limit if limit == 0: limit = len(self._choices) # no limit if self._multiple: # take only the valid choices in the first pass for entry in self._choices: if entry["valid"]: choices.append(entry) limit = limit - 1 # take everything else in a second pass for entry in self._choices: if limit == 0: break if not entry["valid"]: choices.append(entry) limit = limit - 1 else: # need to have a valid entry found_valid = False for entry in self._choices: if limit == 1 and not found_valid and not entry["valid"]: continue elif limit == 0: break choices.append(entry) limit = limit - 1 if entry["valid"]: found_valid = True shuffle(choices) return str(get_template_renderer("templates/tasks/").multiplechoice(self.get_id(), self._multiple, choices))
def POST(self, courseid): """ POST request: update the settings """ course, _ = get_course_and_check_rights(courseid, allow_all_staff=False) contest_data = get_contest_data(course) new_data = web.input() errors = [] try: contest_data['enabled'] = new_data.get('enabled', '0') == '1' contest_data['start'] = new_data["start"] contest_data['end'] = new_data["end"] try: start = datetime.strptime(contest_data['start'], "%Y-%m-%d %H:%M:%S") except: errors.append('Invalid start date') try: end = datetime.strptime(contest_data['end'], "%Y-%m-%d %H:%M:%S") except: errors.append('Invalid end date') if len(errors) == 0: if start >= end: errors.append('Start date should be before end date') try: contest_data['blackout'] = int(new_data["blackout"]) if contest_data['blackout'] < 0: errors.append('Invalid number of hours for the blackout: should be greater than 0') except: errors.append('Invalid number of hours for the blackout') try: contest_data['penalty'] = int(new_data["penalty"]) if contest_data['penalty'] < 0: errors.append('Invalid number of minutes for the penalty: should be greater than 0') except: errors.append('Invalid number of minutes for the penalty') except: errors.append('User returned an invalid form') if len(errors) == 0: save_contest_data(course, contest_data) return get_template_renderer('plugins/contests', '../../templates/layout').admin(course, contest_data, None, True) else: return get_template_renderer('plugins/contests', '../../templates/layout').admin(course, contest_data, errors, False)
def get_menu(course, current): """ Returns the HTML of the menu used in the administration. ```current``` is the current page of section """ custom_renderer = get_template_renderer('templates/') default_entries = [("settings", "<span class='glyphicon glyphicon-cog'></span> Course settings"), ("students", "<span class='glyphicon glyphicon-user'></span> Students"), ("tasks", "<span class='glyphicon glyphicon-tasks'></span> Tasks")] # Hook should return a tuple (link,name) where link is the relative link from the index of the course administration. additionnal_entries = [entry for entry in PluginManager.get_instance().call_hook('course_admin_menu', course=course) if entry is not None] return custom_renderer.course_admin.menu(course, default_entries + additionnal_entries, current)
def course_menu(course): """ Displays some informations about the contest on the course page""" contest_data = get_contest_data(course) if contest_data['enabled']: start = datetime.strptime(contest_data['start'], "%Y-%m-%d %H:%M:%S") end = datetime.strptime(contest_data['end'], "%Y-%m-%d %H:%M:%S") blackout = end - timedelta(hours=contest_data['blackout']) return str(get_template_renderer('frontend/plugins/contests').course_menu(course, start, end, blackout)) else: return None
def get_menu(course, current): """ Returns the HTML of the menu used in the administration. ```current``` is the current page of section """ custom_renderer = get_template_renderer('templates/') default_entries = [] if User.get_username() in course.get_admins(): default_entries += [("settings", "<i class='fa fa-cog fa-fw'></i> Course settings"), ("batch", "<i class='fa fa-rocket fa-fw'></i> Batch operations")] default_entries += [("students", "<i class='fa " + ("fa-group" if course.is_group_course() else "fa-user") + " fa-fw'></i> " + ("Groups" if course.is_group_course() else "Students"))] default_entries += [("tasks", "<i class='fa fa-tasks fa-fw'></i> Tasks")] # Hook should return a tuple (link,name) where link is the relative link from the index of the course administration. additionnal_entries = [entry for entry in PluginManager.get_instance().call_hook('course_admin_menu', course=course) if entry is not None] return custom_renderer.course_admin.menu(course, default_entries + additionnal_entries, current)
def show_tab_file(self, courseid, taskid, _error=False): """ Return the file tab """ return get_template_renderer('templates/').course_admin.edit_tabs.files(FrontendCourse(courseid), taskid, self.get_task_filelist(courseid, taskid))
def show_input(self): """ Show MatchProblem """ return str(get_template_renderer("templates/tasks/").match(self.get_id()))
def GET(self, courseid): # try: course = FrontendCourse(courseid) contest_data = get_contest_data(course) if not contest_data['enabled']: raise web.notfound() start = datetime.strptime(contest_data['start'], "%Y-%m-%d %H:%M:%S") end = datetime.strptime(contest_data['end'], "%Y-%m-%d %H:%M:%S") blackout = end - timedelta(hours=contest_data['blackout']) users = course.get_registered_users(True) tasks = course.get_tasks().keys() db_results = get_database().submissions.find({ "username": {"$in": users}, "courseid": courseid, "submitted_on": {"$gte": start, "$lt": blackout}, "status": "done"}, {"username": True, "_id": False, "taskid": True, "result": True, "submitted_on": True}).sort([("submitted_on", pymongo.ASCENDING)]) task_status = {taskid: {"status": "NA", "tries": 0} for taskid in tasks} results = {username: {"name": UserData(username).get_data()['realname'], "tasks": copy.deepcopy(task_status)} for username in users} activity = [] # Compute stats for each submission task_succeeded = {taskid: False for taskid in tasks} for submission in db_results: if submission['taskid'] not in tasks: continue if submission['username'] not in users: continue status = results[submission['username']]["tasks"][submission['taskid']] if status["status"] == "AC" or status["status"] == "ACF": continue else: if submission['result'] == "success": if not task_succeeded[submission['taskid']]: status["status"] = "ACF" task_succeeded[submission['taskid']] = True else: status["status"] = "AC" status["tries"] += 1 status["time"] = submission['submitted_on'] status["score"] = ((submission['submitted_on'] + ( timedelta(minutes=contest_data["penalty"]) * (status["tries"] - 1))) - start).total_seconds() / 60 elif submission['result'] == "failed": status["status"] = "WA" status["tries"] += 1 elif submission['result'] == "timeout": status["status"] = "TLE" status["tries"] += 1 else: # other internal error continue activity.append({"user": results[submission['username']]["name"], "when": submission['submitted_on'], "result": (status["status"] == 'AC' or status["status"] == 'ACF'), "taskid": submission['taskid']}) activity.reverse() # Compute current score for user in results: score = [0, 0] for data in results[user]["tasks"].values(): if "score" in data: score[0] += 1 score[1] += data["score"] results[user]["score"] = tuple(score) # Sort everybody results = OrderedDict(sorted(results.items(), key=lambda t: (-t[1]["score"][0], t[1]["score"][1]))) # Compute ranking old = None current_rank = 0 for cid, user in enumerate(results.keys()): if results[user]["score"] != old: old = results[user]["score"] current_rank = cid + 1 results[user]["rank"] = current_rank results[user]["displayed_rank"] = str(current_rank) else: results[user]["rank"] = current_rank results[user]["displayed_rank"] = "" return get_template_renderer('plugins/contests', '../../templates/layout').scoreboard(course, start, end, blackout, tasks, results, activity)
def GET(self, courseid): """ GET request: simply display the form """ course, _ = get_course_and_check_rights(courseid, allow_all_staff=False) contest_data = get_contest_data(course) return get_template_renderer('plugins/contests', '../../templates/layout').admin(course, contest_data, None, False)
def show(self): """ Show MultilineBox """ return str(get_template_renderer('templates/tasks/').box_multiline(self.get_complete_id(), self._lines, self._max_chars, self._language))
def show(self): """ Show InputBox """ return str(get_template_renderer('templates/tasks/').box_input(self.get_complete_id(), self._input_type, self._max_chars))
def show(self): """ Show FileBox """ return str(get_template_renderer('templates/tasks/').box_file(self.get_complete_id(), self._max_size, self._allowed_exts, json))
def show(self): """ Show TextBox """ return str(get_template_renderer('templates/tasks/').box_text(self._content))