86 lines
2.0 KiB
Python
86 lines
2.0 KiB
Python
import json
|
|
from dataclasses import asdict, dataclass
|
|
from typing import Optional
|
|
|
|
from dataclass_wizard import JSONWizard
|
|
from django import forms
|
|
from django.contrib.auth import get_user_model
|
|
from people.models import Person
|
|
from scrobbles.forms import form_from_dataclass
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class ScrobbleLogDataEncoder(json.JSONEncoder):
|
|
def default(self, o):
|
|
return o.__dict__
|
|
|
|
|
|
class ScrobbleLogDataDecoder(json.JSONDecoder):
|
|
def default(self, o):
|
|
return o.__dict__
|
|
|
|
|
|
class JSONDataclass(JSONWizard):
|
|
@property
|
|
def asdict(self):
|
|
return asdict(self)
|
|
|
|
@property
|
|
def json(self):
|
|
return json.dumps(self.asdict)
|
|
|
|
|
|
@dataclass
|
|
class BaseLogData(JSONDataclass):
|
|
description: Optional[str] = None
|
|
notes: Optional[list[str]] = None
|
|
|
|
_excluded_fields = {}
|
|
|
|
@classmethod
|
|
def form(cls):
|
|
return form_from_dataclass(cls)
|
|
|
|
@classmethod
|
|
def override_fields(cls) -> dict:
|
|
return {}
|
|
|
|
|
|
@dataclass
|
|
class LongPlayLogData(JSONDataclass):
|
|
long_play_complete: bool = False
|
|
|
|
|
|
@dataclass
|
|
class WithPeopleLogData(JSONDataclass):
|
|
with_people_ids: Optional[list[int]] = None
|
|
|
|
@property
|
|
def with_people(self) -> list["Person"]:
|
|
from people.models import Person
|
|
|
|
if not self.with_people_ids:
|
|
return []
|
|
return [
|
|
Person.objects.filter(id=pid).first()
|
|
for pid in self.with_people_ids
|
|
]
|
|
|
|
@classmethod
|
|
def override_fields(cls) -> dict:
|
|
fields = {}
|
|
for base in cls.mro()[1:]:
|
|
if hasattr(base, "override_fields"):
|
|
base_fields = base.override_fields()
|
|
fields.update(base_fields)
|
|
custom_fields = {
|
|
"with_people_ids": forms.ModelMultipleChoiceField(
|
|
queryset=Person.objects.all(),
|
|
required=False,
|
|
widget=forms.SelectMultiple(attrs={"size": 10}),
|
|
)
|
|
}
|
|
fields.update(custom_fields)
|
|
return fields
|