From 17c88c868e556941c4a981d15124e2339dcd7225 Mon Sep 17 00:00:00 2001 From: didayolo Date: Fri, 25 Apr 2025 12:14:55 +0200 Subject: [PATCH 1/4] Add hide_score_output option --- src/apps/api/serializers/competitions.py | 2 ++ src/apps/api/serializers/submissions.py | 2 +- src/apps/api/views/competitions.py | 1 + .../migrations/0054_auto_20250321_1341.py | 18 ++++++++++++++++++ .../migrations/0056_merge_20250324_2128.py | 14 ++++++++++++++ .../migrations/0057_phase_hide_score_output.py | 18 ++++++++++++++++++ src/apps/competitions/models.py | 1 + src/apps/competitions/tasks.py | 1 + src/apps/competitions/unpackers/v2.py | 1 + .../competitions/detail/submission_modal.tag | 2 +- .../riot/competitions/editor/_phases.tag | 18 +++++++++++++++--- 11 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 src/apps/competitions/migrations/0054_auto_20250321_1341.py create mode 100644 src/apps/competitions/migrations/0056_merge_20250324_2128.py create mode 100644 src/apps/competitions/migrations/0057_phase_hide_score_output.py diff --git a/src/apps/api/serializers/competitions.py b/src/apps/api/serializers/competitions.py index f617fa6b9..d77ec97a8 100644 --- a/src/apps/api/serializers/competitions.py +++ b/src/apps/api/serializers/competitions.py @@ -43,6 +43,7 @@ class Meta: 'max_submissions_per_person', 'auto_migrate_to_this_phase', 'hide_output', + 'hide_score_output', 'leaderboard', 'public_data', 'starting_kit', @@ -124,6 +125,7 @@ class Meta: 'max_submissions_per_person', 'auto_migrate_to_this_phase', 'hide_output', + 'hide_score_output', # no leaderboard 'public_data', 'starting_kit', diff --git a/src/apps/api/serializers/submissions.py b/src/apps/api/serializers/submissions.py index d14df9e11..7298d34f1 100644 --- a/src/apps/api/serializers/submissions.py +++ b/src/apps/api/serializers/submissions.py @@ -271,7 +271,7 @@ def get_detailed_result(self, instance): def get_scoring_result(self, instance): if instance.scoring_result.name: - if instance.phase.hide_output and not instance.phase.competition.user_has_admin_permission(self.context['request'].user): + if (instance.phase.hide_output or instance.phase.hide_score_output) and not instance.phase.competition.user_has_admin_permission(self.context['request'].user): return None return make_url_sassy(instance.scoring_result.name) diff --git a/src/apps/api/views/competitions.py b/src/apps/api/views/competitions.py index 4f53f7f31..f9603f535 100644 --- a/src/apps/api/views/competitions.py +++ b/src/apps/api/views/competitions.py @@ -275,6 +275,7 @@ def update(self, request, *args, **kwargs): name=phase["name"], description=phase["description"], hide_output=phase["hide_output"], + hide_score_output=phase["hide_score_output"], competition=Competition.objects.get(id=data['id']) ) # Get phase id diff --git a/src/apps/competitions/migrations/0054_auto_20250321_1341.py b/src/apps/competitions/migrations/0054_auto_20250321_1341.py new file mode 100644 index 000000000..e5b7a6451 --- /dev/null +++ b/src/apps/competitions/migrations/0054_auto_20250321_1341.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.28 on 2025-03-21 13:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('competitions', '0053_auto_20250218_1151'), + ] + + operations = [ + migrations.AlterField( + model_name='submissiondetails', + name='file_size', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=15, null=True), + ), + ] diff --git a/src/apps/competitions/migrations/0056_merge_20250324_2128.py b/src/apps/competitions/migrations/0056_merge_20250324_2128.py new file mode 100644 index 000000000..16554ffa0 --- /dev/null +++ b/src/apps/competitions/migrations/0056_merge_20250324_2128.py @@ -0,0 +1,14 @@ +# Generated by Django 2.2.28 on 2025-03-24 21:28 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('competitions', '0054_auto_20250321_1341'), + ('competitions', '0055_merge_20250324_0650'), + ] + + operations = [ + ] diff --git a/src/apps/competitions/migrations/0057_phase_hide_score_output.py b/src/apps/competitions/migrations/0057_phase_hide_score_output.py new file mode 100644 index 000000000..1f805e0f4 --- /dev/null +++ b/src/apps/competitions/migrations/0057_phase_hide_score_output.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.28 on 2025-04-25 09:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('competitions', '0056_merge_20250324_2128'), + ] + + operations = [ + migrations.AddField( + model_name='phase', + name='hide_score_output', + field=models.BooleanField(default=False), + ), + ] diff --git a/src/apps/competitions/models.py b/src/apps/competitions/models.py index 4d938895f..bda72df13 100644 --- a/src/apps/competitions/models.py +++ b/src/apps/competitions/models.py @@ -342,6 +342,7 @@ class Phase(ChaHubSaveMixin, models.Model): auto_migrate_to_this_phase = models.BooleanField(default=False) has_been_migrated = models.BooleanField(default=False) hide_output = models.BooleanField(default=False) + hide_score_output = models.BooleanField(default=False) has_max_submissions = models.BooleanField(default=True) max_submissions_per_day = models.PositiveIntegerField(default=5, null=True, blank=True) diff --git a/src/apps/competitions/tasks.py b/src/apps/competitions/tasks.py index 87501be20..419a13f23 100644 --- a/src/apps/competitions/tasks.py +++ b/src/apps/competitions/tasks.py @@ -82,6 +82,7 @@ 'execution_time_limit', 'auto_migrate_to_this_phase', 'hide_output', + 'hide_score_output', ] PHASE_FILES = [ "input_data", diff --git a/src/apps/competitions/unpackers/v2.py b/src/apps/competitions/unpackers/v2.py index 85eddefcb..72a8b6abc 100644 --- a/src/apps/competitions/unpackers/v2.py +++ b/src/apps/competitions/unpackers/v2.py @@ -198,6 +198,7 @@ def _unpack_phases(self): 'max_submissions_per_person': phase_data.get('max_submissions', 100), 'auto_migrate_to_this_phase': phase_data.get('auto_migrate_to_this_phase', False), 'hide_output': phase_data.get('hide_output', False), + 'hide_score_output': phase_data.get('hide_score_output', False), } try: new_phase['tasks'] = phase_data['tasks'] diff --git a/src/static/riot/competitions/detail/submission_modal.tag b/src/static/riot/competitions/detail/submission_modal.tag index 55cb5dde4..3df256fba 100644 --- a/src/static/riot/competitions/detail/submission_modal.tag +++ b/src/static/riot/competitions/detail/submission_modal.tag @@ -27,7 +27,7 @@ - + Output from scoring step diff --git a/src/static/riot/competitions/editor/_phases.tag b/src/static/riot/competitions/editor/_phases.tag index fd0e09cd5..ef82ff274 100644 --- a/src/static/riot/competitions/editor/_phases.tag +++ b/src/static/riot/competitions/editor/_phases.tag @@ -190,10 +190,22 @@
- +
+
+
+ + +
+
@@ -641,7 +653,6 @@ return new Date(Date.parse(date)) } - self.edit = function (index) { self.selected_phase_index = index var phase = self.phases[index] @@ -649,11 +660,11 @@ self.phase_public_data = [phase.public_data] self.phase_starting_kit = [phase.starting_kit] - self.update() set_form_data(phase, self.refs.form) $(self.refs.auto_migrate).prop('checked', _.get(phase, 'auto_migrate_to_this_phase', false)) self.refs.hide_output.checked = phase.hide_output + self.refs.hide_score_output.checked = phase.hide_score_output // Setting description in markdown editor self.simple_markdown_editor.value(self.phases[index].description || '') @@ -812,6 +823,7 @@ } data.auto_migrate_to_this_phase = $(self.refs.auto_migrate).prop('checked') data.hide_output = self.refs.hide_output.checked + data.hide_score_output = self.refs.hide_score_output.checked _.forEach(number_fields, field => { let str = _.get(data, field) if (str) { From ce23b4a0b50ed86dd9ae38c5377439b093929e56 Mon Sep 17 00:00:00 2001 From: didayolo Date: Fri, 25 Apr 2025 12:26:18 +0200 Subject: [PATCH 2/4] Update test --- src/apps/competitions/tests/unpacker_test_data.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/apps/competitions/tests/unpacker_test_data.py b/src/apps/competitions/tests/unpacker_test_data.py index db69ec6dd..a263efa5d 100644 --- a/src/apps/competitions/tests/unpacker_test_data.py +++ b/src/apps/competitions/tests/unpacker_test_data.py @@ -235,7 +235,8 @@ V2_SPECIFIC_PHASE_DATA = [ # Tuples of (key, value) of data specific to v2 unpacker. - ('hide_output', False) + ('hide_output', False), + ('hide_score_output', False) ] From bc9a94a400589b9effca198c20fd8732c0cf5109 Mon Sep 17 00:00:00 2001 From: didayolo Date: Fri, 25 Apr 2025 20:29:01 +0200 Subject: [PATCH 3/4] Add the options for v1 bundles --- src/apps/competitions/unpackers/v1.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/apps/competitions/unpackers/v1.py b/src/apps/competitions/unpackers/v1.py index dc476a5c2..d780c2e5d 100644 --- a/src/apps/competitions/unpackers/v1.py +++ b/src/apps/competitions/unpackers/v1.py @@ -88,6 +88,8 @@ def _unpack_phases(self): 'max_submissions_per_day': phase.get('max_submissions_per_day', 5), 'max_submissions_per_person': phase.get('max_submissions', 100), 'auto_migrate_to_this_phase': phase.get('auto_migration', False), + 'hide_output': phase.get('hide_output', False), + 'hide_score_output': phase.get('hide_score_output', False), } execution_time_limit = phase.get('execution_time_limit') if execution_time_limit: From 5d8df435deaf1fdf9c3998a0136fff6eab0a83f5 Mon Sep 17 00:00:00 2001 From: didayolo Date: Fri, 25 Apr 2025 20:45:20 +0200 Subject: [PATCH 4/4] Make more generic tests (v1, v2) --- src/apps/competitions/tests/unpacker_test_data.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/apps/competitions/tests/unpacker_test_data.py b/src/apps/competitions/tests/unpacker_test_data.py index a263efa5d..c93597671 100644 --- a/src/apps/competitions/tests/unpacker_test_data.py +++ b/src/apps/competitions/tests/unpacker_test_data.py @@ -213,6 +213,8 @@ 'starting_kit': None, 'tasks': [0], 'status': 'Previous', + 'hide_output': False, + 'hide_score_output': False, }, { 'index': 1, @@ -230,15 +232,11 @@ 'tasks': [1], 'status': 'Current', 'is_final_phase': True, + 'hide_output': False, + 'hide_score_output': False, } ] -V2_SPECIFIC_PHASE_DATA = [ - # Tuples of (key, value) of data specific to v2 unpacker. - ('hide_output', False), - ('hide_score_output', False) -] - def get_phases(version): if version == 1: @@ -247,9 +245,6 @@ def get_phases(version): # Make a copy of the list so we aren't mutating the original phases object. May not be strictly necessary, # but if we ever write a test comparing v1 to v2 or something, this would avoid bugs. v2 = [{k: v for k, v in phase.items()} for phase in PHASES] - for phase in v2: - for key, value in V2_SPECIFIC_PHASE_DATA: - phase[key] = value return v2