Skip to content

Commit

Permalink
Merge branch 'backend' into production
Browse files Browse the repository at this point in the history
  • Loading branch information
zakarm committed May 9, 2024
2 parents d8fac4f + 884f9df commit a35188d
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 3 deletions.
76 changes: 76 additions & 0 deletions app/back-end/dashboards/reports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""
Module to retrieve the total minutes played by a user
for a given period (current month, past 3 months, or past year).
"""
from datetime import datetime
from game.models import Match
from django.db.models import Q
import calendar

def get_minutes_per_day(obj, period):
"""
Retrieves the total minutes played by a user for a given period.
Args:
obj (User): The user object.
period (str): The time period ('month', '3_months', or 'year').
Returns:
list: A list of tuples containing (month, day, total_minutes_played).
"""
current_month = datetime.now().month
current_year = datetime.now().year
minutes_periods = []

if period == "month":
days_in_month = calendar.monthrange(current_year, current_month)[1]
month_days = [(current_month, day) for day in range(1, days_in_month + 1)]
minutes_periods = _get_minutes_per_day_for_month_days(obj, month_days)

elif period == "3_months":
for month_offset in range(3):
month = current_month - month_offset
year = current_year
if month < 1:
month += 12
year -= 1
days_in_month = calendar.monthrange(year, month)[1]
month_days = [(month, day) for day in range(1, days_in_month + 1)]
minutes_periods.extend(_get_minutes_per_day_for_month_days(obj, month_days))

elif period == "year":
for month in range(1, 13):
days_in_month = calendar.monthrange(current_year, month)[1]
month_days = [(month, day) for day in range(1, days_in_month + 1)]
minutes_periods.extend(_get_minutes_per_day_for_month_days(obj, month_days))

return minutes_periods

def _get_minutes_per_day_for_month_days(obj, month_days):
"""
Helper function to retrieve the total minutes played
for a list of (month, day) tuples.
Args:
obj (User): The user object.
month_days (list): A list of (month, day) tuples.
Returns:
list: A list of tuples containing (month, day, total_minutes_played).
"""
minutes_per_day = []
for month, day in month_days:
matches = Match.objects.filter(
Q(user_one=obj) &
Q(match_start__month=month) &
Q(match_start__year=datetime.now().year) &
Q(match_start__day=day)
)
match_durations = []
for match in matches:
match_duration = match.match_end - match.match_start
match_durations.append(match_duration.total_seconds() / 60)
total_minutes = sum(match_durations)
minutes_per_day.append((month, day, int(total_minutes)))

return minutes_per_day
45 changes: 44 additions & 1 deletion app/back-end/dashboards/serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
get_lose_games,
get_monthly_game_stats,
get_total_minutes)
import sys
from django.utils import timezone
from .reports import (get_minutes_per_day)

class MatchSerializer(serializers.ModelSerializer):
class Meta:
model = Match
Expand Down Expand Up @@ -171,3 +173,44 @@ def get_notifications(self, obj):
notifications_data = Notification.objects.filter(user = obj)
serializer = NotificationSerializer(notifications_data, many = True)
return serializer.data

class GameHistorySerializer(serializers.ModelSerializer):
matches_as_user_one = serializers.SerializerMethodField()
matches_as_user_two = serializers.SerializerMethodField()
minutes_per_day = serializers.SerializerMethodField()
class Meta:
model = User
fields = ('username', 'email', 'first_name', 'last_name', 'image_url',
'matches_as_user_one', 'matches_as_user_two',
'minutes_per_day')

def get_matches_as_user_one(self, obj):
period = self.context['period']
if period == 'day':
matches = Match.objects.filter(Q(user_one=obj) &
Q(match_start__day=timezone.now().day))
elif period == 'month':
matches = Match.objects.filter(Q(user_one=obj) &
Q(match_start__day=timezone.now().month))
elif period == "year":
matches = Match.objects.filter(Q(user_one=obj) &
Q(match_start__year=timezone.now().year))
serializer = MatchSerializer(matches, many=True)
return serializer.data

def get_matches_as_user_two(self, obj):
period = self.context['period']
if period == 'day':
matches = Match.objects.filter(Q(user_two=obj) &
Q(match_start__day=timezone.now().day))
elif period == 'month':
matches = Match.objects.filter(Q(user_two=obj) &
Q(match_start__day=timezone.now().month))
elif period == "year":
matches = Match.objects.filter(Q(user_two=obj) &
Q(match_start__year=timezone.now().year))
serializer = MatchSerializer(matches, many=True)
return serializer.data

def get_minutes_per_day(self, obj):
return get_minutes_per_day(obj, period=self.context['period'])
4 changes: 3 additions & 1 deletion app/back-end/dashboards/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
BlockFriendshipView,
UnblockFriendshipView,
BlockedFriendsView,
NotificationsView
NotificationsView,
GameHistoryReportView
)

urlpatterns = [
Expand All @@ -26,4 +27,5 @@
path('friends-unblock', UnblockFriendshipView.as_view(), name="friends-unblock"),
path('blocked-friends', BlockedFriendsView.as_view(), name="friends-unblock"),
path('notifications', NotificationsView.as_view(), name="notifications"),
path('game-stats-report', GameHistoryReportView.as_view(), name="game-stats-report")
]
17 changes: 16 additions & 1 deletion app/back-end/dashboards/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
FriendsSerializer,
UserSerializer,
BlockedFriendsSerializer,
NotificationUserSerializer)
NotificationUserSerializer,
GameHistorySerializer)
from .models import Friendship, Notification
from authentication.models import User
from rest_framework import status
Expand Down Expand Up @@ -248,3 +249,17 @@ def get(self, request):
user = request.user
serializer = NotificationUserSerializer(instance=user)
return Response(serializer.data)

class GameHistoryReportView(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]

serializer_class = GameHistorySerializer
def post(self, request):
user = request.user
period = request.data.get("period")
context = {"period": period}
serializer = self.serializer_class(instance=user, context=context)
return Response(serializer.data)


0 comments on commit a35188d

Please sign in to comment.