diff --git a/core/config.py b/core/config.py index 92cf644..cc8c07b 100644 --- a/core/config.py +++ b/core/config.py @@ -5,7 +5,7 @@ import os import sys from pathlib import Path -VERSION = "v1.5.1" +VERSION = "v1.5.2" APP_NAME = "MusicTools" diff --git a/core/downloader.py b/core/downloader.py index 2376e4e..e28151f 100644 --- a/core/downloader.py +++ b/core/downloader.py @@ -146,8 +146,10 @@ def download_playlist( progress_callback(i, total, "", "stopped", 0) return - query = f"{track['name']} - {track['artist']}" - track_only = track['name'] + artist = (track.get('artist') or "").strip() + name = (track.get('name') or "").strip() + query = f"{name} - {artist}" if artist else name + track_only = name # Salta brani gia scaricati in precedenza (file di tracking) if query in done_set: diff --git a/webui/index.html b/webui/index.html index 6ce2cb8..a1cfc62 100644 --- a/webui/index.html +++ b/webui/index.html @@ -75,15 +75,22 @@
- +
+
+ ⓘ +
+ Puoi incollare un link (Spotify, YouTube, SoundCloud…) oppure scrivere direttamente + Artista - Titolo o solo il titolo del brano: l'app cerca il match migliore su YouTube e scarica in MP3. +
+
diff --git a/webui/js/app.js b/webui/js/app.js index d4b6cc1..17d7cf4 100644 --- a/webui/js/app.js +++ b/webui/js/app.js @@ -27,6 +27,24 @@ function waitApi() { }); } +// Riconosce se una stringa e un URL (incluso schema spotify:) +function looksLikeUrl(s) { + if (!s) return false; + if (/^(https?|spotify):/i.test(s)) return true; + if (s.includes("://")) return true; + // Domini comuni anche senza http (es. "youtube.com/...") + return /^(www\.)?(youtube\.com|youtu\.be|spotify\.com|soundcloud\.com|tiktok\.com|instagram\.com|facebook\.com|fb\.watch)\//i.test(s); +} + +// Trasforma una query libera in {name, artist}. +// Formati riconosciuti: "Artista - Titolo" (anche con – o —) oppure solo "Titolo". +function parseQueryToTrack(q) { + const s = (q || "").trim(); + const m = s.match(/^(.+?)\s+[-–—]\s+(.+)$/); + if (m) return { artist: m[1].trim(), name: m[2].trim() }; + return { artist: "", name: s }; +} + // ============================================================ // Bridge — eventi spinti dal backend // ============================================================ @@ -340,11 +358,25 @@ $("#downloadBtn").addEventListener("click", async () => { if (!urls.length) { const single = $("#urlInput").value.trim(); if (!single) { - toast("Inserisci un URL o carica una lista", "error"); + toast("Inserisci un URL, un titolo o carica una lista", "error"); bridgeHandlers["download:done"](); return; } - urls = [single]; + if (looksLikeUrl(single)) { + urls = [single]; + } else { + const track = parseQueryToTrack(single); + res = await window.pywebview.api.start_tracks_download({ + tracks: [track], + output_dir: state.dlOutputDir, + subfolder: "", + }); + if (!res.ok) { + toast(res.error || "Errore", "error"); + bridgeHandlers["download:done"](); + } + return; + } } res = await window.pywebview.api.start_download({ urls,