Files
vrobbler/vrobbler/apps/music/aggregators.py
Colin Powell d700b581a1 Fix filter order with annotations
We were getting all artists of all time, not just for the time period
2023-01-17 00:02:20 -05:00

104 lines
3.5 KiB
Python

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
NOW = timezone.now()
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)
def scrobble_counts():
finished_scrobbles_qs = Scrobble.objects.filter(played_to_completion=True)
data = {}
data['today'] = finished_scrobbles_qs.filter(
timestamp__gte=START_OF_TODAY
).count()
data['week'] = finished_scrobbles_qs.filter(
timestamp__gte=STARTING_DAY_OF_CURRENT_WEEK
).count()
data['month'] = finished_scrobbles_qs.filter(
timestamp__gte=STARTING_DAY_OF_CURRENT_MONTH
).count()
data['year'] = finished_scrobbles_qs.filter(
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]:
scrobble_day_dict = {}
media_filter = Q(track__isnull=False)
for day in range(6, -1, -1):
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()
)
return scrobble_day_dict
def top_tracks(filter: str = "today", limit: int = 15) -> List["Track"]:
time_filter = Q(scrobble__timestamp__gte=START_OF_TODAY)
if filter == "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)
if filter == "year":
time_filter = Q(scrobble__timestamp__gte=STARTING_DAY_OF_CURRENT_YEAR)
return (
Track.objects.filter(time_filter)
.annotate(num_scrobbles=Count("scrobble", distinct=True))
.order_by("-num_scrobbles")[:limit]
)
def top_artists(filter: str = "today", limit: int = 15) -> List["Artist"]:
time_filter = Q(track__scrobble__timestamp__gte=START_OF_TODAY)
if filter == "week":
time_filter = Q(
track__scrobble__timestamp__gte=STARTING_DAY_OF_CURRENT_WEEK
)
if filter == "month":
time_filter = Q(
track__scrobble__timestamp__gte=STARTING_DAY_OF_CURRENT_MONTH
)
if filter == "year":
time_filter = Q(
track__scrobble__timestamp__gte=STARTING_DAY_OF_CURRENT_YEAR
)
return (
Artist.objects.filter(time_filter)
.annotate(num_scrobbles=Count("track__scrobble", distinct=True))
.order_by("-num_scrobbles")[:limit]
)
def artist_scrobble_count(artist_id: int, filter: str = "today") -> int:
return Scrobble.objects.filter(track__artist=artist_id).count()