From 850d3f4b6c2d0eba65f20ff734bb022c38d6ac35 Mon Sep 17 00:00:00 2001 From: luzadev Date: Mon, 8 Jun 2026 11:15:34 +0200 Subject: [PATCH] Rename: l'app si chiama MusicTools (non piu MusicDownload) - main.py: titolo finestra pywebview -> 'MusicTools' - core/config.py: APP_NAME='MusicTools', cartella config bundled ora ~/Library/Application Support/MusicTools/ e %APPDATA%/MusicTools/. Migrazione one-shot: se non esiste la nuova ma esiste la legacy 'MusicDownload', il config.json viene copiato cosi' le impostazioni non vanno perse dopo l'aggiornamento - core/recorder.py: messaggio errore permesso microfono - api/bridge.py: User-Agent update check + guida Spotify menzionano MusicTools - build_macos.py / build_windows.py / .github/workflows/build.yml: prodotti rinominati (MusicTools.app, MusicTools.exe, MusicTools-macOS.zip, MusicTools-Windows.zip, Release 'Build MusicTools') - webui: , brand-name sidebar, intestazioni commenti - README: tutti i riferimenti aggiornati + nota che il repo Git conserva il nome storico 'musicdownload' (URL stabili per release gia' pubblicate) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --- .github/workflows/build.yml | 28 ++++++++++++++-------------- README.md | 28 +++++++++++++++------------- api/bridge.py | 4 ++-- build_macos.py | 18 +++++++++--------- build_windows.py | 18 +++++++++--------- core/config.py | 24 +++++++++++++++++++++--- core/recorder.py | 2 +- main.py | 4 ++-- webui/css/style.css | 2 +- webui/index.html | 4 ++-- webui/js/app.js | 2 +- 11 files changed, 77 insertions(+), 57 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b907eac..4a79248 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build MusicDownload +name: Build MusicTools on: workflow_dispatch: @@ -36,14 +36,14 @@ jobs: - name: Package .app -> zip run: | cd dist - ditto -c -k --sequesterRsrc --keepParent MusicDownload.app ../MusicDownload-macOS.zip - ls -lh ../MusicDownload-macOS.zip + ditto -c -k --sequesterRsrc --keepParent MusicTools.app ../MusicTools-macOS.zip + ls -lh ../MusicTools-macOS.zip - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: MusicDownload-macOS - path: MusicDownload-macOS.zip + name: MusicTools-macOS + path: MusicTools-macOS.zip retention-days: 14 # ========================================================= @@ -69,14 +69,14 @@ jobs: - name: Package -> zip shell: pwsh run: | - Compress-Archive -Path dist/MusicDownload/* -DestinationPath MusicDownload-Windows.zip -CompressionLevel Optimal - Get-Item MusicDownload-Windows.zip + Compress-Archive -Path dist/MusicTools/* -DestinationPath MusicTools-Windows.zip -CompressionLevel Optimal + Get-Item MusicTools-Windows.zip - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: MusicDownload-Windows - path: MusicDownload-Windows.zip + name: MusicTools-Windows + path: MusicTools-Windows.zip retention-days: 14 # ========================================================= @@ -90,22 +90,22 @@ jobs: - name: Download macOS artifact uses: actions/download-artifact@v4 with: - name: MusicDownload-macOS + name: MusicTools-macOS path: artifacts/macos - name: Download Windows artifact uses: actions/download-artifact@v4 with: - name: MusicDownload-Windows + name: MusicTools-Windows path: artifacts/windows - name: Create Release uses: softprops/action-gh-release@v2 with: - name: MusicDownload ${{ github.ref_name }} + name: MusicTools ${{ github.ref_name }} tag_name: ${{ github.ref_name }} generate_release_notes: true fail_on_unmatched_files: true files: | - artifacts/macos/MusicDownload-macOS.zip - artifacts/windows/MusicDownload-Windows.zip + artifacts/macos/MusicTools-macOS.zip + artifacts/windows/MusicTools-Windows.zip diff --git a/README.md b/README.md index c487b6c..7af224d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# MusicDownload +# MusicTools Applicazione desktop per **scaricare musica e video**, **modificare i metadati** dei file audio e **registrare l'audio** da qualsiasi ingresso del computer. @@ -8,6 +8,8 @@ Sviluppata da **LuZa**. Repo: <https://github.com/luzadev/musicdownload> +> ℹ️ Il repo Git conserva il nome storico **`musicdownload`** (l'app prima si chiamava così); URL stabili per release già pubblicate e installazioni esistenti. + ## Funzionalità | Tab | Cosa fa | @@ -91,14 +93,14 @@ brew install blackhole-2ch Anche se non è un microfono fisico, macOS richiede il permesso "Microfono" per leggere da BlackHole via AVFoundation. -Vai su **Preferenze di Sistema → Privacy e sicurezza → Microfono** e abilita l'app da cui lanci MusicDownload (Terminal/iTerm in sviluppo, oppure MusicDownload.app per la build distribuita). Se non vedi nessuna voce, comparirà un popup la prima volta che premi REC — accetta. +Vai su **Preferenze di Sistema → Privacy e sicurezza → Microfono** e abilita l'app da cui lanci MusicTools (Terminal/iTerm in sviluppo, oppure MusicTools.app per la build distribuita). Se non vedi nessuna voce, comparirà un popup la prima volta che premi REC — accetta. ### 3. Setup A — minimo (registri ma non senti l'audio durante) 1. Click sull'icona altoparlante nella barra menu → **Output → BlackHole 2ch** *Oppure: Preferenze di Sistema → Audio → Uscita → BlackHole 2ch* 2. Fai partire lo stream (Spotify/YouTube): non sentirai nulla — è normale, l'audio va a BlackHole -3. App MusicDownload → tab **● Registra** → dispositivo **🔄 BlackHole 2ch (loopback)** → **REC** +3. App MusicTools → tab **● Registra** → dispositivo **🔄 BlackHole 2ch (loopback)** → **REC** 4. **Stop** e riascolta il file MP3 generato ### 4. Setup B — completo (registri E senti l'audio contemporaneamente, consigliato) @@ -119,7 +121,7 @@ Adesso ogni audio del sistema viene riprodotto sugli speaker (lo senti) e contem | Sintomo | Causa probabile | Fix | |---|---|---| | BlackHole non compare nel dropdown | CoreAudio non l'ha ancora caricato dopo l'install | `sudo killall coreaudiod` poi premi **↻ Aggiorna** | -| Errore `ffmpeg exit -6` o `permesso Microfono mancante` | macOS nega l'accesso al device | Privacy e sicurezza → Microfono → abilita Terminal/MusicDownload | +| Errore `ffmpeg exit -6` o `permesso Microfono mancante` | macOS nega l'accesso al device | Privacy e sicurezza → Microfono → abilita Terminal/MusicTools | | File MP3 muto | Output di sistema non passa per BlackHole | Cambia output su BlackHole o Multi-Output Device (vedi Setup A/B) | | Audio doppio/eco nel file | Stai registrando da BlackHole *e* da microfono fisico simultaneamente | Verifica che nel dropdown ci sia solo `BlackHole 2ch` | | Audio crackly/distorto | Sample rate non allineato | In Audio MIDI Setup, BlackHole + altoparlanti tutti a 48 kHz | @@ -127,7 +129,7 @@ Adesso ogni audio del sistema viene riprodotto sugli speaker (lo senti) e contem ## Struttura progetto ``` -MusicDownload/ +MusicTools/ ├── main.py # Entry point — bootstrap pywebview ├── requirements.txt ├── build_macos.py # Script build macOS (.app) @@ -169,8 +171,8 @@ Il file `config.json` viene creato automaticamente al primo avvio: Posizione: - **Sviluppo**: directory del progetto -- **macOS bundle**: `~/Library/Application Support/MusicDownload/` -- **Windows bundle**: `%APPDATA%/MusicDownload/` +- **macOS bundle**: `~/Library/Application Support/MusicTools/` +- **Windows bundle**: `%APPDATA%/MusicTools/` ## Build locale @@ -182,7 +184,7 @@ pip install pyinstaller python3 build_macos.py ``` -Produce `dist/MusicDownload.app` con yt-dlp, ffmpeg, ffprobe e tutte le dylib bundled (rpath patchati con `install_name_tool`). +Produce `dist/MusicTools.app` con yt-dlp, ffmpeg, ffprobe e tutte le dylib bundled (rpath patchati con `install_name_tool`). ### Windows @@ -191,14 +193,14 @@ pip install pyinstaller python build_windows.py ``` -Produce `dist/MusicDownload/MusicDownload.exe`. Lo script scarica automaticamente `yt-dlp.exe` e `ffmpeg.exe`/`ffprobe.exe` static build. +Produce `dist/MusicTools/MusicTools.exe`. Lo script scarica automaticamente `yt-dlp.exe` e `ffmpeg.exe`/`ffprobe.exe` static build. ## Build & Release automatiche (GitHub Actions) Ogni push di un tag `v*` triggera la pipeline `.github/workflows/build.yml`: -1. **`build-macos`** (runner `macos-latest`) → `MusicDownload-macOS.zip` (la `.app` zippata con `ditto`) -2. **`build-windows`** (runner `windows-latest`) → `MusicDownload-Windows.zip` +1. **`build-macos`** (runner `macos-latest`) → `MusicTools-macOS.zip` (la `.app` zippata con `ditto`) +2. **`build-windows`** (runner `windows-latest`) → `MusicTools-Windows.zip` 3. **`release`** → crea automaticamente una GitHub Release con entrambi gli asset allegati Per pubblicare una nuova versione: @@ -211,10 +213,10 @@ git push origin v1.3.0 Per fare solo una build di test (senza release): ```bash -gh workflow run "Build MusicDownload" --ref main +gh workflow run "Build MusicTools" --ref main ``` -oppure dalla UI: **Actions → Build MusicDownload → Run workflow**. +oppure dalla UI: **Actions → Build MusicTools → Run workflow**. Le release ufficiali sono disponibili su <https://github.com/luzadev/musicdownload/releases>. diff --git a/api/bridge.py b/api/bridge.py index d49a329..a910088 100644 --- a/api/bridge.py +++ b/api/bridge.py @@ -38,7 +38,7 @@ SPOTIFY_GUIDE_TEXT = """\ 1) Vai su https://developer.spotify.com/dashboard e accedi (anche con account free). 2) Clicca "Create app". 3) Compila: - - App name: MusicDownload (o quello che vuoi) + - App name: MusicTools (o quello che vuoi) - Description: a piacere - Redirect URI: http://localhost:8888/callback (obbligatorio ma non usato) - Seleziona "Web API" @@ -148,7 +148,7 @@ class Api: API_URL = "https://api.github.com/repos/luzadev/musicdownload/releases/latest" try: resp = requests.get(API_URL, headers={ - "User-Agent": "MusicDownload", + "User-Agent": "MusicTools", "Accept": "application/vnd.github+json", }, timeout=10) resp.raise_for_status() diff --git a/build_macos.py b/build_macos.py index 6edc838..9c58d96 100644 --- a/build_macos.py +++ b/build_macos.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Build script per creare MusicDownload.app su macOS. +Build script per creare MusicTools.app su macOS. Uso: python3 build_macos.py @@ -8,7 +8,7 @@ Uso: Cosa fa: 1. Scarica il binario standalone di yt-dlp per macOS 2. Raccoglie ffmpeg + ffprobe + tutte le loro dylib da Homebrew -3. Esegue PyInstaller per creare MusicDownload.app +3. Esegue PyInstaller per creare MusicTools.app Requisiti: pip3 install pyinstaller @@ -210,7 +210,7 @@ def run_pyinstaller(): cmd = [ sys.executable, "-m", "PyInstaller", - "--name", "MusicDownload", + "--name", "MusicTools", "--windowed", "--onedir", "--noconfirm", @@ -230,7 +230,7 @@ def run_pyinstaller(): log(f"Comando: {' '.join(cmd[:10])}...") subprocess.run(cmd, check=True, cwd=str(ROOT)) - app_path = DIST_DIR / "MusicDownload.app" + app_path = DIST_DIR / "MusicTools.app" if app_path.exists(): log(f"Build completata: {app_path}") # Mostra dimensione @@ -238,8 +238,8 @@ def run_pyinstaller(): log(f"Dimensione: {size / 1024 / 1024:.0f} MB") else: log("ATTENZIONE: .app non trovata, controlla l'output di PyInstaller") - # Potrebbe essere in dist/MusicDownload/ (non .app) - alt = DIST_DIR / "MusicDownload" + # Potrebbe essere in dist/MusicTools/ (non .app) + alt = DIST_DIR / "MusicTools" if alt.exists(): log(f"Trovata directory: {alt}") @@ -249,7 +249,7 @@ def run_pyinstaller(): # ========================================================================= def main(): print("=" * 50) - print(" MusicDownload — Build macOS") + print(" MusicTools — Build macOS") print("=" * 50) # Verifica pyinstaller @@ -272,12 +272,12 @@ def main(): print("\n" + "=" * 50) print(" DONE!") print("=" * 50) - app = DIST_DIR / "MusicDownload.app" + app = DIST_DIR / "MusicTools.app" if app.exists(): print(f"\n L'app e in: {app}") print(f" Per testarla: open '{app}'") print(f"\n Per distribuirla, comprimi la cartella:") - print(f" zip -r MusicDownload.zip dist/MusicDownload.app") + print(f" zip -r MusicTools.zip dist/MusicTools.app") print() diff --git a/build_windows.py b/build_windows.py index 9894ce8..4e47d01 100644 --- a/build_windows.py +++ b/build_windows.py @@ -1,5 +1,5 @@ """ -Build script per creare MusicDownload.exe su Windows. +Build script per creare MusicTools.exe su Windows. Uso: python build_windows.py @@ -7,7 +7,7 @@ Uso: Cosa fa: 1. Scarica il binario standalone di yt-dlp per Windows 2. Scarica ffmpeg static build per Windows -3. Esegue PyInstaller per creare MusicDownload.exe +3. Esegue PyInstaller per creare MusicTools.exe Requisiti: pip install pyinstaller @@ -101,7 +101,7 @@ def run_pyinstaller(): cmd = [ sys.executable, "-m", "PyInstaller", - "--name", "MusicDownload", + "--name", "MusicTools", "--windowed", "--onedir", "--noconfirm", @@ -126,11 +126,11 @@ def run_pyinstaller(): log(f"Comando: {' '.join(cmd[:10])}...") subprocess.run(cmd, check=True, cwd=str(ROOT)) - exe_path = DIST_DIR / "MusicDownload" / "MusicDownload.exe" + exe_path = DIST_DIR / "MusicTools" / "MusicTools.exe" if exe_path.exists(): log(f"Build completata: {exe_path}") else: - log("ATTENZIONE: MusicDownload.exe non trovato, controlla l'output") + log("ATTENZIONE: MusicTools.exe non trovato, controlla l'output") # ========================================================================= @@ -138,7 +138,7 @@ def run_pyinstaller(): # ========================================================================= def main(): print("=" * 50) - print(" MusicDownload - Build Windows") + print(" MusicTools - Build Windows") print("=" * 50) if sys.platform != "win32": @@ -167,12 +167,12 @@ def main(): print("\n" + "=" * 50) print(" DONE!") print("=" * 50) - dist = DIST_DIR / "MusicDownload" + dist = DIST_DIR / "MusicTools" if dist.exists(): print(f"\n L'app e in: {dist}") - print(f" Eseguibile: {dist / 'MusicDownload.exe'}") + print(f" Eseguibile: {dist / 'MusicTools.exe'}") print(f"\n Per distribuirla, comprimi la cartella:") - print(f" Comprimi {dist} -> MusicDownload_Windows.zip") + print(f" Comprimi {dist} -> MusicTools_Windows.zip") print() diff --git a/core/config.py b/core/config.py index 85c40f8..c45e980 100644 --- a/core/config.py +++ b/core/config.py @@ -8,21 +8,39 @@ from pathlib import Path VERSION = "v1.2.2" +APP_NAME = "MusicTools" +_LEGACY_NAME = "MusicDownload" + + def _get_config_dir() -> Path: """Ritorna la directory per config.json. Frozen (bundle PyInstaller): - - macOS: ~/Library/Application Support/MusicDownload/ - - Windows: %APPDATA%/MusicDownload/ + - macOS: ~/Library/Application Support/MusicTools/ + - Windows: %APPDATA%/MusicTools/ Dev (non frozen): - directory del progetto + + Se la cartella nuova non esiste ma quella legacy 'MusicDownload' si', + viene migrata (copia di config.json) cosi' l'utente non perde le + impostazioni dopo il rename. """ if getattr(sys, "frozen", False): if sys.platform == "win32": base = Path(os.environ.get("APPDATA", Path.home())) else: base = Path.home() / "Library" / "Application Support" - config_dir = base / "MusicDownload" + config_dir = base / APP_NAME + legacy_dir = base / _LEGACY_NAME + # Migrazione one-shot: se non esiste la nuova ma esiste la vecchia + if not config_dir.exists() and legacy_dir.exists(): + try: + config_dir.mkdir(parents=True, exist_ok=True) + legacy_cfg = legacy_dir / "config.json" + if legacy_cfg.exists(): + (config_dir / "config.json").write_bytes(legacy_cfg.read_bytes()) + except OSError: + pass config_dir.mkdir(parents=True, exist_ok=True) return config_dir return Path(__file__).resolve().parent.parent diff --git a/core/recorder.py b/core/recorder.py index 9b5fc95..d32136a 100644 --- a/core/recorder.py +++ b/core/recorder.py @@ -350,7 +350,7 @@ def _extract_friendly_error(rc: int) -> str: return "Dispositivo non disponibile (riavvia il servizio audio o ricontrolla la selezione)." if "permission" in text or "not authorized" in text or "not permitted" in text: - return "Permesso microfono negato da macOS. Abilita Python/MusicDownload in Privacy → Microfono." + return "Permesso microfono negato da macOS. Abilita Python/MusicTools in Privacy → Microfono." if "no such device" in text or "no such audio device" in text: return "Dispositivo non trovato. Premi '↻ Aggiorna' e riseleziona." diff --git a/main.py b/main.py index 97ac117..678ec52 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -"""MusicDownload — Entry point (pywebview + WebKit/EdgeChromium).""" +"""MusicTools — Entry point (pywebview + WebKit/EdgeChromium).""" import os import sys @@ -23,7 +23,7 @@ def main(): index_path = _resource_path("webui", "index.html") window = webview.create_window( - title="MusicDownload", + title="MusicTools", url=index_path, js_api=api, width=1080, diff --git a/webui/css/style.css b/webui/css/style.css index 71c8ec4..0979113 100644 --- a/webui/css/style.css +++ b/webui/css/style.css @@ -1,5 +1,5 @@ /* =============================== - MusicDownload — Spotify-like UI + MusicTools — Spotify-like UI =============================== */ :root { diff --git a/webui/index.html b/webui/index.html index 65f7aa6..136ebdf 100644 --- a/webui/index.html +++ b/webui/index.html @@ -3,7 +3,7 @@ <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <title>MusicDownload + MusicTools @@ -15,7 +15,7 @@ -
MusicDownload
+
MusicTools
diff --git a/webui/js/app.js b/webui/js/app.js index 74c24ab..03cf5a5 100644 --- a/webui/js/app.js +++ b/webui/js/app.js @@ -1,5 +1,5 @@ /* ====================================================== - MusicDownload — Frontend (vanilla JS) + MusicTools — Frontend (vanilla JS) ====================================================== */ const $ = (sel) => document.querySelector(sel);