Add independent MCP PDF report delivery
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
"""Shared authoritative PDF-report service for Flask and MCP adapters."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from pdf_report import (
|
||||
report_from_calculation_result,
|
||||
render_roll_report,
|
||||
safe_report_filename,
|
||||
)
|
||||
from roll_calculation import calculate_roll
|
||||
|
||||
|
||||
UNKNOWN_BUILD_INFO = {
|
||||
"version": "unknown",
|
||||
"branch": "unknown",
|
||||
"commit": "unknown",
|
||||
"timestamp": "unknown",
|
||||
}
|
||||
|
||||
|
||||
def create_roll_calculation_pdf(
|
||||
calculation_request: Any,
|
||||
*,
|
||||
build_info: dict[str, str],
|
||||
) -> tuple[bytes, str, dict[str, Any]]:
|
||||
"""Recalculate one request and render the established RollCalc PDF."""
|
||||
result = calculate_roll(calculation_request, build_info=build_info)
|
||||
pdf, filename = create_roll_calculation_pdf_from_result(
|
||||
result,
|
||||
build_info=build_info,
|
||||
)
|
||||
return pdf, filename, result
|
||||
|
||||
|
||||
def create_roll_calculation_pdf_from_result(
|
||||
result: dict[str, Any],
|
||||
*,
|
||||
build_info: dict[str, str],
|
||||
) -> tuple[bytes, str]:
|
||||
"""Render an already-authoritative calculation result using the shared path."""
|
||||
report = report_from_calculation_result(result)
|
||||
generated_at = datetime.now().astimezone()
|
||||
pdf = render_roll_report(
|
||||
report,
|
||||
generated_at=generated_at,
|
||||
build_info=build_info,
|
||||
)
|
||||
article_number = report["article"]["number"] if report["article"] else None
|
||||
return pdf, safe_report_filename(article_number, generated_at)
|
||||
|
||||
|
||||
def load_report_build_info(path: str = "build_info.json") -> dict[str, str]:
|
||||
"""Load the same optional build metadata shown by Flask-generated reports."""
|
||||
try:
|
||||
raw = json.loads(Path(path).read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
return UNKNOWN_BUILD_INFO.copy()
|
||||
if not isinstance(raw, dict):
|
||||
return UNKNOWN_BUILD_INFO.copy()
|
||||
build_info = UNKNOWN_BUILD_INFO.copy()
|
||||
for key in build_info:
|
||||
value = raw.get(key)
|
||||
if isinstance(value, str) and value.strip():
|
||||
build_info[key] = value.strip()
|
||||
return build_info
|
||||
Reference in New Issue
Block a user