diff --git a/cms/db/contest.py b/cms/db/contest.py
index c8aba842cc..05b59a1b03 100644
--- a/cms/db/contest.py
+++ b/cms/db/contest.py
@@ -219,6 +219,9 @@ class Contest(Base):
CheckConstraint("min_user_test_interval > '0 seconds'"),
nullable=True)
+ # Time after which the minimum interval restriction for submissions is lifted
+ restricted_time = Column(Interval, nullable=True)
+
# The scores for this contest will be rounded to this number of
# decimal places.
score_precision = Column(
diff --git a/cms/server/admin/handlers/contest.py b/cms/server/admin/handlers/contest.py
index f2da7631be..0d823d6eb5 100644
--- a/cms/server/admin/handlers/contest.py
+++ b/cms/server/admin/handlers/contest.py
@@ -121,6 +121,7 @@ def post(self, contest_id):
self.get_int(attrs, "max_user_test_number")
self.get_timedelta_sec(attrs, "min_submission_interval")
self.get_timedelta_sec(attrs, "min_user_test_interval")
+ self.get_timedelta_sec(attrs, "restricted_time")
self.get_string(attrs, "timezone", empty=None)
self.get_int(attrs, "score_precision")
diff --git a/cms/server/admin/templates/contest.html b/cms/server/admin/templates/contest.html
index d78d3a9106..2383bcbf33 100644
--- a/cms/server/admin/templates/contest.html
+++ b/cms/server/admin/templates/contest.html
@@ -251,6 +251,15 @@
{% trans %}Testing{% endtrans %}
diff --git a/cms/server/contest/templates/macro/submission.html b/cms/server/contest/templates/macro/submission.html
index 0059b03e6e..d1d3147c1c 100644
--- a/cms/server/contest/templates/macro/submission.html
+++ b/cms/server/contest/templates/macro/submission.html
@@ -53,7 +53,7 @@
{% set num_cols = num_cols + 1 %}
{% endif %}
-{% if can_use_tokens and actual_phase == 0 %}
+{% if can_use_tokens and actual_phase == 0 or actual_phase == 0.5%}
{% set num_cols = num_cols + 1 %}
{% endif %}
@@ -78,7 +78,7 @@
{% if submissions_download_allowed %}
{% trans %}Files{% endtrans %} |
{% endif %}
-{% if can_use_tokens and actual_phase == 0 %}
+{% if can_use_tokens and (actual_phase == 0 or actual_phase == 0.5) %}
{% trans %}Token{% endtrans %} |
{% endif %}
@@ -255,7 +255,7 @@
{% endif %}
{% endif %}
-{% if can_use_tokens and actual_phase == 0 %}
+{% if can_use_tokens and (actual_phase == 0 or actual_phase == 0.5) %}
{% if s.token is not none %}
{% trans %}Played{% endtrans %}
diff --git a/cms/server/contest/templates/overview.html b/cms/server/contest/templates/overview.html
index cf7cfc4163..86574f628e 100644
--- a/cms/server/contest/templates/overview.html
+++ b/cms/server/contest/templates/overview.html
@@ -146,7 +146,7 @@ {% trans %}General information{% endtrans %}
{% elif actual_phase == -1 %}
{% trans %}By clicking on the button below you can start your time frame.{% endtrans %}
{%+ trans %}Once you start, you can submit solutions until the end of the time frame or until the end of the contest, whatever comes first.{% endtrans %}
- {% elif actual_phase == 0 %}
+ {% elif actual_phase == 0 or actual_phase == 0.5 %}
{% trans start_time=participation.starting_time|format_datetime_smart %}You started your time frame at {{ start_time }}.{% endtrans %}
{%+ trans %}You can submit solutions until the end of the time frame or until the end of the contest, whatever comes first.{% endtrans %}
{% elif actual_phase == +1 %}
@@ -179,7 +179,7 @@ {% trans %}General information{% endtrans %}
-{% if actual_phase == 0 or actual_phase == 3%}
+{% if actual_phase == 0 or actual_phase == 0.5 or actual_phase == 3%}
{% trans %}Task overview{% endtrans %}
diff --git a/cms/server/contest/templates/task_submissions.html b/cms/server/contest/templates/task_submissions.html
index acf77d139e..7e3c967b7f 100644
--- a/cms/server/contest/templates/task_submissions.html
+++ b/cms/server/contest/templates/task_submissions.html
@@ -17,7 +17,7 @@
{# Whether the user has a token to play (maybe after waiting some time). #}
{% set can_play_token =
can_use_tokens
- and actual_phase == 0
+ and (actual_phase == 0 or actual_phase == 0.5)
and (tokens_info[0] > 0 or tokens_info[0] == -1) %}
{# Whether the user can play a token right now (only meaningful when
can_play_token = true). #}
@@ -316,7 +316,7 @@ {% trans %}Submit a solution{% endtrans %}
{% trans %}Previous submissions{% endtrans %}
-{% if can_use_tokens_in_contest and actual_phase == 0 %}
+{% if can_use_tokens_in_contest and (actual_phase == 0 or actual_phase == 0.5) %}
{% if score_type.feedback() in ["full", "partial", "no"] %}
{% elif not can_use_tokens %}
@@ -343,7 +343,7 @@ {% trans %}Previous submissions{% endtrans %}0 restrictions are active until start + restricted_time
+ """
+ self.restricted_time = restricted_time
+
def short_path(self, f):
"""
Return a (possibly) shorter name for a file (which can be relative
@@ -566,7 +581,8 @@ def _makecontest(self):
cdb.min_submission_interval = self.min_submission_interval
cdb.max_user_test_number = self.max_user_test_number
cdb.min_user_test_interval = self.min_user_test_interval
-
+ cdb.restricted_time = self.restricted_time
+
self.usersdb = {}
self.participationsdb = {}
diff --git a/cmscontrib/loaders/italy_yaml.py b/cmscontrib/loaders/italy_yaml.py
index 9243d951b9..b0372d1786 100644
--- a/cmscontrib/loaders/italy_yaml.py
+++ b/cmscontrib/loaders/italy_yaml.py
@@ -216,6 +216,7 @@ def get_contest(self):
load(conf, args, "max_user_test_number")
load(conf, args, "min_submission_interval", conv=make_timedelta)
load(conf, args, "min_user_test_interval", conv=make_timedelta)
+ load(conf, args, "restricted_time", conv=make__timedelta)
tasks = load(conf, None, ["tasks", "problemi"])
participations = load(conf, None, ["users", "utenti"])
diff --git a/cmscontrib/loaders/tps.py b/cmscontrib/loaders/tps.py
index 1eb2e68a87..cec588012a 100644
--- a/cmscontrib/loaders/tps.py
+++ b/cmscontrib/loaders/tps.py
@@ -205,6 +205,7 @@ def get_task(self, get_statement=True):
args['min_submission_interval'] = make_timedelta(60)
args['min_user_test_interval'] = make_timedelta(60)
+ args['restricted_time'] = make_timedelta(-60*15)
task = Task(**args)
diff --git a/cmscontrib/updaters/update_45.sql b/cmscontrib/updaters/update_45.sql
new file mode 100644
index 0000000000..5257063876
--- /dev/null
+++ b/cmscontrib/updaters/update_45.sql
@@ -0,0 +1,5 @@
+begin;
+
+alter table contests add restricted_time varchar;
+
+rollback; -- change this to: commit;
diff --git a/cmstestsuite/unit_tests/server/contest/phase_management_test.py b/cmstestsuite/unit_tests/server/contest/phase_management_test.py
index 34e642e0f6..6e08c6672c 100755
--- a/cmstestsuite/unit_tests/server/contest/phase_management_test.py
+++ b/cmstestsuite/unit_tests/server/contest/phase_management_test.py
@@ -59,7 +59,7 @@ def parse_timedelta(value):
def test(contest_start, contest_stop, analysis_start, analysis_end,
- per_user_time, starting_time, delay_time, extra_time, intervals):
+ per_user_time, starting_time, restricted_time, delay_time, extra_time, intervals):
"""Helper to test compute_actual_phase.
It takes all the parameters accepted by compute_actual_phase (with
@@ -87,6 +87,7 @@ def test(contest_start, contest_stop, analysis_start, analysis_end,
user; contest is USACO-like if given and traditional if not.
starting_time (string|None): when the user started their time
frame.
+ restricted_time (string|None): the time the submission interval-restriction is active
delay_time (string): how much the user's start is delayed.
extra_time (string): how much extra time is given to the user at
the end.
@@ -102,6 +103,7 @@ def test(contest_start, contest_stop, analysis_start, analysis_end,
analysis_end = parse_datetime(analysis_end)
per_user_time = parse_timedelta(per_user_time)
starting_time = parse_datetime(starting_time)
+ restricted_time = parse_timedelta(restricted_time)
delay_time = parse_timedelta(delay_time)
extra_time = parse_timedelta(extra_time)
@@ -127,7 +129,7 @@ def test(contest_start, contest_stop, analysis_start, analysis_end,
res = compute_actual_phase(
end - step, contest_start, contest_stop,
analysis_start, analysis_end,
- per_user_time, starting_time, delay_time, extra_time)
+ per_user_time, starting_time, restricted_time, delay_time, extra_time)
assert res == (status, begin, end, valid_begin, valid_end), \
"Check on %s returned %s instead of %s" % (
end - step, res, (status, begin, end,
@@ -137,7 +139,7 @@ def test(contest_start, contest_stop, analysis_start, analysis_end,
res = compute_actual_phase(
begin + step, contest_start, contest_stop,
analysis_start, analysis_end,
- per_user_time, starting_time, delay_time, extra_time)
+ per_user_time, starting_time, restricted_time, delay_time, extra_time)
assert res == (status, begin, end, valid_begin, valid_end), \
"Check on %s returned %s instead of %s" % (
begin + step, res, (status, begin, end,
@@ -149,7 +151,7 @@ def test(contest_start, contest_stop, analysis_start, analysis_end,
res = compute_actual_phase(
begin + step, contest_start, contest_stop,
analysis_start, analysis_end,
- per_user_time, starting_time, delay_time, extra_time)
+ per_user_time, starting_time, restricted_time, delay_time, extra_time)
assert res == (status, begin, end, valid_begin, valid_end), \
"Check on %s returned %s instead of %s" % (
begin + step, res, (status, begin, end,
@@ -157,7 +159,7 @@ def test(contest_start, contest_stop, analysis_start, analysis_end,
res = compute_actual_phase(
end - step, contest_start, contest_stop,
analysis_start, analysis_end,
- per_user_time, starting_time, delay_time, extra_time)
+ per_user_time, starting_time, restricted_time, delay_time, extra_time)
assert res == (status, begin, end, valid_begin, valid_end), \
"Check on %s returned %s instead of %s" % (
end - step, res, (status, begin, end,
@@ -170,66 +172,88 @@ class TestComputeActualPhase(unittest.TestCase):
def test_traditional():
# Test "traditional" contests. There's not much variability, so
# we just test different delay_time/extra_time combinations.
- test("4", "12", None, None, None, None, "0", "0",
+ test("4", "12", None, None, None, None, None, "0", "0",
("4", 0, "12"))
- test("4", "12", None, None, None, None, "0", "2",
+ test("4", "12", None, None, None, None, None, "0", "2",
("4", 0, "14"))
- test("4", "12", None, None, None, None, "2", "0",
+ test("4", "12", None, None, None, None, None, "2", "0",
("4", -1, "6", 0, "14"))
- test("4", "12", None, None, None, None, "2", "2",
+ test("4", "12", None, None, None, None, None, "2", "2",
("4", -1, "6", 0, "16"))
- test("4", "8", None, None, None, None, "5", "0",
+ test("4", "8", None, None, None, None, None, "5", "0",
("4", -1, "9", 0, "13"))
# Almost identical, with starting_time set to make sure it
# doesn't affect anything.
- test("4", "12", None, None, None, "7", "0", "0",
+ test("4", "12", None, None, None, "7", None, "0", "0",
("4", 0, "12"))
- test("4", "12", None, None, None, "7", "0", "2",
+ test("4", "12", None, None, None, "7", None, "0", "2",
("4", 0, "14"))
- test("4", "12", None, None, None, "7", "2", "0",
+ test("4", "12", None, None, None, "7", None, "2", "0",
("4", -1, "6", 0, "14"))
- test("4", "12", None, None, None, "7", "2", "2",
+ test("4", "12", None, None, None, "7", None, "2", "2",
("4", -1, "6", 0, "16"))
- test("4", "8", None, None, None, "7", "5", "0",
+ test("4", "8", None, None, None, "7", None, "5", "0",
("4", -1, "9", 0, "13"))
+ # Almost identical, with restricted_time to test it
+ test("4", "12", None, None, None, "7", "6", "0", "0",
+ ("4", 0, "10", .5, "12"))
+ test("4", "12", None, None, None, "7", "6", "0", "2",
+ ("4", 0, "10", .5, "14"))
+ test("4", "12", None, None, None, "7", "6", "2", "0",
+ ("4", -1, "6", 0 ,"12", .5, "14"))
+ test("4", "12", None, None, None, "7", "6", "2", "2",
+ ("4", -1, "6", 0, "12", .5, "16"))
+ test("4", "8", None, None, None, "7", "6", "5", "0",
+ ("4", -1, "9", 0, "15", .5, "13"))
+ test("4", "12", None, None, None, "7", "-2", "0", "0",
+ ("4", 0, "10", .5, "12"))
+ test("4", "12", None, None, None, "7", "-4", "0", "2",
+ ("4", 0, "10", .5, "14"))
+ test("4", "12", None, None, None, "7", "-2", "2", "0",
+ ("4", -1, "6", 0 ,"12", .5, "14"))
+ test("4", "12", None, None, None, "7", "-4", "2", "2",
+ ("4", -1, "6", 0, "12", .5, "16"))
+ test("4", "8", None, None, None, "7", "-2", "5", "0",
+ ("4", -1, "9", 0, "15", .5, "13"))
+
# Test analysis mode. Almost identical to above
- test("4", "12", "17", "20", None, None, "0", "0",
+ test("4", "12", "17", "20", None, None, None, "0", "0",
("4", 0, "12", 2, "17", 3, "20"))
- test("4", "12", "17", "20", None, None, "0", "2",
+ test("4", "12", "17", "20", None, None, None, "0", "2",
("4", 0, "14", 2, "17", 3, "20"))
- test("4", "12", "17", "20", None, None, "2", "0",
+ test("4", "12", "17", "20", None, None, None, "2", "0",
("4", -1, "6", 0, "14", 2, "17", 3, "20"))
- test("4", "12", "17", "20", None, None, "2", "2",
+ test("4", "12", "17", "20", None, None, None, "2", "2",
("4", -1, "6", 0, "16", 2, "17", 3, "20"))
- test("4", "8", "17", "20", None, None, "5", "0",
+ test("4", "8", "17", "20", None, None, None, "5", "0",
("4", -1, "9", 0, "13", 2, "17", 3, "20"))
- test("4", "12", "17", "20", None, "7", "0", "0",
+ test("4", "12", "17", "20", None, "7", None, "0", "0",
("4", 0, "12", 2, "17", 3, "20"))
- test("4", "12", "17", "20", None, "7", "0", "2",
+ test("4", "12", "17", "20", None, "7", None, "0", "2",
("4", 0, "14", 2, "17", 3, "20"))
- test("4", "12", "17", "20", None, "7", "2", "0",
+ test("4", "12", "17", "20", None, "7", None, "2", "0",
("4", -1, "6", 0, "14", 2, "17", 3, "20"))
- test("4", "12", "17", "20", None, "7", "2", "2",
+ test("4", "12", "17", "20", None, "7", None, "2", "2",
("4", -1, "6", 0, "16", 2, "17", 3, "20"))
- test("4", "8", "17", "20", None, "7", "5", "0",
+ test("4", "8", "17", "20", None, "7", None, "5", "0",
("4", -1, "9", 0, "13", 2, "17", 3, "20"))
# Test for overlapping of contest and analysis for this user
- test("4", "12", "12", "20", None, None, "2", "0",
+ test("4", "12", "12", "20", None, None, None, "2", "0",
("4", -1, "6", 0, "14", 3, "20"))
- test("4", "12", "12", "20", None, None, "0", "2",
+ test("4", "12", "12", "20", None, None, None, "0", "2",
("4", 0, "14", 3, "20"))
- test("4", "12", "12", "20", None, None, "1", "1",
+ test("4", "12", "12", "20", None, None, None, "1", "1",
("4", -1, "5", 0, "14", 3, "20"))
- test("4", "8", "8", "12", None, None, "0", "5",
+ test("4", "8", "8", "12", None, None, None, "0", "5",
("4", 0, "13"))
- test("4", "8", "8", "12", None, None, "5", "0",
+ test("4", "8", "8", "12", None, None, None, "5", "0",
("4", -1, "9", 0, "13"))
- test("4", "8", "8", "12", None, None, "9", "0",
+ test("4", "8", "8", "12", None, None, None, "9", "0",
("4", -1, "13", 0, "17"))
- test("4", "8", "8", "16", None, None, "5", "1",
+ test("4", "8", "8", "16", None, None, None, "5", "1",
("4", -1, "9", 0, "14", 3, "16"))
@staticmethod
@@ -239,109 +263,109 @@ def test_usaco_like():
# contest time as well as cases where it oversteps the end and
# (absurdly) the start of the contest. Also try different
# delay_time/extra_time combinations.
- test("6", "18", None, None, "6", "9", "0", "0",
+ test("6", "18", None, None, "6", "9", None, "0", "0",
("6", -1, "9", 0, "15", +1, "18"))
- test("6", "18", None, None, "6", "3", "0", "0",
+ test("6", "18", None, None, "6", "3", None, "0", "0",
("6", 0, "9", +1, "18"))
- test("6", "18", None, None, "6", "15", "0", "0",
+ test("6", "18", None, None, "6", "15", None, "0", "0",
("6", -1, "15", 0, "18"))
- test("6", "18", None, None, "6", "9", "0", "1",
+ test("6", "18", None, None, "6", "9", None, "0", "1",
("6", -1, "9", 0, "16", +1, "18"))
- test("6", "18", None, None, "6", "3", "0", "1",
+ test("6", "18", None, None, "6", "3", None, "0", "1",
("6", 0, "10", +1, "18"))
- test("6", "18", None, None, "6", "15", "0", "1",
+ test("6", "18", None, None, "6", "15", None, "0", "1",
("6", -1, "15", 0, "19"))
- test("6", "18", None, None, "6", "9", "1", "0",
+ test("6", "18", None, None, "6", "9", None, "1", "0",
("6", -1, "10", 0, "16", +1, "18"))
- test("6", "18", None, None, "6", "3", "1", "0",
+ test("6", "18", None, None, "6", "3", None, "1", "0",
("6", -1, "7", 0, "10", +1, "18"))
- test("6", "18", None, None, "6", "15", "1", "0",
+ test("6", "18", None, None, "6", "15", None, "1", "0",
("6", -1, "16", 0, "19"))
- test("6", "18", None, None, "6", "9", "1", "1",
+ test("6", "18", None, None, "6", "9", None, "1", "1",
("6", -1, "10", 0, "17", +1, "18"))
- test("6", "18", None, None, "6", "3", "1", "1",
+ test("6", "18", None, None, "6", "3", None, "1", "1",
("6", -1, "7", 0, "11", +1, "18"))
- test("6", "18", None, None, "6", "15", "1", "1",
+ test("6", "18", None, None, "6", "15", None, "1", "1",
("6", -1, "16", 0, "20"))
# Test "USACO-like" contests, with unknown starting_time. Just
# make sure delay_time/extra_time don't affect anything.
- test("6", "18", None, None, "6", None, "0", "0",
+ test("6", "18", None, None, "6", None, None, "0", "0",
("6", -1, "18"))
- test("6", "18", None, None, "6", None, "0", "1",
+ test("6", "18", None, None, "6", None, None, "0", "1",
("6", -1, "18"))
- test("6", "18", None, None, "6", None, "1", "0",
+ test("6", "18", None, None, "6", None, None, "1", "0",
("6", -1, "18"))
- test("6", "18", None, None, "6", None, "1", "1",
+ test("6", "18", None, None, "6", None, None, "1", "1",
("6", -1, "18"))
# Test ridiculous corner cases.
- test("6", "18", None, None, "3", "2", "0", "0",
+ test("6", "18", None, None, "3", "2", None, "0", "0",
("6", 0, "6", +1, "18"))
- test("6", "18", None, None, "3", "2", "0", "1",
+ test("6", "18", None, None, "3", "2", None, "0", "1",
("6", 0, "7", +1, "18"))
- test("6", "18", None, None, "3", "2", "1", "0",
+ test("6", "18", None, None, "3", "2", None, "1", "0",
("6", -1, "7", 0, "7", +1, "18"))
- test("6", "18", None, None, "3", "2", "1", "1",
+ test("6", "18", None, None, "3", "2", None, "1", "1",
("6", -1, "7", 0, "8", +1, "18"))
- test("6", "18", None, None, "3", "19", "0", "0",
+ test("6", "18", None, None, "3", "19", None, "0", "0",
("6", -1, "18", 0, "18"))
- test("6", "18", None, None, "3", "19", "0", "1",
+ test("6", "18", None, None, "3", "19", None, "0", "1",
("6", -1, "18", 0, "19"))
# These are plainly absurd.
- test("6", "18", None, None, "3", "19", "1", "0",
+ test("6", "18", None, None, "3", "19", None, "1", "0",
("6", -1, "19", 0, "19"))
- test("6", "18", None, None, "3", "19", "1", "1",
+ test("6", "18", None, None, "3", "19", None, "1", "1",
("6", -1, "19", 0, "20"))
# Identical to above. just to check analysis mode.
- test("6", "18", "21", "23", "6", "9", "0", "0",
+ test("6", "18", "21", "23", "6", "9", None, "0", "0",
("6", -1, "9", 0, "15", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "3", "0", "0",
+ test("6", "18", "21", "23", "6", "3", None, "0", "0",
("6", 0, "9", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "15", "0", "0",
+ test("6", "18", "21", "23", "6", "15", None, "0", "0",
("6", -1, "15", 0, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "9", "0", "1",
+ test("6", "18", "21", "23", "6", "9", None, "0", "1",
("6", -1, "9", 0, "16", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "3", "0", "1",
+ test("6", "18", "21", "23", "6", "3", None, "0", "1",
("6", 0, "10", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "15", "0", "1",
+ test("6", "18", "21", "23", "6", "15", None, "0", "1",
("6", -1, "15", 0, "19", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "9", "1", "0",
+ test("6", "18", "21", "23", "6", "9", None, "1", "0",
("6", -1, "10", 0, "16", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "3", "1", "0",
+ test("6", "18", "21", "23", "6", "3", None, "1", "0",
("6", -1, "7", 0, "10", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "15", "1", "0",
+ test("6", "18", "21", "23", "6", "15", None, "1", "0",
("6", -1, "16", 0, "19", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "9", "1", "1",
+ test("6", "18", "21", "23", "6", "9", None, "1", "1",
("6", -1, "10", 0, "17", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "3", "1", "1",
+ test("6", "18", "21", "23", "6", "3", None, "1", "1",
("6", -1, "7", 0, "11", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", "15", "1", "1",
+ test("6", "18", "21", "23", "6", "15", None, "1", "1",
("6", -1, "16", 0, "20", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", None, "0", "0",
+ test("6", "18", "21", "23", "6", None, None, "0", "0",
("6", -1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", None, "0", "1",
+ test("6", "18", "21", "23", "6", None, None, "0", "1",
("6", -1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", None, "1", "0",
+ test("6", "18", "21", "23", "6", None, None, "1", "0",
("6", -1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "6", None, "1", "1",
+ test("6", "18", "21", "23", "6", None, None, "1", "1",
("6", -1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "3", "2", "0", "0",
+ test("6", "18", "21", "23", "3", "2", None, "0", "0",
("6", 0, "6", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "3", "2", "0", "1",
+ test("6", "18", "21", "23", "3", "2", None, "0", "1",
("6", 0, "7", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "3", "2", "1", "0",
+ test("6", "18", "21", "23", "3", "2", None, "1", "0",
("6", -1, "7", 0, "7", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "3", "2", "1", "1",
+ test("6", "18", "21", "23", "3", "2", None, "1", "1",
("6", -1, "7", 0, "8", +1, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "3", "19", "0", "0",
+ test("6", "18", "21", "23", "3", "19", None, "0", "0",
("6", -1, "18", 0, "18", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "3", "19", "0", "1",
+ test("6", "18", "21", "23", "3", "19", None, "0", "1",
("6", -1, "18", 0, "19", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "3", "19", "1", "0",
+ test("6", "18", "21", "23", "3", "19", None, "1", "0",
("6", -1, "19", 0, "19", 2, "21", 3, "23"))
- test("6", "18", "21", "23", "3", "19", "1", "1",
+ test("6", "18", "21", "23", "3", "19", None, "1", "1",
("6", -1, "19", 0, "20", 2, "21", 3, "23"))
diff --git a/docs/Configuring a contest.rst b/docs/Configuring a contest.rst
index 6858896992..03f25d39bc 100644
--- a/docs/Configuring a contest.rst
+++ b/docs/Configuring a contest.rst
@@ -25,6 +25,7 @@ The limits can be set both for individual tasks and for the whole contest. A sub
Each of these fields can be left unset to prevent the corresponding limitation from being enforced.
+You can set ``restricted_time`` to have the minimum interval restriction on submissions lifted after a certain time. If the field is left unset the restriction is never lifted, if it has a value of zero it is never active. If it is positive the restriction is lifted this much time in seconds after the contest starts, and if it is negative it is lifted this much time in seconds (as an absolute value) before the contest ends.`
Feedback to contestants
=======================
|