diff --git a/home/doris-schoolhouse/app/routes/api_assignments.py b/home/doris-schoolhouse/app/routes/api_assignments.py index 60a137b..e99800a 100644 --- a/home/doris-schoolhouse/app/routes/api_assignments.py +++ b/home/doris-schoolhouse/app/routes/api_assignments.py @@ -1,6 +1,7 @@ import hashlib from pathlib import Path from typing import Any +from urllib.parse import quote_plus from fastapi import APIRouter, File, Form, HTTPException, Request, UploadFile from fastapi.responses import RedirectResponse @@ -40,33 +41,49 @@ def _confirm_submission_to_paperless(current: dict) -> dict: if value: fields[optional_key] = value artifact_kind = handoff.get("artifact_kind") or "document" - if artifact_kind == "source_bundle": - paperless_response = paperless.upload_source_bundle_receipt(current) - enrichment = paperless.enrich_direct_submission(current, paperless_response) + response: dict[str, Any] + body_obj: dict[str, Any] + ok = False + error_detail = None + try: + if artifact_kind == "source_bundle": + paperless_response = paperless.upload_source_bundle_receipt(current) + enrichment = paperless.enrich_direct_submission(current, paperless_response) + response = { + "ok": True, + "status_code": 200, + "body": paperless_response, + "mode": "direct-paperless", + "enrichment": enrichment, + } + task_id = paperless_response.get("task_id") or paperless_response.get("id") + body_obj = { + "paperless_document_id": enrichment.get("document_id"), + "paperless_title": enrichment.get("title") or paperless.build_submission_title(current), + "paperless_task_id": task_id, + "paperless_metadata": enrichment.get("metadata_payload"), + } + ok = True + else: + if handoff.get("artifact_kind"): + fields["artifact_kind"] = str(handoff["artifact_kind"]) + if handoff.get("file_count"): + fields["file_count"] = str(handoff["file_count"]) + response = webhooks.post_multipart(handoff["target_url"], fields, "document", file_path) + body = response.get("body", {}) if isinstance(response, dict) else {} + body_obj = body[0] if isinstance(body, list) and body and isinstance(body[0], dict) else (body if isinstance(body, dict) else {}) + ok = bool(response.get("ok", False)) if isinstance(response, dict) else False + if not ok: + error_detail = str(response.get("error") or response.get("body") or "Paperless confirmation failed.") + except Exception as exc: + error_detail = f"{type(exc).__name__}: {exc}" response = { - "ok": True, - "status_code": 200, - "body": paperless_response, - "mode": "direct-paperless", - "enrichment": enrichment, + "ok": False, + "status_code": 500, + "mode": "direct-paperless" if artifact_kind == "source_bundle" else "webhook", + "error": error_detail, } - task_id = paperless_response.get("task_id") or paperless_response.get("id") - body_obj = { - "paperless_document_id": enrichment.get("document_id"), - "paperless_title": enrichment.get("title") or paperless.build_submission_title(current), - "paperless_task_id": task_id, - "paperless_metadata": enrichment.get("metadata_payload"), - } - ok = True - else: - if handoff.get("artifact_kind"): - fields["artifact_kind"] = str(handoff["artifact_kind"]) - if handoff.get("file_count"): - fields["file_count"] = str(handoff["file_count"]) - response = webhooks.post_multipart(handoff["target_url"], fields, "document", file_path) - body = response.get("body", {}) if isinstance(response, dict) else {} - body_obj = body[0] if isinstance(body, list) and body and isinstance(body[0], dict) else (body if isinstance(body, dict) else {}) - ok = bool(response.get("ok", False)) if isinstance(response, dict) else False + body_obj = {} updates = { "status": "paperless-queued" if ok else "paperless-error", "confirmed_at": store.now(), @@ -76,6 +93,7 @@ def _confirm_submission_to_paperless(current: dict) -> dict: "paperless_task_id": body_obj.get("paperless_task_id"), } updated = repo.update_submission(str(current.get("id")), updates) or current + updated["paperless_error_detail"] = error_detail grade_note = None if ok and updated.get("assignment_id"): grade_note = paperless.append_grade_note_if_available(str(updated.get("assignment_id"))) @@ -87,6 +105,7 @@ def _confirm_submission_to_paperless(current: dict) -> dict: "webhook": [response], "grade_note": grade_note, "file_count": handoff.get("file_count") or 1, + "error_detail": error_detail, } @@ -220,7 +239,10 @@ async def intake_assignment( "backend": repo.backend, } if "text/html" in accept: - redirect_url = "/assignments/upload?submitted=" + str(created["id"]) + "&file_count=" + str(bundle["file_count"]) + "&artifact_kind=" + str(created.get("artifact_kind", "document")) + "&paperless_status=" + str(created.get("status", "uploaded-local")) + status_value = str(created.get("status", "uploaded-local")) + redirect_url = "/assignments/upload?submitted=" + str(created["id"]) + "&file_count=" + str(bundle["file_count"]) + "&artifact_kind=" + str(created.get("artifact_kind", "document")) + "&paperless_status=" + status_value + if auto_confirmed and auto_confirmed.get("error_detail"): + redirect_url += "&paperless_error=" + quote_plus(str(auto_confirmed["error_detail"])) return RedirectResponse(url=redirect_url, status_code=303) return response_payload diff --git a/home/doris-schoolhouse/app/templates/assignment_upload.html b/home/doris-schoolhouse/app/templates/assignment_upload.html index 64f27ea..cc6cd33 100644 --- a/home/doris-schoolhouse/app/templates/assignment_upload.html +++ b/home/doris-schoolhouse/app/templates/assignment_upload.html @@ -1,12 +1,19 @@ {% extends 'base.html' %} {% block content %} {% if request.query_params.get('submitted') %} -
-
Filed
-

Submission Created

+{% set paperless_status = request.query_params.get('paperless_status', 'uploaded-local') %} +
+
{{ 'Filed' if paperless_status == 'paperless-queued' else 'Saved locally' }}
+

{{ 'Submission Created' if paperless_status == 'paperless-queued' else 'Submission Saved, Archive Pending' }}

Submission {{ request.query_params.get('submitted') }} was created successfully.

Artifact: {{ request.query_params.get('artifact_kind', 'document') }} ยท Files: {{ request.query_params.get('file_count', '1') }}

-

Paperless status: {{ request.query_params.get('paperless_status', 'uploaded-local') }}

+

Paperless status: {{ paperless_status }}

+ {% if paperless_status != 'paperless-queued' %} +

Schoolhouse kept the submission locally, but the archive handoff failed this time.

+ {% if request.query_params.get('paperless_error') %} +

Error: {{ request.query_params.get('paperless_error') }}

+ {% endif %} + {% endif %}
{% endif %}