Aurora SpotiRip desktop and web app
- Spotify playlist, library, album and artist browsing with in-app playback - Song, playlist and album downloads via spotdl with YouTube and Bandcamp fallbacks - Electron desktop app (castLabs Widevine) with a permanent sidebar layout - Linux and Windows packaging scripts
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-Location (Split-Path $PSScriptRoot -Parent)
|
||||
|
||||
function Step([string]$Name, [scriptblock]$Command) {
|
||||
Write-Host "==> $Name" -ForegroundColor Cyan
|
||||
& $Command
|
||||
if ($LASTEXITCODE -ne 0) { throw "$Name failed (exit code $LASTEXITCODE)" }
|
||||
}
|
||||
|
||||
foreach ($tool in "node", "pnpm", "py") {
|
||||
if (-not (Get-Command $tool -ErrorAction SilentlyContinue)) {
|
||||
throw "$tool was not found. See docs/building-windows.md for the tools to install."
|
||||
}
|
||||
}
|
||||
|
||||
Step "Installing packages" { pnpm install }
|
||||
Step "Building the downloader" { py -3 scripts\build_downloader.py }
|
||||
Step "Installing the castLabs signing tool" { venv\Scripts\python.exe -m pip install -q --upgrade castlabs-evs }
|
||||
$env:EVS_PYTHON = (Resolve-Path "venv\Scripts\python.exe").Path
|
||||
|
||||
Step "Checking the castLabs account" { venv\Scripts\python.exe -m castlabs_evs.account reauth }
|
||||
Step "Building the app pages" { pnpm vite build }
|
||||
Step "Building the app" { pnpm build:electron }
|
||||
Step "Creating the installer" { pnpm exec electron-builder --win nsis --x64 -c.directories.output=release/windows }
|
||||
|
||||
$installer = Get-ChildItem release\windows -Filter "*.exe" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
Write-Host ""
|
||||
Write-Host "Installer: $($installer.FullName)" -ForegroundColor Green
|
||||
@@ -0,0 +1,63 @@
|
||||
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()
|
||||
@@ -0,0 +1,7 @@
|
||||
const { execFileSync } = require("node:child_process");
|
||||
|
||||
exports.default = async function evsSign(context) {
|
||||
if (!["win32", "darwin"].includes(context.electronPlatformName)) return;
|
||||
const python = process.env.EVS_PYTHON || "python";
|
||||
execFileSync(python, ["-m", "castlabs_evs.vmp", "sign-pkg", context.appOutDir], { stdio: "inherit" });
|
||||
};
|
||||
Reference in New Issue
Block a user