Skip to content

Commit

Permalink
[Backend] Allow disabling leaderboard data (#4180)
Browse files Browse the repository at this point in the history
* Add is_active and endpoint to change it leaderboarddata

* change is_active to is_disabled

* fix comments

* fix is_disabled

* change is_disabled to false

* fix test

* fix migration and remove get_object

* fix migration

* Update views.py

* Delete apps/challenges/migrations/0107_challenge_worker_image_url_alter.py

* Add missing migration

* Add new migration

---------

Co-authored-by: Gunjan Chhablani <[email protected]>
  • Loading branch information
Suryansh5545 and gchhablani authored Oct 24, 2023
1 parent 6d84712 commit ae017b4
Showing 8 changed files with 128 additions and 3 deletions.
1 change: 1 addition & 0 deletions apps/challenges/admin.py
Original file line number Diff line number Diff line change
@@ -329,6 +329,7 @@ class LeaderboardDataAdmin(ImportExportTimeStampedAdmin):
"challenge_phase_split",
"submission",
"leaderboard",
"is_disabled",
"result",
)
list_filter = ("challenge_phase_split", "created_at", "modified_at")
18 changes: 18 additions & 0 deletions apps/challenges/migrations/0107_leaderboarddata_is_disabled.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.20 on 2023-10-24 20:42

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('challenges', '0106_challenge_worker_image_url_alter'),
]

operations = [
migrations.AddField(
model_name='leaderboarddata',
name='is_disabled',
field=models.BooleanField(default=False),
),
]
1 change: 1 addition & 0 deletions apps/challenges/models.py
Original file line number Diff line number Diff line change
@@ -512,6 +512,7 @@ class LeaderboardData(TimeStampedModel):
submission = models.ForeignKey("jobs.Submission", on_delete=models.CASCADE)
leaderboard = models.ForeignKey("Leaderboard", on_delete=models.CASCADE)
result = JSONField()
is_disabled = models.BooleanField(default=False)
error = JSONField(null=True, blank=True)

def __str__(self):
5 changes: 5 additions & 0 deletions apps/challenges/urls.py
Original file line number Diff line number Diff line change
@@ -299,6 +299,11 @@
views.get_sponsors_by_challenge,
name="get_sponsors_by_challenge",
),
url(
r"^challenge/update_leaderboard_data/$",
views.update_leaderboard_data,
name="update_leaderboard_data",
)
]

app_name = "challenges"
63 changes: 62 additions & 1 deletion apps/challenges/views.py
Original file line number Diff line number Diff line change
@@ -160,6 +160,8 @@
send_emails,
)

from jobs.utils import get_submission_model

logger = logging.getLogger(__name__)

try:
@@ -4704,7 +4706,7 @@ def get_leaderboard_data(request, challenge_phase_split_pk):
return Response(response_data, status=status.HTTP_401_UNAUTHORIZED)
try:
challenge_phase_split = get_challenge_phase_split_model(challenge_phase_split_pk)
leaderboard_data = LeaderboardData.objects.filter(challenge_phase_split=challenge_phase_split)
leaderboard_data = LeaderboardData.objects.filter(challenge_phase_split=challenge_phase_split, is_disabled=False)
except LeaderboardData.DoesNotExist:
response_data = {
"error": "Leaderboard data not found!"
@@ -4763,3 +4765,62 @@ def update_challenge_approval(request):
"message": "Challenge updated successfully!"
}
return Response(response_data, status=status.HTTP_200_OK)


@api_view(["PUT"])
@throttle_classes([UserRateThrottle])
@permission_classes((permissions.IsAuthenticated, HasVerifiedEmail))
@authentication_classes((JWTAuthentication, ExpiringTokenAuthentication))
def update_leaderboard_data(request):
"""
API to update leaderboard data
Arguments:
request {dict} -- Request object
Query Parameters:
leaderboard_data {list} -- List of leaderboard data
challenge_phase_split {int} -- Challenge phase split primary key
submission {int} -- Submission primary key
leaderboard {int} -- Leaderboard primary key
is_disabled {int} -- Leaderboard data is disabled
"""
if not is_user_a_staff(request.user):
response_data = {
"error": "Sorry, you are not authorized to access this resource!"
}
return Response(response_data, status=status.HTTP_401_UNAUTHORIZED)

