[charts] Big revamp of the charts app
This commit is contained in:
@ -58,7 +58,6 @@ from scrobbles.export import export_scrobbles
|
||||
from scrobbles.forms import ExportScrobbleForm, ScrobbleForm
|
||||
from scrobbles.models import (
|
||||
AudioScrobblerTSVImport,
|
||||
ChartRecord,
|
||||
KoReaderImport,
|
||||
LastFmImport,
|
||||
RetroarchImport,
|
||||
@ -728,231 +727,6 @@ def export(request):
|
||||
return response
|
||||
|
||||
|
||||
class ChartRecordView(TemplateView):
|
||||
template_name = "scrobbles/chart_index.html"
|
||||
|
||||
@staticmethod
|
||||
def get_media_filter(media_type: str = "") -> Q:
|
||||
filters = {
|
||||
"Track": Q(track__isnull=False),
|
||||
"Artist": Q(artist__isnull=False),
|
||||
"Series": Q(series__isnull=False),
|
||||
"Video": Q(video__isnull=False),
|
||||
"": Q(),
|
||||
}
|
||||
return filters[media_type]
|
||||
|
||||
def get_chart_records(self, media_type: str = "", **kwargs):
|
||||
media_filter = self.get_media_filter(media_type)
|
||||
charts = ChartRecord.objects.filter(
|
||||
media_filter, user=self.request.user, **kwargs
|
||||
).order_by("rank")
|
||||
|
||||
if charts.count() == 0:
|
||||
ChartRecord.build(user=self.request.user, model_str=media_type, **kwargs)
|
||||
charts = ChartRecord.objects.filter(
|
||||
media_filter, user=self.request.user, **kwargs
|
||||
).order_by("rank")
|
||||
return charts
|
||||
|
||||
def get_chart(
|
||||
self, period: str = "all_time", limit=15, media: str = ""
|
||||
) -> QuerySet:
|
||||
now = timezone.now()
|
||||
params = {}
|
||||
params["media_type"] = media
|
||||
if period == "today":
|
||||
params["day"] = now.day
|
||||
params["month"] = now.month
|
||||
params["year"] = now.year
|
||||
if period == "week":
|
||||
params["week"] = now.ioscalendar()[1]
|
||||
params["year"] = now.year
|
||||
if period == "month":
|
||||
params["month"] = now.month
|
||||
params["year"] = now.year
|
||||
if period == "year":
|
||||
params["year"] = now.year
|
||||
return self.get_chart_records(**params)[:limit]
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context_data = super().get_context_data(**kwargs)
|
||||
date = self.request.GET.get("date")
|
||||
media_type = self.request.GET.get("media", "Track")
|
||||
user = self.request.user
|
||||
params = {}
|
||||
context_data["chart_type"] = self.request.GET.get("chart_type", "maloja")
|
||||
context_data["artist_charts"] = {}
|
||||
|
||||
if not date:
|
||||
limit = 20
|
||||
artist = {"user": user, "media_type": "Artist", "limit": limit}
|
||||
# This is weird. They don't display properly as QuerySets, so we cast to lists
|
||||
context_data["chart_keys"] = {
|
||||
"today": "Today",
|
||||
"last7": "Last 7 days",
|
||||
"last30": "Last 30 days",
|
||||
"year": "This year",
|
||||
"all": "All time",
|
||||
}
|
||||
context_data["current_artist_charts"] = batch_live_charts(
|
||||
user=user, media_type="Artist", limit=limit
|
||||
)
|
||||
|
||||
track = {"user": user, "media_type": "Track", "limit": limit}
|
||||
context_data["current_track_charts"] = batch_live_charts(
|
||||
user=user, media_type="Track", limit=limit
|
||||
)
|
||||
|
||||
now = timezone.now()
|
||||
tzinfo = now.tzinfo
|
||||
if user.is_authenticated:
|
||||
now = now_user_timezone(user.profile)
|
||||
tzinfo = now.tzinfo
|
||||
now = now.date()
|
||||
start_of_today = datetime.combine(now, datetime.min.time(), tzinfo)
|
||||
start_day_of_week = start_of_today - timedelta(days=now.isoweekday() % 7)
|
||||
start_day_of_month = now.replace(day=1)
|
||||
|
||||
# TV Series Scrobbles - fetch all and filter in Python
|
||||
series_all = list(
|
||||
Scrobble.objects.with_related()
|
||||
.filter(
|
||||
user=user,
|
||||
video__video_type=Video.VideoType.TV_EPISODE,
|
||||
played_to_completion=True,
|
||||
timestamp__gte=start_day_of_month,
|
||||
)
|
||||
.order_by("-timestamp")
|
||||
)
|
||||
context_data["series_this_week"] = [
|
||||
s for s in series_all if s.timestamp >= start_day_of_week
|
||||
]
|
||||
context_data["series_this_month"] = series_all
|
||||
|
||||
# Movie Scrobbles - fetch all and filter in Python
|
||||
movies_all = list(
|
||||
Scrobble.objects.with_related()
|
||||
.filter(
|
||||
user=user,
|
||||
video__video_type=Video.VideoType.MOVIE,
|
||||
played_to_completion=True,
|
||||
timestamp__gte=start_day_of_month,
|
||||
)
|
||||
.order_by("-timestamp")
|
||||
)
|
||||
context_data["videos_this_week"] = [
|
||||
v for v in movies_all if v.timestamp >= start_day_of_week
|
||||
]
|
||||
context_data["videos_this_month"] = movies_all
|
||||
|
||||
# YouTube Scrobbles - fetch all and filter in Python
|
||||
youtube_all = list(
|
||||
Scrobble.objects.with_related()
|
||||
.filter(
|
||||
user=user,
|
||||
video__video_type=Video.VideoType.YOUTUBE,
|
||||
played_to_completion=True,
|
||||
timestamp__gte=start_day_of_month,
|
||||
)
|
||||
.order_by("-timestamp")
|
||||
)
|
||||
context_data["youtube_this_week"] = [
|
||||
y for y in youtube_all if y.timestamp >= start_day_of_week
|
||||
]
|
||||
context_data["youtube_this_month"] = youtube_all
|
||||
|
||||
context_data["tv_show_charts"] = {
|
||||
"today": list(live_tv_charts(user=user, chart_period="today")),
|
||||
"last7": list(live_tv_charts(user=user, chart_period="last7")),
|
||||
"last30": list(live_tv_charts(user=user, chart_period="last30")),
|
||||
"year": list(live_tv_charts(user=user, chart_period="year")),
|
||||
"all": list(live_tv_charts(user=user, chart_period="all")),
|
||||
}
|
||||
|
||||
context_data["youtube_channel_charts"] = {
|
||||
"today": list(
|
||||
live_youtube_channel_charts(user=user, chart_period="today")
|
||||
),
|
||||
"last7": list(
|
||||
live_youtube_channel_charts(user=user, chart_period="last7")
|
||||
),
|
||||
"last30": list(
|
||||
live_youtube_channel_charts(user=user, chart_period="last30")
|
||||
),
|
||||
"year": list(
|
||||
live_youtube_channel_charts(user=user, chart_period="year")
|
||||
),
|
||||
"all": list(live_youtube_channel_charts(user=user, chart_period="all")),
|
||||
}
|
||||
|
||||
return context_data
|
||||
|
||||
# Date provided, lookup past charts, returning nothing if it's now or in the future.
|
||||
now = timezone.now()
|
||||
year = now.year
|
||||
params = {"year": year}
|
||||
name = f"Chart for {year}"
|
||||
|
||||
date_params = date.split("-")
|
||||
year = int(date_params[0])
|
||||
in_progress = False
|
||||
if len(date_params) == 2:
|
||||
if "W" in date_params[1]:
|
||||
week = int(date_params[1].strip('W"'))
|
||||
params["week"] = week
|
||||
start = datetime.strptime(date + "-1", "%Y-W%W-%w").replace(
|
||||
tzinfo=pytz.utc
|
||||
)
|
||||
end = start + timedelta(days=6)
|
||||
in_progress = start <= now <= end
|
||||
as_str = start.strftime("Week of %B %d, %Y")
|
||||
name = f"Chart for {as_str}"
|
||||
else:
|
||||
month = int(date_params[1])
|
||||
params["month"] = month
|
||||
month_str = calendar.month_name[month]
|
||||
name = f"Chart for {month_str} {year}"
|
||||
in_progress = now.month == month and now.year == year
|
||||
if len(date_params) == 3:
|
||||
month = int(date_params[1])
|
||||
day = int(date_params[2])
|
||||
params["month"] = month
|
||||
params["day"] = day
|
||||
month_str = calendar.month_name[month]
|
||||
name = f"Chart for {month_str} {day}, {year}"
|
||||
in_progress = now.month == month and now.year == year and now.day == day
|
||||
|
||||
media_filter = self.get_media_filter("Track")
|
||||
track_charts = ChartRecord.objects.filter(
|
||||
media_filter, user=self.request.user, **params
|
||||
).order_by("rank")
|
||||
media_filter = self.get_media_filter("Artist")
|
||||
artist_charts = ChartRecord.objects.filter(
|
||||
media_filter, user=self.request.user, **params
|
||||
).order_by("rank")
|
||||
|
||||
if track_charts.count() == 0 and not in_progress:
|
||||
ChartRecord.build(user=self.request.user, model_str="Track", **params)
|
||||
media_filter = self.get_media_filter("Track")
|
||||
track_charts = ChartRecord.objects.filter(
|
||||
media_filter, user=self.request.user, **params
|
||||
).order_by("rank")
|
||||
if artist_charts.count() == 0 and not in_progress:
|
||||
ChartRecord.build(user=self.request.user, model_str="Artist", **params)
|
||||
media_filter = self.get_media_filter("Artist")
|
||||
artist_charts = ChartRecord.objects.filter(
|
||||
media_filter, user=self.request.user, **params
|
||||
).order_by("rank")
|
||||
|
||||
context_data["media_type"] = media_type
|
||||
context_data["track_charts"] = track_charts
|
||||
context_data["artist_charts"] = artist_charts
|
||||
context_data["name"] = " ".join(["Top", media_type, "for", name])
|
||||
context_data["in_progress"] = in_progress
|
||||
return context_data
|
||||
|
||||
|
||||
class ScrobbleStatusView(LoginRequiredMixin, TemplateView):
|
||||
model = Scrobble
|
||||
template_name = "scrobbles/status.html"
|
||||
|
||||
Reference in New Issue
Block a user