Add HTML5 metadata authoring form
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-05-16 23:55:02 +03:00
parent 460881428b
commit 41dc88c33b
3 changed files with 283 additions and 0 deletions
@@ -44,6 +44,8 @@ from api_server.html5 import (
render_html5_authoring_rollback_result,
render_html5_editor,
render_html5_index,
render_html5_metadata_apply_result,
render_html5_metadata_preview_result,
render_html5_project_setup,
render_html5_project_rows,
render_html5_project_report,
@@ -1851,6 +1853,39 @@ async def html5_project_authoring_apply_change_set(project_id: str, request: Req
return Response(html, media_type="text/html; charset=utf-8")
@app.post("/html5/projects/{project_id}/authoring/metadata-object-preview")
async def html5_project_authoring_metadata_object_preview(project_id: str, request: Request) -> Response:
form = await _html5_form_data(request)
raw_payload = _html5_metadata_payload(form)
payload = AuthoringMetadataObjectPreviewRequest(**_html5_metadata_request_payload(raw_payload))
try:
preview = _authoring_metadata_object_preview(project_id, payload)
html = render_html5_metadata_preview_result(project_id, preview, request_payload=raw_payload)
except (HTTPException, ValueError) as error:
detail = getattr(error, "detail", str(error))
html = render_html5_metadata_preview_result(project_id, error=str(detail))
return Response(html, media_type="text/html; charset=utf-8")
@app.post("/html5/projects/{project_id}/authoring/apply-metadata-object")
async def html5_project_authoring_apply_metadata_object(project_id: str, request: Request) -> Response:
form = await _html5_form_data(request)
raw_payload = _html5_metadata_payload(form)
payload = AuthoringApplyMetadataObjectRequest(
**_html5_metadata_request_payload(raw_payload),
expected_next_version_id=_form_value(form, "expected_next_version_id") or "",
approved_by=_form_value(form, "approved_by") or "",
approval_note=_form_value(form, "approval_note"),
)
try:
result = await authoring_apply_metadata_object(project_id, payload)
html = render_html5_metadata_apply_result(project_id, result)
except (HTTPException, ValueError) as error:
detail = getattr(error, "detail", str(error))
html = render_html5_metadata_apply_result(project_id, error=str(detail))
return Response(html, media_type="text/html; charset=utf-8")
@app.get("/html5/projects/{project_id}/setup")
async def html5_project_setup(project_id: str) -> Response:
setup = _project_setup_response(project_id)
@@ -8004,6 +8039,66 @@ def _form_value(form: dict[str, list[str]], key: str) -> str | None:
return value or None
def _html5_metadata_payload(form: dict[str, list[str]]) -> dict:
return {
"object_kind": _form_value(form, "object_kind") or "DOCUMENT",
"name": _form_value(form, "name") or "",
"synonym": _form_value(form, "synonym"),
"attributes": _html5_metadata_attributes(_form_value(form, "attributes") or ""),
"tabular_sections": _html5_metadata_tabular_sections(_form_value(form, "tabular_sections") or ""),
"forms": _html5_csv_values(_form_value(form, "forms") or ""),
"commands": _html5_metadata_commands(_form_value(form, "commands") or ""),
"task_id": _form_value(form, "task_id"),
"session_id": _form_value(form, "session_id"),
"user_id": _form_value(form, "user_id"),
"_raw_attributes": _form_value(form, "attributes") or "",
"_raw_tabular_sections": _form_value(form, "tabular_sections") or "",
"_raw_forms": _form_value(form, "forms") or "",
"_raw_commands": _form_value(form, "commands") or "",
}
def _html5_metadata_request_payload(payload: dict) -> dict:
return {key: value for key, value in payload.items() if not key.startswith("_raw_")}
def _html5_csv_values(raw: str) -> list[str]:
return [item.strip() for item in raw.replace("\n", ",").split(",") if item.strip()]
def _html5_metadata_attributes(raw: str) -> list[dict]:
attributes: list[dict] = []
for item in _html5_csv_values(raw):
name, _, type_name = item.partition(":")
if name.strip():
attributes.append({"name": name.strip(), "type": type_name.strip() or "Строка"})
return attributes
def _html5_metadata_commands(raw: str) -> list[dict]:
commands: list[dict] = []
for item in _html5_csv_values(raw):
name, _, handler = item.partition(":")
if name.strip():
commands.append({"name": name.strip(), "handler": handler.strip() or None})
return commands
def _html5_metadata_tabular_sections(raw: str) -> list[dict]:
sections: list[dict] = []
for item in _html5_csv_values(raw):
name, _, attrs = item.partition("[")
if not name.strip():
continue
attributes = []
for attr in attrs.rstrip("]").split(";"):
attr_name, _, attr_type = attr.partition(":")
if attr_name.strip():
attributes.append({"name": attr_name.strip(), "type": attr_type.strip() or "Строка"})
sections.append({"name": name.strip(), "attributes": attributes})
return sections
def _current_import_source(project_id: str) -> ImportSourceKind:
setup = _project_setup_response(project_id)
if setup.current_source is not None: