"""Attach OCR transcripts under the cited origin media. Local variants are not publication locations; visual selection is driven by the canonical manifest's `embed` flag. python media_embed.py --thread --notes --media-id --attach-ocr """ from __future__ import annotations import argparse import json import sys from pathlib import Path try: from .media_manifest import atomic_write_json, find_location, selected_url, validate_manifest except ImportError: # pragma: no cover - script-mode import if str(Path(__file__).resolve().parent) not in sys.path: sys.path.insert(0, str(Path(__file__).resolve().parent)) from media_manifest import atomic_write_json, find_location, selected_url, validate_manifest OCR_DETAILS = "Text from still" def ocr_block(text: str) -> str: body = text.strip("\n") return ( "
\n" f"{OCR_DETAILS}\n" "\n" "```\n" f"{body}\n" "```\n" "\n" "
" ) def attach_ocr(notes_dir: Path, image_token: str, ocr_text: str) -> int: block = ocr_block(ocr_text) changed = 0 for path in notes_dir.glob("*.md"): text = path.read_text(encoding="utf-8") if image_token not in text: continue if OCR_DETAILS in text and image_token in text: print(f"ocr already near token in {path.name}") continue lines = text.splitlines(keepends=True) out: list[str] = [] inserted = False for i, line in enumerate(lines): out.append(line) if image_token in line and not inserted: if not line.endswith("\n"): out[-1] = line + "\n" out.append("\n") out.append(block + "\n") inserted = True if inserted: path.write_text("".join(out), encoding="utf-8") changed += 1 print(f"attached ocr in {path.name}") return changed def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--thread", type=Path, required=True, help="assets/threads/.../ folder") parser.add_argument("--notes", type=Path, required=True, help="archive/threads/.../ folder") parser.add_argument("--media-id", required=True) parser.add_argument("--attach-ocr", action="store_true") args = parser.parse_args(argv) if args.show: raise SystemExit( "local variants are not publishable locations; after confirming an " "origin failure, use tw.py fallback with the desired --role" ) if not args.attach_ocr: parser.print_help() return 2 media_path = args.thread / "media.json" data = json.loads(media_path.read_text(encoding="utf-8")) issues = validate_manifest(data) if issues: raise SystemExit(f"manifest invalid: {issues[0]}") target = None for item in data.get("items") or []: if ( str(item.get("media_id") or "") == args.media_id and str(item.get("role") or "") == "ocr" ): target = item break if target is None: raise SystemExit(f"no role=ocr for {args.media_id}; run ocr_pass.py first") ocr_path = args.thread / str(target.get("filename") or "") if not ocr_path.is_file(): raise SystemExit(f"missing {ocr_path}") visible = None for item in data.get("items") or []: if str(item.get("media_id") or "") != args.media_id: continue if item.get("embed") and selected_url(item): visible = item break if visible is None: raise SystemExit("media group has no embedded origin") image_token = str(selected_url(visible) or "") if not image_token: raise SystemExit("media group has no selected HTTPS location") attach_ocr(args.notes, image_token, ocr_path.read_text(encoding="utf-8")) atomic_write_json(media_path, data) return 0 if __name__ == "__main__": raise SystemExit(main())