Skip to content
4 changes: 4 additions & 0 deletions src/apps/api/serializers/competitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down
5 changes: 3 additions & 2 deletions src/apps/api/views/competitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)

Expand Down
23 changes: 23 additions & 0 deletions src/apps/competitions/migrations/0038_auto_20230827_2303.py
Original file line number Diff line number Diff line change
@@ -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),
),
]
14 changes: 14 additions & 0 deletions src/apps/competitions/migrations/0039_merge_20230906_1305.py
Original file line number Diff line number Diff line change
@@ -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 = [
]
2 changes: 2 additions & 0 deletions src/apps/competitions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
2 changes: 2 additions & 0 deletions src/apps/competitions/unpackers/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -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": [],
Expand Down
3 changes: 2 additions & 1 deletion src/apps/competitions/unpackers/v2.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os

from django.utils import timezone

from competitions.unpackers.base_unpacker import BaseUnpacker
Expand All @@ -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),
Expand Down
52 changes: 35 additions & 17 deletions src/static/riot/competitions/detail/_tabs.tag
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@
<td>{file.task}</td>
<td>{file.type}</td>
<!-- <td>{file.type === 'Public Data' || file.type === 'Starting Kit' ? 'yes': 'no'}</td> -->
<td>yes</td>
<td class="center aligned">
<i if="{file.available}" class="checkmark box icon green"></i>
</td>
<td>{filesize(file.file_size * 1024)}</td>
</tr>
<!-- Conditional row if no files to show -->
Expand Down Expand Up @@ -184,15 +186,18 @@
</div>
</div>
</div>
<leaderboards class="leaderboard-table"
<!-- If there's no leaderboard, show this message -->
<div show="{_.isEmpty(competition.leaderboards)}">
<div class="center aligned"><h2>No visible leaderboard for this benchmark</h2></div>
</div>
<!-- Else, show the leaderboard -->
<div show="{!_.isEmpty(competition.leaderboards)}">
<leaderboards class="leaderboard-table"
phase_id="{ self.selected_phase_index }"
is_admin="{competition.admin}">
</leaderboards>
</div>
<div show="{!loading && _.isEmpty(competition.leaderboards)}">
<div class="center aligned"><h2>No Visible Leaderboards for this competition</h2></div>
</div>

</leaderboards>
</div>
</div>
</div>
</div>

Expand Down Expand Up @@ -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'){
Expand All @@ -255,7 +270,8 @@
file_size: solution.size,
phase: phase.name,
task: task.name,
type: 'Solution'
type: 'Solution',
available: true
})
})
})
Expand All @@ -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){
Expand All @@ -276,7 +293,8 @@
file_size: phase.public_data.file_size,
phase: phase.name,
task: '-',
type: 'Public Data'
type: 'Public Data',
available: true
})
}
}
Expand Down
25 changes: 25 additions & 0 deletions src/static/riot/competitions/editor/_competition_details.tag
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,27 @@
</div>
</form>
</div>
<div class="field smaller-mde">
<label>
Files Available
<sup>
<a href="https://github.com/codalab/codabench/wiki/Yaml-Structure"
target="_blank"
data-tooltip="What's this?">
<i class="grey question circle icon"></i>
</a>
</sup>
</label>
<div class="ui checkbox">
<label>Make Programs Available</label>
<input type="checkbox" ref="make_programs_available" onchange="{form_updated}">
</div>
<br>
<div class="ui checkbox">
<label>Make Input Data Available</label>
<input type="checkbox" ref="make_input_data_available" onchange="{form_updated}">
</div>
</div>
<div class="field">
<label>Queue</label>
<select class="ui fluid search selection dropdown" ref="queue"></select>
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion src/static/riot/competitions/editor/form.tag
Original file line number Diff line number Diff line change
Expand Up @@ -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){
Expand Down
8 changes: 4 additions & 4 deletions src/templates/pages/server_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ <h1>Monitor queues</h1>
<div id="external_monitors" class="ui two column grid">
<div class="column">
<div class="ui fluid card">
<a class="image" href="//{{ RABBITMQ_MANAGEMENT_URL }}" target="_blank">
<a class="image" href="{{ RABBITMQ_MANAGEMENT_URL}}" target="_blank">
<img class="ui large image" src="/static/img/RabbitMQ.png">
</a>
<div class="content">
<a class="header" href="//{{ RABBITMQ_MANAGEMENT_URL }}" target="_blank">RabbitMQ</a>
<a class="header" href="{{ RABBITMQ_MANAGEMENT_URL }}" target="_blank">RabbitMQ</a>
<div class="meta">
This page allows admins to view connections, queued messages, message rates, channels,
exchanges, and other administrative features relating to RabbitMQ e.g. Creating users,
Expand All @@ -76,11 +76,11 @@ <h1>Monitor queues</h1>
</div>
<div class="column">
<div class="ui fluid card">
<a class="image" href="//{{ FLOWER_URL }}" target="_blank">
<a class="image" href="{{ FLOWER_URL }}" target="_blank">
<img class="ui large image" src="/static/img/Flower.png">
</a>
<div class="content">
<a class="header" href="//{{ FLOWER_URL }}" target="_blank">Flower</a>
<a class="header" href="{{ FLOWER_URL }}" target="_blank">Flower</a>
<div class="meta">
Flower is a powerful web-based Celery monitoring tool designed to keep track of our
tasks.
Expand Down
4 changes: 2 additions & 2 deletions src/utils/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}",
}