import argparse import sys from collections.abc import Sequence from pathlib import Path from copienator import ( EvaluationWorkspace, ExitCode, evaluation_parser, execute, workspace_from_args, ) from copienator.configuration import EXPORT_DIR from copienator.platform import replace_with_link_or_copy ANNOTATION_DIRECTORIES = ("BGnot", "Bnot", "Anot") def export_directory( workspace: EvaluationWorkspace, source_dir_name: str, ) -> ExitCode: workspace.require_directories(source_dir_name) source_dir = workspace.annotation_dir("refaire") if source_dir_name == "BRnot" else workspace.root / source_dir_name session_id = workspace.refaire_session_id if source_dir_name == "BRnot" else None prefix = f"{session_id}__" if session_id else "" sync_dir = Path(EXPORT_DIR).expanduser() / workspace.name if session_id: sync_dir /= session_id sync_dir.mkdir(parents=True, exist_ok=True) subdirs = [directory for directory in source_dir.iterdir() if directory.is_dir()] if source_dir_name == "BGnot" and subdirs: all_start_with_copie = all(directory.name.startswith("Copie") for directory in subdirs) if not all_start_with_copie: subdirs = [directory for directory in subdirs if not directory.name.startswith("Copie")] missing_outputs = 0 for subdir in subdirs: concat_file = next( ( candidate for candidate in (subdir / "Concat.pdf", subdir / "Concat.jpg") if candidate.is_file() ), None, ) if concat_file is None: print( f"Warning: no Concat.pdf or Concat.jpg found in {subdir}", file=sys.stderr, ) missing_outputs += 1 continue destination = sync_dir / f"{prefix}{subdir.name}{concat_file.suffix.lower()}" method = replace_with_link_or_copy(concat_file, destination, prefer="hardlink") print(f"Exported: {destination} ({method})") return ExitCode.PARTIAL if missing_outputs else ExitCode.SUCCESS def build_parser() -> argparse.ArgumentParser: parser = evaluation_parser("Export annotated PDFs to the tablet directory.") parser.add_argument( "annotation_dir", nargs="?", choices=ANNOTATION_DIRECTORIES, default="BGnot", help="Annotation directory to export (default: BGnot)", ) parser.add_argument("--refaire", action="store_true", help="Process only copies/labels defined in refaire.json") return parser def run( workspace: EvaluationWorkspace, *, annotation_dir: str = "BGnot", refaire: bool = False, ) -> ExitCode: return export_directory(workspace, "BRnot" if refaire else annotation_dir) def main(argv: Sequence[str] | None = None) -> int: parser = build_parser() return execute( parser, argv, lambda args: run( workspace_from_args(args), annotation_dir=args.annotation_dir, refaire=args.refaire, ), ) if __name__ == "__main__": raise SystemExit(main())