Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05a2a58ace |
No files matched your search
+1
-1
@@ -5,7 +5,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
VERSION = "v1.5.1"
|
VERSION = "v1.5.2"
|
||||||
|
|
||||||
|
|
||||||
APP_NAME = "MusicTools"
|
APP_NAME = "MusicTools"
|
||||||
|
|||||||
+4
-2
@@ -146,8 +146,10 @@ def download_playlist(
|
|||||||
progress_callback(i, total, "", "stopped", 0)
|
progress_callback(i, total, "", "stopped", 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
query = f"{track['name']} - {track['artist']}"
|
artist = (track.get('artist') or "").strip()
|
||||||
track_only = track['name']
|
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)
|
# Salta brani gia scaricati in precedenza (file di tracking)
|
||||||
if query in done_set:
|
if query in done_set:
|
||||||
|
|||||||
+9
-2
@@ -75,15 +75,22 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="field-label">
|
<label class="field-label">
|
||||||
URL
|
URL o titolo brano
|
||||||
<span class="badge" id="urlListBadge" hidden></span>
|
<span class="badge" id="urlListBadge" hidden></span>
|
||||||
</label>
|
</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<input type="text" id="urlInput" class="input pill" placeholder="Incolla qui un link Spotify, YouTube o SoundCloud…" />
|
<input type="text" id="urlInput" class="input pill" placeholder="Link Spotify/YouTube… oppure Artista - Titolo · Titolo brano" />
|
||||||
<button class="btn btn-ghost pill" id="loadListBtn">
|
<button class="btn btn-ghost pill" id="loadListBtn">
|
||||||
<span>📂</span> Carica lista
|
<span>📂</span> Carica lista
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="hint">
|
||||||
|
<span class="hint-ico">ⓘ</span>
|
||||||
|
<div>
|
||||||
|
Puoi incollare un <strong>link</strong> (Spotify, YouTube, SoundCloud…) oppure scrivere direttamente
|
||||||
|
<strong>Artista - Titolo</strong> o solo il <strong>titolo del brano</strong>: l'app cerca il match migliore su YouTube e scarica in MP3.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
|||||||
+33
-1
@@ -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
|
// Bridge — eventi spinti dal backend
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -340,11 +358,25 @@ $("#downloadBtn").addEventListener("click", async () => {
|
|||||||
if (!urls.length) {
|
if (!urls.length) {
|
||||||
const single = $("#urlInput").value.trim();
|
const single = $("#urlInput").value.trim();
|
||||||
if (!single) {
|
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"]();
|
bridgeHandlers["download:done"]();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (looksLikeUrl(single)) {
|
||||||
urls = [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({
|
res = await window.pywebview.api.start_download({
|
||||||
urls,
|
urls,
|
||||||
|
|||||||
Reference in new issue
Block a user