feat: upgrade archivio con auto-pick, audio preview, cancel-all (v1.9.4)
Tab Upgrade: - Checkbox "Scelta automatica" per skippare il modal quando ci sono multi-match (usa bitrate DESC) - Anteprima audio nel picker: play button sul source + ogni candidato via bridge read_audio_data_url (WKWebView blocca file://) - Bottone "Annulla tutto" nel picker → interrompe l'intera coda - Fix mtime: shutil.copy (non copy2) così il file upgradato ha data odierna nel Finder - Fix stop audio → non triggera più toast di errore - Modal picker più largo (620-780px) con footer wrap Extra: campo release_date estratto anche in Beatport (publish_date) e YouTube (upload_date) — completato scaffold sort colonna Data
This commit is contained in:
1 parent
e10466d93b
commit
e7fde842f2
8 files changed
+219
-13
No files matched your search
@@ -24,6 +24,7 @@ class BeatportTrack:
|
||||
duration_sec: int
|
||||
beatport_id: int
|
||||
image_url: str = "" # URL cover art (default vuoto per retrocompatibilità test)
|
||||
release_date: str = "" # ISO YYYY-MM-DD, vuoto se mancante
|
||||
|
||||
@property
|
||||
def display(self) -> str:
|
||||
@@ -177,6 +178,7 @@ def _parse_tracks(data: dict) -> list:
|
||||
duration_sec=length_ms // 1000,
|
||||
beatport_id=int(item.get("id") or 0),
|
||||
image_url=_extract_image_url(item.get("image")),
|
||||
release_date=str(item.get("publish_date") or item.get("new_release_date") or "").strip(),
|
||||
)
|
||||
except (TypeError, ValueError) as e:
|
||||
raise BeatportParseError(f"track[{i}] shape inattesa: {e}") from e
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
VERSION = "v1.9.3"
|
||||
VERSION = "v1.9.4"
|
||||
|
||||
|
||||
APP_NAME = "MusicTools"
|
||||
|
||||
+5
-2
@@ -188,7 +188,10 @@ def _copy_or_convert_to_mp3(
|
||||
"""
|
||||
try:
|
||||
if src.suffix.lower() == ".mp3":
|
||||
shutil.copy2(str(src), str(dst))
|
||||
# shutil.copy (non copy2): mtime del target = ora, non quello
|
||||
# del sorgente. Così è chiaro nel Finder che il file è stato
|
||||
# aggiornato dall'upgrade.
|
||||
shutil.copy(str(src), str(dst))
|
||||
return dst.exists()
|
||||
# Convert non-mp3 -> mp3 320k
|
||||
ffmpeg_bin = find_ffmpeg() or "ffmpeg"
|
||||
@@ -431,7 +434,7 @@ def upgrade_folder(
|
||||
progress_callback(processed, total, filepath.name,
|
||||
"resolve_wait", current_kbps, 0)
|
||||
try:
|
||||
choice = resolve_callback(filepath.name, cand_payload) or {}
|
||||
choice = resolve_callback(str(filepath), cand_payload) or {}
|
||||
except Exception:
|
||||
choice = {}
|
||||
action = (choice.get("action") or "").strip()
|
||||
|
||||
@@ -63,6 +63,14 @@ def search_youtube(query: str, limit: int = 50) -> list:
|
||||
video_id = e.get("id") or ""
|
||||
url = e.get("url") or (f"https://www.youtube.com/watch?v={video_id}" if video_id else "")
|
||||
image_url = f"https://i.ytimg.com/vi/{video_id}/mqdefault.jpg" if video_id else ""
|
||||
# yt-dlp `upload_date` è YYYYMMDD (stringa). Lo converto in ISO YYYY-MM-DD.
|
||||
# Con --flat-playlist può essere assente; in tal caso resta stringa vuota.
|
||||
raw_date = str(e.get("upload_date") or "").strip()
|
||||
release_date = ""
|
||||
if len(raw_date) == 8 and raw_date.isdigit():
|
||||
release_date = f"{raw_date[0:4]}-{raw_date[4:6]}-{raw_date[6:8]}"
|
||||
elif raw_date:
|
||||
release_date = raw_date # forma sconosciuta, passa così
|
||||
result.append({
|
||||
"id": video_id,
|
||||
"url": url,
|
||||
@@ -70,5 +78,6 @@ def search_youtube(query: str, limit: int = 50) -> list:
|
||||
"channel": e.get("uploader") or e.get("channel") or "",
|
||||
"duration_sec": int(e.get("duration") or 0),
|
||||
"image_url": image_url,
|
||||
"release_date": release_date,
|
||||
})
|
||||
return result
|
||||
Reference in new issue
Block a user