Files
vrobbler/vrobbler/apps/music/views.py

131 lines
4.2 KiB
Python

from charts.models import ChartRecord
from django.db.models import Count
from django.views import generic
from music.models import Album, Artist, Track
from scrobbles.stats import get_scrobble_count_qs
from scrobbles.views import ScrobbleableDetailView, ScrobbleableListView
class TrackListView(ScrobbleableListView):
model = Track
class TrackDetailView(ScrobbleableDetailView):
model = Track
class ArtistListView(generic.ListView):
model = Artist
paginate_by = 100
def get_queryset(self):
qs = super().get_queryset().annotate(scrobble_count=Count("track__scrobble"))
genre = self.request.GET.get("genre")
if genre:
qs = qs.filter(theaudiodb_genre=genre)
mood = self.request.GET.get("mood")
if mood:
qs = qs.filter(theaudiodb_mood=mood)
return qs.order_by("-scrobble_count")
def get_context_data(self, *, object_list=None, **kwargs):
context_data = super().get_context_data(object_list=object_list, **kwargs)
context_data["view"] = self.request.GET.get("view")
genre = self.request.GET.get("genre")
if genre:
context_data["active_filter"] = f"genre: {genre}"
mood = self.request.GET.get("mood")
if mood:
context_data["active_filter"] = f"mood: {mood}"
return context_data
class ArtistDetailView(generic.DetailView):
model = Artist
slug_field = "uuid"
def get_context_data(self, **kwargs):
context_data = super().get_context_data(**kwargs)
artist = context_data["object"]
ranked_tracks = sorted(
artist.tracks.all(), key=lambda t: t.scrobble_count, reverse=True
)[:10]
tracks_ranked = [
(rank, track) for rank, track in enumerate(ranked_tracks, start=1)
]
context_data["tracks_ranked"] = tracks_ranked
charts_qs = ChartRecord.objects.filter(
artist=self.object, rank__in=[1, 2, 3]
).exclude(day__isnull=False)
from collections import OrderedDict
grouped = OrderedDict()
for chart in charts_qs:
grouped.setdefault(chart.period_type, []).append(chart)
context_data["charts"] = grouped
from scrobbles.models import Scrobble
context_data["recent_scrobbles"] = (
Scrobble.objects.filter(track__artists=artist)
.select_related("track", "track__album")
.order_by("-timestamp")[:100]
)
similar = artist.similar_artists or []
if similar:
top = similar[:10]
mbids = [sa["artist_mbid"] for sa in top if sa.get("artist_mbid")]
local_artists = {
a.musicbrainz_id: a
for a in Artist.objects.filter(musicbrainz_id__in=mbids)
}
for sa in top:
local = local_artists.get(sa.get("artist_mbid"))
sa["local_url"] = local.get_absolute_url() if local else None
sa["musicbrainz_url"] = (
f"https://musicbrainz.org/artist/{sa['artist_mbid']}"
if sa.get("artist_mbid")
else None
)
context_data["similar_artists"] = top
if artist.theaudiodb_genre:
context_data["genre_count"] = Artist.objects.filter(
theaudiodb_genre=artist.theaudiodb_genre
).count()
if artist.theaudiodb_mood:
context_data["mood_count"] = Artist.objects.filter(
theaudiodb_mood=artist.theaudiodb_mood
).count()
return context_data
class AlbumListView(generic.ListView):
model = Album
def get_queryset(self):
return (
super()
.get_queryset()
.annotate(scrobble_count=Count("track__scrobble"))
.order_by("-scrobble_count")
)
class AlbumDetailView(generic.DetailView):
model = Album
slug_field = "uuid"
def get_context_data(self, **kwargs):
context_data = super().get_context_data(**kwargs)
# context_data['charts'] = ChartRecord.objects.filter(
# track__album=self.object, rank__in=[1, 2, 3]
# )
return context_data