diff --git a/vrobbler/apps/scrobbles/api/serializers.py b/vrobbler/apps/scrobbles/api/serializers.py
index 68f2811..109bd89 100644
--- a/vrobbler/apps/scrobbles/api/serializers.py
+++ b/vrobbler/apps/scrobbles/api/serializers.py
@@ -1,3 +1,5 @@
+import re
+
from rest_framework import serializers
from scrobbles.models import (
AudioScrobblerTSVImport,
@@ -7,10 +9,52 @@ from scrobbles.models import (
)
+NOTE_POSITION_RE = re.compile(r"\[start:(\d+)\|end:(\d+)\]$")
+
+
class ScrobbleSerializer(serializers.HyperlinkedModelSerializer):
+ note = serializers.CharField(required=False, allow_blank=True)
+ note_position = serializers.DictField(required=False)
+
class Meta:
model = Scrobble
fields = "__all__"
+ extra_kwargs = {
+ "url": {"view_name": "scrobble-detail", "lookup_field": "uuid"},
+ }
+
+ def update(self, instance, validated_data):
+ note = validated_data.pop("note", None)
+ note_position = validated_data.pop("note_position", None)
+
+ instance = super().update(instance, validated_data)
+
+ if note is not None:
+ log = instance.log or {}
+ notes = log.get("notes", [])
+ if isinstance(notes, str):
+ notes = [notes]
+ elif notes is None:
+ notes = []
+
+ if note_position:
+ note = f"{note} [start:{note_position['start']}|end:{note_position['end']}]"
+
+ notes.append(note)
+ log["notes"] = notes
+ instance.log = log
+ instance.save(update_fields=["log"])
+
+ return instance
+
+
+def parse_note_position(note):
+ match = NOTE_POSITION_RE.search(note)
+ if match:
+ start, end = match.groups()
+ text = NOTE_POSITION_RE.sub("", note)
+ return text, {"start": int(start), "end": int(end)}
+ return note, None
class KoReaderImportSerializer(serializers.HyperlinkedModelSerializer):
@@ -19,9 +63,7 @@ class KoReaderImportSerializer(serializers.HyperlinkedModelSerializer):
fields = "__all__"
-class AudioScrobblerTSVImportSerializer(
- serializers.HyperlinkedModelSerializer
-):
+class AudioScrobblerTSVImportSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = AudioScrobblerTSVImport
fields = "__all__"
diff --git a/vrobbler/apps/scrobbles/api/views.py b/vrobbler/apps/scrobbles/api/views.py
index c89b549..320b7cf 100644
--- a/vrobbler/apps/scrobbles/api/views.py
+++ b/vrobbler/apps/scrobbles/api/views.py
@@ -1,3 +1,5 @@
+from logging import getLogger
+
from rest_framework import permissions, viewsets
from scrobbles.api.serializers import (
AudioScrobblerTSVImportSerializer,
@@ -12,11 +14,14 @@ from scrobbles.models import (
LastFmImport,
)
+logger = getLogger(__name__)
+
class ScrobbleViewSet(viewsets.ModelViewSet):
queryset = Scrobble.objects.all().order_by("-timestamp")
serializer_class = ScrobbleSerializer
permission_classes = [permissions.IsAuthenticated]
+ lookup_field = "uuid"
def get_queryset(self):
return super().get_queryset().filter(user=self.request.user)
diff --git a/vrobbler/apps/webpages/views.py b/vrobbler/apps/webpages/views.py
index 62056d5..3856f83 100644
--- a/vrobbler/apps/webpages/views.py
+++ b/vrobbler/apps/webpages/views.py
@@ -16,6 +16,26 @@ class WebPageListView(ScrobbleableListView):
class WebPageDetailView(ScrobbleableDetailView):
model = WebPage
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ if self.request.user.is_authenticated:
+ latest = self.object.scrobbles(self.request.user).first()
+ if latest:
+ context["latest_scrobble_uuid"] = str(latest.uuid)
+ context["latest_scrobble_notes"] = (
+ latest.log.get("notes", []) if latest.log else []
+ )
+ print(
+ f"DEBUG: Found scrobble {latest.uuid} for user {self.request.user}"
+ )
+ else:
+ print(
+ f"DEBUG: No scrobble found for user {self.request.user} on webpage {self.object.uuid}"
+ )
+ else:
+ print(f"DEBUG: User not authenticated")
+ return context
+
class WebPageReadView(
LoginRequiredMixin, generic.edit.FormView, generic.DetailView
diff --git a/vrobbler/templates/webpages/webpage_detail.html b/vrobbler/templates/webpages/webpage_detail.html
index 6a20761..cbfa807 100644
--- a/vrobbler/templates/webpages/webpage_detail.html
+++ b/vrobbler/templates/webpages/webpage_detail.html
@@ -16,12 +16,88 @@
{% endblock %}