Extract managed form elements from XML
This commit is contained in:
@@ -156,8 +156,7 @@ def html5_setup_job(
|
||||
async def html5_setup_reindex(
|
||||
*,
|
||||
project_id: str,
|
||||
reindex: Callable[[str], Any],
|
||||
setup_response: Callable[[str], object],
|
||||
start_reindex_job: Callable[[str], Any],
|
||||
) -> str:
|
||||
await reindex(project_id)
|
||||
return render_html5_setup_summary(project_id, setup_response(project_id))
|
||||
job = await start_reindex_job(project_id)
|
||||
return render_html5_import_job(project_id, job)
|
||||
|
||||
@@ -488,7 +488,7 @@ def _load_persisted_state() -> None:
|
||||
_collaboration.ownership[_collaboration._ownership_key(ownership)] = ownership
|
||||
for payload in _storage.list_documents("operations_jobs"):
|
||||
job = OperationJob.model_validate(payload)
|
||||
if job.kind == "SERVER_IMPORT" and job.status in {OperationJobStatus.QUEUED, OperationJobStatus.RUNNING}:
|
||||
if job.kind in {"SERVER_IMPORT", "REINDEX"} and job.status in {OperationJobStatus.QUEUED, OperationJobStatus.RUNNING}:
|
||||
job.status = OperationJobStatus.FAILED
|
||||
job.error = "Операция была прервана перезапуском сервера."
|
||||
from datetime import datetime, timezone
|
||||
@@ -1738,8 +1738,7 @@ async def html5_project_setup_reindex(project_id: str) -> Response:
|
||||
return _html5_response(
|
||||
await _html5_setup_reindex(
|
||||
project_id=project_id,
|
||||
reindex=reindex_project,
|
||||
setup_response=_project_setup_response,
|
||||
start_reindex_job=start_project_reindex_job,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -2100,6 +2099,33 @@ async def check_project_import(
|
||||
|
||||
@app.post("/projects/{project_id}/reindex", response_model=ImportSummary)
|
||||
async def reindex_project(project_id: str) -> ImportSummary:
|
||||
return _execute_reindex_project(project_id)
|
||||
|
||||
|
||||
@app.post("/projects/{project_id}/reindex/jobs", response_model=OperationJob)
|
||||
async def start_project_reindex_job(project_id: str) -> OperationJob:
|
||||
active_job = _active_project_operation_job(project_id, {"REINDEX"})
|
||||
if active_job is not None:
|
||||
return active_job
|
||||
job = OperationJob(
|
||||
job_id=f"reindex-{uuid4()}",
|
||||
kind="REINDEX",
|
||||
status=OperationJobStatus.QUEUED,
|
||||
payload={
|
||||
"project_id": project_id,
|
||||
"stage": "queued",
|
||||
"message": "Переиндексация поставлена в очередь.",
|
||||
"logs": ["Переиндексация поставлена в очередь."],
|
||||
"started_at": None,
|
||||
"finished_at": None,
|
||||
},
|
||||
)
|
||||
_persist_job(_operations.enqueue(job))
|
||||
threading.Thread(target=_run_reindex_job, args=(job.job_id, project_id), daemon=True).start()
|
||||
return _operations.jobs[job.job_id]
|
||||
|
||||
|
||||
def _execute_reindex_project(project_id: str) -> ImportSummary:
|
||||
state = _project_setup.get(project_id, {})
|
||||
current_source = ImportSourceKind(state.get("current_source") or ImportSourceKind.XML_DUMP.value)
|
||||
last_import = state.get("last_import") or {}
|
||||
@@ -2128,6 +2154,7 @@ async def reindex_project(project_id: str) -> ImportSummary:
|
||||
state["last_import"] = summary.model_dump(mode="json")
|
||||
_append_import_history(project_id, summary)
|
||||
state["status"] = ProjectSetupStatus.INDEXED.value
|
||||
_storage.write_document("project_settings", project_id, state)
|
||||
return summary
|
||||
|
||||
|
||||
@@ -7850,32 +7877,11 @@ def _form_semantics_response(item) -> FormSemanticsResponse:
|
||||
def _form_semantics_for_lineages(snapshot: SirSnapshot, form_lineages: set[str]) -> list[FormSemanticsResponse]:
|
||||
if not form_lineages:
|
||||
return []
|
||||
nodes = {node.lineage_id: node for node in snapshot.nodes}
|
||||
forms = {
|
||||
lineage_id: FormSemanticsResponse(form=_named_node(node), commands=[], elements=[], command_handlers={})
|
||||
for lineage_id, node in nodes.items()
|
||||
if lineage_id in form_lineages and node.kind == NodeKind.FORM
|
||||
}
|
||||
command_to_form: dict[str, FormSemanticsResponse] = {}
|
||||
for edge in snapshot.edges:
|
||||
form = forms.get(edge.source_lineage)
|
||||
target = nodes.get(edge.target_lineage)
|
||||
if form is None or target is None:
|
||||
continue
|
||||
if edge.kind == EdgeKind.HAS_COMMAND:
|
||||
named_target = _named_node(target)
|
||||
form.commands.append(named_target)
|
||||
command_to_form[target.lineage_id] = form
|
||||
elif edge.kind == EdgeKind.HAS_ELEMENT:
|
||||
form.elements.append(_named_node(target))
|
||||
for edge in snapshot.edges:
|
||||
if edge.kind != EdgeKind.HANDLES:
|
||||
continue
|
||||
form = command_to_form.get(edge.source_lineage)
|
||||
handler = nodes.get(edge.target_lineage)
|
||||
if form is not None and handler is not None:
|
||||
form.command_handlers[edge.source_lineage] = _named_node(handler)
|
||||
return sorted(forms.values(), key=lambda item: item.form.qualified_name)
|
||||
return [
|
||||
_form_semantics_response(item)
|
||||
for item in form_semantics(snapshot)
|
||||
if item.form.lineage_id in form_lineages
|
||||
]
|
||||
|
||||
|
||||
def _persist_job(job: OperationJob) -> OperationJob:
|
||||
@@ -7916,6 +7922,35 @@ def _run_server_import_job(job_id: str, project_id: str, request: ImportRequest)
|
||||
)
|
||||
|
||||
|
||||
def _run_reindex_job(job_id: str, project_id: str) -> None:
|
||||
if job_id not in _operations.jobs:
|
||||
return
|
||||
_update_import_job_progress(job_id, "Переиндексация запущена.", stage="running", status=OperationJobStatus.RUNNING)
|
||||
try:
|
||||
_update_import_job_progress(job_id, "Пересборка snapshot и UI-семантики.", stage="indexing")
|
||||
summary = _execute_reindex_project(project_id)
|
||||
except Exception as error:
|
||||
_update_import_job_progress(
|
||||
job_id,
|
||||
f"Переиндексация завершилась ошибкой: {error}",
|
||||
stage="failed",
|
||||
status=OperationJobStatus.FAILED,
|
||||
error=str(error),
|
||||
finished_at=_current_timestamp(),
|
||||
)
|
||||
return
|
||||
status = OperationJobStatus.SUCCEEDED if summary.applied is not False and not summary.errors else OperationJobStatus.FAILED
|
||||
_update_import_job_progress(
|
||||
job_id,
|
||||
"Переиндексация завершена." if status == OperationJobStatus.SUCCEEDED else "Переиндексация остановлена. Проверьте ошибки.",
|
||||
stage="done" if status == OperationJobStatus.SUCCEEDED else "failed",
|
||||
status=status,
|
||||
result={"import_summary": summary.model_dump(mode="json")},
|
||||
error="; ".join(summary.errors) if summary.errors else None,
|
||||
finished_at=_current_timestamp(),
|
||||
)
|
||||
|
||||
|
||||
def _create_agent_server_import_job(agent_job: AgentImportJob, request: ImportRequest) -> OperationJob:
|
||||
operation_job = OperationJob(
|
||||
job_id=f"server-import-{uuid4()}",
|
||||
@@ -8091,11 +8126,15 @@ def _run_agent_uploaded_zip_job(job_id: str, upload_path_raw: str, import_root_r
|
||||
|
||||
|
||||
def _active_server_import_job(project_id: str) -> OperationJob | None:
|
||||
return _active_project_operation_job(project_id, {"SERVER_IMPORT"})
|
||||
|
||||
|
||||
def _active_project_operation_job(project_id: str, kinds: set[str]) -> OperationJob | None:
|
||||
active_statuses = {OperationJobStatus.QUEUED, OperationJobStatus.RUNNING}
|
||||
candidates = [
|
||||
job
|
||||
for job in _operations.jobs.values()
|
||||
if job.kind == "SERVER_IMPORT"
|
||||
if job.kind in kinds
|
||||
and job.payload.get("project_id") == project_id
|
||||
and job.status in active_statuses
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user