[templates] Clean up widgets
All checks were successful
build & deploy / test (push) Successful in 1m53s
build & deploy / deploy (push) Successful in 25s

This commit is contained in:
2026-03-20 18:37:11 -04:00
parent e8f120f85e
commit 49b8b86249
7 changed files with 168 additions and 445 deletions

View File

@ -8,12 +8,17 @@ import pytz
from dateutil.relativedelta import relativedelta
from django.apps import apps
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db.models import Count, Max, Q
from django.db.models.query import QuerySet
from django.http import FileResponse, Http404, HttpResponseRedirect, JsonResponse
from django.http import (
FileResponse,
Http404,
HttpResponseRedirect,
JsonResponse,
)
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.utils import timezone
@ -24,13 +29,15 @@ from django.views.generic.list import ListView
from moods.models import Mood
from music.aggregators import (
artist_scrobble_count,
week_of_scrobbles,
scrobble_counts,
live_charts,
live_tv_charts,
live_youtube_channel_charts,
scrobble_counts,
week_of_scrobbles,
)
from pendulum.parsing.exceptions import ParserError
from profiles.models import UserProfile
from profiles.utils import now_user_timezone
from rest_framework import status
from rest_framework.decorators import (
api_view,
@ -67,8 +74,6 @@ from scrobbles.utils import (
get_long_plays_completed,
get_long_plays_in_progress,
)
from profiles.models import UserProfile
from profiles.utils import now_user_timezone
User = get_user_model()
@ -1019,170 +1024,156 @@ class ScrobbleDetailView(DetailView):
return context
class EmbeddableTopArtistWidget(TemplateView):
template_name = "scrobbles/embeddable_top_artist.html"
class BaseEmbeddableWidget(TemplateView):
template_name = "scrobbles/embeddable_top_media.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
media_type = "Media"
count_label = "plays"
no_data_message = "No scrobbles"
model = None
scrobble_filter = {}
def get_user_and_profile(self):
user_id = self.kwargs.get("user_id")
try:
user = User.objects.get(id=user_id)
except User.DoesNotExist:
context["error"] = "User not found"
return context
user = User.objects.get(id=user_id)
profile = user.profile
if not profile.enable_public_widgets:
raise Http404("Public widgets are not enabled for this user")
return user, profile
def get_date_range(self, user):
now = timezone.now()
if user.is_authenticated:
now = now_user_timezone(user.profile)
now = now.date()
period = self.kwargs.get("period", "week")
if period == "month":
start = now.replace(day=1)
label = now.strftime("%B %Y")
elif period == "year":
start = now.replace(month=1, day=1)
label = now.strftime("%Y")
else:
start = now - timedelta(days=now.isoweekday() % 7)
label = "This Week"
return start, label
def get_items(self, user, start_date, model=None):
from django.db.models import Count
model = model or self.model
queryset = (
model.objects.filter(
scrobble__user=user,
scrobble__timestamp__gte=start_date,
**self.scrobble_filter,
)
.annotate(count=Count("scrobble", distinct=True))
.order_by("-count")[:10]
)
items = list(queryset)
for item in items:
if not hasattr(item, "name") and hasattr(item, "title"):
item.name = item.title
return items
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user, profile = self.get_user_and_profile()
context["user"] = user
context["custom_css"] = profile.widget_custom_css
context["media_type"] = self.media_type
context["count_label"] = self.count_label
artist = {
"user": user,
"media_type": "Artist",
"limit": 10,
}
context["top_artists"] = list(live_charts(**artist, chart_period="last7"))
start_date, period_label = self.get_date_range(user)
context["period_label"] = period_label
items = self.get_items(user, start_date)
context["items"] = items
context["no_data_message"] = self.no_data_message
return context
class EmbeddableTopBoardGamesMonthWidget(TemplateView):
template_name = "scrobbles/embeddable_top_board_games_month.html"
class EmbeddableTopArtistsWidget(TemplateView):
template_name = "scrobbles/embeddable_top_media.html"
media_type = "Artists"
count_label = "scrobbles"
no_data_message = "No scrobbles"
def get_user_and_profile(self):
user_id = self.kwargs.get("user_id")
user = User.objects.get(id=user_id)
profile = user.profile
if not profile.enable_public_widgets:
raise Http404("Public widgets are not enabled for this user")
return user, profile
def get_context_data(self, **kwargs):
from django.db.models import Count
from django.utils import timezone
context = super().get_context_data(**kwargs)
user, profile = self.get_user_and_profile()
context["user"] = user
context["custom_css"] = profile.widget_custom_css
context["media_type"] = self.media_type
context["count_label"] = self.count_label
context["no_data_message"] = self.no_data_message
period = self.kwargs.get("period", "week")
period_map = {"week": "last7", "month": "last30", "year": "year"}
chart_period = period_map.get(period, "last7")
artist = {"user": user, "media_type": "Artist", "limit": 10}
items = list(live_charts(**artist, chart_period=chart_period))
for item in items:
item.count = item.num_scrobbles
context["items"] = items
from datetime import timedelta
from boardgames.models import BoardGame
context = super().get_context_data(**kwargs)
user_id = self.kwargs.get("user_id")
try:
user = User.objects.get(id=user_id)
except User.DoesNotExist:
context["error"] = "User not found"
return context
profile = user.profile
if not profile.enable_public_widgets:
raise Http404("Public widgets are not enabled for this user")
context["user"] = user
context["custom_css"] = profile.widget_custom_css
now = timezone.now()
if user.is_authenticated:
now = now_user_timezone(user.profile)
now = now.date()
start_day_of_month = now.replace(day=1)
top_games = (
BoardGame.objects.filter(
scrobble__user=user,
scrobble__timestamp__gte=start_day_of_month,
scrobble__played_to_completion=True,
)
.annotate(num_plays=Count("scrobble", distinct=True))
.order_by("-num_plays")[:10]
)
context["top_board_games"] = list(top_games)
context["month"] = now.strftime("%B %Y")
return context
class EmbeddableTopBoardGamesWeekWidget(TemplateView):
template_name = "scrobbles/embeddable_top_board_games_week.html"
def get_context_data(self, **kwargs):
from django.db.models import Count
from django.utils import timezone
from datetime import timedelta
from boardgames.models import BoardGame
context = super().get_context_data(**kwargs)
user_id = self.kwargs.get("user_id")
try:
user = User.objects.get(id=user_id)
except User.DoesNotExist:
context["error"] = "User not found"
return context
profile = user.profile
if not profile.enable_public_widgets:
raise Http404("Public widgets are not enabled for this user")
context["user"] = user
context["custom_css"] = profile.widget_custom_css
now = timezone.now()
if user.is_authenticated:
now = now_user_timezone(user.profile)
now = now.date()
start_day_of_week = now - timedelta(days=now.isoweekday() % 7)
top_games = (
BoardGame.objects.filter(
scrobble__user=user,
scrobble__timestamp__gte=start_day_of_week,
scrobble__played_to_completion=True,
)
.annotate(num_plays=Count("scrobble", distinct=True))
.order_by("-num_plays")[:10]
)
context["top_board_games"] = list(top_games)
if period == "month":
context["period_label"] = now.strftime("%B %Y")
elif period == "year":
context["period_label"] = now.strftime("%Y")
else:
start = now - timedelta(days=now.isoweekday() % 7)
context["period_label"] = "This Week"
return context
class EmbeddableTopBoardGamesYearWidget(TemplateView):
template_name = "scrobbles/embeddable_top_board_games_year.html"
class EmbeddableTopBoardGamesWidget(BaseEmbeddableWidget):
media_type = "Board Games"
count_label = "plays"
no_data_message = "No board games played"
scrobble_filter = {"scrobble__played_to_completion": True}
def get_context_data(self, **kwargs):
from django.db.models import Count
from django.utils import timezone
def get_items(self, user, start_date):
from boardgames.models import BoardGame
context = super().get_context_data(**kwargs)
user_id = self.kwargs.get("user_id")
return super().get_items(user, start_date, BoardGame)
try:
user = User.objects.get(id=user_id)
except User.DoesNotExist:
context["error"] = "User not found"
return context
profile = user.profile
if not profile.enable_public_widgets:
raise Http404("Public widgets are not enabled for this user")
class EmbeddableTopBooksWidget(BaseEmbeddableWidget):
media_type = "Books"
count_label = "reads"
no_data_message = "No books read"
scrobble_filter = {"scrobble__long_play_complete": True}
context["user"] = user
context["custom_css"] = profile.widget_custom_css
def get_items(self, user, start_date):
from books.models import Book
now = timezone.now()
if user.is_authenticated:
now = now_user_timezone(user.profile)
now = now.date()
start_day_of_year = now.replace(month=1, day=1)
top_games = (
BoardGame.objects.filter(
scrobble__user=user,
scrobble__timestamp__gte=start_day_of_year,
scrobble__played_to_completion=True,
)
.annotate(num_plays=Count("scrobble", distinct=True))
.order_by("-num_plays")[:10]
)
context["top_board_games"] = list(top_games)
context["year"] = now.strftime("%Y")
return context
return super().get_items(user, start_date, Book)