bridge: metodi Api per tab Charts + bump v1.12.0
- api.charts_fetch(payload): dispatcher unico su iTunes/Last.fm/Spotify/
M2O, persiste la sorgente/params scelti in config, ritorna
{ok, source, entries}
- api.charts_add_to_queue(entries): normalizza le entry selezionate in
tracklist "Artista - Titolo" ed emette l'evento `charts:add_to_queue`
che la UI aggancia per popolare la tab Scarica
- config.DEFAULTS: aggiunte chiavi charts_last_source, charts_itunes_
country, charts_lastfm_decade/genre, charts_spotify_playlist,
lastfm_api_key
- VERSION -> v1.12.0
This commit is contained in:
1 parent
75e3da5f82
commit
29c177ff69
2 files changed
+114
-1
No files matched your search
+106
@@ -49,6 +49,7 @@ from core.upgrader import (
|
||||
from core import dedup
|
||||
from core import catalog
|
||||
from core import flatten
|
||||
from core import charts
|
||||
|
||||
|
||||
SPOTIFY_GUIDE_TEXT = """\
|
||||
@@ -2263,3 +2264,108 @@ class Api:
|
||||
"n_matched": n_matched,
|
||||
"n_unmatched": n_unmatched,
|
||||
})
|
||||
|
||||
# ================================================================
|
||||
# CHARTS — classifiche musicali (iTunes / Spotify / M2O / Last.fm)
|
||||
# ================================================================
|
||||
def charts_fetch(self, payload: dict) -> dict:
|
||||
"""Ritorna le entry di una chart per la sorgente/params richiesti.
|
||||
|
||||
Payload:
|
||||
{
|
||||
source: "itunes" | "spotify" | "m2o" | "lastfm",
|
||||
country?: "it"|"us"|"gb"|"ww", # solo itunes
|
||||
playlist_key?: str, # solo spotify (chiave _SPOTIFY_CHARTS)
|
||||
decade?: str, # solo lastfm ("" | "70s"|"80s"|...)
|
||||
genre?: str, # solo lastfm ("" | pop|rock|dance|...)
|
||||
force?: bool, # bypass cache
|
||||
}
|
||||
Persiste anche la scelta corrente in config.
|
||||
"""
|
||||
payload = payload or {}
|
||||
source = (payload.get("source") or "itunes").strip().lower()
|
||||
force = bool(payload.get("force", False))
|
||||
|
||||
# Persist scelta corrente (best-effort, non blocca la fetch)
|
||||
try:
|
||||
cfg = load_config()
|
||||
cfg["charts_last_source"] = source
|
||||
if source == "itunes":
|
||||
cfg["charts_itunes_country"] = (
|
||||
payload.get("country") or cfg.get("charts_itunes_country") or "it"
|
||||
)
|
||||
elif source == "lastfm":
|
||||
cfg["charts_lastfm_decade"] = (
|
||||
payload.get("decade") if payload.get("decade") is not None
|
||||
else cfg.get("charts_lastfm_decade", "90s")
|
||||
)
|
||||
cfg["charts_lastfm_genre"] = (
|
||||
payload.get("genre") if payload.get("genre") is not None
|
||||
else cfg.get("charts_lastfm_genre", "dance")
|
||||
)
|
||||
elif source == "spotify":
|
||||
cfg["charts_spotify_playlist"] = (
|
||||
payload.get("playlist_key")
|
||||
or cfg.get("charts_spotify_playlist")
|
||||
or "top50_global"
|
||||
)
|
||||
save_config(cfg)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
if source == "itunes":
|
||||
country = (payload.get("country") or "it").strip().lower() or "it"
|
||||
entries = charts.fetch_itunes(country, force=force)
|
||||
elif source == "lastfm":
|
||||
decade = payload.get("decade") or ""
|
||||
genre = payload.get("genre") or ""
|
||||
entries = charts.fetch_lastfm(decade, genre, force=force)
|
||||
elif source == "spotify":
|
||||
playlist_key = (payload.get("playlist_key") or "top50_global").strip()
|
||||
entries = charts.fetch_spotify(playlist_key, force=force)
|
||||
elif source == "m2o":
|
||||
entries = charts.fetch_m2o(force=force)
|
||||
else:
|
||||
return {"ok": False, "error": f"Sorgente sconosciuta: {source}"}
|
||||
except Exception as e:
|
||||
self._log("charts", f"[ERRORE] fetch {source}: {e}")
|
||||
return {"ok": False, "error": str(e)}
|
||||
|
||||
self._log("charts", f"[INFO] {source}: {len(entries)} brani ricevuti")
|
||||
return {"ok": True, "source": source, "entries": entries}
|
||||
|
||||
def charts_add_to_queue(self, entries: list) -> dict:
|
||||
"""Riceve una lista di entry `{artist, title}` selezionate dalla UI
|
||||
e le converte in una tracklist compatibile con la tab Scarica.
|
||||
|
||||
Emette l'evento `charts:add_to_queue` col testo formattato
|
||||
(`Artista - Titolo` una per riga) e la lista strutturata. La UI
|
||||
popola l'input della tab Scarica e commuta view.
|
||||
"""
|
||||
if not isinstance(entries, list):
|
||||
return {"ok": False, "error": "entries deve essere una lista"}
|
||||
|
||||
tracks = []
|
||||
lines = []
|
||||
for e in entries:
|
||||
if not isinstance(e, dict):
|
||||
continue
|
||||
artist = (e.get("artist") or "").strip()
|
||||
title = (e.get("title") or "").strip()
|
||||
if not title:
|
||||
continue
|
||||
tracks.append({"artist": artist, "name": title})
|
||||
if artist:
|
||||
lines.append(f"{artist} - {title}")
|
||||
else:
|
||||
lines.append(title)
|
||||
|
||||
if not tracks:
|
||||
return {"ok": False, "error": "Nessun brano valido selezionato"}
|
||||
|
||||
text = "\n".join(lines)
|
||||
payload = {"text": text, "count": len(tracks), "tracks": tracks}
|
||||
self._emit("charts:add_to_queue", payload)
|
||||
self._log("charts", f"[INFO] {len(tracks)} brani inviati alla coda Scarica")
|
||||
return {"ok": True, "count": len(tracks)}
|
||||
+8
-1
@@ -5,7 +5,7 @@ import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
VERSION = "v1.11.3"
|
||||
VERSION = "v1.12.0"
|
||||
|
||||
|
||||
APP_NAME = "MusicTools"
|
||||
@@ -88,6 +88,13 @@ DEFAULTS = {
|
||||
"catalog_last_target": "",
|
||||
"catalog_recursive": True,
|
||||
"acoustid_app_key": "", # opzionale: se vuoto usa default in core/acoustid.py
|
||||
# ---- Charts (iTunes RSS + Last.fm + Spotify + M2O) ----
|
||||
"charts_last_source": "itunes", # "itunes" | "spotify" | "m2o" | "lastfm"
|
||||
"charts_itunes_country": "it", # "it" | "us" | "gb" | "ww"
|
||||
"charts_lastfm_decade": "90s", # "" | "70s" | "80s" | "90s" | "2000s" | "2010s"
|
||||
"charts_lastfm_genre": "dance", # "" | pop, rock, dance, ...
|
||||
"charts_spotify_playlist": "top50_global", # chiave in charts._SPOTIFY_CHARTS
|
||||
"lastfm_api_key": "", # opzionale: override della chiave demo
|
||||
# ---- Licenza ----
|
||||
"license_key": "", # chiave fornita all'utente via email
|
||||
"license_email": "", # email associata all'acquisto
|
||||
|
||||
Reference in new issue
Block a user