import shutil import subprocess import sys import venv from pathlib import Path ROOT = Path(__file__).resolve().parent.parent WINDOWS = sys.platform == "win32" VENV = ROOT / "venv" BIN = VENV / ("Scripts" if WINDOWS else "bin") PYTHON = BIN / ("python.exe" if WINDOWS else "python") EXE = ".exe" if WINDOWS else "" OS_NAME = {"win32": "windows", "darwin": "mac"}.get(sys.platform, "linux") OUT = ROOT / "build" / OS_NAME COLLECT_ALL = [ "spotdl", "yt_dlp", "yt_dlp_ejs", "ytmusicapi", "syncedlyrics", "spotapi", "spotipyfree", "pykakasi", "curl_cffi", ] def run(*args): print("+", " ".join(str(a) for a in args), flush=True) subprocess.run([str(a) for a in args], check=True, cwd=ROOT) def main(): if not PYTHON.exists(): venv.create(VENV, with_pip=True) run(PYTHON, "-m", "pip", "install", "-q", "--upgrade", "pip", "spotdl", "pyinstaller") shutil.rmtree(OUT / "downloader", ignore_errors=True) shutil.rmtree(OUT / "pyinstaller", ignore_errors=True) args = [ PYTHON, "-m", "PyInstaller", "spotify_downloader.py", "--onedir", "--noconfirm", "--clean", "--name", "spotify_downloader", "--distpath", OUT / "downloader", "--workpath", OUT / "pyinstaller", "--specpath", OUT / "pyinstaller", ] for package in COLLECT_ALL: args += ["--collect-all", package] run(*args) locate = "from spotdl.utils.ffmpeg import get_local_ffmpeg; p = get_local_ffmpeg(); print(p or '')" found = subprocess.run([str(PYTHON), "-c", locate], capture_output=True, text=True, cwd=ROOT).stdout.strip() if not found: run(PYTHON, "-m", "spotdl", "--download-ffmpeg") found = subprocess.run([str(PYTHON), "-c", locate], capture_output=True, text=True, cwd=ROOT).stdout.strip() if not found: sys.exit("Could not find or download ffmpeg.") target = OUT / "ffmpeg" / ("ffmpeg" + EXE) target.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(found, target) target.chmod(0o755) print(f"Downloader: {(OUT / 'downloader' / 'spotify_downloader' / ('spotify_downloader' + EXE)).relative_to(ROOT)}") print(f"ffmpeg: {target.relative_to(ROOT)}") if __name__ == "__main__": main()