96 lines
3.5 KiB
Python
96 lines
3.5 KiB
Python
import dataclasses
|
|
from collections.abc import Iterable, Iterator
|
|
|
|
from folkugat_web.dal.sql.temes import scores as scores_dal
|
|
from folkugat_web.model import temes as model
|
|
from folkugat_web.services import files as files_service
|
|
from folkugat_web.services.lilypond import build as lilypond_build
|
|
from folkugat_web.services.lilypond import render as lilypond_render
|
|
from folkugat_web.services.lilypond import source as lilypond_source
|
|
|
|
|
|
def add_scores_to_tema(tema: model.Tema) -> model.Tema:
|
|
if tema.id is not None:
|
|
tema.scores = list(scores_dal.get_scores(tema_id=tema.id))
|
|
return tema
|
|
|
|
|
|
def add_scores_to_temes(temes: Iterable[model.Tema]) -> Iterator[model.Tema]:
|
|
return map(add_scores_to_tema, temes)
|
|
|
|
|
|
def get_score_by_id(score_id: int, tema_id: int | None = None) -> model.Score | None:
|
|
return next(iter(scores_dal.get_scores(score_id=score_id, tema_id=tema_id)), None)
|
|
|
|
|
|
def update_score(score: model.Score):
|
|
scores_dal.update_score(score=score)
|
|
|
|
|
|
def delete_score(score_id: int, tema_id: int | None = None):
|
|
scores_dal.delete_score(score_id=score_id, tema_id=tema_id)
|
|
|
|
|
|
def create_score(tema_id: int) -> model.Score:
|
|
new_score = model.Score(
|
|
id=None,
|
|
tema_id=tema_id,
|
|
title="",
|
|
source="",
|
|
errors=[],
|
|
img_url=None,
|
|
pdf_url=None,
|
|
preview_url=None,
|
|
hidden=True,
|
|
)
|
|
return scores_dal.insert_score(score=new_score)
|
|
|
|
|
|
async def render_score(score: model.Score, title: str, source: str) -> model.Score:
|
|
tune = lilypond_build.tune_from_tema_id(tema_id=score.tema_id, score_source=source)
|
|
output_file = files_service.create_tema_filename(tema_id=score.tema_id)
|
|
|
|
tune_source = lilypond_source.tune_source(tune=tune)
|
|
async with files_service.tmp_file(content=tune_source) as source_file:
|
|
# Render PDF
|
|
pdf_result = await lilypond_render.render_file(
|
|
input_file=source_file,
|
|
output=lilypond_render.RenderOutput.PDF,
|
|
output_file=output_file,
|
|
)
|
|
if errors := pdf_result.error:
|
|
return dataclasses.replace(score, source=source, title=title, errors=errors)
|
|
# Render IMAGE
|
|
img_result = await lilypond_render.render_file(
|
|
input_file=source_file,
|
|
output=lilypond_render.RenderOutput.PNG_CROPPED,
|
|
output_file=output_file,
|
|
)
|
|
if errors := img_result.error:
|
|
return dataclasses.replace(score, source=source, title=title, errors=errors)
|
|
|
|
preview_source = lilypond_source.preview_source(tune=tune)
|
|
async with files_service.tmp_file(content=preview_source) as source_file:
|
|
# Render PREVIEW
|
|
preview_result = await lilypond_render.render_file(
|
|
input_file=source_file,
|
|
output=lilypond_render.RenderOutput.PREVIEW,
|
|
output_file=output_file,
|
|
)
|
|
if errors := preview_result.error:
|
|
return dataclasses.replace(score, source=source, title=title, errors=errors)
|
|
|
|
pdf_file = pdf_result.result
|
|
img_file = img_result.result
|
|
preview_file = preview_result.result if preview_result.result and preview_result.result.exists() else None
|
|
|
|
return dataclasses.replace(
|
|
score,
|
|
source=source,
|
|
title=title,
|
|
pdf_url=files_service.get_db_file_path(pdf_file) if pdf_file else None,
|
|
img_url=files_service.get_db_file_path(img_file) if img_file else None,
|
|
preview_url=files_service.get_db_file_path(preview_file) if preview_file else None,
|
|
errors=[],
|
|
)
|