Files
2025-07-28 22:45:45 +02:00

133 lines
4.6 KiB
Python

import dataclasses
from typing import Annotated
from fastapi import HTTPException, Request
from fastapi.params import Form
from fastapi.responses import HTMLResponse
from folkugat_web.api.router import get_router
from folkugat_web.fragments import temes
from folkugat_web.fragments.tema import scores as scores_fragments
from folkugat_web.services import auth, files
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
from folkugat_web.services.temes import scores as scores_service
router = get_router()
@router.get("/api/tema/{tema_id}/score/{score_id}")
def score(request: Request, logged_in: auth.LoggedIn, tema_id: int, score_id: int):
score = scores_service.get_score_by_id(score_id=score_id, tema_id=tema_id)
if not score:
raise HTTPException(status_code=404, detail="Could not find lyric!")
return scores_fragments.score(request=request, logged_in=logged_in, score=score)
@router.put("/api/tema/{tema_id}/score/{score_id}")
async def set_score(
request: Request,
logged_in: auth.RequireLogin,
tema_id: int,
score_id: int,
title: Annotated[str, Form()],
source: Annotated[str, Form()],
):
source = source.strip()
score = scores_service.get_score_by_id(score_id=score_id, tema_id=tema_id)
if not score:
raise HTTPException(status_code=404, detail="Could not find lyric!")
new_score = await scores_service.render_score(score=score, title=title, source=source)
scores_service.update_score(score=new_score)
files.clean_orphan_files()
return scores_fragments.score(request=request, logged_in=logged_in, score=new_score)
@router.post("/api/tema/{tema_id}/score")
def add_score(
request: Request,
logged_in: auth.RequireLogin,
tema_id: int,
):
score = scores_service.create_score(tema_id=tema_id)
return scores_fragments.score_editor(
request=request,
logged_in=logged_in,
score=score,
)
@router.delete("/api/tema/{tema_id}/score/{score_id}")
def delete_score(request: Request, logged_in: auth.RequireLogin, tema_id: int, score_id: int):
scores_service.delete_score(score_id=score_id, tema_id=tema_id)
files.clean_orphan_files()
return HTMLResponse()
@router.get("/api/tema/{tema_id}/editor/score/{score_id}")
def score_editor(
request: Request,
logged_in: auth.RequireLogin,
tema_id: int,
score_id: int,
):
score = scores_service.get_score_by_id(score_id=score_id, tema_id=tema_id)
if not score:
raise HTTPException(status_code=404, detail="Could not find lyric!")
return scores_fragments.score_editor(
request=request,
logged_in=logged_in,
score=score,
)
@router.post("/api/tema/{tema_id}/editor/score/{score_id}/render")
async def render(
request: Request,
_: auth.RequireLogin,
tema_id: int,
score_id: int,
source: Annotated[str, Form()],
):
tune = lilypond_build.tune_from_tema_id(tema_id=tema_id, score_source=source)
full_source = lilypond_source.tune_source(tune=tune)
png_result = await lilypond_render.render(
source=full_source,
output=lilypond_render.RenderOutput.PNG_CROPPED,
)
if output_filename := png_result.result:
score_render_url = files.get_db_file_path(output_filename)
return temes.score_render(request=request, score_id=score_id, score_render_url=score_render_url)
else:
return temes.score_render(request=request, score_id=score_id, errors=png_result.error)
@router.put("/api/tema/{tema_id}/score/{score_id}/show")
async def show_score(
request: Request,
logged_in: auth.RequireLogin,
tema_id: int,
score_id: int,
):
score = scores_service.get_score_by_id(score_id=score_id, tema_id=tema_id)
if not score:
raise HTTPException(status_code=404, detail="Could not find lyric!")
new_score = dataclasses.replace(score, hidden=False)
scores_service.update_score(score=new_score)
return scores_fragments.score(request=request, logged_in=logged_in, score=new_score)
@router.put("/api/tema/{tema_id}/score/{score_id}/hide")
async def hide_score(
request: Request,
logged_in: auth.RequireLogin,
tema_id: int,
score_id: int,
):
score = scores_service.get_score_by_id(score_id=score_id, tema_id=tema_id)
if not score:
raise HTTPException(status_code=404, detail="Could not find lyric!")
new_score = dataclasses.replace(score, hidden=True)
scores_service.update_score(score=new_score)
return scores_fragments.score(request=request, logged_in=logged_in, score=new_score)