53 lines
2.0 KiB
Python
53 lines
2.0 KiB
Python
"""Local archive deliverer: writes reports/YYYY-MM-DD.md (+ .json) keyed by payload.krx_date."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from zoneinfo import ZoneInfo
|
|
|
|
from us2kr.config import KST
|
|
from us2kr.deliver.base import DeliveryError
|
|
from us2kr.models import BriefingResult
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class FileDeliverer:
|
|
"""Archive each briefing as Markdown and as the full BriefingResult JSON."""
|
|
|
|
name = "file"
|
|
|
|
def __init__(self, reports_dir: Path) -> None:
|
|
self.reports_dir = Path(reports_dir)
|
|
|
|
def _ensure_dir(self) -> None:
|
|
self.reports_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
def deliver(self, result: BriefingResult) -> str:
|
|
"""Write {krx_date}.md and {krx_date}.json; return the Markdown path."""
|
|
stem = result.payload.krx_date.isoformat()
|
|
md_path = self.reports_dir / f"{stem}.md"
|
|
json_path = self.reports_dir / f"{stem}.json"
|
|
try:
|
|
self._ensure_dir()
|
|
md_path.write_text(result.markdown, encoding="utf-8")
|
|
json_path.write_text(result.model_dump_json(indent=2), encoding="utf-8")
|
|
except OSError as exc:
|
|
raise DeliveryError(f"file delivery failed for {stem}: {exc}") from exc
|
|
log.info("report archived: %s (+ .json)", md_path)
|
|
return str(md_path)
|
|
|
|
def notify_error(self, subject: str, detail: str) -> None:
|
|
"""Append a timestamped line to {reports_dir}/errors.log. Never raises."""
|
|
try:
|
|
self._ensure_dir()
|
|
ts = datetime.now(ZoneInfo(KST)).isoformat(timespec="seconds")
|
|
flat_detail = " | ".join(part.strip() for part in detail.splitlines() if part.strip())
|
|
line = f"{ts}\t{subject}\t{flat_detail}\n"
|
|
with (self.reports_dir / "errors.log").open("a", encoding="utf-8") as fh:
|
|
fh.write(line)
|
|
except Exception:
|
|
log.exception("could not append to errors.log")
|