131 lines
4.2 KiB
Python
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
|