Rendering code refactor
This commit is contained in:
0
folkugat_web/model/lilypond/__init__.py
Normal file
0
folkugat_web/model/lilypond/__init__.py
Normal file
24
folkugat_web/model/lilypond/processing.py
Normal file
24
folkugat_web/model/lilypond/processing.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import dataclasses
|
||||
from typing import Self
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class RenderError:
|
||||
line: int
|
||||
pos: int
|
||||
error: str
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, error_match: dict[str, str]) -> Self:
|
||||
return cls(
|
||||
line=int(error_match["line"]),
|
||||
pos=int(error_match["pos"]),
|
||||
error=error_match["error"],
|
||||
)
|
||||
|
||||
def to_dict(self) -> dict[str, str]:
|
||||
return dict(
|
||||
line=str(self.line),
|
||||
pos=str(self.pos),
|
||||
error=self.error,
|
||||
)
|
||||
91
folkugat_web/model/lilypond/score.py
Normal file
91
folkugat_web/model/lilypond/score.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import dataclasses
|
||||
import zlib
|
||||
from typing import Self
|
||||
|
||||
from folkugat_web.model import temes
|
||||
from folkugat_web.utils import batched
|
||||
|
||||
|
||||
def get_hash(*v: bytes) -> bytes:
|
||||
return zlib.adler32(b"".join(v)).to_bytes(4)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class LyricsParagraph:
|
||||
lines: list[str]
|
||||
|
||||
def hash(self) -> bytes:
|
||||
return get_hash(*(get_hash(line.encode()) for line in self.lines))
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class LyricsLine:
|
||||
paragraphs: list[LyricsParagraph]
|
||||
|
||||
def hash(self) -> bytes:
|
||||
return get_hash(*(paragraph.hash() for paragraph in self.paragraphs))
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class LyricsText:
|
||||
lines: list[LyricsLine]
|
||||
|
||||
@classmethod
|
||||
def from_lyrics(cls, lyrics: temes.Lyrics, max_cols: int = 3) -> Self:
|
||||
paragraphs = [
|
||||
LyricsParagraph(lines=par_str.splitlines())
|
||||
for par_str in lyrics.content.split("\n\n") if par_str
|
||||
]
|
||||
return cls(lines=[
|
||||
LyricsLine(paragraphs=list(line_pars))
|
||||
for line_pars in batched(paragraphs, max_cols)
|
||||
])
|
||||
|
||||
def hash(self) -> bytes:
|
||||
return get_hash(*(line.hash() for line in self.lines))
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class HeaderData:
|
||||
title: str
|
||||
composer: str | None
|
||||
|
||||
@classmethod
|
||||
def from_tema(cls, tema: temes.Tema) -> Self:
|
||||
return cls(
|
||||
title=tema.title,
|
||||
composer=tema.composer() or tema.origin(),
|
||||
)
|
||||
|
||||
def hash(self) -> bytes:
|
||||
return get_hash(
|
||||
self.title.encode(),
|
||||
(self.composer or "").encode(),
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class LilypondTune:
|
||||
header: HeaderData
|
||||
score_source: str | None
|
||||
lyrics: LyricsText | None
|
||||
is_unknown: bool = False
|
||||
|
||||
def hash(self) -> bytes:
|
||||
return get_hash(
|
||||
self.header.hash(),
|
||||
(self.score_source or "").encode(),
|
||||
self.lyrics.hash() if self.lyrics else b"",
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class LilypondSet:
|
||||
title: str
|
||||
tunes: list[LilypondTune]
|
||||
|
||||
def hash(self) -> bytes:
|
||||
return get_hash(
|
||||
self.title.encode(),
|
||||
*(tune.hash() for tune in self.tunes),
|
||||
)
|
||||
Reference in New Issue
Block a user