if request.method == "PUT":
leaderboard_data_pk = request.data.get("leaderboard_data")
leaderboard_pk = request.data.get("leaderboard")
challenge_phase_split_pk = request.data.get("challenge_phase_split")
submission_pk = request.data.get("submission")
is_disabled = request.data.get("is_disabled")

# Perform lookups and handle errors
try:
if leaderboard_data_pk:
leaderboard_data = LeaderboardData.objects.get(pk=leaderboard_data_pk)
else:
submission = get_submission_model(submission_pk)
challenge_phase_split = get_challenge_phase_split_model(challenge_phase_split_pk)
leaderboard = get_leaderboard_model(leaderboard_pk)
leaderboard_data = LeaderboardData.objects.get(
submission=submission,
challenge_phase_split=challenge_phase_split,
leaderboard=leaderboard
)
except Exception:
response_data = {
"error": "Resource not found!"
}
return Response(response_data, status=status.HTTP_404_NOT_FOUND)

# Update the 'is_disabled' attribute
leaderboard_data.is_disabled = bool(int(is_disabled))
leaderboard_data.save()

# Serialize and return the updated data
response_data = {
"message": "Leaderboard data updated successfully!"
}
return Response(response_data, status=status.HTTP_200_OK)
3 changes: 2 additions & 1 deletion apps/jobs/utils.py
Original file line number Diff line number Diff line change
@@ -357,7 +357,7 @@ def calculate_distinct_sorted_leaderboard_data(
leaderboard_data = LeaderboardData.objects.exclude(
Q(submission__created_by__email__in=challenge_hosts_emails)
& Q(submission__is_baseline=False)
)
).filter(is_disabled=False)

# Get all the successful submissions related to the challenge phase split
all_valid_submission_status = [Submission.FINISHED]
@@ -519,6 +519,7 @@ def get_leaderboard_data_model(submission_pk, challenge_phase_split_pk):
leaderboard_data = LeaderboardData.objects.get(
submission=submission_pk,
challenge_phase_split__pk=challenge_phase_split_pk,
is_disabled=False,
)
return leaderboard_data

2 changes: 1 addition & 1 deletion apps/jobs/views.py
Original file line number Diff line number Diff line change
@@ -2265,7 +2265,7 @@ def update_leaderboard_data(request, leaderboard_data_pk):
"""

try:
leaderboard_data = LeaderboardData.objects.get(pk=leaderboard_data_pk)
leaderboard_data = LeaderboardData.objects.get(pk=leaderboard_data_pk, is_disabled=False)
except LeaderboardData.DoesNotExist:
response_data = {"error": "Leaderboard data does not exist"}
return Response(response_data, status=status.HTTP_404_NOT_FOUND)
38 changes: 38 additions & 0 deletions tests/unit/challenges/test_views.py
Original file line number Diff line number Diff line change
@@ -6073,6 +6073,44 @@ def test_get_leaderboard_data_when_not_staff(self):
self.assertEqual(response.data, expected)
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

def test_update_leaderboard_data_when_not_staff(self):
self.url = reverse_lazy("challenges:update_leaderboard_data")
self.user.is_staff = False
self.user.save()
expected = {
"error": "Sorry, you are not authorized to access this resource!"
}
response = self.client.put(self.url)
self.assertEqual(response.data, expected)
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

def test_update_leaderboard_data_success(self):
self.url = reverse_lazy(
"challenges:update_leaderboard_data")
data = {"leaderboard_data": self.leaderboard_data.pk,
"is_disabled": 0
}
expected = {
"message": "Leaderboard data updated successfully!"
}
response = self.client.put(self.url, data)
self.assertEqual(response.data, expected)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_update_leaderboard_data_with_other_parameters(self):
self.url = reverse_lazy("challenges:update_leaderboard_data")
data = {"leaderboard": self.leaderboard.pk,
"challenge_phase_split": self.challenge_phase_split.pk,
"submission": self.submission.pk,
"is_disabled": 0
}
expected = {
"message": "Leaderboard data updated successfully!"
}
response = self.client.put(self.url, data)
self.assertEqual(response.data, expected)
self.assertEqual(response.status_code, status.HTTP_200_OK)


class TestUpdateChallenge(BaseAPITestClass):
def setUp(self):

0 comments on commit ae017b4

Please sign in to comment.