Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Several small-ish things coming from the IOI #483

Merged
merged 5 commits into from
Nov 29, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cms/db/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@

# Instantiate or import these objects.

version = 16
version = 18


engine = create_engine(config.database, echo=config.database_debug,
Expand Down
10 changes: 9 additions & 1 deletion cms/db/contest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Contest Management System - http://cms-dev.github.io/
# Copyright © 2010-2012 Giovanni Mascellani <mascellani@poisson.phc.unipi.it>
# Copyright © 2010-2013 Stefano Maggiolo <s.maggiolo@gmail.com>
# Copyright © 2010-2015 Stefano Maggiolo <s.maggiolo@gmail.com>
# Copyright © 2010-2012 Matteo Boscariol <boscarim@hotmail.com>
# Copyright © 2012-2014 Luca Wehrstedt <luca.wehrstedt@gmail.com>
# Copyright © 2013 Bernard Blackham <bernard@largestprime.net>
Expand Down Expand Up @@ -88,6 +88,14 @@ class Contest(Base):
nullable=False,
default=True)

# Whether to automatically log in users connecting from an IP
# address specified in the ip field of a participation to this
# contest.
ip_autologin = Column(
Boolean,
nullable=False,
default=False)

# The parameters that control contest-tokens follow. Note that
# their effect during the contest depends on the interaction with
# the parameters that control task-tokens, defined on each Task.
Expand Down
2 changes: 2 additions & 0 deletions cms/server/admin/handlers/contest.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def post(self):
attrs["languages"] = self.get_arguments("languages")

self.get_bool(attrs, "submissions_download_allowed")
self.get_bool(attrs, "ip_autologin")

self.get_string(attrs, "token_mode")
self.get_int(attrs, "token_max_number")
Expand Down Expand Up @@ -127,6 +128,7 @@ def post(self, contest_id):
attrs["languages"] = self.get_arguments("languages")

self.get_bool(attrs, "submissions_download_allowed")
self.get_bool(attrs, "ip_autologin")

self.get_string(attrs, "token_mode")
self.get_int(attrs, "token_max_number")
Expand Down
6 changes: 6 additions & 0 deletions cms/server/admin/templates/contest.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ <h1>Contest information</h1>
<input type="checkbox" id="submissions_download_allowed" name="submissions_download_allowed" {{ "checked" if contest.submissions_download_allowed else "" }}/>
</td>
</tr>
<tr>
<td><label for="ip_autologin">IP based autologin</label></td>
<td>
<input type="checkbox" id="ip_autologin" name="ip_autologin" {{ "checked" if contest.ip_autologin else "" }}/>
</td>
</tr>
<tr>
<td>Token mode</td>
<td>
Expand Down
18 changes: 12 additions & 6 deletions cms/server/admin/templates/submission.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
{% from cms.grading.scoretypes import get_score_type %}
{% set st = get_score_type(dataset=shown_dataset) %}
{% set sr = s.get_result(shown_dataset) %}
{% set status = SubmissionResult.COMPILING %}
{% if sr is not None %}
{% set status = sr.get_status() %}
{% end %}
<div class="core_title">
<h1>Submission {{ s.id }} (Task: <a href="{{ url_root }}/task/{{ s.task.id }}">{{ s.task.name }}</a>)</h1>
</div>
Expand Down Expand Up @@ -62,21 +66,23 @@ <h2 id="title_details" class="toggling_on">Submission details</h2>
<tr>
<td>Status</td>
<td id="submission_status">
{% if sr is None or sr.compilation_outcome is None %}
{% if status == SubmissionResult.COMPILING %}
Compiling...
{% elif sr.compilation_outcome == "fail" %}
{% elif status == SubmissionResult.COMPILATION_FAILED %}
Compilation failed
{% elif not sr.evaluated() %}
{% elif status == SubmissionResult.EVALUATING %}
Evaluating...
{% elif sr.scored() %}
{% elif status == SubmissionResult.SCORING %}
Scoring...
{% elif status == SubmissionResult.SCORED %}
{% try %}
{% set max_score = st.max_score %}
{% except %}
{% set max_score = "[Cannot get score type - see logs]" %}
{% end %}
Evaluated ({{ sr.score }} / {{ max_score }})
Scored ({{ sr.score }} / {{ max_score }})
{% else %}
Evaluated
N/A
{% end %}
</td>
</tr>
Expand Down
18 changes: 18 additions & 0 deletions cms/server/contest/handlers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,24 @@ def get_current_user(self):
current contest), return None.

