Rendering code refactor

This commit is contained in:
marc
2025-04-26 19:09:59 +02:00
parent 7a823a98ab
commit d132e6fd60
33 changed files with 638 additions and 188 deletions

View File

View 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,
)

View 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),
)