Fix strutturale ricorrente errore "yt-dlp exit 1" nel download.
YouTube rompe API ogni 1-2 settimane; yt-dlp stable esce ogni ~4
settimane, quindi la build imbarcava binari gia' obsoleti al rilascio.
- build_macos.py + build_windows.py: URL switch da
yt-dlp/yt-dlp/releases/latest → yt-dlp/yt-dlp-nightly-builds
- Sempre re-download (niente skip se bundle_bin/yt-dlp esiste) —
garantisce binario 24-48h, non 3-4 settimane
Nuovo modulo core.dedup per rilevare brani audio duplicati usando
Chromaprint (fpcalc): scan cartella (opzionalmente ricorsivo),
fingerprint acustico via fpcalc -json, cache SQLite in
_get_config_dir()/dedup_cache.db per non ricalcolare al re-scan,
raggruppamento per fingerprint identico + ordering per bitrate DESC.
move_to_trash() usa send2trash (reversibile via Finder/Explorer).
- core/paths.py: find_fpcalc() con fallback dev su project bundle_bin
- core/dedup.py: scan_folder, compute_fingerprint, move_to_trash
- tests/test_dedup.py: 9 unit test (mock fpcalc + send2trash)
- requirements.txt: send2trash>=1.8.0
- build_macos.py: download fpcalc universal binary da GitHub releases
- build_windows.py: download fpcalc.exe da GitHub releases
- requirements.txt: certifi come dep esplicita
- main.py: setta SSL_CERT_FILE/REQUESTS_CA_BUNDLE su certifi.where() al boot
- build_windows.py + build_macos.py: --collect-data certifi nel PyInstaller
Bugfix: senza certifi bundlato, le chiamate HTTPS dal build Windows
falliscono con CERTIFICATE_VERIFY_FAILED (attivazione licenza impossibile).
Preload esplicito di pythonnet.load("netfx") in main.py PRIMA di
importare webview: il lazy-import del 'clr' fallisce sotto PyInstaller
perche' Python.Runtime.dll viene bundlata ma il loader netfx non sa
risolverla.
Aggiunti:
- main.py: bootstrap pythonnet con PYTHONNET_RUNTIME=netfx + load()
- build_windows.py: --clean rebuild, --collect-data pythonnet/clr_loader
(per Python.Runtime.runtimeconfig.json e altri non-Python files),
hidden-import clr_loader.netfx
PyInstaller non bundlava i file di supporto di pythonnet/clr_loader
(Python.Runtime.dll, nethost.dll, runtimeconfig.json), per cui al
caricamento di webview.platforms.winforms.py l'import 'clr' moriva.
Aggiunti --collect-all pythonnet/clr_loader + copy-metadata.
Pinnata pythonnet a 3.0.3 (l'ultima compatibile con PyInstaller
senza patch aggiuntive).
Creata un'icona coerente con la palette dell'app: squircle Apple-style
(corner radius ~22%), gradient verde Spotify -> verde scuro, nota
musicale (♫) bianca centrata con leggero glow, sottile highlight in
alto e bordo soft per definizione.
- assets/generate_icon.py: script PIL riproducibile, produce
icon.png (master 1024) -> icon.iconset/ -> iconutil -> icon.icns
(macOS) e icon.ico multi-size (Windows)
- assets/icon.png / icon.icns / icon.ico committati
- assets/icon.iconset/ in .gitignore (intermedio rigenerabile)
- build_macos.py: --icon assets/icon.icns se presente
- build_windows.py: --icon assets/icon.ico se presente
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 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: <title>, 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>
Nuova sezione 'Metadati' nella sidebar con editor completo dei tag:
titolo, artista, album, album artist, anno, traccia, genere, BPM,
key, commento, copertina.
- core/metadata.py: read/write metadati via mutagen, supporto ID3
(MP3), MP4 atoms (M4A/AAC) e Vorbis comments (FLAC)
- api/bridge.py: pick_audio_file, pick_image_file, read_metadata,
save_metadata. Cover passata come base64 al frontend per preview
- webui: hero ambra, form a griglia 2 colonne, anteprima cover 180x180,
bottoni cambia/rimuovi copertina, ricarica file
- requirements.txt: aggiunto mutagen>=1.47.0
- build_macos.py / build_windows.py: --collect-all mutagen
Modifiche correlate (in attesa di decisione utente sulla
distribuzione degli aggiornamenti):
- VERSION bumpato a v1.2.2 in core/config.py
- check_update ora interroga l'API GitHub Releases invece di
djluza.com/version.json (funzionera quando il repo sara pubblico)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>