[templates] Allow going back and forward in time

This commit is contained in:
2025-06-07 15:17:56 -04:00
parent 99a6e5107b
commit 69aa80e6c1
6 changed files with 219 additions and 324 deletions

View File

@ -604,45 +604,39 @@ class Scrobble(TimeStampedModel):
@classmethod
def for_year(cls, user, year):
return cls.objects.filter(timestamp__year=year, user=user)
return cls.objects.filter(timestamp__year=year, user=user).order_by(
"-timestamp"
)
@classmethod
def for_month(cls, user, year, month):
return cls.objects.filter(
timestamp__year=year, timestamp__month=month, user=user
)
).order_by("-timestamp")
@classmethod
def for_day(cls, user, year, day, month):
def for_day(cls, user, year, month, day):
return cls.objects.filter(
timestamp__year=year,
timestamp__month=month,
timestamp__day=day,
user=user,
)
@classmethod
def for_day_dict(
cls, user_id: int, year: int, month: int, day: int
) -> dict:
scrobbles_by_type = defaultdict(list)
scrobbles = cls.objects.filter(
timestamp__year=year,
timestamp__month=month,
timestamp__day=day,
user_id=user_id,
).order_by("-timestamp")
for scrobble in scrobbles:
scrobbles_by_type[scrobble.media_type].append(scrobble)
return scrobbles_by_type
@classmethod
def for_week(cls, user, year, week):
return cls.objects.filter(
timestamp__year=year, timestamp__week=week, user=user
)
).order_by("-timestamp")
@classmethod
def as_dict_by_type(cls, scrobble_qs: models.QuerySet) -> dict:
scrobbles_by_type = defaultdict(list)
for scrobble in scrobble_qs:
scrobbles_by_type[scrobble.media_type].append(scrobble)
return scrobbles_by_type
@classmethod
def in_progress_for_user(cls, user_id: int) -> models.QuerySet:
@ -847,7 +841,10 @@ class Scrobble(TimeStampedModel):
@property
def elapsed_time(self) -> int | None:
if self.played_to_completion:
return self.playback_position_seconds
if self.playback_position_seconds:
return self.playback_position_seconds
if self.media_obj.run_time_seconds:
return self.media_obj.run_time_seconds
return (timezone.now() - self.timestamp).seconds
@property

View File

@ -2,9 +2,9 @@ import calendar
import json
import logging
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
import pendulum
from pendulum.parsing.exceptions import ParserError
import pytz
from django.apps import apps
from django.contrib import messages
@ -109,20 +109,92 @@ class RecentScrobbleList(ListView):
user = self.request.user
data["date"] = ""
if user.is_authenticated:
date = self.request.GET.get("date", "")
today = timezone.localtime(timezone.now())
self.queryset = self.get_queryset().filter(user=user)
user_id = self.request.user.id
year = today.year
month = today.month
day = today.day
if date:
today = timezone.localtime(timezone.now())
date_str = self.request.GET.get("date", "")
date = today
if date_str:
try:
data["date"] = pendulum.parse(date)
year, month, day = date.split("-")
date = pendulum.parse(date_str)
except:
pass
data = data | Scrobble.for_day_dict(user_id, year, month, day)
if date_str:
if date_str == "this_week" or "-W" in date_str:
next_date = date + timedelta(weeks=+2)
prev_date = date + timedelta(weeks=-1)
if date.isocalendar()[1] < today.isocalendar()[1]:
data[
"next_link"
] = f"?date={next_date.strftime('%Y-W%W')}"
data["prev_link"] = f"?date={prev_date.strftime('%Y-W%W')}"
data[
"title"
] = f"Week {date.strftime('%-W')} of {date.year}"
data = data | Scrobble.as_dict_by_type(
Scrobble.for_week(
user_id, date.year, date.isocalendar()[1]
)
)
elif date_str == "this_month" or date_str.count("-") == 1:
next_date = date + relativedelta(months=1)
prev_date = date + relativedelta(months=-1)
if date.month < today.month:
data[
"next_link"
] = f"?date={next_date.strftime('%Y-%m')}"
data["title"] = f"{date.strftime('%B %Y')}"
data["prev_link"] = f"?date={prev_date.strftime('%Y-%m')}"
data = data | Scrobble.as_dict_by_type(
Scrobble.for_month(user_id, date.year, date.month)
)
elif date_str == "today" or date_str.count("-") == 2:
next_date = date + timedelta(days=1)
prev_date = date - timedelta(days=1)
data[
"prev_link"
] = f"?date={prev_date.strftime('%Y-%m-%d')}"
if date < today:
data[
"next_link"
] = f"?date={next_date.strftime('%Y-%m-%d')}"
if date == today:
data["title"] = "Today"
else:
data["title"] = f"{date.strftime('%Y-%m-%d')}"
data[
"today_link"
] = f"?date={today.strftime('%Y-%m-%d')}"
data = data | Scrobble.as_dict_by_type(
Scrobble.for_day(
user_id, date.year, date.month, date.day
)
)
elif date_str == "this_year" or date_str.count("-") == 0:
next_date = date + relativedelta(years=+1)
prev_date = date + relativedelta(years=-1)
data["next_link"] = ""
if date.year < today.year:
data["title"] = f"{date.strftime('%Y')}"
data["next_link"] = f"?date={next_date.year}"
data["title"] = f"{date.year}"
data["prev_link"] = f"?date={prev_date.year}"
data = data | Scrobble.as_dict_by_type(
Scrobble.for_year(user_id, date.year)
)
else:
next_date = today - timedelta(days=1)
prev_date = today - timedelta(days=1)
data["title"] = "Today"
data["next_link"] = ""
data["prev_link"] = f"?date={prev_date.strftime('%Y-%m-%d')}"
data = data | Scrobble.as_dict_by_type(
Scrobble.for_day(user_id, date.year, date.month, date.day)
)
data[
"today_link"
] = "" # f"?date={today.strftime('%Y-%m-%d')}"
data["active_imports"] = AudioScrobblerTSVImport.objects.filter(
processing_started__isnull=False,
@ -139,9 +211,7 @@ class RecentScrobbleList(ListView):
return data
def get_queryset(self):
return Scrobble.objects.filter(
track__isnull=False, in_progress=False
).order_by("-timestamp")[:15]
return Scrobble.objects.all().order_by("-timestamp")
class ScrobbleLongPlaysView(TemplateView):
@ -453,6 +523,7 @@ def gps_webhook(request):
return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
@csrf_exempt
@api_view(["POST"])
def emacs_webhook(request):
@ -474,9 +545,9 @@ def emacs_webhook(request):
if request.user.id:
user_id = request.user.id
#scrobble = gpslogger_scrobble_location(data_dict, user_id)
# scrobble = gpslogger_scrobble_location(data_dict, user_id)
#if not scrobble:
# if not scrobble:
# return Response({}, status=status.HTTP_200_OK)
return Response({"post_data": post_data}, status=status.HTTP_200_OK)