|
| 1 | +#!/usr/bin/env python3 |
| 2 | +""" |
| 3 | +Check a local PDF against pywikitools PDF metadata rules (same logic as resourcesbot). |
| 4 | +
|
| 5 | +Usage (from repository root): |
| 6 | + ./env/bin/python check_pdf_metadata.py WORKSHEET_NAME LANGUAGE_CODE PATH_TO_PDF |
| 7 | +
|
| 8 | +Title and expected version are read from the wiki unless you pass --title and/or --version. |
| 9 | +For languages other than English, the wiki API is used for language names (subject line check). |
| 10 | +
|
| 11 | +Examples: |
| 12 | + ./env/bin/python check_pdf_metadata.py Hearing_from_God de ~/Gottes_Reden_wahrnehmen.pdf |
| 13 | + ./env/bin/python check_pdf_metadata.py Dealing_with_Money de ./Umgang_mit_Geld.pdf \\ |
| 14 | + --title "Umgang mit Geld" --version 1.0 |
| 15 | +""" |
| 16 | + |
| 17 | +import argparse |
| 18 | +import logging |
| 19 | +import os |
| 20 | +import sys |
| 21 | +from typing import List, Optional |
| 22 | + |
| 23 | +from pywikitools.family import Family |
| 24 | +from pywikitools.fortraininglib import ForTrainingLib |
| 25 | +from pywikitools.pdftools.metadata import check_metadata |
| 26 | +from pywikitools.resourcesbot.data_structures import TranslationProgress, WorksheetInfo |
| 27 | + |
| 28 | +_DEFAULT_SITE = "4training" |
| 29 | +_family = Family() |
| 30 | +DEFAULT_BASE_URL = _family.base_url(_DEFAULT_SITE, "") |
| 31 | +DEFAULT_SCRIPT_PATH = _family.scriptpath(_DEFAULT_SITE) |
| 32 | + |
| 33 | + |
| 34 | +def build_worksheet_info( |
| 35 | + lib: ForTrainingLib, |
| 36 | + worksheet_name: str, |
| 37 | + language_code: str, |
| 38 | + title: Optional[str], |
| 39 | + version: Optional[str], |
| 40 | +) -> WorksheetInfo: |
| 41 | + """Resolve title/version from API when omitted.""" |
| 42 | + resolved_title = title |
| 43 | + if resolved_title is None: |
| 44 | + fetched = lib.get_translated_title(worksheet_name, language_code) |
| 45 | + if fetched is None: |
| 46 | + raise ValueError( |
| 47 | + f"Could not fetch translated title for {worksheet_name}/{language_code}. " |
| 48 | + "Use --title or check the worksheet name and language code." |
| 49 | + ) |
| 50 | + resolved_title = fetched.strip() |
| 51 | + |
| 52 | + resolved_version = version |
| 53 | + if resolved_version is None: |
| 54 | + fetched = lib.get_version(worksheet_name, language_code) |
| 55 | + if fetched is None: |
| 56 | + raise ValueError( |
| 57 | + f"Could not fetch version for {worksheet_name}/{language_code}. Use --version." |
| 58 | + ) |
| 59 | + resolved_version = fetched.strip() |
| 60 | + |
| 61 | + progress = TranslationProgress(translated=1, fuzzy=0, total=1) |
| 62 | + return WorksheetInfo(worksheet_name, language_code, resolved_title, progress, resolved_version) |
| 63 | + |
| 64 | + |
| 65 | +def main(argv: Optional[List[str]] = None) -> int: |
| 66 | + parser = argparse.ArgumentParser( |
| 67 | + description="Check PDF metadata against 4training standards (same checks as resourcesbot)." |
| 68 | + ) |
| 69 | + parser.add_argument( |
| 70 | + "worksheet_name", |
| 71 | + help="English worksheet page name, e.g. Hearing_from_God", |
| 72 | + ) |
| 73 | + parser.add_argument("language_code", help="Language code, e.g. de or en") |
| 74 | + parser.add_argument("pdf_path", help="Path to the local PDF file") |
| 75 | + parser.add_argument( |
| 76 | + "--base-url", |
| 77 | + default=DEFAULT_BASE_URL, |
| 78 | + help=f"MediaWiki site base URL (default: {DEFAULT_BASE_URL})", |
| 79 | + ) |
| 80 | + parser.add_argument( |
| 81 | + "--script-path", |
| 82 | + default=DEFAULT_SCRIPT_PATH, |
| 83 | + help=f"MediaWiki $wgScriptPath (default: {DEFAULT_SCRIPT_PATH!r})", |
| 84 | + ) |
| 85 | + parser.add_argument( |
| 86 | + "--title", |
| 87 | + help="Translated worksheet title (if omitted, fetched from the wiki)", |
| 88 | + ) |
| 89 | + parser.add_argument( |
| 90 | + "--version", |
| 91 | + help="Expected worksheet version string (if omitted, fetched from the wiki)", |
| 92 | + ) |
| 93 | + args = parser.parse_args(argv) |
| 94 | + |
| 95 | + logging.basicConfig(level=logging.WARNING) |
| 96 | + |
| 97 | + pdf_path = os.path.abspath(args.pdf_path) |
| 98 | + if not os.path.isfile(pdf_path): |
| 99 | + print(f"Error: not a file: {pdf_path}", file=sys.stderr) |
| 100 | + return 2 |
| 101 | + |
| 102 | + lib = ForTrainingLib(args.base_url, args.script_path) |
| 103 | + try: |
| 104 | + info = build_worksheet_info( |
| 105 | + lib, |
| 106 | + args.worksheet_name, |
| 107 | + args.language_code, |
| 108 | + args.title, |
| 109 | + args.version, |
| 110 | + ) |
| 111 | + except ValueError as err: |
| 112 | + print(str(err), file=sys.stderr) |
| 113 | + return 2 |
| 114 | + |
| 115 | + result = check_metadata(lib, pdf_path, info) |
| 116 | + print(result.to_string(include_version=True)) |
| 117 | + return 0 if result.correct else 1 |
| 118 | + |
| 119 | + |
| 120 | +if __name__ == "__main__": |
| 121 | + sys.exit(main()) |
0 commit comments