From 2546aa0503e5c0b82967bbe9541e60610fb4f393 Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Sun, 11 Feb 2024 15:09:37 +0500 Subject: [PATCH 01/17] rerun whole phase, only rerun submissions with no parent (this automatically runs parents and children submissions --- src/apps/api/views/competitions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/api/views/competitions.py b/src/apps/api/views/competitions.py index 3dc2f0bba..ef86c11cc 100644 --- a/src/apps/api/views/competitions.py +++ b/src/apps/api/views/competitions.py @@ -634,8 +634,8 @@ def rerun_submissions(self, request, pk): phase = self.get_object() comp = phase.competition - # Get submissions - submissions = phase.submissions.all() + # Get submissions with no parent + submissions = phase.submissions.filter(parent__isnull=True) can_re_run_submissions = False error_message = "" From 5179ec32abb17789c09c239aa99383e5d1133f2b Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Sun, 11 Feb 2024 19:37:14 +0500 Subject: [PATCH 02/17] add message in the empty error --- src/apps/api/views/submissions.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/apps/api/views/submissions.py b/src/apps/api/views/submissions.py index f9582488d..f3d410792 100644 --- a/src/apps/api/views/submissions.py +++ b/src/apps/api/views/submissions.py @@ -209,9 +209,14 @@ def submission_leaderboard_connection(self, request, pk): submission = self.get_object() phase = submission.phase - if not (request.user.is_superuser or request.user == submission.owner): - if not phase.competition.collaborators.filter(pk=request.user.pk).exists(): - raise Http404 + # only super user, owner of submission and competition organizer can proceed + if not ( + request.user.is_superuser or + request.user == submission.owner or + request.user in phase.competition.all_organizers + ): + raise ValidationError("You cannot perform this action, contact the competition organizer!") + if submission.phase.leaderboard.submission_rule in Leaderboard.AUTO_SUBMISSION_RULES and not request.user.is_superuser: raise ValidationError("Users are not allowed to edit the leaderboard on this Competition") From 35eaaee6bf181cfdc904910ec66430b95164f4ea Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Sun, 11 Feb 2024 19:41:57 +0500 Subject: [PATCH 03/17] unused import removed --- src/apps/api/views/submissions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/apps/api/views/submissions.py b/src/apps/api/views/submissions.py index f3d410792..2a5278b97 100644 --- a/src/apps/api/views/submissions.py +++ b/src/apps/api/views/submissions.py @@ -6,7 +6,6 @@ from django_filters.rest_framework import DjangoFilterBackend from rest_framework import status from rest_framework.decorators import api_view, permission_classes, action -from django.http import Http404 from rest_framework.exceptions import PermissionDenied, ValidationError from rest_framework.filters import SearchFilter from rest_framework.generics import get_object_or_404 From 3513e9efd745245605535e45bf6c4fe2408cc0a3 Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Mon, 12 Feb 2024 12:24:04 +0500 Subject: [PATCH 04/17] test fixed, additional test added --- src/apps/api/views/submissions.py | 8 ++++++-- src/apps/competitions/tests/test_submissions.py | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/apps/api/views/submissions.py b/src/apps/api/views/submissions.py index 2a5278b97..2eb4a8cee 100644 --- a/src/apps/api/views/submissions.py +++ b/src/apps/api/views/submissions.py @@ -205,7 +205,11 @@ def has_admin_permission(self, user, submission): @action(detail=True, methods=('POST', 'DELETE')) def submission_leaderboard_connection(self, request, pk): + + # get submission submission = self.get_object() + + # get submission phase phase = submission.phase # only super user, owner of submission and competition organizer can proceed @@ -214,10 +218,10 @@ def submission_leaderboard_connection(self, request, pk): request.user == submission.owner or request.user in phase.competition.all_organizers ): - raise ValidationError("You cannot perform this action, contact the competition organizer!") + raise PermissionDenied("You cannot perform this action, contact the competition organizer!") if submission.phase.leaderboard.submission_rule in Leaderboard.AUTO_SUBMISSION_RULES and not request.user.is_superuser: - raise ValidationError("Users are not allowed to edit the leaderboard on this Competition") + raise PermissionDenied("Users are not allowed to edit the leaderboard on this Competition") if request.method == 'POST': # Removing any existing submissions on leaderboard unless multiples are allowed diff --git a/src/apps/competitions/tests/test_submissions.py b/src/apps/competitions/tests/test_submissions.py index 4e58ebd93..a7ae024f2 100644 --- a/src/apps/competitions/tests/test_submissions.py +++ b/src/apps/competitions/tests/test_submissions.py @@ -155,7 +155,21 @@ def test_only_owner_can_add_submission_to_leaderboard(self): self.client.force_login(different_user) url = reverse('submission-submission-leaderboard-connection', kwargs={'pk': parent_sub.pk}) resp = self.client.post(url) - assert resp.status_code == 404 + assert resp.status_code == 403 + assert resp.data["detail"] == "You cannot perform this action, contact the competition organizer!" + + def test_only_owner_can_remove_submission_from_leaderboard(self): + parent_sub = SubmissionFactory(has_children=True) + leaderboard = LeaderboardFactory() + parent_sub.phase.leaderboard = leaderboard + parent_sub.phase.save() + + different_user = UserFactory() + self.client.force_login(different_user) + url = reverse('submission-submission-leaderboard-connection', kwargs={'pk': parent_sub.pk}) + resp = self.client.delete(url) + assert resp.status_code == 403 + assert resp.data["detail"] == "You cannot perform this action, contact the competition organizer!" def test_adding_submission_removes_other_submissions_from_owner(self): leaderboard = LeaderboardFactory() From b1d549d166aea54e56a1416d0e5a224a2047b12b Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Wed, 14 Feb 2024 15:35:40 +0500 Subject: [PATCH 05/17] leaderboard number of enteries: exlude failed and cancelled submissions --- src/apps/api/views/competitions.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/apps/api/views/competitions.py b/src/apps/api/views/competitions.py index 3dc2f0bba..790b9066b 100644 --- a/src/apps/api/views/competitions.py +++ b/src/apps/api/views/competitions.py @@ -704,12 +704,18 @@ def get_leaderboard(self, request, pk): submission_detailed_results = {} for submission in query['submissions']: # count number of entries/number of submissions for the owner of this submission for this phase - # count all submissions with no parent and count all parents without counting the children + # count all submissions except: + # - child submissions (submissions who has a parent i.e. parent field is not null) + # - Failed submissions + # - Cancelled submissions num_entries = Submission.objects.filter( - Q(owner__username=submission['owner']) | Q(parent__owner__username=submission['owner']), + Q(owner__username=submission['owner']) | + Q(parent__owner__username=submission['owner']), phase=phase, ).exclude( - parent__isnull=False + Q(status=Submission.FAILED) | + Q(status=Submission.CANCELLED) | + Q(parent__isnull=False) ).count() submission_key = f"{submission['owner']}{submission['parent'] or submission['id']}" From 16579a7209a72ce2e482019cc3a63cfdefaf347d Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Thu, 15 Feb 2024 22:58:17 +0500 Subject: [PATCH 06/17] empty error is now shown to participant --- src/apps/api/views/submissions.py | 1 + src/static/riot/competitions/detail/submission_manager.tag | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/apps/api/views/submissions.py b/src/apps/api/views/submissions.py index 2eb4a8cee..394e160bb 100644 --- a/src/apps/api/views/submissions.py +++ b/src/apps/api/views/submissions.py @@ -220,6 +220,7 @@ def submission_leaderboard_connection(self, request, pk): ): raise PermissionDenied("You cannot perform this action, contact the competition organizer!") + # only super user and with these leaderboard rules (FORCE_LAST, FORCE_BEST, FORCE_LATEST_MULTIPLE) can proceed if submission.phase.leaderboard.submission_rule in Leaderboard.AUTO_SUBMISSION_RULES and not request.user.is_superuser: raise PermissionDenied("Users are not allowed to edit the leaderboard on this Competition") diff --git a/src/static/riot/competitions/detail/submission_manager.tag b/src/static/riot/competitions/detail/submission_manager.tag index e7a6f17ed..95db0f866 100644 --- a/src/static/riot/competitions/detail/submission_manager.tag +++ b/src/static/riot/competitions/detail/submission_manager.tag @@ -262,7 +262,7 @@ CODALAB.events.trigger('submission_changed_on_leaderboard') }) .fail(function (response) { - toastr.error(response.responseJSON) + toastr.error(response.responseJSON.detail) }) event.stopPropagation() } @@ -273,7 +273,7 @@ CODALAB.events.trigger('submission_changed_on_leaderboard') }) .fail(function (response) { - toastr.error(response.responseJSON) + toastr.error(response.responseJSON.detail) }) event.stopPropagation() } From fca617e39daac215a1ffbf13fa8d55c6bcc564be Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Fri, 16 Feb 2024 12:21:23 +0500 Subject: [PATCH 07/17] empty error resolved --- src/apps/api/views/submissions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/api/views/submissions.py b/src/apps/api/views/submissions.py index 394e160bb..2ce2d3fbe 100644 --- a/src/apps/api/views/submissions.py +++ b/src/apps/api/views/submissions.py @@ -237,7 +237,7 @@ def submission_leaderboard_connection(self, request, pk): if request.method == 'DELETE': if submission.phase.leaderboard.submission_rule not in [Leaderboard.ADD_DELETE, Leaderboard.ADD_DELETE_MULTIPLE]: - raise ValidationError("You are not allowed to remove a submission on this phase") + raise PermissionDenied("You are not allowed to remove a submission on this phase") submission.leaderboard = None submission.save() Submission.objects.filter(parent=submission).update(leaderboard=None) From 18f521bc65e180cf6f5946fa877d4a838337ae89 Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Fri, 16 Feb 2024 14:43:01 +0500 Subject: [PATCH 08/17] small logo for popular and featured comps on home page --- src/apps/api/serializers/competitions.py | 1 + src/static/riot/competitions/tile/competition_tile.tag | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/apps/api/serializers/competitions.py b/src/apps/api/serializers/competitions.py index e3bc20fb7..7006529aa 100644 --- a/src/apps/api/serializers/competitions.py +++ b/src/apps/api/serializers/competitions.py @@ -404,6 +404,7 @@ class Meta: 'published', 'participant_count', 'logo', + 'logo_icon', 'description', 'competition_type', 'reward', diff --git a/src/static/riot/competitions/tile/competition_tile.tag b/src/static/riot/competitions/tile/competition_tile.tag index 5c4fdcb7e..59f48003e 100644 --- a/src/static/riot/competitions/tile/competition_tile.tag +++ b/src/static/riot/competitions/tile/competition_tile.tag @@ -2,7 +2,7 @@
- +
From 14901088bfe29870d10532cc704d8b821efc89ad Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Fri, 16 Feb 2024 17:27:39 +0500 Subject: [PATCH 09/17] privacy link updated --- src/templates/emails/base_email.html | 2 +- src/templates/emails/base_email.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/templates/emails/base_email.html b/src/templates/emails/base_email.html index 53b214c40..903e75e33 100644 --- a/src/templates/emails/base_email.html +++ b/src/templates/emails/base_email.html @@ -98,7 +98,7 @@

Hello{% if user %} {{ user.username }}{% endif %},

{% endif %}
diff --git a/src/templates/emails/base_email.txt b/src/templates/emails/base_email.txt index 7048b2617..927e2db0c 100644 --- a/src/templates/emails/base_email.txt +++ b/src/templates/emails/base_email.txt @@ -14,4 +14,4 @@ Unsubscribe or manage notification settings: http://{{ site.domain }} Privacy policy: -http://codalab.github.io/codalab/notices.html +https://github.com/codalab/codalab-competitions/wiki/Privacy From 76e4d2b193c52e9e164758f98183e51c5b9993d9 Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Sat, 17 Feb 2024 21:04:05 +0500 Subject: [PATCH 10/17] html tags in email text --- src/utils/email.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/utils/email.py b/src/utils/email.py index ec557fdcf..846a5edbc 100644 --- a/src/utils/email.py +++ b/src/utils/email.py @@ -41,9 +41,10 @@ def sanitize(content): def codalab_send_markdown_email(subject, markdown_content, recipient_list, from_email=None): from_email = from_email if from_email else settings.DEFAULT_FROM_EMAIL - message = sanitize(markdown_content) - html_message = sanitize(markdown.markdown(message)) + html_message = markdown.markdown(markdown_content) + # message = sanitize(markdown_content) + # html_message = sanitize(markdown.markdown(message)) - message = EmailMultiAlternatives(subject, message, from_email=from_email, bcc=recipient_list) + message = EmailMultiAlternatives(subject, '', from_email=from_email, bcc=recipient_list) message.attach_alternative(html_message, 'text/html') message.send() From a3787e453ae730d376552b86971f45cf9531400e Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Tue, 20 Feb 2024 18:20:31 +0500 Subject: [PATCH 11/17] removed caching competitions for the public page --- src/apps/api/views/competitions.py | 1 - src/static/riot/competitions/public-list.tag | 24 ++++++++------------ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/apps/api/views/competitions.py b/src/apps/api/views/competitions.py index 5e3a6aa43..a08aa6cdb 100644 --- a/src/apps/api/views/competitions.py +++ b/src/apps/api/views/competitions.py @@ -533,7 +533,6 @@ def create_dump(self, request, pk=None): serializer = CompetitionCreationTaskStatusSerializer({"status": "Success. Competition dump is being created."}) return Response(serializer.data, status=201) - @cache_response(key_func=DefaultListKeyConstructor()) @action(detail=False, methods=('GET',), pagination_class=LargePagination) def public(self, request): qs = self.get_queryset() diff --git a/src/static/riot/competitions/public-list.tag b/src/static/riot/competitions/public-list.tag index c9c8e4680..c2eef1f43 100644 --- a/src/static/riot/competitions/public-list.tag +++ b/src/static/riot/competitions/public-list.tag @@ -49,7 +49,6 @@