Condense live charts to one function
This commit is contained in:
@ -5,12 +5,7 @@ import time_machine
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from music.aggregators import (
|
from music.aggregators import live_charts, scrobble_counts, week_of_scrobbles
|
||||||
scrobble_counts,
|
|
||||||
top_artists,
|
|
||||||
top_tracks,
|
|
||||||
week_of_scrobbles,
|
|
||||||
)
|
|
||||||
from profiles.models import UserProfile
|
from profiles.models import UserProfile
|
||||||
from scrobbles.models import Scrobble
|
from scrobbles.models import Scrobble
|
||||||
|
|
||||||
@ -55,7 +50,7 @@ def test_week_of_scrobbles_data(client, mopidy_track_request_data):
|
|||||||
def test_top_tracks_by_day(client, mopidy_track_request_data):
|
def test_top_tracks_by_day(client, mopidy_track_request_data):
|
||||||
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
||||||
user = get_user_model().objects.first()
|
user = get_user_model().objects.first()
|
||||||
tops = top_tracks(user)
|
tops = live_charts(user)
|
||||||
assert tops[0].title == "Same in the End"
|
assert tops[0].title == "Same in the End"
|
||||||
|
|
||||||
|
|
||||||
@ -63,7 +58,7 @@ def test_top_tracks_by_day(client, mopidy_track_request_data):
|
|||||||
def test_top_tracks_by_week(client, mopidy_track_request_data):
|
def test_top_tracks_by_week(client, mopidy_track_request_data):
|
||||||
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
||||||
user = get_user_model().objects.first()
|
user = get_user_model().objects.first()
|
||||||
tops = top_tracks(user, filter='week')
|
tops = live_charts(user, chart_period='week')
|
||||||
assert tops[0].title == "Same in the End"
|
assert tops[0].title == "Same in the End"
|
||||||
|
|
||||||
|
|
||||||
@ -71,7 +66,7 @@ def test_top_tracks_by_week(client, mopidy_track_request_data):
|
|||||||
def test_top_tracks_by_month(client, mopidy_track_request_data):
|
def test_top_tracks_by_month(client, mopidy_track_request_data):
|
||||||
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
||||||
user = get_user_model().objects.first()
|
user = get_user_model().objects.first()
|
||||||
tops = top_tracks(user, filter='month')
|
tops = live_charts(user, chart_period='month')
|
||||||
assert tops[0].title == "Same in the End"
|
assert tops[0].title == "Same in the End"
|
||||||
|
|
||||||
|
|
||||||
@ -79,7 +74,7 @@ def test_top_tracks_by_month(client, mopidy_track_request_data):
|
|||||||
def test_top_tracks_by_year(client, mopidy_track_request_data):
|
def test_top_tracks_by_year(client, mopidy_track_request_data):
|
||||||
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
||||||
user = get_user_model().objects.first()
|
user = get_user_model().objects.first()
|
||||||
tops = top_tracks(user, filter='year')
|
tops = live_charts(user, chart_period='year')
|
||||||
assert tops[0].title == "Same in the End"
|
assert tops[0].title == "Same in the End"
|
||||||
|
|
||||||
|
|
||||||
@ -87,7 +82,7 @@ def test_top_tracks_by_year(client, mopidy_track_request_data):
|
|||||||
def test_top__artists_by_week(client, mopidy_track_request_data):
|
def test_top__artists_by_week(client, mopidy_track_request_data):
|
||||||
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
||||||
user = get_user_model().objects.first()
|
user = get_user_model().objects.first()
|
||||||
tops = top_artists(user, filter='week')
|
tops = live_charts(user, chart_period='week', media_type="Artist")
|
||||||
assert tops[0].name == "Sublime"
|
assert tops[0].name == "Sublime"
|
||||||
|
|
||||||
|
|
||||||
@ -95,7 +90,7 @@ def test_top__artists_by_week(client, mopidy_track_request_data):
|
|||||||
def test_top__artists_by_month(client, mopidy_track_request_data):
|
def test_top__artists_by_month(client, mopidy_track_request_data):
|
||||||
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
||||||
user = get_user_model().objects.first()
|
user = get_user_model().objects.first()
|
||||||
tops = top_artists(user, filter='month')
|
tops = live_charts(user, chart_period='month', media_type="Artist")
|
||||||
assert tops[0].name == "Sublime"
|
assert tops[0].name == "Sublime"
|
||||||
|
|
||||||
|
|
||||||
@ -103,5 +98,5 @@ def test_top__artists_by_month(client, mopidy_track_request_data):
|
|||||||
def test_top__artists_by_year(client, mopidy_track_request_data):
|
def test_top__artists_by_year(client, mopidy_track_request_data):
|
||||||
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
build_scrobbles(client, mopidy_track_request_data, 7, 1)
|
||||||
user = get_user_model().objects.first()
|
user = get_user_model().objects.first()
|
||||||
tops = top_artists(user, filter='year')
|
tops = live_charts(user, chart_period='year', media_type="Artist")
|
||||||
assert tops[0].name == "Sublime"
|
assert tops[0].name == "Sublime"
|
||||||
|
|||||||
@ -1,22 +1,14 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import List, Optional
|
from typing import List
|
||||||
|
|
||||||
import pytz
|
from django.apps import apps
|
||||||
from django.db.models import Count, Q, Sum
|
from django.db.models import Count, Q, QuerySet
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from music.models import Artist, Track
|
from music.models import Artist, Track
|
||||||
from scrobbles.models import Scrobble
|
from scrobbles.models import Scrobble
|
||||||
from videos.models import Video
|
from videos.models import Video
|
||||||
from vrobbler.apps.profiles.utils import now_user_timezone
|
from vrobbler.apps.profiles.utils import now_user_timezone
|
||||||
|
|
||||||
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(user=None):
|
def scrobble_counts(user=None):
|
||||||
|
|
||||||
@ -92,39 +84,61 @@ def week_of_scrobbles(
|
|||||||
return scrobble_day_dict
|
return scrobble_day_dict
|
||||||
|
|
||||||
|
|
||||||
def top_tracks(
|
def live_charts(
|
||||||
user: "User", filter: str = "today", limit: int = 30
|
user: "User",
|
||||||
) -> List["Track"]:
|
media_type: str = "Track",
|
||||||
|
chart_period: str = "all",
|
||||||
|
limit: int = 15,
|
||||||
|
) -> QuerySet:
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
|
tzinfo = now.tzinfo
|
||||||
|
now = now.date()
|
||||||
if user.is_authenticated:
|
if user.is_authenticated:
|
||||||
now = now_user_timezone(user.profile)
|
now = now_user_timezone(user.profile)
|
||||||
|
tzinfo = now.tzinfo
|
||||||
|
|
||||||
start_of_today = datetime.combine(
|
start_of_today = datetime.combine(now, datetime.min.time(), tzinfo)
|
||||||
now.date(), datetime.min.time(), now.tzinfo
|
start_day_of_week = now - timedelta(days=now.today().isoweekday() % 7)
|
||||||
)
|
start_day_of_month = now.replace(day=1)
|
||||||
starting_day_of_current_week = now.date() - timedelta(
|
start_day_of_year = now.replace(month=1, day=1)
|
||||||
days=now.today().isoweekday() % 7
|
|
||||||
)
|
media_model = apps.get_model(app_label='music', model_name=media_type)
|
||||||
starting_day_of_current_month = now.date().replace(day=1)
|
|
||||||
starting_day_of_current_year = now.date().replace(month=1, day=1)
|
period_queries = {
|
||||||
|
'today': {'scrobble__timestamp__gte': start_of_today},
|
||||||
|
'week': {'scrobble__timestamp__gte': start_day_of_week},
|
||||||
|
'month': {'scrobble__timestamp__gte': start_day_of_month},
|
||||||
|
'year': {'scrobble__timestamp__gte': start_day_of_year},
|
||||||
|
'all': {},
|
||||||
|
}
|
||||||
|
|
||||||
time_filter = Q()
|
time_filter = Q()
|
||||||
if filter == "today":
|
completion_filter = Q(
|
||||||
time_filter = Q(scrobble__timestamp__gte=start_of_today)
|
scrobble__user=user, scrobble__played_to_completion=True
|
||||||
if filter == "week":
|
)
|
||||||
time_filter = Q(scrobble__timestamp__gte=starting_day_of_current_week)
|
user_filter = Q(scrobble__user=user)
|
||||||
if filter == "month":
|
count_field = "scrobble"
|
||||||
time_filter = Q(scrobble__timestamp__gte=starting_day_of_current_month)
|
|
||||||
if filter == "year":
|
if media_type == "Artist":
|
||||||
time_filter = Q(scrobble__timestamp__gte=starting_day_of_current_year)
|
for period, query_dict in period_queries.items():
|
||||||
|
period_queries[period] = {
|
||||||
|
"track__" + k: v for k, v in query_dict.items()
|
||||||
|
}
|
||||||
|
completion_filter = Q(
|
||||||
|
track__scrobble__user=user,
|
||||||
|
track__scrobble__played_to_completion=True,
|
||||||
|
)
|
||||||
|
count_field = "track__scrobble"
|
||||||
|
user_filter = Q(track__scrobble__user=user)
|
||||||
|
|
||||||
|
time_filter = Q(**period_queries[chart_period])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
Track.objects.filter(time_filter)
|
media_model.objects.filter(user_filter, time_filter)
|
||||||
.annotate(
|
.annotate(
|
||||||
num_scrobbles=Count(
|
num_scrobbles=Count(
|
||||||
"scrobble",
|
count_field,
|
||||||
filter=Q(scrobble__played_to_completion=True),
|
filter=completion_filter,
|
||||||
distinct=True,
|
distinct=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -132,35 +146,5 @@ def top_tracks(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
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(
|
|
||||||
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",
|
|
||||||
filter=Q(track__scrobble__played_to_completion=True),
|
|
||||||
distinct=True,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.order_by("-num_scrobbles")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def artist_scrobble_count(artist_id: int, filter: str = "today") -> int:
|
def artist_scrobble_count(artist_id: int, filter: str = "today") -> int:
|
||||||
return Scrobble.objects.filter(track__artist=artist_id).count()
|
return Scrobble.objects.filter(track__artist=artist_id).count()
|
||||||
|
|||||||
Reference in New Issue
Block a user