Files
video-download-helper/build.py

212 lines
7.7 KiB
Python

import os
import sys
import shutil
import subprocess
import argparse
import importlib.util
import json
import re
def check_requirements():
"""Überprüft, ob alle erforderlichen Pakete installiert sind."""
try:
import PyQt5
import PyInstaller
except ImportError as e:
print(f"Fehler: {e}")
print("Bitte führe 'pip install -r requirements.txt' aus.")
return False
return True
def find_yt_dlp():
"""Versucht, yt-dlp im PATH zu finden."""
try:
result = subprocess.run(
["where", "yt-dlp"] if os.name == "nt" else ["which", "yt-dlp"],
capture_output=True,
text=True
)
if result.returncode == 0:
path = result.stdout.strip().split("\n")[0]
return path
return None
except Exception:
return None
def download_yt_dlp():
"""Lädt die aktuelle Version von yt-dlp herunter."""
bin_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "bin")
if not os.path.exists(bin_dir):
os.makedirs(bin_dir)
print("Lade yt-dlp herunter...")
ytdlp_url = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe"
ytdlp_path = os.path.join(bin_dir, "yt-dlp.exe")
try:
import requests
response = requests.get(ytdlp_url)
with open(ytdlp_path, "wb") as f:
f.write(response.content)
print(f"yt-dlp wurde nach {ytdlp_path} heruntergeladen.")
return True
except Exception as e:
print(f"Fehler beim Herunterladen von yt-dlp: {e}")
print("Bitte lade yt-dlp manuell herunter und platziere es im 'bin' Ordner.")
return False
def copy_yt_dlp_from_path():
"""Kopiert yt-dlp aus dem PATH in den bin-Ordner."""
ytdlp_path = find_yt_dlp()
if not ytdlp_path:
print("yt-dlp wurde nicht im PATH gefunden.")
return False
bin_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "bin")
if not os.path.exists(bin_dir):
os.makedirs(bin_dir)
try:
dest_path = os.path.join(bin_dir, "yt-dlp.exe" if os.name == "nt" else "yt-dlp")
shutil.copy2(ytdlp_path, dest_path)
print(f"yt-dlp wurde nach {dest_path} kopiert.")
return True
except Exception as e:
print(f"Fehler beim Kopieren von yt-dlp: {e}")
return False
def build_exe(onedir=False, console=False):
"""Erstellt die ausführbare Datei mit PyInstaller."""
print("Erstelle EXE-Datei...")
# Nur Default-Presets übernehmen
main_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "main.py")
with open(main_path, "r", encoding="utf-8") as f:
main_code = f.read()
# Default-Presets extrahieren (vereinfachte Suche)
match = re.search(r'defaults\s*=\s*\[(.*?)\n\s*\]', main_code, re.DOTALL)
if match:
defaults_code = "[" + match.group(1) + "]"
try:
# eval mit eingeschränktem Namespace
defaults = eval(defaults_code, {"__builtins__": None}, {})
except Exception as e:
print(f"Fehler beim Parsen der Default-Presets: {e}")
defaults = []
else:
print("Konnte Default-Presets nicht finden!")
defaults = []
# Presets-Ordner bereinigen und nur Default-Presets schreiben
bin_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "bin")
presets_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "presets")
if os.path.exists(presets_dir):
for f in os.listdir(presets_dir):
if f.endswith('.json'):
try:
os.remove(os.path.join(presets_dir, f))
except Exception:
pass
else:
os.makedirs(presets_dir)
for preset in defaults:
filename = f"{preset['name'].lower().replace(' ', '_')}.json"
try:
with open(os.path.join(presets_dir, filename), 'w', encoding='utf-8') as f:
json.dump(preset, f, indent=4, ensure_ascii=False)
except Exception as e:
print(f"Fehler beim Schreiben von Default-Preset {preset['name']}: {e}")
# Rest wie gehabt
cmd = ["pyinstaller"]
if not onedir:
cmd.append("--onefile")
if not console:
cmd.append("--windowed")
# Icon-Pfad festlegen und zur Befehlszeile hinzufügen
icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "icon.ico")
if os.path.exists(icon_path):
cmd.extend(["--icon", icon_path])
print(f"Icon wird verwendet: {icon_path}")
else:
print("Warnung: icon.ico wurde nicht gefunden.")
if os.path.exists(bin_dir) and os.listdir(bin_dir):
cmd.extend(["--add-data", f"{bin_dir}{os.pathsep}bin"])
if os.path.exists(presets_dir):
cmd.extend(["--add-data", f"{presets_dir}{os.pathsep}presets"])
cmd.append("main.py")
print(f"Führe aus: {' '.join(cmd)}")
try:
try:
subprocess.run(cmd, check=True)
except FileNotFoundError:
print("pyinstaller nicht im PATH gefunden, versuche 'python -m PyInstaller' ...")
cmd[0:1] = [sys.executable, "-m", "PyInstaller"]
subprocess.run(cmd, check=True)
if onedir:
print("Die ausführbare Datei wurde im 'dist/main' Ordner erstellt.")
else:
print("Die ausführbare Datei wurde als 'dist/main.exe' erstellt.")
return True
except subprocess.CalledProcessError as e:
print(f"Fehler beim Erstellen der EXE-Datei: {e}")
return False
except Exception as e:
print(f"Unerwarteter Fehler: {e}")
return False
def parse_arguments():
"""Parst die Kommandozeilenargumente."""
parser = argparse.ArgumentParser(description="Build-Skript für YT-DLP GUI")
parser.add_argument("--onedir", action="store_true", help="Erstellt einen Ordner statt einer einzelnen Datei")
parser.add_argument("--console", action="store_true", help="Zeigt die Konsole an")
parser.add_argument("--download-ytdlp", action="store_true", help="Lädt yt-dlp herunter")
parser.add_argument("--copy-ytdlp", action="store_true", help="Kopiert yt-dlp aus dem PATH")
return parser.parse_args()
def main():
args = parse_arguments()
if not check_requirements():
return 1
# Überprüfe, ob yt-dlp bereits im bin-Ordner existiert
bin_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "bin")
ytdlp_exists = os.path.exists(os.path.join(bin_dir, "yt-dlp.exe" if os.name == "nt" else "yt-dlp"))
if not ytdlp_exists:
if args.download_ytdlp:
if not download_yt_dlp():
return 1
elif args.copy_ytdlp:
if not copy_yt_dlp_from_path():
print("yt-dlp konnte nicht kopiert werden. Versuche, es herunterzuladen...")
if not download_yt_dlp():
return 1
else:
# Frage den Benutzer
print("yt-dlp wurde nicht im bin-Ordner gefunden.")
choice = input("Möchten Sie (1) yt-dlp herunterladen, (2) aus dem PATH kopieren oder (3) ohne fortfahren? [1/2/3]: ")
if choice == "1":
if not download_yt_dlp():
return 1
elif choice == "2":
if not copy_yt_dlp_from_path():
print("yt-dlp konnte nicht kopiert werden. Versuche, es herunterzuladen...")
if not download_yt_dlp():
return 1
# Erstelle die ausführbare Datei
if not build_exe(onedir=args.onedir, console=args.console):
return 1
return 0
if __name__ == "__main__":
sys.exit(main())