Rewrite Curator in Rust with an egui GUI
This commit is contained in:
@@ -1,107 +0,0 @@
|
||||
"""One-off migration: rename a tag category inside a pool's metadata index.
|
||||
|
||||
Tags are stored in ``<pool>/.Curator.!index`` as ``"Category/Name"`` strings.
|
||||
This rewrites every tag whose category matches ``--old`` to use ``--new``,
|
||||
leaving the tag name untouched. A timestamped backup of the index is written
|
||||
before saving.
|
||||
|
||||
Usage:
|
||||
uv run python scripts/migrate_tag_category.py <pool_dir> \
|
||||
--old "Země" --new "Země původu"
|
||||
|
||||
If ``<pool_dir>`` is omitted, the pool from the global config is used.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from loguru import logger
|
||||
|
||||
# Allow running as a plain script (``python scripts/...``) by exposing the repo root.
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from src.core.config import load_global_config
|
||||
from src.core.pool_index import INDEX_FILENAME
|
||||
|
||||
|
||||
def _rename_in_tags(tags: list[str], old: str, new: str) -> tuple[list[str], int]:
|
||||
"""Return (rewritten tags, number of tags changed) for one record."""
|
||||
prefix = f"{old}/"
|
||||
changed = 0
|
||||
result: list[str] = []
|
||||
for tag in tags:
|
||||
if isinstance(tag, str) and tag.startswith(prefix):
|
||||
result.append(f"{new}/{tag[len(prefix) :]}")
|
||||
changed += 1
|
||||
else:
|
||||
result.append(tag)
|
||||
return result, changed
|
||||
|
||||
|
||||
def migrate(index_path: Path, old: str, new: str) -> int:
|
||||
"""Rewrite the category in place and return the number of tags changed."""
|
||||
with open(index_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
movies: dict[str, dict] = data.get("movies", {})
|
||||
total_changed = 0
|
||||
affected_records = 0
|
||||
for key, record in movies.items():
|
||||
tags = record.get("tags", [])
|
||||
new_tags, changed = _rename_in_tags(tags, old, new)
|
||||
if changed:
|
||||
record["tags"] = new_tags
|
||||
total_changed += changed
|
||||
affected_records += 1
|
||||
logger.debug(f"{key}: {changed} tag(s) renamed")
|
||||
|
||||
if total_changed == 0:
|
||||
logger.info(f"No '{old}/…' tags found — nothing to migrate")
|
||||
return 0
|
||||
|
||||
backup = index_path.with_suffix(
|
||||
index_path.suffix + f".bak-{datetime.now():%Y%m%d-%H%M%S}"
|
||||
)
|
||||
shutil.copy2(index_path, backup)
|
||||
logger.info(f"Backup written: {backup}")
|
||||
|
||||
with open(index_path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
logger.info(
|
||||
f"Migrated '{old}' → '{new}': {total_changed} tag(s) "
|
||||
f"across {affected_records} record(s)"
|
||||
)
|
||||
return total_changed
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"pool_dir",
|
||||
nargs="?",
|
||||
help="Pool root (default: pool_dir from the global config)",
|
||||
)
|
||||
parser.add_argument("--old", default="Země", help="Category to rename from")
|
||||
parser.add_argument("--new", default="Země původu", help="Category to rename to")
|
||||
args = parser.parse_args()
|
||||
|
||||
pool_dir = args.pool_dir or load_global_config().get("pool_dir")
|
||||
if not pool_dir:
|
||||
parser.error("No pool_dir given and none configured in the global config")
|
||||
|
||||
index_path = Path(pool_dir) / INDEX_FILENAME
|
||||
if not index_path.exists():
|
||||
parser.error(f"No index found at {index_path}")
|
||||
|
||||
migrate(index_path, args.old, args.new)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,124 +0,0 @@
|
||||
"""One-off migration: split combined country tags in a pool's metadata index.
|
||||
|
||||
Before multi-country support, a co-production fetched from ČSFD was stored as a
|
||||
single ``"Země původu/USA / Velká Británie"`` tag. This rewrites each such tag
|
||||
into one tag per country (``"Země původu/USA"`` + ``"Země původu/Velká
|
||||
Británie"``), de-duplicating within each record. A timestamped backup of the
|
||||
index is written before saving.
|
||||
|
||||
Usage:
|
||||
uv run python scripts/split_country_tags.py [<pool_dir>] [--category "Země původu"]
|
||||
|
||||
If ``<pool_dir>`` is omitted, the pool from the global config is used.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from loguru import logger
|
||||
|
||||
# Allow running as a plain script (``python scripts/...``) by exposing the repo root.
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from src.core.config import load_global_config
|
||||
from src.core.pool_index import INDEX_FILENAME
|
||||
|
||||
|
||||
def _split_record_tags(tags: list[str], category: str) -> tuple[list[str], int]:
|
||||
"""Return (rewritten tags, number of combined tags split) for one record.
|
||||
|
||||
Order is preserved; duplicates produced by the split are dropped.
|
||||
"""
|
||||
prefix = f"{category}/"
|
||||
result: list[str] = []
|
||||
seen: set[str] = set()
|
||||
split_count = 0
|
||||
|
||||
def _add(tag: str) -> None:
|
||||
if tag not in seen:
|
||||
seen.add(tag)
|
||||
result.append(tag)
|
||||
|
||||
for tag in tags:
|
||||
if (
|
||||
isinstance(tag, str)
|
||||
and tag.startswith(prefix)
|
||||
and "/" in tag[len(prefix) :]
|
||||
):
|
||||
value = tag[len(prefix) :]
|
||||
countries = [c.strip() for c in value.split("/") if c.strip()]
|
||||
for country in countries:
|
||||
_add(f"{prefix}{country}")
|
||||
split_count += 1
|
||||
else:
|
||||
_add(tag)
|
||||
return result, split_count
|
||||
|
||||
|
||||
def migrate(index_path: Path, category: str) -> int:
|
||||
"""Split combined ``category`` tags in place; return number of tags split."""
|
||||
with open(index_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
movies: dict[str, dict] = data.get("movies", {})
|
||||
total_split = 0
|
||||
affected = 0
|
||||
for key, record in movies.items():
|
||||
tags = record.get("tags", [])
|
||||
new_tags, split_count = _split_record_tags(tags, category)
|
||||
if split_count:
|
||||
record["tags"] = new_tags
|
||||
total_split += split_count
|
||||
affected += 1
|
||||
logger.debug(f"{key}: {split_count} combined tag(s) split")
|
||||
|
||||
if total_split == 0:
|
||||
logger.info(f"No combined '{category}/…' tags found — nothing to migrate")
|
||||
return 0
|
||||
|
||||
backup = index_path.with_suffix(
|
||||
index_path.suffix + f".bak-{datetime.now():%Y%m%d-%H%M%S}"
|
||||
)
|
||||
shutil.copy2(index_path, backup)
|
||||
logger.info(f"Backup written: {backup}")
|
||||
|
||||
with open(index_path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
logger.info(
|
||||
f"Split {total_split} combined '{category}' tag(s) across {affected} record(s)"
|
||||
)
|
||||
return total_split
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"pool_dir",
|
||||
nargs="?",
|
||||
help="Pool root (default: pool_dir from the global config)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--category", default="Země původu", help="Tag category to split"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
pool_dir = args.pool_dir or load_global_config().get("pool_dir")
|
||||
if not pool_dir:
|
||||
parser.error("No pool_dir given and none configured in the global config")
|
||||
|
||||
index_path = Path(pool_dir) / INDEX_FILENAME
|
||||
if not index_path.exists():
|
||||
parser.error(f"No index found at {index_path}")
|
||||
|
||||
migrate(index_path, args.category)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,111 +0,0 @@
|
||||
"""One-off migration: drop the old decade-band rating tags from a pool index.
|
||||
|
||||
Earlier the ČSFD rating was stored bucketed (e.g. ``Hodnocení/90–100 %``). Now
|
||||
the tag carries the exact value (``Hodnocení/90``) and the band is only a folder.
|
||||
This removes the legacy band tags (``Hodnocení/<x>–<y> %``) so re-fetching from
|
||||
ČSFD leaves only the exact ratings. Exact rating tags are kept. A timestamped
|
||||
backup of the index is written first.
|
||||
|
||||
Usage:
|
||||
uv run python scripts/strip_rating_bands.py [<pool_dir>] [--category "Hodnocení"]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from loguru import logger
|
||||
|
||||
# Allow running as a plain script (``python scripts/...``) by exposing the repo root.
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from src.core.config import load_global_config
|
||||
from src.core.pool_index import INDEX_FILENAME
|
||||
|
||||
# A band tag looks like "Hodnocení/90–100 %" — value has a dash range and a "%".
|
||||
_BAND_RE = re.compile(r"\d+\s*[–-]\s*\d+\s*%")
|
||||
|
||||
|
||||
def _strip_bands(tags: list[str], category: str) -> tuple[list[str], int]:
|
||||
"""Return (kept tags, removed count), dropping ``category`` band tags."""
|
||||
prefix = f"{category}/"
|
||||
kept = [
|
||||
t
|
||||
for t in tags
|
||||
if not (isinstance(t, str) and t.startswith(prefix) and _BAND_RE.search(t))
|
||||
]
|
||||
return kept, len(tags) - len(kept)
|
||||
|
||||
|
||||
def migrate(index_path: Path, category: str) -> int:
|
||||
"""Remove band rating tags in place; return number of tags removed."""
|
||||
with open(index_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
movies: dict[str, dict] = data.get("movies", {})
|
||||
total_removed = 0
|
||||
affected = 0
|
||||
for key, record in movies.items():
|
||||
tags = record.get("tags", [])
|
||||
kept, removed = _strip_bands(tags, category)
|
||||
if removed:
|
||||
record["tags"] = kept
|
||||
# also drop them from the ČSFD provenance set, if present
|
||||
if isinstance(record.get("csfd_tags"), list):
|
||||
record["csfd_tags"] = [
|
||||
t
|
||||
for t in record["csfd_tags"]
|
||||
if not (t.startswith(f"{category}/") and _BAND_RE.search(t))
|
||||
]
|
||||
total_removed += removed
|
||||
affected += 1
|
||||
logger.debug(f"{key}: removed {removed} band tag(s)")
|
||||
|
||||
if total_removed == 0:
|
||||
logger.info(f"No '{category}/…–… %' band tags found — nothing to migrate")
|
||||
return 0
|
||||
|
||||
backup = index_path.with_suffix(
|
||||
index_path.suffix + f".bak-{datetime.now():%Y%m%d-%H%M%S}"
|
||||
)
|
||||
shutil.copy2(index_path, backup)
|
||||
logger.info(f"Backup written: {backup}")
|
||||
|
||||
with open(index_path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
logger.info(
|
||||
f"Removed {total_removed} band '{category}' tag(s) across {affected} record(s)"
|
||||
)
|
||||
return total_removed
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"pool_dir",
|
||||
nargs="?",
|
||||
help="Pool root (default: pool_dir from the global config)",
|
||||
)
|
||||
parser.add_argument("--category", default="Hodnocení", help="Rating category")
|
||||
args = parser.parse_args()
|
||||
|
||||
pool_dir = args.pool_dir or load_global_config().get("pool_dir")
|
||||
if not pool_dir:
|
||||
parser.error("No pool_dir given and none configured in the global config")
|
||||
|
||||
index_path = Path(pool_dir) / INDEX_FILENAME
|
||||
if not index_path.exists():
|
||||
parser.error(f"No index found at {index_path}")
|
||||
|
||||
migrate(index_path, args.category)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,101 +0,0 @@
|
||||
"""One-off migration: drop all tags of given categories from a pool's index.
|
||||
|
||||
Used to remove tag categories that turned out to be a bad idea (e.g. Režie /
|
||||
Herec produced far too many folders). Cached ČSFD data is left intact — only the
|
||||
``tags`` lists are pruned. A timestamped backup of the index is written first.
|
||||
|
||||
Usage:
|
||||
uv run python scripts/strip_tag_categories.py [<pool_dir>] \
|
||||
--categories "Režie" "Herec"
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from loguru import logger
|
||||
|
||||
# Allow running as a plain script (``python scripts/...``) by exposing the repo root.
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from src.core.config import load_global_config
|
||||
from src.core.pool_index import INDEX_FILENAME
|
||||
|
||||
|
||||
def _strip(tags: list[str], prefixes: tuple[str, ...]) -> tuple[list[str], int]:
|
||||
"""Return (kept tags, number removed) dropping tags under any prefix."""
|
||||
kept = [t for t in tags if not (isinstance(t, str) and t.startswith(prefixes))]
|
||||
return kept, len(tags) - len(kept)
|
||||
|
||||
|
||||
def migrate(index_path: Path, categories: list[str]) -> int:
|
||||
"""Remove all tags of ``categories`` in place; return number of tags removed."""
|
||||
prefixes = tuple(f"{c}/" for c in categories)
|
||||
|
||||
with open(index_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
movies: dict[str, dict] = data.get("movies", {})
|
||||
total_removed = 0
|
||||
affected = 0
|
||||
for key, record in movies.items():
|
||||
tags = record.get("tags", [])
|
||||
kept, removed = _strip(tags, prefixes)
|
||||
if removed:
|
||||
record["tags"] = kept
|
||||
total_removed += removed
|
||||
affected += 1
|
||||
logger.debug(f"{key}: removed {removed} tag(s)")
|
||||
|
||||
if total_removed == 0:
|
||||
logger.info(f"No tags in {categories} found — nothing to migrate")
|
||||
return 0
|
||||
|
||||
backup = index_path.with_suffix(
|
||||
index_path.suffix + f".bak-{datetime.now():%Y%m%d-%H%M%S}"
|
||||
)
|
||||
shutil.copy2(index_path, backup)
|
||||
logger.info(f"Backup written: {backup}")
|
||||
|
||||
with open(index_path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
logger.info(
|
||||
f"Removed {total_removed} tag(s) of {categories} across {affected} record(s)"
|
||||
)
|
||||
return total_removed
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"pool_dir",
|
||||
nargs="?",
|
||||
help="Pool root (default: pool_dir from the global config)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--categories",
|
||||
nargs="+",
|
||||
default=["Režie", "Herec"],
|
||||
help="Tag categories to strip",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
pool_dir = args.pool_dir or load_global_config().get("pool_dir")
|
||||
if not pool_dir:
|
||||
parser.error("No pool_dir given and none configured in the global config")
|
||||
|
||||
index_path = Path(pool_dir) / INDEX_FILENAME
|
||||
if not index_path.exists():
|
||||
parser.error(f"No index found at {index_path}")
|
||||
|
||||
migrate(index_path, args.categories)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -7,6 +7,6 @@ RequiresMountsFor=/mnt/c34a47db-0bdf-4c4c-8187-14711c022cf0
|
||||
Type=oneshot
|
||||
User=honza
|
||||
Group=honza
|
||||
ExecStart=/usr/bin/python3 /mnt/c34a47db-0bdf-4c4c-8187-14711c022cf0/Filmotéka/Tools/tipy_dne.py --pool /mnt/c34a47db-0bdf-4c4c-8187-14711c022cf0/Filmotéka --output /mnt/c34a47db-0bdf-4c4c-8187-14711c022cf0/Filmy --count 15
|
||||
ExecStart=/mnt/c34a47db-0bdf-4c4c-8187-14711c022cf0/Filmotéka/Tools/tipy-dne --pool /mnt/c34a47db-0bdf-4c4c-8187-14711c022cf0/Filmotéka --output /mnt/c34a47db-0bdf-4c4c-8187-14711c022cf0/Filmy --count 15
|
||||
Nice=10
|
||||
NoNewPrivileges=true
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Standalone "Tipy dne" generator — deployable next to a Filmotéka (e.g. cron).
|
||||
|
||||
On each run it reads the pool index (``<pool>/.Curator.!index``), picks N random
|
||||
pool movies, clears the tips folder in the output and recreates it as hardlinks.
|
||||
It does not import Curator — only the Python standard library — so it can live on
|
||||
the server with the Filmotéka, independent of the app.
|
||||
|
||||
Paths come from CLI args, or fall back to the global config (``.Curator.!gtag``,
|
||||
keys ``pool_dir`` / ``filmoteka_dir``) when ``--config`` is given or one is found.
|
||||
|
||||
Examples:
|
||||
python scripts/tipy_dne.py --pool /mnt/srv/Filmoteka --output /mnt/srv/Filmy/Filmoteka_v2
|
||||
python scripts/tipy_dne.py --count 15 # uses the repo's global config
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
INDEX_FILENAME = ".Curator.!index"
|
||||
GLOBAL_CONFIG_FILENAME = ".Curator.!gtag"
|
||||
DEFAULT_SUBFOLDER = "- Tipy dne" # "- " prefix sorts it first in DLNA/TV browsers
|
||||
DEFAULT_COUNT = 15
|
||||
|
||||
|
||||
def _load_config_paths(config_path: Path) -> tuple[Path | None, Path | None]:
|
||||
"""Read (pool_dir, filmoteka_dir) from a global config file, if present."""
|
||||
try:
|
||||
with open(config_path, "r", encoding="utf-8") as f:
|
||||
cfg = json.load(f)
|
||||
except OSError, json.JSONDecodeError:
|
||||
return None, None
|
||||
pool = cfg.get("pool_dir")
|
||||
out = cfg.get("filmoteka_dir")
|
||||
return (Path(pool) if pool else None, Path(out) if out else None)
|
||||
|
||||
|
||||
def _pool_movies(pool_dir: Path) -> list[Path]:
|
||||
"""Existing pool movie files listed in the index (copy-as-is folders aren't
|
||||
indexed, so this is the pool/Filmy set only)."""
|
||||
index_path = pool_dir / INDEX_FILENAME
|
||||
with open(index_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
movies: list[Path] = []
|
||||
for rel in data.get("movies", {}):
|
||||
path = pool_dir / rel
|
||||
if path.is_file():
|
||||
movies.append(path)
|
||||
return movies
|
||||
|
||||
|
||||
def _clear_folder(folder: Path) -> int:
|
||||
"""Remove the files in ``folder`` (the old tips). Returns how many removed."""
|
||||
removed = 0
|
||||
if folder.exists():
|
||||
for child in folder.iterdir():
|
||||
if child.is_file() or child.is_symlink():
|
||||
try:
|
||||
child.unlink()
|
||||
removed += 1
|
||||
except OSError as exc:
|
||||
print(f" ! nelze smazat {child}: {exc}", file=sys.stderr)
|
||||
return removed
|
||||
|
||||
|
||||
def generate_tips(pool_dir: Path, output_dir: Path, count: int, subfolder: str) -> int:
|
||||
"""Refresh the tips folder with ``count`` random pool movies as hardlinks."""
|
||||
movies = _pool_movies(pool_dir)
|
||||
if not movies:
|
||||
print("Index neobsahuje žádné filmy.", file=sys.stderr)
|
||||
return 0
|
||||
|
||||
tips_dir = output_dir / subfolder
|
||||
cleared = _clear_folder(tips_dir)
|
||||
tips_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
chosen = random.sample(movies, min(count, len(movies)))
|
||||
created = 0
|
||||
for src in chosen:
|
||||
target = tips_dir / src.name
|
||||
try:
|
||||
if target.exists():
|
||||
target.unlink()
|
||||
os.link(src, target)
|
||||
created += 1
|
||||
print(f" + {src.name}")
|
||||
except OSError as exc:
|
||||
print(f" ! {src.name}: {exc}", file=sys.stderr)
|
||||
|
||||
print(f"\nTipy dne: smazáno {cleared}, vytvořeno {created} (z {len(movies)} filmů)")
|
||||
return created
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Vygeneruje složku Tipy dne.")
|
||||
parser.add_argument(
|
||||
"--pool", type=Path, help="Pool root (obsahuje .Curator.!index)"
|
||||
)
|
||||
parser.add_argument("--output", type=Path, help="Výstupní složka Filmotéky")
|
||||
parser.add_argument(
|
||||
"--count",
|
||||
type=int,
|
||||
default=DEFAULT_COUNT,
|
||||
help=f"Počet náhodných titulů (výchozí {DEFAULT_COUNT})",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--subfolder",
|
||||
default=DEFAULT_SUBFOLDER,
|
||||
help=f'Název složky tipů (výchozí "{DEFAULT_SUBFOLDER}")',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--config",
|
||||
type=Path,
|
||||
help="Cesta ke global configu (.Curator.!gtag) pro doplnění cest",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
pool, output = args.pool, args.output
|
||||
if pool is None or output is None:
|
||||
config_path = args.config or (
|
||||
Path(__file__).resolve().parent.parent / GLOBAL_CONFIG_FILENAME
|
||||
)
|
||||
cfg_pool, cfg_out = _load_config_paths(config_path)
|
||||
pool = pool or cfg_pool
|
||||
output = output or cfg_out
|
||||
|
||||
if pool is None or output is None:
|
||||
parser.error("Chybí --pool a/nebo --output (a nenalezeny v global configu).")
|
||||
if not (pool / INDEX_FILENAME).is_file():
|
||||
parser.error(f"Index nenalezen: {pool / INDEX_FILENAME}")
|
||||
|
||||
created = generate_tips(pool, output, args.count, args.subfolder)
|
||||
sys.exit(0 if created else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user