diff --git a/src/apps/api/serializers/competitions.py b/src/apps/api/serializers/competitions.py index 9b622b3dc..41cd51341 100644 --- a/src/apps/api/serializers/competitions.py +++ b/src/apps/api/serializers/competitions.py @@ -254,7 +254,10 @@ class Meta: 'registration_auto_approve', 'queue', 'enable_detailed_results', + 'show_detailed_results_in_submission_panel', + 'show_detailed_results_in_leaderboard', 'auto_run_submissions', + 'can_participants_make_submissions_public', 'make_programs_available', 'make_input_data_available', 'docker_image', @@ -373,7 +376,10 @@ class Meta: 'submission_count', 'queue', 'enable_detailed_results', + 'show_detailed_results_in_submission_panel', + 'show_detailed_results_in_leaderboard', 'auto_run_submissions', + 'can_participants_make_submissions_public', 'make_programs_available', 'make_input_data_available', 'docker_image', diff --git a/src/apps/api/serializers/submissions.py b/src/apps/api/serializers/submissions.py index 33fe9241e..05191e8e3 100644 --- a/src/apps/api/serializers/submissions.py +++ b/src/apps/api/serializers/submissions.py @@ -42,6 +42,7 @@ class SubmissionSerializer(serializers.ModelSerializer): task = TaskSerializer() created_when = serializers.DateTimeField(format="%Y-%m-%d %H:%M") auto_run = serializers.SerializerMethodField(read_only=True) + can_make_submissions_public = serializers.SerializerMethodField(read_only=True) class Meta: model = Submission @@ -67,7 +68,8 @@ class Meta: 'leaderboard', 'on_leaderboard', 'task', - 'auto_run' + 'auto_run', + 'can_make_submissions_public', ) read_only_fields = ( 'pk', @@ -85,6 +87,10 @@ def get_auto_run(self, instance): # returns this submission's competition auto_run_submissions Flag return instance.phase.competition.auto_run_submissions + def get_can_make_submissions_public(self, instance): + # returns this submission's competition can_participants_make_submissions_public Flag + return instance.phase.competition.can_participants_make_submissions_public + class SubmissionLeaderBoardSerializer(serializers.ModelSerializer): scores = SubmissionScoreSerializer(many=True) diff --git a/src/apps/api/views/submissions.py b/src/apps/api/views/submissions.py index d0c0defb7..fccaeefd4 100644 --- a/src/apps/api/views/submissions.py +++ b/src/apps/api/views/submissions.py @@ -352,15 +352,15 @@ def get_detail_result(self, request, pk): ) else: return Response({ - "error_msg": "Visualizations are disabled"}, + "error_msg": "Detailed results are disable for this competition!"}, status=status.HTTP_404_NOT_FOUND ) @action(detail=True, methods=('GET',)) def toggle_public(self, request, pk): submission = super().get_object() - if not self.has_admin_permission(request.user, submission): - raise PermissionDenied(f'You do not have permission to publish this submissions') + if not submission.phase.competition.can_participants_make_submissions_public: + raise PermissionDenied("You do not have permission to make this submissions public/private") is_public = not submission.is_public submission.data.is_public = is_public submission.data.save(send=False) diff --git a/src/apps/competitions/migrations/0047_competition_can_participants_make_submissions_public.py b/src/apps/competitions/migrations/0047_competition_can_participants_make_submissions_public.py new file mode 100644 index 000000000..2b750fa02 --- /dev/null +++ b/src/apps/competitions/migrations/0047_competition_can_participants_make_submissions_public.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.17 on 2024-03-28 13:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('competitions', '0046_merge_20240222_1916'), + ] + + operations = [ + migrations.AddField( + model_name='competition', + name='can_participants_make_submissions_public', + field=models.BooleanField(default=True), + ), + ] diff --git a/src/apps/competitions/migrations/0048_auto_20240401_1646.py b/src/apps/competitions/migrations/0048_auto_20240401_1646.py new file mode 100644 index 000000000..3ed2ad446 --- /dev/null +++ b/src/apps/competitions/migrations/0048_auto_20240401_1646.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.17 on 2024-04-01 16:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('competitions', '0047_competition_can_participants_make_submissions_public'), + ] + + operations = [ + migrations.AddField( + model_name='competition', + name='show_detailed_results_in_leaderboard', + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name='competition', + name='show_detailed_results_in_submission_panel', + field=models.BooleanField(default=True), + ), + ] diff --git a/src/apps/competitions/models.py b/src/apps/competitions/models.py index 03d8b65fc..777dbb86a 100644 --- a/src/apps/competitions/models.py +++ b/src/apps/competitions/models.py @@ -49,6 +49,10 @@ class Competition(ChaHubSaveMixin, models.Model): description = models.TextField(null=True, blank=True) docker_image = models.CharField(max_length=128, default="codalab/codalab-legacy:py37") enable_detailed_results = models.BooleanField(default=False) + # If true, show detailed results in submission panel + show_detailed_results_in_submission_panel = models.BooleanField(default=True) + # If true, show detailed results in leaderboard + show_detailed_results_in_leaderboard = models.BooleanField(default=True) make_programs_available = models.BooleanField(default=False) make_input_data_available = models.BooleanField(default=False) @@ -69,6 +73,9 @@ class Competition(ChaHubSaveMixin, models.Model): # if false, submissions run will be intiiated by organizer auto_run_submissions = models.BooleanField(default=True) + # If true, participants see the make their submissions public + can_participants_make_submissions_public = models.BooleanField(default=True) + def __str__(self): return f"competition-{self.title}-{self.pk}-{self.competition_type}" diff --git a/src/apps/competitions/unpackers/v1.py b/src/apps/competitions/unpackers/v1.py index 91496ddca..dc476a5c2 100644 --- a/src/apps/competitions/unpackers/v1.py +++ b/src/apps/competitions/unpackers/v1.py @@ -23,6 +23,8 @@ def __init__(self, *args, **kwargs): "description": self.competition_yaml.get("description", ""), "docker_image": docker_image, "enable_detailed_results": self.competition_yaml.get('enable_detailed_results', False), + "show_detailed_results_in_submission_panel": self.competition_yaml.get('show_detailed_results_in_submission_panel', True), + "show_detailed_results_in_leaderboard": self.competition_yaml.get('show_detailed_results_in_leaderboard', True), "auto_run_submissions": self.competition_yaml.get('auto_run_submissions', True), "make_programs_available": self.competition_yaml.get('make_programs_available', False), "make_input_data_available": self.competition_yaml.get('make_input_data_available', False), diff --git a/src/apps/competitions/unpackers/v2.py b/src/apps/competitions/unpackers/v2.py index 8de2a42ad..b825e9ee2 100644 --- a/src/apps/competitions/unpackers/v2.py +++ b/src/apps/competitions/unpackers/v2.py @@ -14,7 +14,10 @@ def __init__(self, *args, **kwargs): "registration_auto_approve": self.competition_yaml.get('registration_auto_approve', False), "docker_image": self.competition_yaml.get('docker_image', 'codalab/codalab-legacy:py37'), "enable_detailed_results": self.competition_yaml.get('enable_detailed_results', False), + "show_detailed_results_in_submission_panel": self.competition_yaml.get('show_detailed_results_in_submission_panel', True), + "show_detailed_results_in_leaderboard": self.competition_yaml.get('show_detailed_results_in_leaderboard', True), "auto_run_submissions": self.competition_yaml.get('auto_run_submissions', True), + "can_participants_make_submissions_public": self.competition_yaml.get('can_participants_make_submissions_public', True), "make_programs_available": self.competition_yaml.get('make_programs_available', False), "make_input_data_available": self.competition_yaml.get('make_input_data_available', False), "description": self.competition_yaml.get("description", ""), diff --git a/src/static/riot/competitions/detail/leaderboards.tag b/src/static/riot/competitions/detail/leaderboards.tag index 0617a38ea..2f09f26f5 100644 --- a/src/static/riot/competitions/detail/leaderboards.tag +++ b/src/static/riot/competitions/detail/leaderboards.tag @@ -78,6 +78,7 @@ self.phase_id = null self.competition_id = null self.enable_detailed_results = false + self.show_detailed_results_in_leaderboard = false self.bold_class = function(column, submission){ @@ -168,7 +169,7 @@ self.columns.push(column) } // -1 id is used for fact sheet answers - if(self.enable_detailed_results & task.id != -1){ + if(self.enable_detailed_results & self.show_detailed_results_in_leaderboard & task.id != -1){ self.columns.push({ task_id: task.id, title: "Detailed Results" @@ -200,6 +201,7 @@ self.competition_id = competition.id self.opts.is_admin ? self.show_download = "visible": self.show_download = "hidden" self.enable_detailed_results = competition.enable_detailed_results + self.show_detailed_results_in_leaderboard = competition.show_detailed_results_in_leaderboard }) diff --git a/src/static/riot/competitions/detail/submission_manager.tag b/src/static/riot/competitions/detail/submission_manager.tag index 5cfa0c7f5..f99b70046 100644 --- a/src/static/riot/competitions/detail/submission_manager.tag +++ b/src/static/riot/competitions/detail/submission_manager.tag @@ -64,6 +64,7 @@