diff --git a/api/launchpad/launchpad_views.py b/api/launchpad/launchpad_views.py index a7cbe916..ff31dee7 100644 --- a/api/launchpad/launchpad_views.py +++ b/api/launchpad/launchpad_views.py @@ -2,10 +2,10 @@ from rest_framework.views import APIView -from .serializers import LaunchpadLeaderBoardSerializer +from .serializers import LaunchpadLeaderBoardSerializer, LaunchpadParticipantsSerializer from utils.response import CustomResponse from utils.utils import CommonUtils -from db.user import User +from db.user import User, UserRoleLink from db.organization import UserOrganizationLink from db.task import KarmaActivityLog @@ -61,3 +61,116 @@ def get(self, request): return CustomResponse().paginated_response( data=serializer.data, pagination=paginated_queryset.get("pagination") ) + + +class ListParticipantsAPI(APIView): + def get(self, request): + allowed_org_types = ["College", "School", "Company"] + allowed_levels = [ + "IEEE Launchpad Level 1", + "IEEE Launchpad Level 2", + "IEEE Launchpad Level 3", + "IEEE Launchpad Level 4" + ] + + intro_task_completed_users = KarmaActivityLog.objects.filter( + task__event='launchpad', + appraiser_approved=True, + task__hashtag='#lp24-introduction', + ).values('user') + + users = User.objects.filter( + karma_activity_log_user__task__event="launchpad", + karma_activity_log_user__appraiser_approved=True, + id__in=intro_task_completed_users + ).prefetch_related( + Prefetch( + "user_organization_link_user", + queryset=UserOrganizationLink.objects.filter(org__org_type__in=allowed_org_types), + ), + Prefetch( + "user_role_link_user", + queryset=UserRoleLink.objects.filter(verified=True, role__title__in=allowed_levels).select_related('role') + ) + ).filter( + user_organization_link_user__id__in=UserOrganizationLink.objects.filter( + org__org_type__in=allowed_org_types + ).values("id") + ).annotate( + org=F("user_organization_link_user__org__title"), + district_name=F("user_organization_link_user__org__district__name"), + state=F("user_organization_link_user__org__district__zone__state__name"), + level=F("user_role_link_user__role__title"), + time_=Max("karma_activity_log_user__created_at"), + ).filter( + level__in=allowed_levels + ).distinct() + + paginated_queryset = CommonUtils.get_paginated_queryset( + users, + request, + ["full_name", "level", "org", "district_name", "state"] + ) + + serializer = LaunchpadParticipantsSerializer( + paginated_queryset.get("queryset"), many=True + ) + return CustomResponse().paginated_response( + data=serializer.data, pagination=paginated_queryset.get("pagination") + ) + + +class LaunchpadDetailsCount(APIView): + def get(self, request): + allowed_org_types = ["College", "School", "Company"] + allowed_levels = [ + "IEEE Launchpad Level 1", + "IEEE Launchpad Level 2", + "IEEE Launchpad Level 3", + "IEEE Launchpad Level 4" + ] + + intro_task_completed_users = KarmaActivityLog.objects.filter( + task__event='launchpad', + appraiser_approved=True, + task__hashtag='#lp24-introduction', + ).values('user') + + users = User.objects.filter( + karma_activity_log_user__task__event="launchpad", + karma_activity_log_user__appraiser_approved=True, + id__in=intro_task_completed_users + ).prefetch_related( + Prefetch( + "user_organization_link_user", + queryset=UserOrganizationLink.objects.filter(org__org_type__in=allowed_org_types), + ), + Prefetch( + "user_role_link_user", + queryset=UserRoleLink.objects.filter(verified=True, + role__title__in=allowed_levels).select_related('role') + ) + ).filter( + user_organization_link_user__id__in=UserOrganizationLink.objects.filter( + org__org_type__in=allowed_org_types + ).values("id") + ).annotate( + org=F("user_organization_link_user__org__title"), + district_name=F("user_organization_link_user__org__district__name"), + state=F("user_organization_link_user__org__district__zone__state__name"), + level=F("user_role_link_user__role__title"), + time_=Max("karma_activity_log_user__created_at"), + ).filter( + level__in=allowed_levels + ).distinct() + + # Count participants at each level + level_counts = { + "total_participants": users.count(), + "Level_1": users.filter(level="IEEE Launchpad Level 1").count(), + "Level_2": users.filter(level="IEEE Launchpad Level 2").count(), + "Level_3": users.filter(level="IEEE Launchpad Level 3").count(), + "Level_4": users.filter(level="IEEE Launchpad Level 4").count(), + } + + return CustomResponse(response=level_counts).get_success_response() diff --git a/api/launchpad/serializers.py b/api/launchpad/serializers.py index 1714d1e0..fdfbeba5 100644 --- a/api/launchpad/serializers.py +++ b/api/launchpad/serializers.py @@ -1,15 +1,10 @@ -from django.db.models import Sum, Max, Prefetch, F, OuterRef, Subquery, Window, IntegerField -from django.db.models.functions import Rank - from rest_framework import serializers from db.user import User -from db.organization import UserOrganizationLink -from db.task import KarmaActivityLog -import json + class LaunchpadLeaderBoardSerializer(serializers.ModelSerializer): - rank = serializers.SerializerMethodField() + rank = serializers.IntegerField() karma = serializers.IntegerField() org = serializers.CharField() district_name = serializers.CharField() @@ -19,46 +14,13 @@ class Meta: model = User fields = ("rank", "full_name", "karma", "org", "district_name", "state") - def get_rank(self, obj): - total_karma_subquery = KarmaActivityLog.objects.filter( - user=OuterRef('id'), - task__event='launchpad', - appraiser_approved=True, - ).values('user').annotate( - total_karma=Sum('karma') - ).values('total_karma') - allowed_org_types = ["College", "School", "Company"] - intro_task_completed_users = KarmaActivityLog.objects.filter( - task__event='launchpad', - appraiser_approved=True, - task__hashtag='#lp24-introduction', - ).values('user') - - users = User.objects.filter( - karma_activity_log_user__task__event="launchpad", - karma_activity_log_user__appraiser_approved=True, - id__in=intro_task_completed_users - ).prefetch_related( - Prefetch( - "user_organization_link_user", - queryset=UserOrganizationLink.objects.filter(org__org_type__in=allowed_org_types), - ) - ).filter( - user_organization_link_user__id__in=UserOrganizationLink.objects.filter( - org__org_type__in=allowed_org_types - ).values("id") - ).annotate( - karma=Subquery(total_karma_subquery, output_field=IntegerField()), - time_=Max("karma_activity_log_user__created_at"), - ).order_by("-karma", "time_") - - # high complexity - rank = 0 - for data in users: - rank += 1 - if data.id == obj.id: - break - - return rank +class LaunchpadParticipantsSerializer(serializers.ModelSerializer): + org = serializers.CharField() + district_name = serializers.CharField() + state = serializers.CharField() + level = serializers.CharField() + class Meta: + model = User + fields = ("full_name", "level", "org", "district_name", "state") \ No newline at end of file diff --git a/api/launchpad/urls.py b/api/launchpad/urls.py index 51a7db3e..093c6ec2 100644 --- a/api/launchpad/urls.py +++ b/api/launchpad/urls.py @@ -4,4 +4,6 @@ urlpatterns = [ path('leaderboard/', launchpad_views.Leaderboard.as_view()), + path('list-participants/', launchpad_views.ListParticipantsAPI.as_view()), + path('launchpad-details/', launchpad_views.LaunchpadDetailsCount.as_view()) ] \ No newline at end of file diff --git a/db/task.py b/db/task.py index f8f0457e..cccd6666 100644 --- a/db/task.py +++ b/db/task.py @@ -10,6 +10,7 @@ # fmt: off # noinspection PyPep8 + class Channel(models.Model): id = models.CharField(primary_key=True, max_length=36) name = models.CharField(max_length=75, unique=True) diff --git a/db/url_shortener.py b/db/url_shortener.py index b7b6a9aa..7981eb88 100644 --- a/db/url_shortener.py +++ b/db/url_shortener.py @@ -7,6 +7,7 @@ # fmt: off # noinspection PyPep8 + class UrlShortener(models.Model): id = models.CharField(primary_key=True, max_length=36) title = models.CharField(max_length=100) @@ -40,6 +41,7 @@ class UrlShortenerTracker(models.Model): location = models.CharField(max_length=36, blank=True, null=True) referrer = models.CharField(max_length=36, blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) + class Meta: managed = False db_table = 'url_shortener_tracker' diff --git a/db/user.py b/db/user.py index 24ab129b..3177c558 100644 --- a/db/user.py +++ b/db/user.py @@ -208,9 +208,6 @@ class Meta: db_table = 'dynamic_user' - - - class UserCouponLink(models.Model): id = models.CharField(primary_key=True, max_length=36) user = models.ForeignKey('User', on_delete=models.CASCADE, related_name='usercouponlink_user')