Add timezone support and an authenticated view
This commit is contained in:
@ -1,12 +1,13 @@
|
||||
from django.db.models import Q, Count, Sum
|
||||
from typing import List, Optional
|
||||
from scrobbles.models import Scrobble
|
||||
from music.models import Track, Artist
|
||||
from videos.models import Video
|
||||
|
||||
from django.utils import timezone
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List, Optional
|
||||
|
||||
import pytz
|
||||
from django.db.models import Count, Q, Sum
|
||||
from django.utils import timezone
|
||||
from music.models import Artist, Track
|
||||
from scrobbles.models import Scrobble
|
||||
from videos.models import Video
|
||||
from vrobbler.apps.profiles.utils import now_user_timezone
|
||||
|
||||
NOW = timezone.now()
|
||||
START_OF_TODAY = datetime.combine(NOW.date(), datetime.min.time(), NOW.tzinfo)
|
||||
@ -17,58 +18,103 @@ STARTING_DAY_OF_CURRENT_MONTH = NOW.date().replace(day=1)
|
||||
STARTING_DAY_OF_CURRENT_YEAR = NOW.date().replace(month=1, day=1)
|
||||
|
||||
|
||||
def scrobble_counts():
|
||||
finished_scrobbles_qs = Scrobble.objects.filter(played_to_completion=True)
|
||||
def scrobble_counts(user):
|
||||
|
||||
now = timezone.now()
|
||||
user_filter = Q()
|
||||
if user.is_authenticated:
|
||||
now = now_user_timezone(user.profile)
|
||||
user_filter = Q(user=user)
|
||||
|
||||
start_of_today = datetime.combine(
|
||||
now.date(), datetime.min.time(), now.tzinfo
|
||||
)
|
||||
starting_day_of_current_week = now.date() - timedelta(
|
||||
days=now.today().isoweekday() % 7
|
||||
)
|
||||
starting_day_of_current_month = now.date().replace(day=1)
|
||||
starting_day_of_current_year = now.date().replace(month=1, day=1)
|
||||
|
||||
finished_scrobbles_qs = Scrobble.objects.filter(
|
||||
user_filter, played_to_completion=True
|
||||
)
|
||||
data = {}
|
||||
data['today'] = finished_scrobbles_qs.filter(
|
||||
timestamp__gte=START_OF_TODAY
|
||||
timestamp__gte=start_of_today
|
||||
).count()
|
||||
data['week'] = finished_scrobbles_qs.filter(
|
||||
timestamp__gte=STARTING_DAY_OF_CURRENT_WEEK
|
||||
timestamp__gte=starting_day_of_current_week
|
||||
).count()
|
||||
data['month'] = finished_scrobbles_qs.filter(
|
||||
timestamp__gte=STARTING_DAY_OF_CURRENT_MONTH
|
||||
timestamp__gte=starting_day_of_current_month
|
||||
).count()
|
||||
data['year'] = finished_scrobbles_qs.filter(
|
||||
timestamp__gte=STARTING_DAY_OF_CURRENT_YEAR
|
||||
timestamp__gte=starting_day_of_current_year
|
||||
).count()
|
||||
data['alltime'] = finished_scrobbles_qs.count()
|
||||
return data
|
||||
|
||||
|
||||
def week_of_scrobbles(media: str = 'tracks') -> dict[str, int]:
|
||||
def week_of_scrobbles(user=None, media: str = 'tracks') -> dict[str, int]:
|
||||
|
||||
now = timezone.now()
|
||||
user_filter = Q()
|
||||
if user.is_authenticated:
|
||||
now = now_user_timezone(user.profile)
|
||||
user_filter = Q(user=user)
|
||||
|
||||
start_of_today = datetime.combine(
|
||||
now.date(), datetime.min.time(), now.tzinfo
|
||||
)
|
||||
|
||||
scrobble_day_dict = {}
|
||||
base_qs = Scrobble.objects.filter(user_filter, played_to_completion=True)
|
||||
|
||||
media_filter = Q(track__isnull=False)
|
||||
if media == 'movies':
|
||||
media_filter = Q(video__video_type=Video.VideoType.MOVIE)
|
||||
if media == 'series':
|
||||
media_filter = Q(video__video_type=Video.VideoType.TV_EPISODE)
|
||||
|
||||
for day in range(6, -1, -1):
|
||||
start = START_OF_TODAY - timedelta(days=day)
|
||||
end = datetime.combine(start, datetime.max.time(), NOW.tzinfo)
|
||||
start = start_of_today - timedelta(days=day)
|
||||
end = datetime.combine(start, datetime.max.time(), now.tzinfo)
|
||||
day_of_week = start.strftime('%A')
|
||||
if media == 'movies':
|
||||
media_filter = Q(video__videotype=Video.VideoType.MOVIE)
|
||||
if media == 'series':
|
||||
media_filter = Q(video__videotype=Video.VideoType.TV_EPISODE)
|
||||
scrobble_day_dict[day_of_week] = (
|
||||
Scrobble.objects.filter(media_filter)
|
||||
.filter(
|
||||
timestamp__gte=start,
|
||||
timestamp__lte=end,
|
||||
played_to_completion=True,
|
||||
)
|
||||
.count()
|
||||
)
|
||||
|
||||
scrobble_day_dict[day_of_week] = base_qs.filter(
|
||||
media_filter,
|
||||
timestamp__gte=start,
|
||||
timestamp__lte=end,
|
||||
played_to_completion=True,
|
||||
).count()
|
||||
|
||||
return scrobble_day_dict
|
||||
|
||||
|
||||
def top_tracks(filter: str = "today", limit: int = 15) -> List["Track"]:
|
||||
time_filter = Q(scrobble__timestamp__gte=START_OF_TODAY)
|
||||
def top_tracks(
|
||||
user: "User", filter: str = "today", limit: int = 15
|
||||
) -> List["Track"]:
|
||||
|
||||
now = timezone.now()
|
||||
if user.is_authenticated:
|
||||
now = now_user_timezone(user.profile)
|
||||
|
||||
start_of_today = datetime.combine(
|
||||
now.date(), datetime.min.time(), now.tzinfo
|
||||
)
|
||||
starting_day_of_current_week = now.date() - timedelta(
|
||||
days=now.today().isoweekday() % 7
|
||||
)
|
||||
starting_day_of_current_month = now.date().replace(day=1)
|
||||
starting_day_of_current_year = now.date().replace(month=1, day=1)
|
||||
|
||||
time_filter = Q(scrobble__timestamp__gte=start_of_today)
|
||||
if filter == "week":
|
||||
time_filter = Q(scrobble__timestamp__gte=STARTING_DAY_OF_CURRENT_WEEK)
|
||||
time_filter = Q(scrobble__timestamp__gte=starting_day_of_current_week)
|
||||
if filter == "month":
|
||||
time_filter = Q(scrobble__timestamp__gte=STARTING_DAY_OF_CURRENT_MONTH)
|
||||
time_filter = Q(scrobble__timestamp__gte=starting_day_of_current_month)
|
||||
if filter == "year":
|
||||
time_filter = Q(scrobble__timestamp__gte=STARTING_DAY_OF_CURRENT_YEAR)
|
||||
time_filter = Q(scrobble__timestamp__gte=starting_day_of_current_year)
|
||||
|
||||
return (
|
||||
Track.objects.filter(time_filter)
|
||||
@ -77,7 +123,9 @@ def top_tracks(filter: str = "today", limit: int = 15) -> List["Track"]:
|
||||
)
|
||||
|
||||
|
||||
def top_artists(filter: str = "today", limit: int = 15) -> List["Artist"]:
|
||||
def top_artists(
|
||||
user: "User", filter: str = "today", limit: int = 15
|
||||
) -> List["Artist"]:
|
||||
time_filter = Q(track__scrobble__timestamp__gte=START_OF_TODAY)
|
||||
if filter == "week":
|
||||
time_filter = Q(
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import datetime
|
||||
import settings
|
||||
|
||||
import pytz
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
# need to translate to a non-naive timezone, even if timezone == settings.TIME_ZONE, so we can compare two dates
|
||||
def to_user_timezone(date, profile):
|
||||
@ -17,7 +20,12 @@ def to_system_timezone(date, profile):
|
||||
)
|
||||
|
||||
|
||||
def now_timezone():
|
||||
def now_user_timezone(profile):
|
||||
timezone.activate(pytz.timezone(profile.timezone))
|
||||
return timezone.localtime(timezone.now())
|
||||
|
||||
|
||||
def now_system_timezone():
|
||||
return (
|
||||
datetime.datetime.now()
|
||||
.replace(tzinfo=pytz.timezone(settings.TIME_ZONE))
|
||||
|
||||
@ -9,6 +9,7 @@ from django.utils import timezone
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.generic import FormView
|
||||
from django.views.generic.list import ListView
|
||||
import pytz
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
@ -45,31 +46,44 @@ class RecentScrobbleList(ListView):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
data = super().get_context_data(**kwargs)
|
||||
user = self.request.user
|
||||
now = timezone.now()
|
||||
data['now_playing_list'] = Scrobble.objects.filter(
|
||||
in_progress=True,
|
||||
is_paused=False,
|
||||
timestamp__lte=now,
|
||||
)
|
||||
data['video_scrobble_list'] = Scrobble.objects.filter(
|
||||
video__isnull=False, played_to_completion=True
|
||||
).order_by('-timestamp')[:15]
|
||||
data['podcast_scrobble_list'] = Scrobble.objects.filter(
|
||||
podcast_episode__isnull=False, played_to_completion=True
|
||||
).order_by('-timestamp')[:15]
|
||||
data['sport_scrobble_list'] = Scrobble.objects.filter(
|
||||
sport_event__isnull=False, played_to_completion=True
|
||||
).order_by('-timestamp')[:15]
|
||||
# data['top_daily_tracks'] = top_tracks()
|
||||
# data['top_weekly_tracks'] = top_tracks(filter='week')
|
||||
data['top_monthly_tracks'] = top_tracks(filter='month')
|
||||
if self.request.user.is_authenticated:
|
||||
timezone.activate(pytz.timezone(user.profile.timezone))
|
||||
now = timezone.localtime(timezone.now())
|
||||
data['now_playing_list'] = Scrobble.objects.filter(
|
||||
in_progress=True,
|
||||
is_paused=False,
|
||||
timestamp__lte=now,
|
||||
user=user,
|
||||
)
|
||||
|
||||
# data['top_daily_artists'] = top_artists()
|
||||
data['top_weekly_artists'] = top_artists(filter='week')
|
||||
data['top_monthly_artists'] = top_artists(filter='month')
|
||||
completed_for_user = Scrobble.objects.filter(
|
||||
played_to_completion=True, user=user
|
||||
)
|
||||
data['video_scrobble_list'] = completed_for_user.filter(
|
||||
video__isnull=False
|
||||
).order_by('-timestamp')[:15]
|
||||
|
||||
data["weekly_data"] = week_of_scrobbles()
|
||||
data['counts'] = scrobble_counts()
|
||||
data['podcast_scrobble_list'] = completed_for_user.filter(
|
||||
podcast_episode__isnull=False
|
||||
).order_by('-timestamp')[:15]
|
||||
|
||||
data['sport_scrobble_list'] = completed_for_user.filter(
|
||||
sport_event__isnull=False
|
||||
).order_by('-timestamp')[:15]
|
||||
|
||||
# data['top_daily_tracks'] = top_tracks()
|
||||
data['top_weekly_tracks'] = top_tracks(user, filter='week')
|
||||
data['top_monthly_tracks'] = top_tracks(user, filter='month')
|
||||
|
||||
# data['top_daily_artists'] = top_artists()
|
||||
data['top_weekly_artists'] = top_artists(user, filter='week')
|
||||
data['top_monthly_artists'] = top_artists(user, filter='month')
|
||||
|
||||
data["weekly_data"] = week_of_scrobbles(user=user)
|
||||
|
||||
data['counts'] = scrobble_counts(user)
|
||||
data['imdb_form'] = ScrobbleForm
|
||||
return data
|
||||
|
||||
|
||||
Reference in New Issue
Block a user