diff --git a/src/apps/api/serializers/competitions.py b/src/apps/api/serializers/competitions.py index 7d157e103..2f580903b 100644 --- a/src/apps/api/serializers/competitions.py +++ b/src/apps/api/serializers/competitions.py @@ -238,6 +238,8 @@ class Meta: 'registration_auto_approve', 'queue', 'enable_detailed_results', + 'make_programs_available', + 'make_input_data_available', 'docker_image', 'allow_robot_submissions', 'competition_type', @@ -328,6 +330,8 @@ class Meta: 'submission_count', 'queue', 'enable_detailed_results', + 'make_programs_available', + 'make_input_data_available', 'docker_image', 'allow_robot_submissions', 'competition_type', diff --git a/src/apps/api/views/competitions.py b/src/apps/api/views/competitions.py index 3e3622cc2..d58c057e3 100644 --- a/src/apps/api/views/competitions.py +++ b/src/apps/api/views/competitions.py @@ -295,7 +295,6 @@ def update(self, request, *args, **kwargs): phase['starting_kit'] = Data.objects.filter(key=phase['starting_kit']['value'])[0].id except TypeError: phase['starting_kit'] = None - serializer = self.get_serializer(instance, data=data, partial=partial) type(serializer) serializer.is_valid(raise_exception=True) @@ -523,6 +522,7 @@ def create_dump(self, request, pk=None): def public(self, request): qs = self.get_queryset() qs = qs.filter(published=True) + qs = qs.order_by('-id') queryset = self.filter_queryset(qs) page = self.paginate_queryset(queryset) @@ -564,8 +564,9 @@ def perform_create(self, serializer): def perform_update(self, serializer): instance = self.get_object() + instance.make_programs_available + instance.make_input_data_available initial_tasks = {phase.id: set(phase.tasks.all()) for phase in instance.phases.all().prefetch_related('tasks')} - instance = serializer.save() self._ensure_organizer_participants_accepted(instance) diff --git a/src/apps/competitions/migrations/0038_auto_20230827_2303.py b/src/apps/competitions/migrations/0038_auto_20230827_2303.py new file mode 100644 index 000000000..4384783c6 --- /dev/null +++ b/src/apps/competitions/migrations/0038_auto_20230827_2303.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.17 on 2023-08-27 23:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('competitions', '0037_auto_20230826_0859'), + ] + + operations = [ + migrations.AddField( + model_name='competition', + name='make_input_data_available', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='competition', + name='make_programs_available', + field=models.BooleanField(default=False), + ), + ] diff --git a/src/apps/competitions/migrations/0039_merge_20230906_1305.py b/src/apps/competitions/migrations/0039_merge_20230906_1305.py new file mode 100644 index 000000000..b65b56953 --- /dev/null +++ b/src/apps/competitions/migrations/0039_merge_20230906_1305.py @@ -0,0 +1,14 @@ +# Generated by Django 2.2.17 on 2023-09-06 13:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('competitions', '0038_auto_20230827_2303'), + ('competitions', '0038_auto_20230830_1631'), + ] + + operations = [ + ] diff --git a/src/apps/competitions/models.py b/src/apps/competitions/models.py index 4a8a8c582..f139ce29b 100644 --- a/src/apps/competitions/models.py +++ b/src/apps/competitions/models.py @@ -44,6 +44,8 @@ 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) + make_programs_available = models.BooleanField(default=False) + make_input_data_available = models.BooleanField(default=False) queue = models.ForeignKey('queues.Queue', on_delete=models.SET_NULL, null=True, blank=True, related_name='competitions') diff --git a/src/apps/competitions/unpackers/v1.py b/src/apps/competitions/unpackers/v1.py index a2dd694c4..6802002ac 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), + "make_programs_available": self.competition_yaml.get('make_programs_available', False), + "make_input_data_available": self.competition_yaml.get('make_input_data_available', False), "end_date": self.competition_yaml.get('end_date', None), "pages": [], "phases": [], diff --git a/src/apps/competitions/unpackers/v2.py b/src/apps/competitions/unpackers/v2.py index 6c335e9ea..b3c87b2f4 100644 --- a/src/apps/competitions/unpackers/v2.py +++ b/src/apps/competitions/unpackers/v2.py @@ -1,5 +1,4 @@ import os - from django.utils import timezone from competitions.unpackers.base_unpacker import BaseUnpacker @@ -15,6 +14,8 @@ 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), + "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", ""), "competition_type": self.competition_yaml.get("competition_type", "competition"), "fact_sheet": self.competition_yaml.get("fact_sheet", None), diff --git a/src/static/riot/competitions/detail/_tabs.tag b/src/static/riot/competitions/detail/_tabs.tag index 00e94357b..dccee3d94 100644 --- a/src/static/riot/competitions/detail/_tabs.tag +++ b/src/static/riot/competitions/detail/_tabs.tag @@ -75,7 +75,9 @@ {file.task} {file.type} - yes + + + {filesize(file.file_size * 1024)} @@ -184,15 +186,18 @@ - +
+

