Example #1
0
    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))
Example #2
0
    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)
Example #3
0
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)
Example #4
0
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
Example #5
0
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>&nbsp; Course settings"),
                            ("batch", "<i class='fa fa-rocket fa-fw'></i>&nbsp; Batch operations")]

    default_entries += [("students", "<i class='fa " + ("fa-group" if course.is_group_course() else "fa-user")
                         + " fa-fw'></i>&nbsp; " + ("Groups" if course.is_group_course() else "Students"))]

    default_entries += [("tasks", "<i class='fa fa-tasks fa-fw'></i>&nbsp; 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)
Example #6
0
 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))
Example #7
0
 def show_input(self):
     """ Show MatchProblem """
     return str(get_template_renderer("templates/tasks/").match(self.get_id()))
Example #8
0
    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)
Example #9
0
 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)
Example #10
0
 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))
Example #11
0
 def show(self):
     """ Show InputBox """
     return str(get_template_renderer('templates/tasks/').box_input(self.get_complete_id(), self._input_type, self._max_chars))
Example #12
0
 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))
Example #13
0
 def show(self):
     """ Show TextBox """
     return str(get_template_renderer('templates/tasks/').box_text(self._content))