109 lines
2.8 KiB
Python
109 lines
2.8 KiB
Python
import dataclasses
|
|
import enum
|
|
from collections.abc import Iterator
|
|
from typing import Self
|
|
|
|
from folkugat_web.model.temes import Tema
|
|
from folkugat_web.utils import groupby
|
|
|
|
|
|
class PlaylistType(enum.Enum):
|
|
SESSION_SETLIST = "session_setlist"
|
|
SESSION_SLOWJAM = "session_slowjam"
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class PlaylistEntry:
|
|
id: int | None
|
|
playlist_id: int
|
|
set_id: int
|
|
tema_id: int | None
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class TemaInSet:
|
|
id: int | None
|
|
tema_id: int | None
|
|
tema: Tema | None
|
|
|
|
def to_playlist_entry(self, playlist_id: int, set_id: int) -> PlaylistEntry:
|
|
return PlaylistEntry(
|
|
id=self.id,
|
|
playlist_id=playlist_id,
|
|
set_id=set_id,
|
|
tema_id=self.tema_id,
|
|
)
|
|
|
|
@classmethod
|
|
def from_playlist_entry(cls, entry: PlaylistEntry) -> Self:
|
|
return cls(
|
|
id=entry.id,
|
|
tema_id=entry.tema_id,
|
|
tema=None,
|
|
)
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class SetScore:
|
|
img_url: str | None
|
|
pdf_url: str | None
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class PlaylistScore:
|
|
img_url: str | None
|
|
pdf_url: str | None
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class Set:
|
|
id: int
|
|
temes: list[TemaInSet]
|
|
score: SetScore | None
|
|
|
|
def to_playlist_entries(self, playlist_id: int) -> Iterator[PlaylistEntry]:
|
|
for tema_in_set in self.temes:
|
|
yield tema_in_set.to_playlist_entry(
|
|
playlist_id=playlist_id,
|
|
set_id=self.id,
|
|
)
|
|
|
|
@classmethod
|
|
def from_playlist_entries(cls, set_id: int, entries: list[PlaylistEntry]) -> Self:
|
|
if any(entry.set_id != set_id for entry in entries):
|
|
raise ValueError("All PlaylistEntries must have the same session_id")
|
|
return cls(
|
|
id=set_id,
|
|
temes=[
|
|
TemaInSet.from_playlist_entry(entry)
|
|
for entry in sorted(entries, key=lambda e: e.id or 0)
|
|
],
|
|
score=None,
|
|
)
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class Playlist:
|
|
id: int
|
|
name: str | None
|
|
sets: list[Set]
|
|
hidden: bool = True
|
|
playlist_score: PlaylistScore | None = None
|
|
|
|
def to_playlist_entries(self) -> Iterator[PlaylistEntry]:
|
|
for set_entry in self.sets:
|
|
yield from set_entry.to_playlist_entries(playlist_id=self.id)
|
|
|
|
@classmethod
|
|
def from_playlist_entries(cls, playlist_id: int, name: str | None, entries: list[PlaylistEntry]) -> Self:
|
|
if any(entry.playlist_id != playlist_id for entry in entries):
|
|
raise ValueError("All PlaylistEntries must have the same playlist_id")
|
|
return cls(
|
|
id=playlist_id,
|
|
name=name,
|
|
sets=[
|
|
Set.from_playlist_entries(set_id, set_entries)
|
|
for set_id, set_entries in groupby(entries, key_fn=lambda e: e.set_id, group_fn=list)
|
|
],
|
|
)
|