Files
folkugat-web/folkugat_web/fragments/temes.py
2025-10-10 00:14:36 +02:00

191 lines
5.7 KiB
Python

import json
import urllib.parse
from fastapi import Request
from folkugat_web.model import temes as model
from folkugat_web.model.lilypond.processing import RenderError
from folkugat_web.model.pagines import Pages
from folkugat_web.model.search import Order, OrderBy, OrderParams
from folkugat_web.services import sessions as sessions_service
from folkugat_web.services.sessions import get_date_names
from folkugat_web.services.temes import query as temes_q
from folkugat_web.services.temes import scores as scores_service
from folkugat_web.services.temes import search as temes_s
from folkugat_web.templates import templates
from folkugat_web.utils import FnChain
def build_temes_params(
query: str,
properties: list[str],
order_params: OrderParams | None = None,
) -> str:
content_params = [
("query", query),
*[("properties", prop) for prop in properties or []]
]
if order_params:
content_params.append(("order_by", order_params.order_by.value))
content_params.append(("order", order_params.order.value))
return urllib.parse.urlencode(content_params)
def build_hx_vars(*vars_dicts: dict[str, str]) -> str:
result = ",".join(f"{var}:{value}" for hx_vars in vars_dicts for var, value in hx_vars.items())
return result
def build_property_str(properties: list[str]) -> str:
return json.dumps(properties).replace("'", "\\'").replace('"', "'")
def build_order_params_dict(order_params: OrderParams | None) -> dict[str, str]:
if not order_params:
return {}
return {
"order_by": f"'{order_params.order_by.value}'",
"order": f"'{order_params.order.value}'",
}
def temes_pagina(
request: Request,
logged_in: bool,
query: str,
properties: list[str],
order_params: OrderParams | None,
):
properties_str = build_property_str(properties)
order_params_dict = build_order_params_dict(order_params)
return templates.TemplateResponse(
"fragments/temes/pagina.html",
{
"request": request,
"logged_in": logged_in,
"query": query,
"properties": properties,
"properties_str": properties_str,
"order_params": order_params,
"order_params_dict": order_params_dict,
"build_hx_vars": build_hx_vars,
"property_results": [],
"Order": Order,
"OrderBy": OrderBy,
"Pages": Pages,
"get_date_names": get_date_names,
"menu_selected_id": Pages.Temes,
}
)
def temes_busca(
request: Request,
logged_in: bool,
query: str,
properties: list[str],
order_params: OrderParams | None = None,
offset: int = 0,
limit: int = 10,
):
temes = temes_s.busca_temes(
query=query,
properties=properties,
order_params=order_params,
hidden=logged_in,
limit=limit + 1,
offset=offset,
)
next_offset, prev_offset = None, None
if len(temes) > limit:
next_offset = offset + limit
temes = temes[:limit]
if offset > 0:
prev_offset = max(offset - limit, 0)
temes = (
FnChain.transform(temes) |
temes_q.temes_compute_stats |
scores_service.add_scores_to_temes |
# No properties added because search already does that
list
).result()
property_results = [
prop for prop in temes_s.busca_properties(query=query, limit=5)
if prop not in properties
]
temes_params = build_temes_params(
query=query,
properties=properties,
order_params=order_params,
)
temes_url = f"/temes?{temes_params}"
def _add_property_str(prop: str) -> str:
properties_dedup = list(set(properties + [prop]))
return build_property_str(properties_dedup)
def _remove_property_str(prop: str) -> str:
properties_clean = [p for p in properties if p.lower() != prop.lower()]
return build_property_str(properties_clean)
return templates.TemplateResponse(
"fragments/temes/results.html",
{
"request": request,
"logged_in": logged_in,
"temes": temes,
"query": query,
"properties": properties,
"properties_str": build_property_str(properties),
"order_params": order_params,
"order_params_dict": build_order_params_dict(order_params),
"property_results": property_results,
"prev_offset": prev_offset,
"next_offset": next_offset,
"LinkType": model.LinkType,
"ContentType": model.ContentType,
"Order": Order,
"OrderBy": OrderBy,
"get_date_names": get_date_names,
"add_property_str": _add_property_str,
"remove_property_str": _remove_property_str,
"build_hx_vars": build_hx_vars,
},
headers={"HX-Replace-Url": temes_url},
)
def tema(request: Request, logged_in: bool, tema: model.Tema):
return templates.TemplateResponse(
"fragments/tema/pagina.html",
{
"request": request,
"logged_in": logged_in,
"Pages": Pages,
"LinkType": model.LinkType,
"ContentType": model.ContentType,
"tema": tema,
"date_names": sessions_service.get_date_names,
}
)
def score_render(
request: Request,
score_id: int,
score_render_url: str = "",
errors: list[RenderError] | None = None,
):
return templates.TemplateResponse(
"fragments/tema/editor/score_render.html",
{
"request": request,
"score_id": score_id,
"score_render_url": score_render_url,
"errors": errors,
}
)