[scrobbles] Add dynamic forms for LogData classes

This commit is contained in:
2025-08-17 12:37:06 -04:00
parent 1093aa2376
commit 52494651bf
20 changed files with 352 additions and 28 deletions

View File

@ -4,12 +4,13 @@ import logging
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from django.shortcuts import redirect
import pendulum
import pytz
from django.apps import apps
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Count, Q
from django.db.models import Count, Q, Max
from django.db.models.query import QuerySet
from django.http import FileResponse, HttpResponseRedirect, JsonResponse
from django.urls import reverse_lazy
@ -75,12 +76,17 @@ class ScrobbleableListView(ListView):
user_filter = Q(scrobble__user=self.request.user)
queryset = (
queryset.filter(user_filter).annotate(
scrobble_count=Count("scrobble")
).filter(scrobble_count__gt=0).order_by("-scrobble_count")
queryset.filter(user_filter)
.annotate(
scrobble_count=Count("scrobble", distinct=True),
last_scrobble=Max("scrobble__timestamp"),
)
.filter(scrobble_count__gt=0)
.order_by("-last_scrobble")
)
return queryset
class ScrobbleableDetailView(DetailView):
model = None
slug_field = "uuid"
@ -926,3 +932,57 @@ class ScrobbleStatusView(LoginRequiredMixin, TemplateView):
).first()
return data
class ScrobbleDetailView(DetailView):
model = Scrobble
slug_field = "uuid"
slug_url_kwarg = "uuid"
def get_form_class(self):
return self.object.media_obj.logdata_cls.form()
def get_form(self):
FormClass = self.get_form_class()
log = self.object.log or {}
initial_notes = log.get("notes", [])
if isinstance(initial_notes, list):
notes_str = "\n".join(initial_notes)
notes_str_fixed = notes_str.encode("utf-8").decode(
"unicode_escape"
)
log["notes"] = notes_str_fixed
return FormClass(initial=log)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
FormClass = self.get_form_class()
form = FormClass(request.POST)
if form.is_valid():
data = form.cleaned_data.copy()
for field_name, field in form.fields.items():
if field.disabled:
original_value = (self.object.log or {}).get(field_name)
data[field_name] = original_value
if "with_people_ids" in data:
data["with_people_ids"] = [
p.id for p in data["with_people_ids"]
]
self.object.log = data
self.object.save(update_fields=["log"])
return redirect(self.object.get_absolute_url())
context = self.get_context_data(log_form=form)
return self.render_to_response(context)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if "log_form" not in context:
context["log_form"] = self.get_form()
return context