[charts] Clean up how they're displayed
All checks were successful
build & deploy / test (push) Successful in 1m51s
build & deploy / build-and-deploy (push) Successful in 30s

This commit is contained in:
2026-05-15 16:03:53 -04:00
parent 2b04a17d77
commit bf7e5677e6
8 changed files with 217 additions and 22 deletions

View File

@ -110,14 +110,13 @@ class ChartRecord(TimeStampedModel):
@property
def period_str(self) -> str:
period = str(self.year)
if self.month:
period = f"{calendar.month_name[self.month]} {period}"
if self.week:
period = f"Week {self.week}, {period}"
if self.day:
period = f"{calendar.month_name[self.month]} {self.day}, {period}"
return period
return f"{calendar.month_name[self.month]} {self.day}, {self.year}"
if self.week:
return f"Week {self.week}, {self.year}"
if self.month:
return f"{calendar.month_name[self.month]} {self.year}"
return str(self.year)
@property
def period_type(self) -> str:

View File

@ -1,4 +1,4 @@
from charts.views import BirdsChartView, ChartRecordView, SpotifyTracksView
from charts.views import BirdsChartView, ChartDetailView, ChartRecordView, SpotifyTracksView
from django.urls import path
app_name = "charts"
@ -7,4 +7,5 @@ urlpatterns = [
path("charts/", ChartRecordView.as_view(), name="charts-home"),
path("charts/spotify/", SpotifyTracksView.as_view(), name="spotify-tracks"),
path("charts/birds/", BirdsChartView.as_view(), name="birds-chart"),
path("charts/<slug:media_type>/", ChartDetailView.as_view(), name="chart-detail"),
]

View File

@ -3,6 +3,7 @@ from datetime import timedelta
from charts.models import ChartRecord
from django.db.models import Count, Q
from django.http import Http404
from django.utils import timezone
from django.views.generic import TemplateView
from profiles.utils import now_user_timezone
@ -617,6 +618,103 @@ class ChartRecordView(TemplateView):
}
MEDIA_TYPE_LABELS = {
"artist": ("🎤", "Top Artists"),
"album": ("💿", "Top Albums"),
"track": ("🎵", "Top Tracks"),
"tv_series": ("📺", "Top TV Series"),
"video": ("🎬", "Top Videos"),
"podcast": ("🎙️", "Top Podcasts"),
"podcast_episode": ("🎙️", "Top Podcast Episodes"),
"board_game": ("🎲", "Top Board Games"),
"book": ("📚", "Top Books"),
"food": ("🍽️", "Top Foods"),
"trail": ("🥾", "Top Trails"),
"geo_location": ("📍", "Top Locations"),
}
class ChartDetailView(TemplateView):
template_name = "charts/chart_detail.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user = self.request.user
media_type = kwargs.get("media_type")
if media_type not in MEDIA_TYPE_FILTERS:
raise Http404
date_param = self.request.GET.get("date")
now = timezone.now()
if user.is_authenticated:
now = now_user_timezone(user.profile)
today = now.date()
year = today.year
month = None
week = None
day = None
if date_param:
parts = date_param.split("-")
year = int(parts[0])
if len(parts) >= 2 and parts[1].startswith("W"):
week = int(parts[1].lstrip("W"))
month = None
elif len(parts) >= 2:
try:
month = int(parts[1])
except ValueError:
pass
if len(parts) >= 3:
if parts[2].startswith("W"):
week = int(parts[2].lstrip("W"))
else:
day = int(parts[2])
params = {"user": user}
if year:
params["year"] = year
if month:
params["month"] = month
if week:
params["week"] = week
if day:
params["day"] = day
media_filter = MEDIA_TYPE_FILTERS.get(media_type, Q())
qs = ChartRecord.objects.filter(media_filter, **params)
if day is not None:
qs = qs.filter(day__isnull=False)
elif week is not None:
qs = qs.filter(week__isnull=False, day__isnull=True)
elif month is not None:
qs = qs.filter(month__isnull=False, week__isnull=True, day__isnull=True)
else:
qs = qs.filter(month__isnull=True, week__isnull=True, day__isnull=True)
context["page_charts"] = qs.order_by("rank")
context["media_type"] = media_type
emoji, label = MEDIA_TYPE_LABELS.get(media_type, ("", media_type))
context["media_label"] = label
context["media_emoji"] = emoji
context["year"] = year
context["month"] = month
context["week"] = week
context["day"] = day
context["chart_years"] = list(
ChartRecord.objects.filter(Q(user=user) & media_filter)
.values_list("year", flat=True)
.distinct()
.order_by("-year")
)
return context
class SpotifyTracksView(TemplateView):
template_name = "charts/spotify_tracks.html"