From 959d77666b2f01fbde3936e9546e27eacb0109a1 Mon Sep 17 00:00:00 2001 From: OhMaley Date: Mon, 16 Sep 2024 11:02:09 -0400 Subject: [PATCH 01/26] Fix string concat in case of no email in analytics api --- src/apps/api/views/analytics.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/apps/api/views/analytics.py b/src/apps/api/views/analytics.py index 922d0f438..0c056cd73 100644 --- a/src/apps/api/views/analytics.py +++ b/src/apps/api/views/analytics.py @@ -231,10 +231,12 @@ def competitions_usage(request): 'datefield' ) for su in query.order_by("-datefield", "competition__id"): + username = su['competition__created_by__username'] or ("user #" + su['competition__created_by__id']) or "unknown user" + email = su['competition__created_by__email'] or "no email" competitions_usage.setdefault(su['datefield'].isoformat(), {})[su['competition__id']] = { 'snapshot_id': su['id'], 'title': su['competition__title'], - 'organizer': su['competition__created_by__username'] + " (" + su['competition__created_by__email'] + ")", + 'organizer': username + " (" + email + ")", 'created_when': su['competition__created_when'], 'datasets': su['datasets_total'], } @@ -275,9 +277,11 @@ def users_usage(request): 'datefield' ) for su in query.order_by("-datefield", "user__id"): + username = su['user__username'] or ("user #" + su['user__id']) or "unknown user" + email = su['user__email'] or "no email" users_usage.setdefault(su['datefield'].isoformat(), {})[su['user__id']] = { 'snapshot_id': su['id'], - 'name': su['user__username'] + " (" + su['user__email'] + ")", + 'name': username + " (" + email + ")", 'date_joined': su['user__date_joined'], 'datasets': su['datasets_total'], 'submissions': su['submissions_total'], From 346bc535254c89b1576da0aa188be3d602a1fe6a Mon Sep 17 00:00:00 2001 From: Ihsan Ullah Date: Fri, 4 Oct 2024 14:18:52 +0500 Subject: [PATCH 02/26] resource interface-> task updates --- src/apps/api/serializers/tasks.py | 29 ++++++++++++++++--------- src/static/riot/tasks/management.tag | 32 +++++++++++++++++----------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/apps/api/serializers/tasks.py b/src/apps/api/serializers/tasks.py index acd07a8c4..35dcfe66a 100644 --- a/src/apps/api/serializers/tasks.py +++ b/src/apps/api/serializers/tasks.py @@ -99,6 +99,7 @@ class TaskDetailSerializer(WritableNestedModelSerializer): solutions = SolutionSerializer(many=True, required=False, read_only=True) validated = serializers.SerializerMethodField(required=False) shared_with = serializers.SerializerMethodField() + competitions = serializers.SerializerMethodField() class Meta: model = Task @@ -112,6 +113,8 @@ class Meta: 'created_when', 'is_public', 'validated', + 'shared_with', + 'competitions', # Data pieces 'input_data', @@ -119,9 +122,16 @@ class Meta: 'reference_data', 'scoring_program', 'solutions', - 'shared_with', ) + def get_competitions(self, instance): + + # Fech competitions which hase phases with this task + # competitions = Phase.objects.filter(tasks__in=[instance.pk]).values('competition') + competitions = Competition.objects.filter(phases__tasks__in=[instance.pk]).values("id", "title").distinct() + + return competitions + def get_validated(self, task): return task.validated is not None @@ -136,10 +146,9 @@ def get_owner_display_name(self, instance): class TaskListSerializer(serializers.ModelSerializer): solutions = SolutionListSerializer(many=True, required=False, read_only=True) value = serializers.CharField(source='key', required=False) - competitions = serializers.SerializerMethodField() - shared_with = serializers.SerializerMethodField() created_by = serializers.CharField(source='created_by.username', read_only=True) owner_display_name = serializers.SerializerMethodField() + is_used_in_competitions = serializers.SerializerMethodField() class Meta: model = Task @@ -150,21 +159,21 @@ class Meta: 'owner_display_name', 'key', 'name', + 'description', 'solutions', 'ingestion_only_during_scoring', # Value is used for Semantic Multiselect dropdown api calls 'value', - 'competitions', - 'shared_with', + 'is_public', + 'is_used_in_competitions', ) - def get_competitions(self, instance): + def get_is_used_in_competitions(self, instance): - # Fech competitions which hase phases with this task - # competitions = Phase.objects.filter(tasks__in=[instance.pk]).values('competition') - competitions = Competition.objects.filter(phases__tasks__in=[instance.pk]).values("id", "title").distinct() + # Count competitions that are using this task + num_competitions = Competition.objects.filter(phases__tasks__in=[instance.pk]).distinct().count() - return competitions + return num_competitions > 0 def get_shared_with(self, instance): return self.context['shared_with'][instance.pk] diff --git a/src/static/riot/tasks/management.tag b/src/static/riot/tasks/management.tag index 37510275e..93d2a65bb 100644 --- a/src/static/riot/tasks/management.tag +++ b/src/static/riot/tasks/management.tag @@ -19,9 +19,9 @@ Name - Benchmarks - Shared With - Uploaded... + Description + Creator + In Use Public Actions @@ -30,17 +30,11 @@ { task.name } - -
- -
- - + { task.description } + {task.owner_display_name} + + - { task.shared_with.join(', ') } - { timeSince(Date.parse(task.created_when)) } ago @@ -88,6 +82,7 @@ +