"""
remote_ip = self.request.remote_ip
if self.contest.ip_autologin:
self.clear_cookie("login")
participations = self.sql_session.query(Participation)\
.filter(Participation.contest == self.contest)\
.filter(Participation.ip == remote_ip)\
.all()
if len(participations) == 1:
return participations[0]

if len(participations) > 1:
logger.error("Multiple users have IP %s." % (remote_ip))
else:
logger.error("No user has IP %s" % (remote_ip))

# If IP autologin is set, we do not allow password logins.
return None

if self.get_secure_cookie("login") is None:
return None

Expand Down
2 changes: 1 addition & 1 deletion cmscontrib/AddTask.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@
from cms.db import Contest, SessionGen, Task
from cms.db.filecacher import FileCacher

from cmscontrib import BaseImporter
from cmscontrib.loaders import choose_loader, build_epilog

from . import BaseImporter

logger = logging.getLogger(__name__)

Expand Down
41 changes: 41 additions & 0 deletions cmscontrib/updaters/update_18.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-

# Contest Management System - http://cms-dev.github.io/
# Copyright © 2015 Stefano Maggiolo <s.maggiolo@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""A class to update a dump created by CMS.

Used by ContestImporter and DumpUpdater.

This updater is no-op as the new field (ip_autologin) has a proper
default value.

"""

from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function


class Updater(object):

def __init__(self, data):
assert data["_version"] == 17
self.objs = data

def run(self):
return self.objs
20 changes: 18 additions & 2 deletions cmsranking/static/Overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ var Overview = new function () {

self.MARKER_PADDING = 2;
self.MARKER_RADIUS = 2.5;
self.MARKER_LABEL_WIDTH = 30;
self.MARKER_LABEL_WIDTH = 50;
self.MARKER_LABEL_HEIGHT = 20;
self.MARKER_ARROW_WIDTH = 20;
self.MARKER_STROKE_WIDTH = 2;
Expand Down Expand Up @@ -346,7 +346,7 @@ var Overview = new function () {
// Place the text inside the label, with a padding-right equal to its
// padding-top and padding-bottom.
var t_x = self.width - self.PAD_R - self.MARKER_ARROW_WIDTH - (self.MARKER_LABEL_HEIGHT - 12) / 2;
self.paper.text(t_x, u_h, user["key"]).attr({
self.paper.text(t_x, u_h, self.transform_key(user)).attr({
"fill": "#ffffff",
"stroke": "none",
"font-family": "sans-serif",
Expand All @@ -368,6 +368,22 @@ var Overview = new function () {
set.animate(user["marker_c_anim"]);
};

self.transform_key = function(user) {
var s = user['f_name'] + ' ' + user['l_name'];
var sl = s.split(' ');
var out = '';
for (var i = 0; i < sl.length; i++) {
if (sl[i].length > 0) {
out += sl[i][0];
}
}
if (user["team"] != null && user["team"] != undefined) {
return user['team'] + '-' + out;
} else {
return out;
}
};


self.update_marker = function (user, s_h, u_h, r_h, t) {
var d = self.make_path_for_marker(s_h, u_h, r_h);
Expand Down
2 changes: 1 addition & 1 deletion cmsranking/static/Ranking.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ abbr {
position: absolute;
left: 0;
top: 208px;
bottom: 24px;
bottom: 30px;
width: 220px;
border-width: 2px 2px 2px 0;
border-style: solid;
Expand Down
3 changes: 3 additions & 0 deletions cmsranking/static/Ranking.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
</div>
<div id="SidePanel">
<div id="Overview"></div>
<div style="color: #999; text-align: center; font-size: 12px; padding-top: 5px;">
Powered by <a style="color: #00A3DA; text-decoration: none;" href="https://cms-dev.github.io/" target="_blank">CMS</a>
</div>
</div>
<div id="InnerFrame">
<table id="Scoreboard">
Expand Down
6 changes: 3 additions & 3 deletions cmstestsuite/Test.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ def check(self, *args, **kwargs):

class CheckOverallScore(Check):
# This check searches for a string such :
# Evaluated (100.0 / 100.0)
# Scored (100.0 / 100.0)
# in status and checks the score.

score_re = re.compile(r'^Evaluated \(([0-9.]+) / ([0-9/.]+)\)')
score_re = re.compile(r'^Scored \(([0-9.]+) / ([0-9/.]+)\)')

def __init__(self, expected_score, expected_total):
self.expected_score = expected_score
Expand Down Expand Up @@ -83,7 +83,7 @@ def __init__(self, short_adjective, failure_string):
self.failure_string = failure_string

def check(self, result_info):
if 'Evaluated' not in result_info['status']:
if 'Scored' not in result_info['status']:
raise TestFailure("Expected a successful evaluation, got: %s" %
result_info['status'])
if not result_info['evaluations']:
Expand Down