Files
Copies/copienator/dispatcher.py
T

77 lines
3.5 KiB
Python

from __future__ import annotations
import importlib
import sys
from collections.abc import Sequence
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class Command:
module: str
description: str
COMMANDS: dict[str, Command] = {
"statement": Command("gemini_for_enonce", "Analyse the exam statement with Gemini"),
"statement-personal": Command("enonce_info", "Generate personal statement metadata"),
"copies": Command("copies_tools", "Rotate or rename scanned copies"),
"page-split": Command("page_splitter", "Split and reorder scanned PDF pages"),
"crop-labels": Command("cutleft", "Crop the label margin from copies"),
"labels": Command("gemini_for_labels", "Detect question labels with Gemini"),
"review-labels": Command("plotting", "Review detected labels interactively"),
"split-answers": Command("splitting_int", "Split copies into answers"),
"group-answers": Command("grouping", "Group answers by question"),
"verify-groups": Command("verify_groups", "Verify grouped answer metadata"),
"correct": Command("correction", "Generate or integrate corrections"),
"batch-submit": Command("submit_batches", "Submit Gemini batch jobs"),
"batch-status": Command("batch_status", "Inspect Gemini batch jobs"),
"batch-fetch": Command("fetch_batched_results", "Fetch Gemini batch results"),
"post-correction": Command("post_correction", "Clean generated correction text"),
"resolve-manual": Command("resolve_manual", "Resolve manual label conflicts"),
"annotate-simple": Command("annotating", "Generate simple annotations"),
"annotate-checks": Command("annotating_with_checks", "Generate checkable annotations"),
"annotate-grouped": Command("annotating_by_label", "Generate grouped annotations"),
"export": Command("export", "Export annotations"),
"import": Command("import_annotations", "Import handwritten annotations"),
"read-annotations": Command("reading_annotations", "Read checkable annotations"),
"read-grouped": Command("reading_grouped_annotations", "Read grouped annotations"),
"giving-names": Command("giving_names", "Name copies and prepare A Rendre"),
"update-ods": Command("update_ods", "Update the configured score spreadsheet"),
"add-final-score": Command("add_final_score", "Stamp final scores on copies"),
"gui": Command("@gui", "Launch the graphical workflow assistant"),
}
def _print_help() -> None:
print("Usage: copienator COMMAND [ARGUMENTS]")
print(" python -m copienator COMMAND [ARGUMENTS]")
print("\nCommands:")
width = max(len(name) for name in COMMANDS)
for name, command in COMMANDS.items():
print(f" {name:<{width}} {command.description}")
print("\nUse 'copienator COMMAND --help' for command-specific help.")
def main(argv: Sequence[str] | None = None) -> int:
arguments = list(sys.argv[1:] if argv is None else argv)
if not arguments or arguments[0] in {"-h", "--help"}:
_print_help()
return 0
command_name = arguments.pop(0)
command = COMMANDS.get(command_name)
if command is None:
print(f"Unknown command: {command_name}", file=sys.stderr)
print("Use 'copienator --help' to list commands.", file=sys.stderr)
return 2
module_name = (
"copienator_gui.__main__"
if command.module == "@gui"
else f"copienator.commands.{command.module}"
)
module = importlib.import_module(module_name)
result = module.main(arguments)
return int(result or 0)