7 Commits
Author SHA1 Message Date
luciano ed1059bf8c feat: sidebar scroll + log persistente (v1.11.1)
- Sidebar diventata troppo lunga (14+ tab): overflow-y auto sulla nav,
  brand e footer restano sticky. Scrollbar 6px tema-coerente
- Nuovo core/applog.py: TimedRotatingFileHandler daily con 7 giorni
  di retention. NON tocca sys.stdout/stderr (causa segfault WebKit
  su macOS); cattura tracebacks via sys.excepthook + threading.excepthook
- bridge._log mirror su logger persistente (ui.<view>) → tutto quello
  che vedi nei log delle tab e' anche su file
- Bridge: get_log_file_path() + open_log_folder() per la nuova sezione
  Impostazioni con path visibile e bottone "Apri cartella"
2026-08-27 11:27:57 +02:00
luciano cdbb1d85d5 feat: fallback Spotify + layout selector + tab Appiattisci (v1.11.0)
Cataloga:
- Fallback Spotify quando AcoustID non trova (copertura ottima per
  dance/electronic mashup/bootleg/remix)
- Dropdown "Struttura cartelle" per scegliere tra <Anno>/<Genere>/ e
  <Genere>/<Anno>/
- Chiave AcoustID default sostituita da placeholder invalido a quella
  pubblica di MusicBrainz Picard (valida)

Nuova tab Appiattisci:
- Sposta tutti i file audio delle sotto-cartelle nella cartella padre
- Utile come undo della catalogazione o merge di archivi frammentati
- Rimuove sotto-cartelle vuote dopo il move (opzionale)
- Suffisso _1, _2 su nomi duplicati (no overwrite)
2026-08-27 10:57:04 +02:00
luciano e7d11d0235 feat: Dedup enhancements (streaming, retry, filename mode, scroll, auto-select)
Iterazioni sul feature Dedup (v1.10.0) da subito-post-scaffolding:
- compute_fingerprint espone il vero errore invece del generico None,
  worker propaga l'err_msg via progress_callback esteso
- Retry automatico: -length 30 su "invalid data / decoding frame",
  -length 60 + -algorithm 1 su "fingerprint vuoto"
- Nuovo metodo "filename" (Jaccard sui token nome file) con algoritmo
  incrementale O(N·K) — utile per file corrotti o per anteprima veloce
- Streaming groups: sia fingerprint che filename emettono `dedup:group`
  appena un gruppo raggiunge >=2 file; JS accumula in Map per update
  in-place. Progress bar avanza in tempo reale
- Fix shape bug che dava "NaN duplicati" nella summary line
- .dedup-groups-scroll: max-height 55vh + overflow-y auto per non
  perdere l'header/footer scrollando molti gruppi
- Bottone "Seleziona tutti i consigliati" nel footer: ripristina la
  selezione di default (tutti tranne il TIENI marcati per cancellazione)
- .gitignore: dedup_cache.db (SQLite locale per macchina utente)
2026-08-02 13:59:39 +02:00
luzadevandClaude Opus 4.7 5202b2c586 Setup commercial launch: licenze + backend Cloudflare Worker
Client (Python/JS):
- core/license.py: attivazione, validazione, deactivate (HTTP client + JWT decode)
- core/config.py: campi license_* + URL endpoint + costanti grace/revalidate
- api/bridge.py: get_init_data ritorna license status; activate_license/
  deactivate_license/revalidate_license/open_purchase_page
- check_update riscritto: punta a musictools.djluza.com/api/latest con
  Bearer token, URL di download firmato dal server solo se licensed
- webui: schermata di attivazione bloccante all'avvio; sezione Licenza
  in Impostazioni con verifica/disattiva

Backend (server/):
- Cloudflare Worker + D1 + R2 (vedi server/README.md)
- Endpoints: /api/license/{activate,validate,deactivate}, /api/latest,
  /api/webhook/lemonsqueezy, /api/health
- JWT HS256 con rotazione; max 3 attivazioni/licenza
- Generazione licenze via webhook Lemon Squeezy + email Resend
- Schema D1 in migrations/0001_init.sql

Memory: nuova musictools-commercial-launch.md, rimosso pending obsoleto

NON taggare finche backend non e' deployato (l'app e' bloccante)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 23:36:41 +02:00
luzadevandClaude Opus 4.7 52002f5184 Icona dell'app: squircle verde con nota musicale
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>
2026-06-08 11:26:06 +02:00
luzadevandClaude Opus 4.7 878e024c13 Rimuovi playlist personali dal repo
Tolgo dal tracking i file di playlist personali presenti nel
working tree fin dai primi commit:

- Beatport Top 100 Melodic House & Techno.txt
- PlayList_2026.txt
- PlayList_da_scaricare.txt
- Vibes_List.txt

Aggiunti i pattern al .gitignore cosi' non rientrano per sbaglio.
I file rimangono sul disco locale (git rm --cached, non -rf).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 11:19:37 +02:00
luzadevandClaude Opus 4.7 8c06a26ddb Initial commit: MusicDownload con UI pywebview
- Frontend HTML/CSS/JS in webui/ (stile Spotify-like, hero gradient, modal blur)
- API bridge JS<->Python in api/bridge.py
- Core invariato: downloader yt-dlp, upgrader, spotify client, config
- Build scripts macOS (WebKit) e Windows (EdgeChromium)
- .gitignore esclude credenziali (config.json, cookies.txt) e artefatti build

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 12:48:58 +02:00