feat: Arbeitsordner je Video, Quellenangabe und automatisches Video-Glossar
- Ohne -o/-d schreiben yt_untertitel.py, extract_text.py und abschrift_korrigieren.py -u in abschriften/<Name>/ (ein Ordner je Video, auch für alle Ausschnitte). - Beim Download entsteht neben dem Rohtext <Rohtext>.quelle.json mit Titel, Kanal, Datum und URL, für den Quellenkopf des fertigen Textes. - Ein Glossar, das wie sein Ordner heißt (abschriften/<Name>/<Name>.glossar.txt), nutzen abschrift_korrigieren.py, glossar_vorschlag.py und aenderungen.py automatisch, nach den mit -g angegebenen gemeinsamen Glossaren. - .gitignore: abschriften/, fertig/, *.quelle.json. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
acf9e33382
commit
3aa04fff4b
1 changed files with 195 additions and 34 deletions
|
|
@ -21,7 +21,9 @@ from vtt2txt import (
|
|||
add_time_options, join_segments, range_argv, resolve_time_ranges, split_segments,
|
||||
time_suffix, vtt_to_text,
|
||||
)
|
||||
from yt_untertitel import YT_DLP, base_language, default_name, original_language
|
||||
from yt_untertitel import (
|
||||
YT_DLP, base_language, default_name, original_language, work_folder, write_source,
|
||||
)
|
||||
|
||||
MODEL = "qwen3:32b"
|
||||
OLLAMA_URL = "http://127.0.0.1:11434/api/chat"
|
||||
|
|
@ -264,6 +266,22 @@ def read_glossary(path):
|
|||
return terms, replacements
|
||||
|
||||
|
||||
def video_glossary(folder):
|
||||
"""Glossary of the video in `folder`, named like the folder:
|
||||
abschriften/<Name>/<Name>.glossar.txt; None if there is none."""
|
||||
path = folder / f"{folder.resolve().name}.glossar.txt"
|
||||
return path if path.is_file() else None
|
||||
|
||||
|
||||
def with_video_glossary(glossaries, folder):
|
||||
"""The given glossaries plus the video glossary of `folder` (last, after the
|
||||
shared ones), unless it was given; returns (glossaries, added or None)."""
|
||||
found = video_glossary(folder)
|
||||
if found is None or any(g.resolve() == found.resolve() for g in glossaries):
|
||||
return list(glossaries), None
|
||||
return [*glossaries, found], found
|
||||
|
||||
|
||||
def apply_replacements(text, replacements):
|
||||
"""Replace whole words in file order; report rules without any match."""
|
||||
unmatched = []
|
||||
|
|
@ -633,8 +651,8 @@ def parse_args():
|
|||
parser.add_argument(
|
||||
"-o", "--output", type=Path,
|
||||
help="Ausgabedatei (Standard: <Eingabe ohne Endung>.korrigiert.txt, "
|
||||
"mit -u <Kanal>_<Titel>_<Datum>.korrigiert.txt; mit -z zusätzlich "
|
||||
"die Bereiche)",
|
||||
"mit -u abschriften/<Name>/<Name>.korrigiert.txt mit "
|
||||
"<Name> = <Kanal>_<Titel>_<Datum>; mit -z zusätzlich die Bereiche)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-g", "--glossar", type=Path, action="append", default=[],
|
||||
|
|
@ -709,9 +727,12 @@ def read_source(args):
|
|||
f"Der Beitrag ist auf „{lang}“; unterstützt: {', '.join(PROMPTS)} (-l)."
|
||||
)
|
||||
suffix = time_suffix(args.bereiche)
|
||||
target = args.output or Path(f"{default_name(info)}{suffix}.korrigiert.txt")
|
||||
name = default_name(info)
|
||||
target = args.output or work_folder(name) / f"{name}{suffix}.korrigiert.txt"
|
||||
raw = text + "\n"
|
||||
save_raw_text(raw_text_path(target), raw)
|
||||
raw_path = raw_text_path(target)
|
||||
save_raw_text(raw_path, raw)
|
||||
write_source(info, raw_path.with_suffix(".quelle.json"))
|
||||
return raw, target, lang
|
||||
|
||||
raw = args.input.read_text(encoding="utf-8-sig")
|
||||
|
|
@ -762,10 +783,12 @@ def main():
|
|||
parts_dir = target.with_suffix(".parts")
|
||||
|
||||
terms, replacements = [], []
|
||||
for glossary in args.glossar:
|
||||
glossaries, automatic = with_video_glossary(args.glossar, target.parent)
|
||||
for glossary in glossaries:
|
||||
more_terms, more_replacements = read_glossary(glossary)
|
||||
note = " (Video-Glossar, automatisch)" if glossary == automatic else ""
|
||||
print(
|
||||
f"Glossar {glossary}: {len(more_terms)} Begriffe, "
|
||||
f"Glossar {glossary}{note}: {len(more_terms)} Begriffe, "
|
||||
f"{len(more_replacements)} feste Ersetzungen"
|
||||
)
|
||||
terms += more_terms
|
||||
|
|
|
|||
Loading…
Reference in a new issue