No visible leaderboard for this benchmark

+
+ +
+ - -
-
-

No Visible Leaderboards for this competition

-
- +
+ + @@ -226,24 +231,34 @@ let type = 'input_data' if(dataset.type === "input_data"){ type = 'Input Data' - input_data = {key: dataset.key, name: dataset.name, file_size: dataset.file_size, phase: phase.name, task: task.name, type: type} + input_data = {key: dataset.key, name: dataset.name, file_size: dataset.file_size, phase: phase.name, task: task.name, type: type, available: self.competition.make_input_data_available} }else if(dataset.type === "reference_data"){ type = 'Reference Data' - reference_data = {key: dataset.key, name: dataset.name, file_size: dataset.file_size, phase: phase.name, task: task.name, type: type} + reference_data = {key: dataset.key, name: dataset.name, file_size: dataset.file_size, phase: phase.name, task: task.name, type: type, available: false} }else if(dataset.type === "ingestion_program"){ type = 'Ingestion Program' - ingestion_program = {key: dataset.key, name: dataset.name, file_size: dataset.file_size, phase: phase.name, task: task.name, type: type} + ingestion_program = {key: dataset.key, name: dataset.name, file_size: dataset.file_size, phase: phase.name, task: task.name, type: type, available: self.competition.make_programs_available} }else if(dataset.type === "scoring_program"){ type = 'Scoring Program' - scoring_program = {key: dataset.key, name: dataset.name, file_size: dataset.file_size, phase: phase.name, task: task.name, type: type} + scoring_program = {key: dataset.key, name: dataset.name, file_size: dataset.file_size, phase: phase.name, task: task.name, type: type, available: self.competition.make_programs_available} } }) - if(self.competition.admin){ + if(self.competition.participant_status === 'approved' && self.competition.make_programs_available){ + self.competition.files.push(ingestion_program) + self.competition.files.push(scoring_program) + }if(self.competition.participant_status === 'approved' && self.competition.make_input_data_available){ self.competition.files.push(input_data) - self.competition.files.push(reference_data) + } + if(self.competition.admin && !self.competition.make_programs_available){ self.competition.files.push(ingestion_program) self.competition.files.push(scoring_program) } + if(self.competition.admin && !self.competition.make_input_data_available){ + self.competition.files.push(input_data) + } + if(self.competition.admin){ + self.competition.files.push(reference_data) + } }) // Need code for public_data and starting_kit at phase level if(self.competition.participant_status === 'approved'){ @@ -255,7 +270,8 @@ file_size: solution.size, phase: phase.name, task: task.name, - type: 'Solution' + type: 'Solution', + available: true }) }) }) @@ -266,7 +282,8 @@ file_size: phase.starting_kit.file_size, phase: phase.name, task: '-', - type: 'Starting Kit' + type: 'Starting Kit', + available: true }) } if (phase.public_data != null){ @@ -276,7 +293,8 @@ file_size: phase.public_data.file_size, phase: phase.name, task: '-', - type: 'Public Data' + type: 'Public Data', + available: true }) } } diff --git a/src/static/riot/competitions/editor/_competition_details.tag b/src/static/riot/competitions/editor/_competition_details.tag index c09643f3a..50f301342 100644 --- a/src/static/riot/competitions/editor/_competition_details.tag +++ b/src/static/riot/competitions/editor/_competition_details.tag @@ -82,6 +82,27 @@ +
+ +
+ + +
+
+
+ + +
+
@@ -192,6 +213,8 @@ self.data["description"] = self.markdown_editor.value() self.data["queue"] = self.refs.queue.value self.data["enable_detailed_results"] = self.refs.detailed_results.checked + self.data["make_programs_available"] = self.refs.make_programs_available.checked + self.data["make_input_data_available"] = self.refs.make_input_data_available.checked self.data["docker_image"] = $(self.refs.docker_image).val() self.data["competition_type"] = $(self.refs.competition_type).dropdown('get value') self.data['fact_sheet'] = self.serialize_fact_sheet_questions() @@ -323,6 +346,8 @@ .dropdown('set value', competition.queue.id) } self.refs.detailed_results.checked = competition.enable_detailed_results + self.refs.make_programs_available.checked = competition.make_programs_available + self.refs.make_input_data_available.checked = competition.make_input_data_available $(self.refs.docker_image).val(competition.docker_image) $(self.refs.reward).val(competition.reward) $(self.refs.contact_email).val(competition.contact_email) diff --git a/src/static/riot/competitions/editor/form.tag b/src/static/riot/competitions/editor/form.tag index 015949810..ef7a0e5e1 100644 --- a/src/static/riot/competitions/editor/form.tag +++ b/src/static/riot/competitions/editor/form.tag @@ -229,7 +229,6 @@ self.competition.collaborators = _.map(self.competition.collaborators, collab => collab.id ? collab.id : collab) var api_endpoint = self.opts.competition_id ? CODALAB.api.update_competition : CODALAB.api.create_competition - self.competition_return = JSON.parse(JSON.stringify(self.competition)) for(phase of self.competition_return.phases){ for(taskord of phase.task_instances){ diff --git a/src/templates/pages/server_status.html b/src/templates/pages/server_status.html index 946bad77e..ddd4a92b7 100644 --- a/src/templates/pages/server_status.html +++ b/src/templates/pages/server_status.html @@ -61,11 +61,11 @@

Monitor queues

- +
- RabbitMQ + RabbitMQ
This page allows admins to view connections, queued messages, message rates, channels, exchanges, and other administrative features relating to RabbitMQ e.g. Creating users, @@ -76,11 +76,11 @@

Monitor queues

- +
- Flower + Flower
Flower is a powerful web-based Celery monitoring tool designed to keep track of our tasks. diff --git a/src/utils/context_processors.py b/src/utils/context_processors.py index 38bcef301..74213b888 100644 --- a/src/utils/context_processors.py +++ b/src/utils/context_processors.py @@ -21,6 +21,6 @@ def common_settings(request): return { 'STORAGE_TYPE': settings.STORAGE_TYPE, 'USER_JSON_DATA': json.dumps(user_json_data), - 'RABBITMQ_MANAGEMENT_URL': f"{settings.RABBITMQ_HOST}:{settings.RABBITMQ_MANAGEMENT_PORT}", - 'FLOWER_URL': f"{settings.FLOWER_HOST}:{settings.FLOWER_PUBLIC_PORT}", + 'RABBITMQ_MANAGEMENT_URL': f"https://{settings.DOMAIN_NAME}:{settings.RABBITMQ_MANAGEMENT_PORT}", + 'FLOWER_URL': f"https://{settings.DOMAIN_NAME}:{settings.FLOWER_PUBLIC_PORT}", }