Reformat using black
This commit is contained in:
parent
efee4ad081
commit
a87fb49918
221 changed files with 19127 additions and 7310 deletions
File diff suppressed because one or more lines are too long
|
@ -7,33 +7,61 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0084_contest_formats'),
|
||||
("judge", "0084_contest_formats"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SubmissionSource',
|
||||
name="SubmissionSource",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('source', models.TextField(max_length=65536, verbose_name='source code')),
|
||||
('submission', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='link', to='judge.Submission', verbose_name='associated submission')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"source",
|
||||
models.TextField(max_length=65536, verbose_name="source code"),
|
||||
),
|
||||
(
|
||||
"submission",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="link",
|
||||
to="judge.Submission",
|
||||
verbose_name="associated submission",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.RunSQL(
|
||||
['''INSERT INTO judge_submissionsource (source, submission_id)
|
||||
SELECT source, id AS 'submission_id' FROM judge_submission;'''],
|
||||
['''UPDATE judge_submission sub
|
||||
[
|
||||
"""INSERT INTO judge_submissionsource (source, submission_id)
|
||||
SELECT source, id AS 'submission_id' FROM judge_submission;"""
|
||||
],
|
||||
[
|
||||
"""UPDATE judge_submission sub
|
||||
INNER JOIN judge_submissionsource src ON sub.id = src.submission_id
|
||||
SET sub.source = src.source;'''],
|
||||
SET sub.source = src.source;"""
|
||||
],
|
||||
elidable=True,
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='submission',
|
||||
name='source',
|
||||
model_name="submission",
|
||||
name="source",
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='submissionsource',
|
||||
name='submission',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='source', to='judge.Submission', verbose_name='associated submission'),
|
||||
model_name="submissionsource",
|
||||
name="submission",
|
||||
field=models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="source",
|
||||
to="judge.Submission",
|
||||
verbose_name="associated submission",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,18 +6,28 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0085_submission_source'),
|
||||
("judge", "0085_submission_source"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='rating_ceiling',
|
||||
field=models.IntegerField(blank=True, help_text='Rating ceiling for contest', null=True, verbose_name='rating ceiling'),
|
||||
model_name="contest",
|
||||
name="rating_ceiling",
|
||||
field=models.IntegerField(
|
||||
blank=True,
|
||||
help_text="Rating ceiling for contest",
|
||||
null=True,
|
||||
verbose_name="rating ceiling",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='rating_floor',
|
||||
field=models.IntegerField(blank=True, help_text='Rating floor for contest', null=True, verbose_name='rating floor'),
|
||||
model_name="contest",
|
||||
name="rating_floor",
|
||||
field=models.IntegerField(
|
||||
blank=True,
|
||||
help_text="Rating floor for contest",
|
||||
null=True,
|
||||
verbose_name="rating floor",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,18 +7,28 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0086_rating_ceiling'),
|
||||
("judge", "0086_rating_ceiling"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='problem',
|
||||
name='memory_limit',
|
||||
field=models.PositiveIntegerField(help_text='The memory limit for this problem, in kilobytes (e.g. 64mb = 65536 kilobytes).', verbose_name='memory limit'),
|
||||
model_name="problem",
|
||||
name="memory_limit",
|
||||
field=models.PositiveIntegerField(
|
||||
help_text="The memory limit for this problem, in kilobytes (e.g. 64mb = 65536 kilobytes).",
|
||||
verbose_name="memory limit",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problem',
|
||||
name='time_limit',
|
||||
field=models.FloatField(help_text='The time limit for this problem, in seconds. Fractional seconds (e.g. 1.5) are supported.', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(2000)], verbose_name='time limit'),
|
||||
model_name="problem",
|
||||
name="time_limit",
|
||||
field=models.FloatField(
|
||||
help_text="The time limit for this problem, in seconds. Fractional seconds (e.g. 1.5) are supported.",
|
||||
validators=[
|
||||
django.core.validators.MinValueValidator(0),
|
||||
django.core.validators.MaxValueValidator(2000),
|
||||
],
|
||||
verbose_name="time limit",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,32 +6,53 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0087_problem_resource_limits'),
|
||||
("judge", "0087_problem_resource_limits"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='contest',
|
||||
options={'permissions': (('see_private_contest', 'See private contests'), ('edit_own_contest', 'Edit own contests'), ('edit_all_contest', 'Edit all contests'), ('contest_rating', 'Rate contests'), ('contest_access_code', 'Contest access codes'), ('create_private_contest', 'Create private contests')), 'verbose_name': 'contest', 'verbose_name_plural': 'contests'},
|
||||
name="contest",
|
||||
options={
|
||||
"permissions": (
|
||||
("see_private_contest", "See private contests"),
|
||||
("edit_own_contest", "Edit own contests"),
|
||||
("edit_all_contest", "Edit all contests"),
|
||||
("contest_rating", "Rate contests"),
|
||||
("contest_access_code", "Contest access codes"),
|
||||
("create_private_contest", "Create private contests"),
|
||||
),
|
||||
"verbose_name": "contest",
|
||||
"verbose_name_plural": "contests",
|
||||
},
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='contest',
|
||||
old_name='is_public',
|
||||
new_name='is_visible',
|
||||
model_name="contest",
|
||||
old_name="is_public",
|
||||
new_name="is_visible",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='is_organization_private',
|
||||
field=models.BooleanField(default=False, verbose_name='private to organizations'),
|
||||
model_name="contest",
|
||||
name="is_organization_private",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="private to organizations"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='private_contestants',
|
||||
field=models.ManyToManyField(blank=True, help_text='If private, only these users may see the contest', related_name='_contest_private_contestants_+', to='judge.Profile', verbose_name='private contestants'),
|
||||
model_name="contest",
|
||||
name="private_contestants",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="If private, only these users may see the contest",
|
||||
related_name="_contest_private_contestants_+",
|
||||
to="judge.Profile",
|
||||
verbose_name="private contestants",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contest',
|
||||
name='is_private',
|
||||
field=models.BooleanField(default=False, verbose_name='private to specific users'),
|
||||
model_name="contest",
|
||||
name="is_private",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="private to specific users"
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,21 +7,31 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0088_private_contests'),
|
||||
("judge", "0088_private_contests"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='submission',
|
||||
name='contest_object',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='judge.Contest', verbose_name='contest'),
|
||||
model_name="submission",
|
||||
name="contest_object",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name="+",
|
||||
to="judge.Contest",
|
||||
verbose_name="contest",
|
||||
),
|
||||
),
|
||||
migrations.RunSQL('''
|
||||
migrations.RunSQL(
|
||||
"""
|
||||
UPDATE `judge_submission`
|
||||
INNER JOIN `judge_contestsubmission`
|
||||
ON (`judge_submission`.`id` = `judge_contestsubmission`.`submission_id`)
|
||||
INNER JOIN `judge_contestparticipation`
|
||||
ON (`judge_contestsubmission`.`participation_id` = `judge_contestparticipation`.`id`)
|
||||
SET `judge_submission`.`contest_object_id` = `judge_contestparticipation`.`contest_id`
|
||||
''', migrations.RunSQL.noop),
|
||||
""",
|
||||
migrations.RunSQL.noop,
|
||||
),
|
||||
]
|
||||
|
|
|
@ -4,16 +4,19 @@ from django.db import migrations
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0089_submission_to_contest'),
|
||||
("judge", "0089_submission_to_contest"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunSQL('''
|
||||
migrations.RunSQL(
|
||||
"""
|
||||
UPDATE `judge_contest`
|
||||
SET `judge_contest`.`is_private` = 0, `judge_contest`.`is_organization_private` = 1
|
||||
WHERE `judge_contest`.`is_private` = 1
|
||||
''', '''
|
||||
""",
|
||||
"""
|
||||
UPDATE `judge_contest`
|
||||
SET `judge_contest`.`is_private` = `judge_contest`.`is_organization_private`
|
||||
'''),
|
||||
""",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -5,17 +5,17 @@ from lxml.html.clean import clean_html
|
|||
|
||||
|
||||
def strip_error_html(apps, schema_editor):
|
||||
Submission = apps.get_model('judge', 'Submission')
|
||||
Submission = apps.get_model("judge", "Submission")
|
||||
for sub in Submission.objects.filter(error__isnull=False).iterator():
|
||||
if sub.error:
|
||||
sub.error = clean_html(lh.fromstring(sub.error)).text_content()
|
||||
sub.save(update_fields=['error'])
|
||||
sub.save(update_fields=["error"])
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0090_fix_contest_visibility'),
|
||||
("judge", "0090_fix_contest_visibility"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
|
|
@ -6,12 +6,24 @@ from django.db import migrations
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0091_compiler_message_ansi2html'),
|
||||
("judge", "0091_compiler_message_ansi2html"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='contest',
|
||||
options={'permissions': (('see_private_contest', 'See private contests'), ('edit_own_contest', 'Edit own contests'), ('edit_all_contest', 'Edit all contests'), ('clone_contest', 'Clone contest'), ('contest_rating', 'Rate contests'), ('contest_access_code', 'Contest access codes'), ('create_private_contest', 'Create private contests')), 'verbose_name': 'contest', 'verbose_name_plural': 'contests'},
|
||||
name="contest",
|
||||
options={
|
||||
"permissions": (
|
||||
("see_private_contest", "See private contests"),
|
||||
("edit_own_contest", "Edit own contests"),
|
||||
("edit_all_contest", "Edit all contests"),
|
||||
("clone_contest", "Clone contest"),
|
||||
("contest_rating", "Rate contests"),
|
||||
("contest_access_code", "Contest access codes"),
|
||||
("create_private_contest", "Create private contests"),
|
||||
),
|
||||
"verbose_name": "contest",
|
||||
"verbose_name_plural": "contests",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,39 +7,70 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0092_contest_clone'),
|
||||
("judge", "0092_contest_clone"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ContestMoss',
|
||||
name="ContestMoss",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('language', models.CharField(max_length=10)),
|
||||
('submission_count', models.PositiveIntegerField(default=0)),
|
||||
('url', models.URLField(blank=True, null=True)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("language", models.CharField(max_length=10)),
|
||||
("submission_count", models.PositiveIntegerField(default=0)),
|
||||
("url", models.URLField(blank=True, null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'contest moss result',
|
||||
'verbose_name_plural': 'contest moss results',
|
||||
"verbose_name": "contest moss result",
|
||||
"verbose_name_plural": "contest moss results",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='contest',
|
||||
options={'permissions': (('see_private_contest', 'See private contests'), ('edit_own_contest', 'Edit own contests'), ('edit_all_contest', 'Edit all contests'), ('clone_contest', 'Clone contest'), ('moss_contest', 'MOSS contest'), ('contest_rating', 'Rate contests'), ('contest_access_code', 'Contest access codes'), ('create_private_contest', 'Create private contests')), 'verbose_name': 'contest', 'verbose_name_plural': 'contests'},
|
||||
name="contest",
|
||||
options={
|
||||
"permissions": (
|
||||
("see_private_contest", "See private contests"),
|
||||
("edit_own_contest", "Edit own contests"),
|
||||
("edit_all_contest", "Edit all contests"),
|
||||
("clone_contest", "Clone contest"),
|
||||
("moss_contest", "MOSS contest"),
|
||||
("contest_rating", "Rate contests"),
|
||||
("contest_access_code", "Contest access codes"),
|
||||
("create_private_contest", "Create private contests"),
|
||||
),
|
||||
"verbose_name": "contest",
|
||||
"verbose_name_plural": "contests",
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contestmoss',
|
||||
name='contest',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='moss', to='judge.Contest', verbose_name='contest'),
|
||||
model_name="contestmoss",
|
||||
name="contest",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="moss",
|
||||
to="judge.Contest",
|
||||
verbose_name="contest",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contestmoss',
|
||||
name='problem',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='moss', to='judge.Problem', verbose_name='problem'),
|
||||
model_name="contestmoss",
|
||||
name="problem",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="moss",
|
||||
to="judge.Problem",
|
||||
verbose_name="problem",
|
||||
),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='contestmoss',
|
||||
unique_together={('contest', 'problem', 'language')},
|
||||
name="contestmoss",
|
||||
unique_together={("contest", "problem", "language")},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -3,12 +3,12 @@ from django.db import migrations
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('judge', '0093_contest_moss'),
|
||||
("judge", "0093_contest_moss"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name='submissiontestcase',
|
||||
unique_together={('submission', 'case')},
|
||||
name="submissiontestcase",
|
||||
unique_together={("submission", "case")},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,13 +6,19 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0094_submissiontestcase_unique_together'),
|
||||
("judge", "0094_submissiontestcase_unique_together"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='organization',
|
||||
name='logo_override_image',
|
||||
field=models.CharField(blank=True, default='', help_text='This image will replace the default site logo for users viewing the organization.', max_length=150, verbose_name='Logo override image'),
|
||||
model_name="organization",
|
||||
name="logo_override_image",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
help_text="This image will replace the default site logo for users viewing the organization.",
|
||||
max_length=150,
|
||||
verbose_name="Logo override image",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,21 +7,26 @@ import judge.models.runtime
|
|||
|
||||
|
||||
def create_python3(apps, schema_editor):
|
||||
Language = apps.get_model('judge', 'Language')
|
||||
Language.objects.get_or_create(key='PY3', defaults={'name': 'Python 3'})[0]
|
||||
Language = apps.get_model("judge", "Language")
|
||||
Language.objects.get_or_create(key="PY3", defaults={"name": "Python 3"})[0]
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0095_organization_logo_override'),
|
||||
("judge", "0095_organization_logo_override"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_python3, reverse_code=migrations.RunPython.noop),
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='language',
|
||||
field=models.ForeignKey(default=judge.models.runtime.Language.get_default_language_pk, on_delete=django.db.models.deletion.SET_DEFAULT, to='judge.Language', verbose_name='preferred language'),
|
||||
model_name="profile",
|
||||
name="language",
|
||||
field=models.ForeignKey(
|
||||
default=judge.models.runtime.Language.get_default_language_pk,
|
||||
on_delete=django.db.models.deletion.SET_DEFAULT,
|
||||
to="judge.Language",
|
||||
verbose_name="preferred language",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,18 +6,26 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0096_profile_language_set_default'),
|
||||
("judge", "0096_profile_language_set_default"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contestparticipation',
|
||||
name='is_disqualified',
|
||||
field=models.BooleanField(default=False, help_text='Whether this participation is disqualified.', verbose_name='is disqualified'),
|
||||
model_name="contestparticipation",
|
||||
name="is_disqualified",
|
||||
field=models.BooleanField(
|
||||
default=False,
|
||||
help_text="Whether this participation is disqualified.",
|
||||
verbose_name="is disqualified",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contestparticipation',
|
||||
name='virtual',
|
||||
field=models.IntegerField(default=0, help_text='0 means non-virtual, otherwise the n-th virtual participation.', verbose_name='virtual participation id'),
|
||||
model_name="contestparticipation",
|
||||
name="virtual",
|
||||
field=models.IntegerField(
|
||||
default=0,
|
||||
help_text="0 means non-virtual, otherwise the n-th virtual participation.",
|
||||
verbose_name="virtual participation id",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -8,23 +8,59 @@ import judge.utils.problem_data
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0098_auto_20200123_2136'),
|
||||
("judge", "0098_auto_20200123_2136"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='problemdata',
|
||||
name='custom_checker',
|
||||
field=models.FileField(blank=True, null=True, storage=judge.utils.problem_data.ProblemDataStorage(), upload_to=judge.models.problem_data.problem_directory_file, verbose_name='custom checker file'),
|
||||
model_name="problemdata",
|
||||
name="custom_checker",
|
||||
field=models.FileField(
|
||||
blank=True,
|
||||
null=True,
|
||||
storage=judge.utils.problem_data.ProblemDataStorage(),
|
||||
upload_to=judge.models.problem_data.problem_directory_file,
|
||||
verbose_name="custom checker file",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problemdata',
|
||||
name='checker',
|
||||
field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker')], max_length=10, verbose_name='checker'),
|
||||
model_name="problemdata",
|
||||
name="checker",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("standard", "Standard"),
|
||||
("floats", "Floats"),
|
||||
("floatsabs", "Floats (absolute)"),
|
||||
("floatsrel", "Floats (relative)"),
|
||||
("rstripped", "Non-trailing spaces"),
|
||||
("sorted", "Unordered"),
|
||||
("identical", "Byte identical"),
|
||||
("linecount", "Line-by-line"),
|
||||
("custom", "Custom checker"),
|
||||
],
|
||||
max_length=10,
|
||||
verbose_name="checker",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problemtestcase',
|
||||
name='checker',
|
||||
field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker')], max_length=10, verbose_name='checker'),
|
||||
model_name="problemtestcase",
|
||||
name="checker",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("standard", "Standard"),
|
||||
("floats", "Floats"),
|
||||
("floatsabs", "Floats (absolute)"),
|
||||
("floatsrel", "Floats (relative)"),
|
||||
("rstripped", "Non-trailing spaces"),
|
||||
("sorted", "Unordered"),
|
||||
("identical", "Byte identical"),
|
||||
("linecount", "Line-by-line"),
|
||||
("custom", "Custom checker"),
|
||||
],
|
||||
max_length=10,
|
||||
verbose_name="checker",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -9,13 +9,24 @@ import judge.utils.problem_data
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0099_custom_checker'),
|
||||
("judge", "0099_custom_checker"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='problemdata',
|
||||
name='custom_checker',
|
||||
field=models.FileField(blank=True, null=True, storage=judge.utils.problem_data.ProblemDataStorage(), upload_to=judge.models.problem_data.problem_directory_file, validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['py'])], verbose_name='custom checker file'),
|
||||
model_name="problemdata",
|
||||
name="custom_checker",
|
||||
field=models.FileField(
|
||||
blank=True,
|
||||
null=True,
|
||||
storage=judge.utils.problem_data.ProblemDataStorage(),
|
||||
upload_to=judge.models.problem_data.problem_directory_file,
|
||||
validators=[
|
||||
django.core.validators.FileExtensionValidator(
|
||||
allowed_extensions=["py"]
|
||||
)
|
||||
],
|
||||
verbose_name="custom checker file",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,18 +6,50 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0101_custom_validator'),
|
||||
("judge", "0101_custom_validator"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='problemdata',
|
||||
name='checker',
|
||||
field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker'), ('customval', 'Custom Validator')], max_length=10, verbose_name='checker'),
|
||||
model_name="problemdata",
|
||||
name="checker",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("standard", "Standard"),
|
||||
("floats", "Floats"),
|
||||
("floatsabs", "Floats (absolute)"),
|
||||
("floatsrel", "Floats (relative)"),
|
||||
("rstripped", "Non-trailing spaces"),
|
||||
("sorted", "Unordered"),
|
||||
("identical", "Byte identical"),
|
||||
("linecount", "Line-by-line"),
|
||||
("custom", "Custom checker"),
|
||||
("customval", "Custom Validator"),
|
||||
],
|
||||
max_length=10,
|
||||
verbose_name="checker",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problemtestcase',
|
||||
name='checker',
|
||||
field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker'), ('customval', 'Custom Validator')], max_length=10, verbose_name='checker'),
|
||||
model_name="problemtestcase",
|
||||
name="checker",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("standard", "Standard"),
|
||||
("floats", "Floats"),
|
||||
("floatsabs", "Floats (absolute)"),
|
||||
("floatsrel", "Floats (relative)"),
|
||||
("rstripped", "Non-trailing spaces"),
|
||||
("sorted", "Unordered"),
|
||||
("identical", "Byte identical"),
|
||||
("linecount", "Line-by-line"),
|
||||
("custom", "Custom checker"),
|
||||
("customval", "Custom Validator"),
|
||||
],
|
||||
max_length=10,
|
||||
verbose_name="checker",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,13 +6,13 @@ from django.db import migrations
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0102_fix_custom_validator'),
|
||||
("judge", "0102_fix_custom_validator"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='problemdata',
|
||||
old_name='custom_valid',
|
||||
new_name='custom_validator',
|
||||
model_name="problemdata",
|
||||
old_name="custom_valid",
|
||||
new_name="custom_validator",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,23 +6,57 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0103_fix_custom_validator'),
|
||||
("judge", "0103_fix_custom_validator"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contestproblem',
|
||||
name='output_prefix_override',
|
||||
field=models.IntegerField(blank=True, default=0, null=True, verbose_name='visible testcases'),
|
||||
model_name="contestproblem",
|
||||
name="output_prefix_override",
|
||||
field=models.IntegerField(
|
||||
blank=True, default=0, null=True, verbose_name="visible testcases"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problemdata',
|
||||
name='checker',
|
||||
field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker (PY)'), ('customval', 'Custom validator (CPP)')], max_length=10, verbose_name='checker'),
|
||||
model_name="problemdata",
|
||||
name="checker",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("standard", "Standard"),
|
||||
("floats", "Floats"),
|
||||
("floatsabs", "Floats (absolute)"),
|
||||
("floatsrel", "Floats (relative)"),
|
||||
("rstripped", "Non-trailing spaces"),
|
||||
("sorted", "Unordered"),
|
||||
("identical", "Byte identical"),
|
||||
("linecount", "Line-by-line"),
|
||||
("custom", "Custom checker (PY)"),
|
||||
("customval", "Custom validator (CPP)"),
|
||||
],
|
||||
max_length=10,
|
||||
verbose_name="checker",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problemtestcase',
|
||||
name='checker',
|
||||
field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker (PY)'), ('customval', 'Custom validator (CPP)')], max_length=10, verbose_name='checker'),
|
||||
model_name="problemtestcase",
|
||||
name="checker",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("standard", "Standard"),
|
||||
("floats", "Floats"),
|
||||
("floatsabs", "Floats (absolute)"),
|
||||
("floatsrel", "Floats (relative)"),
|
||||
("rstripped", "Non-trailing spaces"),
|
||||
("sorted", "Unordered"),
|
||||
("identical", "Byte identical"),
|
||||
("linecount", "Line-by-line"),
|
||||
("custom", "Custom checker (PY)"),
|
||||
("customval", "Custom validator (CPP)"),
|
||||
],
|
||||
max_length=10,
|
||||
verbose_name="checker",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,16 +7,31 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0105_auto_20200523_0756'),
|
||||
("judge", "0105_auto_20200523_0756"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Friend',
|
||||
name="Friend",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('current_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='following_users', to='judge.Profile')),
|
||||
('users', models.ManyToManyField(to='judge.Profile')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"current_user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="following_users",
|
||||
to="judge.Profile",
|
||||
),
|
||||
),
|
||||
("users", models.ManyToManyField(to="judge.Profile")),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,19 +7,45 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0106_friend'),
|
||||
("judge", "0106_friend"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Notification',
|
||||
name="Notification",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('time', models.DateTimeField(auto_now_add=True, verbose_name='posted time')),
|
||||
('read', models.BooleanField(default=False, verbose_name='read')),
|
||||
('category', models.CharField(max_length=10, verbose_name='category')),
|
||||
('comment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='judge.Comment', verbose_name='comment')),
|
||||
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to='judge.Profile', verbose_name='owner')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="posted time"),
|
||||
),
|
||||
("read", models.BooleanField(default=False, verbose_name="read")),
|
||||
("category", models.CharField(max_length=10, verbose_name="category")),
|
||||
(
|
||||
"comment",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="judge.Comment",
|
||||
verbose_name="comment",
|
||||
),
|
||||
),
|
||||
(
|
||||
"owner",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="notifications",
|
||||
to="judge.Profile",
|
||||
verbose_name="owner",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,13 +6,15 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0107_notification'),
|
||||
("judge", "0107_notification"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='submission',
|
||||
name='judged_date',
|
||||
field=models.DateTimeField(default=None, null=True, verbose_name='submission judge time'),
|
||||
model_name="submission",
|
||||
name="judged_date",
|
||||
field=models.DateTimeField(
|
||||
default=None, null=True, verbose_name="submission judge time"
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,18 +7,27 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0108_submission_judged_date'),
|
||||
("judge", "0108_submission_judged_date"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='html_link',
|
||||
field=models.TextField(default='', max_length=1000, verbose_name='html link to comments, used for non-comments'),
|
||||
model_name="notification",
|
||||
name="html_link",
|
||||
field=models.TextField(
|
||||
default="",
|
||||
max_length=1000,
|
||||
verbose_name="html link to comments, used for non-comments",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='notification',
|
||||
name='comment',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='judge.Comment', verbose_name='comment'),
|
||||
model_name="notification",
|
||||
name="comment",
|
||||
field=models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="judge.Comment",
|
||||
verbose_name="comment",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,13 +7,18 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0109_auto_20201017_1151'),
|
||||
("judge", "0109_auto_20201017_1151"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='author',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='judge.Profile', verbose_name='who trigger, used for non-comment'),
|
||||
model_name="notification",
|
||||
name="author",
|
||||
field=models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="judge.Profile",
|
||||
verbose_name="who trigger, used for non-comment",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,18 +7,26 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0110_notification_author'),
|
||||
("judge", "0110_notification_author"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='points_precision',
|
||||
field=models.IntegerField(default=2, help_text='Number of digits to round points to.', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(10)], verbose_name='precision points'),
|
||||
model_name="contest",
|
||||
name="points_precision",
|
||||
field=models.IntegerField(
|
||||
default=2,
|
||||
help_text="Number of digits to round points to.",
|
||||
validators=[
|
||||
django.core.validators.MinValueValidator(0),
|
||||
django.core.validators.MaxValueValidator(10),
|
||||
],
|
||||
verbose_name="precision points",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contestparticipation',
|
||||
name='score',
|
||||
field=models.FloatField(db_index=True, default=0, verbose_name='score'),
|
||||
model_name="contestparticipation",
|
||||
name="score",
|
||||
field=models.FloatField(db_index=True, default=0, verbose_name="score"),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,13 +6,19 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0111_contest_decimal_points'),
|
||||
("judge", "0111_contest_decimal_points"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='view_contest_scoreboard',
|
||||
field=models.ManyToManyField(blank=True, help_text='These users will be able to view the scoreboard.', related_name='view_contest_scoreboard', to='judge.Profile', verbose_name='view contest scoreboard'),
|
||||
model_name="contest",
|
||||
name="view_contest_scoreboard",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="These users will be able to view the scoreboard.",
|
||||
related_name="view_contest_scoreboard",
|
||||
to="judge.Profile",
|
||||
verbose_name="view contest scoreboard",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,12 +6,26 @@ from django.db import migrations
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0112_contest_view_contest_scoreboard'),
|
||||
("judge", "0112_contest_view_contest_scoreboard"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='contest',
|
||||
options={'permissions': (('see_private_contest', 'See private contests'), ('edit_own_contest', 'Edit own contests'), ('edit_all_contest', 'Edit all contests'), ('clone_contest', 'Clone contest'), ('moss_contest', 'MOSS contest'), ('contest_rating', 'Rate contests'), ('contest_access_code', 'Contest access codes'), ('create_private_contest', 'Create private contests'), ('change_contest_visibility', 'Change contest visibility')), 'verbose_name': 'contest', 'verbose_name_plural': 'contests'},
|
||||
name="contest",
|
||||
options={
|
||||
"permissions": (
|
||||
("see_private_contest", "See private contests"),
|
||||
("edit_own_contest", "Edit own contests"),
|
||||
("edit_all_contest", "Edit all contests"),
|
||||
("clone_contest", "Clone contest"),
|
||||
("moss_contest", "MOSS contest"),
|
||||
("contest_rating", "Rate contests"),
|
||||
("contest_access_code", "Contest access codes"),
|
||||
("create_private_contest", "Create private contests"),
|
||||
("change_contest_visibility", "Change contest visibility"),
|
||||
),
|
||||
"verbose_name": "contest",
|
||||
"verbose_name_plural": "contests",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,18 +6,25 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0113_auto_20201228_0911'),
|
||||
("judge", "0113_auto_20201228_0911"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='blogpost',
|
||||
name='is_organization_private',
|
||||
field=models.BooleanField(default=False, verbose_name='private to organizations'),
|
||||
model_name="blogpost",
|
||||
name="is_organization_private",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="private to organizations"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='blogpost',
|
||||
name='organizations',
|
||||
field=models.ManyToManyField(blank=True, help_text='If private, only these organizations may see the blog post.', to='judge.Organization', verbose_name='organizations'),
|
||||
model_name="blogpost",
|
||||
name="organizations",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="If private, only these organizations may see the blog post.",
|
||||
to="judge.Organization",
|
||||
verbose_name="organizations",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -2,62 +2,109 @@
|
|||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def hide_scoreboard_eq_true(apps, schema_editor):
|
||||
Contest = apps.get_model('judge', 'Contest')
|
||||
Contest.objects.filter(hide_scoreboard=True).update(scoreboard_visibility='C')
|
||||
Contest = apps.get_model("judge", "Contest")
|
||||
Contest.objects.filter(hide_scoreboard=True).update(scoreboard_visibility="C")
|
||||
|
||||
|
||||
def scoreboard_visibility_eq_contest(apps, schema_editor):
|
||||
Contest = apps.get_model('judge', 'Contest')
|
||||
Contest.objects.filter(scoreboard_visibility__in=('C', 'P')).update(hide_scoreboard=True)
|
||||
Contest = apps.get_model("judge", "Contest")
|
||||
Contest.objects.filter(scoreboard_visibility__in=("C", "P")).update(
|
||||
hide_scoreboard=True
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0114_auto_20201228_1041'),
|
||||
("judge", "0114_auto_20201228_1041"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='contest',
|
||||
options={'permissions': (('see_private_contest', 'See private contests'), ('edit_own_contest', 'Edit own contests'), ('edit_all_contest', 'Edit all contests'), ('clone_contest', 'Clone contest'), ('moss_contest', 'MOSS contest'), ('contest_rating', 'Rate contests'), ('contest_access_code', 'Contest access codes'), ('create_private_contest', 'Create private contests'), ('change_contest_visibility', 'Change contest visibility'), ('contest_problem_label', 'Edit contest problem label script')), 'verbose_name': 'contest', 'verbose_name_plural': 'contests'},
|
||||
name="contest",
|
||||
options={
|
||||
"permissions": (
|
||||
("see_private_contest", "See private contests"),
|
||||
("edit_own_contest", "Edit own contests"),
|
||||
("edit_all_contest", "Edit all contests"),
|
||||
("clone_contest", "Clone contest"),
|
||||
("moss_contest", "MOSS contest"),
|
||||
("contest_rating", "Rate contests"),
|
||||
("contest_access_code", "Contest access codes"),
|
||||
("create_private_contest", "Create private contests"),
|
||||
("change_contest_visibility", "Change contest visibility"),
|
||||
("contest_problem_label", "Edit contest problem label script"),
|
||||
),
|
||||
"verbose_name": "contest",
|
||||
"verbose_name_plural": "contests",
|
||||
},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='contest',
|
||||
name='hide_scoreboard',
|
||||
model_name="contest",
|
||||
name="hide_scoreboard",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='contest',
|
||||
name='organizers',
|
||||
model_name="contest",
|
||||
name="organizers",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='authors',
|
||||
field=models.ManyToManyField(help_text='These users will be able to edit the contest.', related_name='_contest_authors_+', to='judge.Profile'),
|
||||
model_name="contest",
|
||||
name="authors",
|
||||
field=models.ManyToManyField(
|
||||
help_text="These users will be able to edit the contest.",
|
||||
related_name="_contest_authors_+",
|
||||
to="judge.Profile",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='curators',
|
||||
field=models.ManyToManyField(blank=True, help_text='These users will be able to edit the contest, but will not be listed as authors.', related_name='_contest_curators_+', to='judge.Profile'),
|
||||
model_name="contest",
|
||||
name="curators",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="These users will be able to edit the contest, but will not be listed as authors.",
|
||||
related_name="_contest_curators_+",
|
||||
to="judge.Profile",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='problem_label_script',
|
||||
field=models.TextField(blank=True, help_text='A custom Lua function to generate problem labels. Requires a single function with an integer parameter, the zero-indexed contest problem index, and returns a string, the label.', verbose_name='contest problem label script'),
|
||||
model_name="contest",
|
||||
name="problem_label_script",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
help_text="A custom Lua function to generate problem labels. Requires a single function with an integer parameter, the zero-indexed contest problem index, and returns a string, the label.",
|
||||
verbose_name="contest problem label script",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='scoreboard_visibility',
|
||||
field=models.CharField(choices=[('V', 'Visible'), ('C', 'Hidden for duration of contest'), ('P', 'Hidden for duration of participation')], default='V', help_text='Scoreboard visibility through the duration of the contest', max_length=1, verbose_name='scoreboard visibility'),
|
||||
model_name="contest",
|
||||
name="scoreboard_visibility",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("V", "Visible"),
|
||||
("C", "Hidden for duration of contest"),
|
||||
("P", "Hidden for duration of participation"),
|
||||
],
|
||||
default="V",
|
||||
help_text="Scoreboard visibility through the duration of the contest",
|
||||
max_length=1,
|
||||
verbose_name="scoreboard visibility",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contest',
|
||||
name='testers',
|
||||
field=models.ManyToManyField(blank=True, help_text='These users will be able to view the contest, but not edit it.', related_name='_contest_testers_+', to='judge.Profile'),
|
||||
model_name="contest",
|
||||
name="testers",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="These users will be able to view the contest, but not edit it.",
|
||||
related_name="_contest_testers_+",
|
||||
to="judge.Profile",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contestparticipation',
|
||||
name='tiebreaker',
|
||||
field=models.FloatField(default=0.0, verbose_name='tie-breaking field'),
|
||||
model_name="contestparticipation",
|
||||
name="tiebreaker",
|
||||
field=models.FloatField(default=0.0, verbose_name="tie-breaking field"),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,13 +6,25 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0115_auto_20210525_0222'),
|
||||
("judge", "0115_auto_20210525_0222"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contest',
|
||||
name='format_name',
|
||||
field=models.CharField(choices=[('atcoder', 'AtCoder'), ('default', 'Default'), ('ecoo', 'ECOO'), ('icpc', 'ICPC'), ('ioi', 'IOI')], default='default', help_text='The contest format module to use.', max_length=32, verbose_name='contest format'),
|
||||
model_name="contest",
|
||||
name="format_name",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("atcoder", "AtCoder"),
|
||||
("default", "Default"),
|
||||
("ecoo", "ECOO"),
|
||||
("icpc", "ICPC"),
|
||||
("ioi", "IOI"),
|
||||
],
|
||||
default="default",
|
||||
help_text="The contest format module to use.",
|
||||
max_length=32,
|
||||
verbose_name="contest format",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,7 +7,7 @@ from django.db.models.functions import Coalesce
|
|||
from django.utils import timezone
|
||||
|
||||
|
||||
def tie_ranker(iterable, key=attrgetter('points')):
|
||||
def tie_ranker(iterable, key=attrgetter("points")):
|
||||
rank = 0
|
||||
delta = 1
|
||||
last = None
|
||||
|
@ -53,7 +53,9 @@ def WP(RA, RB, VA, VB):
|
|||
return (math.erf((RB - RA) / math.sqrt(2 * (VA * VA + VB * VB))) + 1) / 2.0
|
||||
|
||||
|
||||
def recalculate_ratings(old_rating, old_volatility, actual_rank, times_rated, is_disqualified):
|
||||
def recalculate_ratings(
|
||||
old_rating, old_volatility, actual_rank, times_rated, is_disqualified
|
||||
):
|
||||
# actual_rank: 1 is first place, N is last place
|
||||
# if there are ties, use the average of places (if places 2, 3, 4, 5 tie, use 3.5 for all of them)
|
||||
|
||||
|
@ -74,7 +76,9 @@ def recalculate_ratings(old_rating, old_volatility, actual_rank, times_rated, is
|
|||
for i in range(N):
|
||||
ERank = 0.5
|
||||
for j in range(N):
|
||||
ERank += WP(old_rating[i], old_rating[j], old_volatility[i], old_volatility[j])
|
||||
ERank += WP(
|
||||
old_rating[i], old_rating[j], old_volatility[i], old_volatility[j]
|
||||
)
|
||||
|
||||
EPerf = -normal_CDF_inverse((ERank - 0.5) / N)
|
||||
APerf = -normal_CDF_inverse((actual_rank[i] - 0.5) / N)
|
||||
|
@ -98,8 +102,10 @@ def recalculate_ratings(old_rating, old_volatility, actual_rank, times_rated, is
|
|||
if times_rated[i] == 0:
|
||||
new_volatility[i] = 385
|
||||
else:
|
||||
new_volatility[i] = math.sqrt(((new_rating[i] - old_rating[i]) ** 2) / Weight +
|
||||
(old_volatility[i] ** 2) / (Weight + 1))
|
||||
new_volatility[i] = math.sqrt(
|
||||
((new_rating[i] - old_rating[i]) ** 2) / Weight
|
||||
+ (old_volatility[i] ** 2) / (Weight + 1)
|
||||
)
|
||||
|
||||
if is_disqualified[i]:
|
||||
# DQed users can manipulate TopCoder ratings to get higher volatility in order to increase their rating
|
||||
|
@ -112,23 +118,49 @@ def recalculate_ratings(old_rating, old_volatility, actual_rank, times_rated, is
|
|||
# inflate a little if we have to so people who placed first don't lose rating
|
||||
best_rank = min(actual_rank)
|
||||
for i in range(N):
|
||||
if abs(actual_rank[i] - best_rank) <= 1e-3 and new_rating[i] < old_rating[i] + 1:
|
||||
if (
|
||||
abs(actual_rank[i] - best_rank) <= 1e-3
|
||||
and new_rating[i] < old_rating[i] + 1
|
||||
):
|
||||
new_rating[i] = old_rating[i] + 1
|
||||
return list(map(int, map(round, new_rating))), list(map(int, map(round, new_volatility)))
|
||||
return list(map(int, map(round, new_rating))), list(
|
||||
map(int, map(round, new_volatility))
|
||||
)
|
||||
|
||||
|
||||
def tc_rate_contest(contest, Rating, Profile):
|
||||
rating_subquery = Rating.objects.filter(user=OuterRef('user'))
|
||||
rating_sorted = rating_subquery.order_by('-contest__end_time')
|
||||
users = contest.users.order_by('is_disqualified', '-score', 'cumtime', 'tiebreaker') \
|
||||
.annotate(submissions=Count('submission'),
|
||||
last_rating=Coalesce(Subquery(rating_sorted.values('rating')[:1]), 1200),
|
||||
volatility=Coalesce(Subquery(rating_sorted.values('volatility')[:1]), 535),
|
||||
times=Coalesce(Subquery(rating_subquery.order_by().values('user_id')
|
||||
.annotate(count=Count('id')).values('count')), 0)) \
|
||||
.exclude(user_id__in=contest.rate_exclude.all()) \
|
||||
.filter(virtual=0).values('id', 'user_id', 'score', 'cumtime', 'tiebreaker', 'is_disqualified',
|
||||
'last_rating', 'volatility', 'times')
|
||||
rating_subquery = Rating.objects.filter(user=OuterRef("user"))
|
||||
rating_sorted = rating_subquery.order_by("-contest__end_time")
|
||||
users = (
|
||||
contest.users.order_by("is_disqualified", "-score", "cumtime", "tiebreaker")
|
||||
.annotate(
|
||||
submissions=Count("submission"),
|
||||
last_rating=Coalesce(Subquery(rating_sorted.values("rating")[:1]), 1200),
|
||||
volatility=Coalesce(Subquery(rating_sorted.values("volatility")[:1]), 535),
|
||||
times=Coalesce(
|
||||
Subquery(
|
||||
rating_subquery.order_by()
|
||||
.values("user_id")
|
||||
.annotate(count=Count("id"))
|
||||
.values("count")
|
||||
),
|
||||
0,
|
||||
),
|
||||
)
|
||||
.exclude(user_id__in=contest.rate_exclude.all())
|
||||
.filter(virtual=0)
|
||||
.values(
|
||||
"id",
|
||||
"user_id",
|
||||
"score",
|
||||
"cumtime",
|
||||
"tiebreaker",
|
||||
"is_disqualified",
|
||||
"last_rating",
|
||||
"volatility",
|
||||
"times",
|
||||
)
|
||||
)
|
||||
if not contest.rate_all:
|
||||
users = users.filter(submissions__gt=0)
|
||||
if contest.rating_floor is not None:
|
||||
|
@ -137,46 +169,68 @@ def tc_rate_contest(contest, Rating, Profile):
|
|||
users = users.exclude(last_rating__gt=contest.rating_ceiling)
|
||||
|
||||
users = list(users)
|
||||
participation_ids = list(map(itemgetter('id'), users))
|
||||
user_ids = list(map(itemgetter('user_id'), users))
|
||||
is_disqualified = list(map(itemgetter('is_disqualified'), users))
|
||||
ranking = list(tie_ranker(users, key=itemgetter('score', 'cumtime', 'tiebreaker')))
|
||||
old_rating = list(map(itemgetter('last_rating'), users))
|
||||
old_volatility = list(map(itemgetter('volatility'), users))
|
||||
times_ranked = list(map(itemgetter('times'), users))
|
||||
rating, volatility = recalculate_ratings(old_rating, old_volatility, ranking, times_ranked, is_disqualified)
|
||||
participation_ids = list(map(itemgetter("id"), users))
|
||||
user_ids = list(map(itemgetter("user_id"), users))
|
||||
is_disqualified = list(map(itemgetter("is_disqualified"), users))
|
||||
ranking = list(tie_ranker(users, key=itemgetter("score", "cumtime", "tiebreaker")))
|
||||
old_rating = list(map(itemgetter("last_rating"), users))
|
||||
old_volatility = list(map(itemgetter("volatility"), users))
|
||||
times_ranked = list(map(itemgetter("times"), users))
|
||||
rating, volatility = recalculate_ratings(
|
||||
old_rating, old_volatility, ranking, times_ranked, is_disqualified
|
||||
)
|
||||
|
||||
now = timezone.now()
|
||||
ratings = [Rating(user_id=i, contest=contest, rating=r, volatility=v, last_rated=now, participation_id=p, rank=z)
|
||||
for i, p, r, v, z in zip(user_ids, participation_ids, rating, volatility, ranking)]
|
||||
ratings = [
|
||||
Rating(
|
||||
user_id=i,
|
||||
contest=contest,
|
||||
rating=r,
|
||||
volatility=v,
|
||||
last_rated=now,
|
||||
participation_id=p,
|
||||
rank=z,
|
||||
)
|
||||
for i, p, r, v, z in zip(
|
||||
user_ids, participation_ids, rating, volatility, ranking
|
||||
)
|
||||
]
|
||||
|
||||
Rating.objects.bulk_create(ratings)
|
||||
|
||||
Profile.objects.filter(contest_history__contest=contest, contest_history__virtual=0).update(
|
||||
rating=Subquery(Rating.objects.filter(user=OuterRef('id'))
|
||||
.order_by('-contest__end_time').values('rating')[:1]))
|
||||
Profile.objects.filter(
|
||||
contest_history__contest=contest, contest_history__virtual=0
|
||||
).update(
|
||||
rating=Subquery(
|
||||
Rating.objects.filter(user=OuterRef("id"))
|
||||
.order_by("-contest__end_time")
|
||||
.values("rating")[:1]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# inspired by rate_all_view
|
||||
def rate_tc(apps, schema_editor):
|
||||
Contest = apps.get_model('judge', 'Contest')
|
||||
Rating = apps.get_model('judge', 'Rating')
|
||||
Profile = apps.get_model('judge', 'Profile')
|
||||
Contest = apps.get_model("judge", "Contest")
|
||||
Rating = apps.get_model("judge", "Rating")
|
||||
Profile = apps.get_model("judge", "Profile")
|
||||
|
||||
with schema_editor.connection.cursor() as cursor:
|
||||
cursor.execute('TRUNCATE TABLE `%s`' % Rating._meta.db_table)
|
||||
cursor.execute("TRUNCATE TABLE `%s`" % Rating._meta.db_table)
|
||||
Profile.objects.update(rating=None)
|
||||
for contest in Contest.objects.filter(is_rated=True, end_time__lte=timezone.now()).order_by('end_time'):
|
||||
for contest in Contest.objects.filter(
|
||||
is_rated=True, end_time__lte=timezone.now()
|
||||
).order_by("end_time"):
|
||||
tc_rate_contest(contest, Rating, Profile)
|
||||
|
||||
|
||||
# inspired by rate_all_view
|
||||
def rate_elo_mmr(apps, schema_editor):
|
||||
Rating = apps.get_model('judge', 'Rating')
|
||||
Profile = apps.get_model('judge', 'Profile')
|
||||
Rating = apps.get_model("judge", "Rating")
|
||||
Profile = apps.get_model("judge", "Profile")
|
||||
|
||||
with schema_editor.connection.cursor() as cursor:
|
||||
cursor.execute('TRUNCATE TABLE `%s`' % Rating._meta.db_table)
|
||||
cursor.execute("TRUNCATE TABLE `%s`" % Rating._meta.db_table)
|
||||
Profile.objects.update(rating=None)
|
||||
# Don't populate Rating
|
||||
|
||||
|
@ -184,25 +238,25 @@ def rate_elo_mmr(apps, schema_editor):
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0117_auto_20211209_0612'),
|
||||
("judge", "0117_auto_20211209_0612"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(migrations.RunPython.noop, rate_tc, atomic=True),
|
||||
migrations.AddField(
|
||||
model_name='rating',
|
||||
name='mean',
|
||||
field=models.FloatField(verbose_name='raw rating'),
|
||||
model_name="rating",
|
||||
name="mean",
|
||||
field=models.FloatField(verbose_name="raw rating"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rating',
|
||||
name='performance',
|
||||
field=models.FloatField(verbose_name='contest performance'),
|
||||
model_name="rating",
|
||||
name="performance",
|
||||
field=models.FloatField(verbose_name="contest performance"),
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='rating',
|
||||
name='volatility',
|
||||
field=models.IntegerField(verbose_name='volatility'),
|
||||
model_name="rating",
|
||||
name="volatility",
|
||||
field=models.IntegerField(verbose_name="volatility"),
|
||||
),
|
||||
migrations.RunPython(rate_elo_mmr, migrations.RunPython.noop, atomic=True),
|
||||
]
|
||||
]
|
||||
|
|
|
@ -6,13 +6,17 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0118_rating'),
|
||||
("judge", "0118_rating"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contest',
|
||||
name='hide_problem_tags',
|
||||
field=models.BooleanField(default=True, help_text='Whether problem tags should be hidden by default.', verbose_name='hide problem tags'),
|
||||
model_name="contest",
|
||||
name="hide_problem_tags",
|
||||
field=models.BooleanField(
|
||||
default=True,
|
||||
help_text="Whether problem tags should be hidden by default.",
|
||||
verbose_name="hide problem tags",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -8,27 +8,68 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0119_auto_20220306_0512'),
|
||||
("judge", "0119_auto_20220306_0512"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='profile',
|
||||
name='is_banned_problem_voting',
|
||||
field=models.BooleanField(default=False, help_text="User will not be able to vote on problems' point values.", verbose_name='banned from voting'),
|
||||
model_name="profile",
|
||||
name="is_banned_problem_voting",
|
||||
field=models.BooleanField(
|
||||
default=False,
|
||||
help_text="User will not be able to vote on problems' point values.",
|
||||
verbose_name="banned from voting",
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProblemPointsVote',
|
||||
name="ProblemPointsVote",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('points', models.IntegerField(help_text='The amount of points you think this problem deserves.', validators=[django.core.validators.MinValueValidator(100), django.core.validators.MaxValueValidator(600)], verbose_name='proposed point value')),
|
||||
('vote_time', models.DateTimeField(auto_now_add=True, verbose_name='The time this vote was cast')),
|
||||
('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='problem_points_votes', to='judge.Problem')),
|
||||
('voter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='problem_points_votes', to='judge.Profile')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"points",
|
||||
models.IntegerField(
|
||||
help_text="The amount of points you think this problem deserves.",
|
||||
validators=[
|
||||
django.core.validators.MinValueValidator(100),
|
||||
django.core.validators.MaxValueValidator(600),
|
||||
],
|
||||
verbose_name="proposed point value",
|
||||
),
|
||||
),
|
||||
(
|
||||
"vote_time",
|
||||
models.DateTimeField(
|
||||
auto_now_add=True, verbose_name="The time this vote was cast"
|
||||
),
|
||||
),
|
||||
(
|
||||
"problem",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="problem_points_votes",
|
||||
to="judge.Problem",
|
||||
),
|
||||
),
|
||||
(
|
||||
"voter",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="problem_points_votes",
|
||||
to="judge.Profile",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'vote',
|
||||
'verbose_name_plural': 'votes',
|
||||
"verbose_name": "vote",
|
||||
"verbose_name_plural": "votes",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -9,23 +9,68 @@ import judge.utils.problem_data
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0120_auto_20220306_1124'),
|
||||
("judge", "0120_auto_20220306_1124"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='problemdata',
|
||||
name='interactive_judge',
|
||||
field=models.FileField(blank=True, null=True, storage=judge.utils.problem_data.ProblemDataStorage(), upload_to=judge.models.problem_data.problem_directory_file, validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['cpp'])], verbose_name='interactive judge'),
|
||||
model_name="problemdata",
|
||||
name="interactive_judge",
|
||||
field=models.FileField(
|
||||
blank=True,
|
||||
null=True,
|
||||
storage=judge.utils.problem_data.ProblemDataStorage(),
|
||||
upload_to=judge.models.problem_data.problem_directory_file,
|
||||
validators=[
|
||||
django.core.validators.FileExtensionValidator(
|
||||
allowed_extensions=["cpp"]
|
||||
)
|
||||
],
|
||||
verbose_name="interactive judge",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problemdata',
|
||||
name='checker',
|
||||
field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker (PY)'), ('customval', 'Custom validator (CPP)'), ('interact', 'Interactive')], max_length=10, verbose_name='checker'),
|
||||
model_name="problemdata",
|
||||
name="checker",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("standard", "Standard"),
|
||||
("floats", "Floats"),
|
||||
("floatsabs", "Floats (absolute)"),
|
||||
("floatsrel", "Floats (relative)"),
|
||||
("rstripped", "Non-trailing spaces"),
|
||||
("sorted", "Unordered"),
|
||||
("identical", "Byte identical"),
|
||||
("linecount", "Line-by-line"),
|
||||
("custom", "Custom checker (PY)"),
|
||||
("customval", "Custom validator (CPP)"),
|
||||
("interact", "Interactive"),
|
||||
],
|
||||
max_length=10,
|
||||
verbose_name="checker",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problemtestcase',
|
||||
name='checker',
|
||||
field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker (PY)'), ('customval', 'Custom validator (CPP)'), ('interact', 'Interactive')], max_length=10, verbose_name='checker'),
|
||||
model_name="problemtestcase",
|
||||
name="checker",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("standard", "Standard"),
|
||||
("floats", "Floats"),
|
||||
("floatsabs", "Floats (absolute)"),
|
||||
("floatsrel", "Floats (relative)"),
|
||||
("rstripped", "Non-trailing spaces"),
|
||||
("sorted", "Unordered"),
|
||||
("identical", "Byte identical"),
|
||||
("linecount", "Line-by-line"),
|
||||
("custom", "Custom checker (PY)"),
|
||||
("customval", "Custom validator (CPP)"),
|
||||
("interact", "Interactive"),
|
||||
],
|
||||
max_length=10,
|
||||
verbose_name="checker",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,13 +6,18 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0121_auto_20220415_0135'),
|
||||
("judge", "0121_auto_20220415_0135"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contest',
|
||||
name='time_limit',
|
||||
field=models.DurationField(blank=True, help_text='Format hh:mm:ss. For example, if you want a 2-hour contest, enter 02:00:00', null=True, verbose_name='time limit'),
|
||||
model_name="contest",
|
||||
name="time_limit",
|
||||
field=models.DurationField(
|
||||
blank=True,
|
||||
help_text="Format hh:mm:ss. For example, if you want a 2-hour contest, enter 02:00:00",
|
||||
null=True,
|
||||
verbose_name="time limit",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,30 +7,85 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('judge', '0122_auto_20220425_1202'),
|
||||
("judge", "0122_auto_20220425_1202"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='problem',
|
||||
options={'permissions': (('see_private_problem', 'See hidden problems'), ('edit_own_problem', 'Edit own problems'), ('edit_all_problem', 'Edit all problems'), ('edit_public_problem', 'Edit all public problems'), ('clone_problem', 'Clone problem'), ('change_public_visibility', 'Change is_public field'), ('change_manually_managed', 'Change is_manually_managed field'), ('see_organization_problem', 'See organization-private problems'), ('suggest_problem_changes', 'Suggest changes to problem')), 'verbose_name': 'problem', 'verbose_name_plural': 'problems'},
|
||||
name="problem",
|
||||
options={
|
||||
"permissions": (
|
||||
("see_private_problem", "See hidden problems"),
|
||||
("edit_own_problem", "Edit own problems"),
|
||||
("edit_all_problem", "Edit all problems"),
|
||||
("edit_public_problem", "Edit all public problems"),
|
||||
("clone_problem", "Clone problem"),
|
||||
("change_public_visibility", "Change is_public field"),
|
||||
("change_manually_managed", "Change is_manually_managed field"),
|
||||
("see_organization_problem", "See organization-private problems"),
|
||||
("suggest_problem_changes", "Suggest changes to problem"),
|
||||
),
|
||||
"verbose_name": "problem",
|
||||
"verbose_name_plural": "problems",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='VolunteerProblemVote',
|
||||
name="VolunteerProblemVote",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('time', models.DateTimeField(auto_now_add=True)),
|
||||
('knowledge_points', models.PositiveIntegerField(help_text='Points awarded by knowledge difficulty', verbose_name='knowledge points')),
|
||||
('thinking_points', models.PositiveIntegerField(help_text='Points awarded by thinking difficulty', verbose_name='thinking points')),
|
||||
('feedback', models.TextField(blank=True, verbose_name='feedback')),
|
||||
('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='volunteer_user_votes', to='judge.Problem')),
|
||||
('types', models.ManyToManyField(help_text="The type of problem, as shown on the problem's page.", to='judge.ProblemType', verbose_name='problem types')),
|
||||
('voter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='volunteer_problem_votes', to='judge.Profile')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("time", models.DateTimeField(auto_now_add=True)),
|
||||
(
|
||||
"knowledge_points",
|
||||
models.PositiveIntegerField(
|
||||
help_text="Points awarded by knowledge difficulty",
|
||||
verbose_name="knowledge points",
|
||||
),
|
||||
),
|
||||
(
|
||||
"thinking_points",
|
||||
models.PositiveIntegerField(
|
||||
help_text="Points awarded by thinking difficulty",
|
||||
verbose_name="thinking points",
|
||||
),
|
||||
),
|
||||
("feedback", models.TextField(blank=True, verbose_name="feedback")),
|
||||
(
|
||||
"problem",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="volunteer_user_votes",
|
||||
to="judge.Problem",
|
||||
),
|
||||
),
|
||||
(
|
||||
"types",
|
||||
models.ManyToManyField(
|
||||
help_text="The type of problem, as shown on the problem's page.",
|
||||
to="judge.ProblemType",
|
||||
verbose_name="problem types",
|
||||
),
|
||||
),
|
||||
(
|
||||
"voter",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="volunteer_problem_votes",
|
||||
to="judge.Profile",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'volunteer vote',
|
||||
'verbose_name_plural': 'volunteer votes',
|
||||
'unique_together': {('voter', 'problem')},
|
||||
"verbose_name": "volunteer vote",
|
||||
"verbose_name_plural": "volunteer votes",
|
||||
"unique_together": {("voter", "problem")},
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue