Files
vrobbler/vrobbler/apps/scrobbles/api/serializers.py
Colin Powell 7f3076608f
Some checks failed
build / test (push) Has been cancelled
[scrobbles] Add sharing of scrobbles
2026-06-09 12:33:25 -04:00

77 lines
2.1 KiB
Python

import re
from rest_framework import serializers
from scrobbles.constants import Visibility
from scrobbles.models import (
AudioScrobblerTSVImport,
KoReaderImport,
LastFmImport,
Scrobble,
)
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):
class Meta:
model = KoReaderImport
fields = "__all__"
class AudioScrobblerTSVImportSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = AudioScrobblerTSVImport
fields = "__all__"
class LastFmImportSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = LastFmImport
fields = "__all__"