Add batch processing for pending OCR
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
Run and validate OCR processing for one movie in the SQLite index.
|
||||
|
||||
The script accepts a WCX movie ID, retrieves the movie name and thumbnail URL
|
||||
from the database, and then coordinates the complete OCR workflow:
|
||||
from the selected database, and coordinates the complete OCR workflow:
|
||||
|
||||
1. Run ocr.sh for the thumbnail URL.
|
||||
2. Pass the raw OCR text to parse_ocr.py.
|
||||
@ -30,21 +30,48 @@ updated.
|
||||
|
||||
Usage:
|
||||
check_ocr.py <movie-id>
|
||||
check_ocr.py <movie-id> --database /path/to/wcx.db
|
||||
|
||||
Example:
|
||||
check_ocr.py susana-melo_6707
|
||||
"""
|
||||
|
||||
|
||||
import argparse
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
DATABASE_FILE = Path("/storage/disk1/WCX/database/wcx.db")
|
||||
OCR_SCRIPT = Path("/storage/disk1/WCX/scripts/ocr.sh")
|
||||
PARSER_SCRIPT = Path("/storage/disk1/WCX/scripts/parse_ocr.py")
|
||||
DEFAULT_DATABASE_FILE = Path(
|
||||
"/storage/disk1/WCX/database/wcx.db"
|
||||
)
|
||||
OCR_SCRIPT = Path(
|
||||
"/storage/disk1/WCX/scripts/ocr.sh"
|
||||
)
|
||||
PARSER_SCRIPT = Path(
|
||||
"/storage/disk1/WCX/scripts/parse_ocr.py"
|
||||
)
|
||||
|
||||
|
||||
def parse_arguments() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Run OCR processing for one WCX movie."
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"movie_id",
|
||||
help="Movie ID to process.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--database",
|
||||
type=Path,
|
||||
default=DEFAULT_DATABASE_FILE,
|
||||
help=f"SQLite database; default: {DEFAULT_DATABASE_FILE}",
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def parse_key_value_output(output: str) -> dict[str, str]:
|
||||
@ -147,13 +174,26 @@ def set_ocr_completed(
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) != 2:
|
||||
print(f"Användning: {sys.argv[0]} <movie-id>", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
args = parse_arguments()
|
||||
movie_id = args.movie_id
|
||||
database_file = args.database
|
||||
|
||||
movie_id = sys.argv[1]
|
||||
if not database_file.is_file():
|
||||
raise FileNotFoundError(
|
||||
f"Database file does not exist: {database_file}"
|
||||
)
|
||||
|
||||
with sqlite3.connect(DATABASE_FILE) as connection:
|
||||
if not OCR_SCRIPT.is_file():
|
||||
raise FileNotFoundError(
|
||||
f"OCR script does not exist: {OCR_SCRIPT}"
|
||||
)
|
||||
|
||||
if not PARSER_SCRIPT.is_file():
|
||||
raise FileNotFoundError(
|
||||
f"OCR parser does not exist: {PARSER_SCRIPT}"
|
||||
)
|
||||
|
||||
with sqlite3.connect(database_file) as connection:
|
||||
row = connection.execute(
|
||||
"""
|
||||
SELECT name, thumbnail
|
||||
@ -165,7 +205,7 @@ def main() -> None:
|
||||
|
||||
if row is None:
|
||||
print(
|
||||
f"Filmen finns inte i databasen: {movie_id}",
|
||||
f"Movie does not exist in database: {movie_id}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
@ -173,7 +213,7 @@ def main() -> None:
|
||||
database_name, thumbnail = row
|
||||
|
||||
if not thumbnail:
|
||||
error_message = "Filmen saknar thumbnail."
|
||||
error_message = "Movie has no thumbnail."
|
||||
|
||||
set_ocr_failed(
|
||||
connection,
|
||||
@ -193,7 +233,7 @@ def main() -> None:
|
||||
if ocr_result.returncode != 0:
|
||||
error_message = (
|
||||
ocr_result.stderr.strip()
|
||||
or "OCR-körningen misslyckades."
|
||||
or "OCR execution failed."
|
||||
)
|
||||
|
||||
set_ocr_failed(
|
||||
@ -203,7 +243,7 @@ def main() -> None:
|
||||
ocr_result.stdout.strip() or None,
|
||||
)
|
||||
|
||||
print("OCR-körningen misslyckades:", file=sys.stderr)
|
||||
print("OCR execution failed:", file=sys.stderr)
|
||||
print(error_message, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
@ -219,7 +259,7 @@ def main() -> None:
|
||||
if parser_result.returncode != 0:
|
||||
error_message = (
|
||||
parser_result.stderr.strip()
|
||||
or "Tolkningen av OCR-resultatet misslyckades."
|
||||
or "OCR output parsing failed."
|
||||
)
|
||||
|
||||
set_manual_review(
|
||||
@ -230,7 +270,7 @@ def main() -> None:
|
||||
)
|
||||
|
||||
print(
|
||||
"Tolkningen av OCR-resultatet misslyckades:",
|
||||
"OCR output parsing failed:",
|
||||
file=sys.stderr,
|
||||
)
|
||||
print(error_message, file=sys.stderr)
|
||||
@ -253,7 +293,7 @@ def main() -> None:
|
||||
|
||||
if missing_fields:
|
||||
error_message = (
|
||||
"Parsern saknar fält: "
|
||||
"Parser output is missing fields: "
|
||||
+ ", ".join(missing_fields)
|
||||
)
|
||||
|
||||
@ -275,7 +315,7 @@ def main() -> None:
|
||||
|
||||
if not names_match:
|
||||
error_message = (
|
||||
"OCR-namnet matchar inte databasnamnet: "
|
||||
"OCR name does not match database name: "
|
||||
f"{ocr_name!r} != {database_name!r}"
|
||||
)
|
||||
|
||||
@ -299,6 +339,7 @@ def main() -> None:
|
||||
)
|
||||
|
||||
print(f"id={movie_id}")
|
||||
print(f"database={database_file}")
|
||||
print(f"database_name={database_name}")
|
||||
print(f"ocr_name={ocr_name}")
|
||||
print("name_match=yes")
|
||||
@ -309,5 +350,11 @@ def main() -> None:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
try:
|
||||
main()
|
||||
except (
|
||||
FileNotFoundError,
|
||||
sqlite3.Error,
|
||||
) as error:
|
||||
print(f"Error: {error}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
Reference in New Issue
Block a user