""" 报价 PDF 任务壳:入队后由 LibreOffice **单槽**消费。 本文件职责:enqueue_pdf_job / process 调用 LibreOfficeConverter。 禁止:在 http_jobs 槽跑 soffice;禁止回调线程转换。 """ from __future__ import annotations import logging from dataclasses import dataclass from typing import Any, Optional from agent.jobs.libreoffice import LibreOfficeConverter, LibreOfficeResult from agent.redis_coord import get_redis_runtime, try_acquire_idempotency from agent.redis_coord.keys import STREAM_PDF from agent.redis_coord.runtime import RedisRuntime from agent.redis_coord.stream_queue import StreamQueue logger = logging.getLogger(__name__) @dataclass class PdfEnqueueResult: accepted: bool entry_id: str = "" reason: str = "" def pdf_stream(redis: Optional[RedisRuntime] = None) -> StreamQueue: rt = redis or get_redis_runtime() return StreamQueue(client=rt.client, stream_suffix=STREAM_PDF) def enqueue_pdf_job( *, xlsx_path: str, inquiry_no: str = "", quote_version: int = 0, idempotency_key: str = "", redis: Optional[RedisRuntime] = None, ) -> PdfEnqueueResult: """Excel→PDF 任务入队;真正转换只在 LibreOffice 槽。""" rt = redis or get_redis_runtime() q = pdf_stream(rt) q.ensure_group() if idempotency_key: ok = try_acquire_idempotency( rt.client, scope="pdf", idempotency_key=idempotency_key, ttl_seconds=600, ) if not ok: return PdfEnqueueResult(accepted=False, reason="duplicate_idempotency_key") payload = { "xlsx_path": xlsx_path, "inquiry_no": inquiry_no, "quote_version": quote_version, } entry_id = q.enqueue(payload=payload, idempotency_key=idempotency_key) logger.info("pdf.enqueue id=%s inquiry=%s", entry_id, inquiry_no or "-") return PdfEnqueueResult(accepted=True, entry_id=entry_id) def process_pdf_job( data: dict[str, Any], *, converter: Optional[LibreOfficeConverter] = None, ) -> LibreOfficeResult: """ 处理一条 PDF 任务(调用方必须已占用 libreoffice 槽)。 缺 xlsx_path 或本机无 soffice 时返回 ok=False,不抛崩 Worker。 """ path = str(data.get("xlsx_path") or "") conv = converter or LibreOfficeConverter.from_settings() if not path: return LibreOfficeResult(ok=False, error="missing_xlsx_path") return conv.convert_xlsx_to_pdf(path)