"""HandBrakeCLI für den Bau beschaffen — damit Rippy ohne Netz arbeiten kann. ## Warum HandBrake mitgeliefert wird und MakeMKV nicht Commander am 28.08.2026: *„handbrake und makemkv MÜSSEN mitgeliefert werden oder während des Setups separat installiert werden! Ohne das ist das tool NICHT einsatzfähig."* Er hat recht. Die beiden gehen aber unterschiedliche Wege, und der Grund ist die Lizenz, nicht die Bequemlichkeit: * **HandBrake ist GPL-2.** Weitergabe ist ausdrücklich erlaubt, solange Lizenztext und Quellverweis dabei sind. Also kommt es mit ins Paket, und Rippy kann auch auf einem Rechner ohne Internet komprimieren. * **MakeMKV ist proprietär.** Die Lizenz erlaubt keine Weitergabe durch Dritte. Rippy lädt die offizielle Datei beim Einrichten vom Hersteller und startet dessen Installer — der Nutzer bezieht sie also weiterhin von MakeMKV, Rippy nimmt ihm nur die Handgriffe ab. Dieselbe Black-Box-Trennung wie in `KONZEPT.md` § 6 und `KONZEPT-V2.md` § 4.1. ## Warum die Datei nicht im Repo liegt 24,5 MB Binärdatei in git wären bei jedem Klon dabei und bei jedem HandBrake-Update ein zweites Mal. Der Bau holt sie stattdessen nach `dist/windows/vendor/` (nicht versioniert) und nimmt sie von dort ins Paket — dasselbe Muster wie der `vendor/`-Ordner für MakeMKV auf der VM. Beim zweiten Bau liegt sie schon da und wird nicht erneut geladen. """ import os import shutil import sys HIER = os.path.dirname(os.path.abspath(__file__)) REPO = os.path.dirname(os.path.dirname(HIER)) # Der Lizenztext gehört ins Paket, nicht nur in einen Kommentar. GPL-2 # verlangt ihn bei jeder Weitergabe. GPL_HINWEIS = """HandBrakeCLI — mitgeliefert unter der GNU General Public License v2 Rippy liefert HandBrakeCLI unveraendert mit. HandBrake ist freie Software und steht unter der GPL-2. Das bedeutet fuer dich: * Du darfst es weitergeben und veraendern. * Der Quelltext ist oeffentlich verfuegbar unter: https://github.com/HandBrake/HandBrake * Der vollstaendige Lizenztext steht dort in COPYING, ausserdem unter: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html Mitgelieferte Fassung: {version} Bezogen von: {url} MakeMKV ist NICHT Teil dieser Lieferung. Es ist proprietaer und wird beim Einrichten von makemkv.com geladen und mit dem Installer des Herstellers installiert. """ def vendor_ordner(basis: str = None) -> str: return os.path.join(basis or os.path.join(REPO, "dist", "windows"), "vendor") def handbrake_bereitstellen(ziel_basis: str = None, melden=print) -> dict: """Sorgt dafür, dass HandBrakeCLI im vendor-Ordner liegt. Gibt `{"pfad": …, "version": …, "geladen": bool}` zurück; `pfad` ist leer, wenn es nicht geklappt hat. Wirft NICHT — ein Bau ohne Netz soll möglich bleiben, muss dann aber laut sagen, was fehlt. """ sys.path.insert(0, os.path.join(REPO, "src")) from rippy.tools import beschaffen ordner = os.path.join(vendor_ordner(ziel_basis), "handbrake") exe = os.path.join(ordner, "HandBrakeCLI.exe") if os.path.isfile(exe) and os.path.getsize(exe) > 1024 * 1024: return {"pfad": exe, "version": _version_von(exe), "geladen": False} melden(" HandBrakeCLI wird geholt …") try: pfad = beschaffen.handbrake_holen( ziel_ordner=ordner, fortschritt=lambda t, anteil=None: melden(" " + t)) except Exception as e: # noqa: BLE001 melden(" X HandBrakeCLI konnte nicht geholt werden: %s" % e) return {"pfad": "", "version": "", "geladen": False} return {"pfad": pfad, "version": _version_von(pfad), "geladen": True} def _version_von(exe: str) -> str: sys.path.insert(0, os.path.join(REPO, "src")) from rippy.tools import katalog try: return katalog.version_von("handbrake", exe) or "" except Exception: # noqa: BLE001 return "" def paket_ordner_bauen(ziel_basis: str = None, melden=print) -> str: """Baut den `tools`-Ordner, der ins Paket wandert. "" wenn nichts drin ist. Struktur — genau die, in der `katalog.kandidaten()` sucht: tools/handbrake/HandBrakeCLI.exe tools/handbrake/LIZENZ-HandBrake.txt """ hb = handbrake_bereitstellen(ziel_basis, melden) if not hb["pfad"]: return "" basis = os.path.join(vendor_ordner(ziel_basis), "paket") ordner = os.path.join(basis, "handbrake") os.makedirs(ordner, exist_ok=True) ziel_exe = os.path.join(ordner, "HandBrakeCLI.exe") if os.path.abspath(hb["pfad"]) != os.path.abspath(ziel_exe): shutil.copy2(hb["pfad"], ziel_exe) from rippy.tools import beschaffen with open(os.path.join(ordner, "LIZENZ-HandBrake.txt"), "w", encoding="utf-8") as f: f.write(GPL_HINWEIS.format(version=hb["version"] or "unbekannt", url=beschaffen.HANDBRAKE_API)) melden(" HandBrakeCLI %s liegt im Paket (%.1f MB)" % (hb["version"] or "?", os.path.getsize(ziel_exe) / 1024**2)) return basis if __name__ == "__main__": ordner = paket_ordner_bauen() print("Paket-Ordner:", ordner or "(leer)") raise SystemExit(0 if ordner else 1)