Compare commits
2 commits
main
...
plex-integ
| Author | SHA1 | Date | |
|---|---|---|---|
| b9a288461e | |||
| 56e1061325 |
6 changed files with 133 additions and 3 deletions
35
create_monthly_playlist.py
Normal file
35
create_monthly_playlist.py
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#create_monthly_playlist.py
|
||||||
|
from plex_helpers import create_or_update_playlist
|
||||||
|
from musicbrainz_helpers import load_cache
|
||||||
|
import time
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("Startar spellistgenerator")
|
||||||
|
cache = load_cache()
|
||||||
|
added_artists = cache.get("added_artists", [])
|
||||||
|
added_tracks = cache.get("added_tracks", [])
|
||||||
|
|
||||||
|
print(f"📦 Antal artists i cache: {len(added_artists)}")
|
||||||
|
if not added_artists:
|
||||||
|
print("[PLEX] Ingen artist har lagts till ännu.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not added_artists:
|
||||||
|
print("[PLEX] Ingen artist har lagts till ännu.")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"[PLEX] Skapar spellista för {len(added_artists)} artister...")
|
||||||
|
timestamp = time.strftime("%Y-%m")
|
||||||
|
playlist_name = f"DiscoveryLidarr {timestamp}"
|
||||||
|
|
||||||
|
success, new_tracks = create_or_update_playlist(
|
||||||
|
playlist_name, added_artists, top_n=3, already_added=added_tracks
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
cache["added_tracks"] = list(set(added_tracks + new_tracks))
|
||||||
|
print(f"[PLEX] 🎵 Spellistan '{playlist_name}' skapad med {len(new_tracks)} nya spår.")
|
||||||
|
from musicbrainz_helpers import save_cache
|
||||||
|
save_cache(cache)
|
||||||
|
else:
|
||||||
|
print(f"[PLEX] ❌ Spellistan '{playlist_name}' kunde inte skapas.")
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
## discovery_sync.py
|
||||||
from config import *
|
from config import *
|
||||||
from lastfm_helpers import lf_request, recent_artists
|
from lastfm_helpers import lf_request, recent_artists
|
||||||
from lidarr_helpers import lidarr_api_add_artist
|
from lidarr_helpers import lidarr_api_add_artist
|
||||||
|
|
|
||||||
|
|
@ -45,3 +45,9 @@ def recent_artists():
|
||||||
page += 1
|
page += 1
|
||||||
|
|
||||||
return [(n, m) for (n, m), c in counts.items() if c >= MIN_PLAYS]
|
return [(n, m) for (n, m), c in counts.items() if c >= MIN_PLAYS]
|
||||||
|
|
||||||
|
def get_top_tracks(artist_name, limit=3):
|
||||||
|
res = lf_request("artist.getTopTracks", artist=artist_name, limit=limit)
|
||||||
|
if not res:
|
||||||
|
return []
|
||||||
|
return [t["name"] for t in res.get("toptracks", {}).get("track", [])]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#lidarr_helpers.py
|
||||||
from config import (
|
from config import (
|
||||||
LIDARR_URL,
|
LIDARR_URL,
|
||||||
LIDARR_API_KEY,
|
LIDARR_API_KEY,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#musicbrainz_helpers.py
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
@ -7,12 +8,25 @@ def load_cache():
|
||||||
try:
|
try:
|
||||||
if not CACHE_FILE.exists():
|
if not CACHE_FILE.exists():
|
||||||
with open(CACHE_FILE, "w") as f:
|
with open(CACHE_FILE, "w") as f:
|
||||||
json.dump({"added_artists": [], "similar_cache": {}}, f)
|
json.dump({
|
||||||
|
"added_artists": [],
|
||||||
|
"similar_cache": {},
|
||||||
|
"added_tracks": []
|
||||||
|
}, f)
|
||||||
with open(CACHE_FILE, "r") as f:
|
with open(CACHE_FILE, "r") as f:
|
||||||
return json.load(f)
|
data = json.load(f)
|
||||||
|
data.setdefault("added_artists", [])
|
||||||
|
data.setdefault("similar_cache", {})
|
||||||
|
data.setdefault("added_tracks", [])
|
||||||
|
return data
|
||||||
except Exception:
|
except Exception:
|
||||||
return {"added_artists": [], "similar_cache": {}}
|
return {
|
||||||
|
"added_artists": [],
|
||||||
|
"similar_cache": {},
|
||||||
|
"added_tracks": []
|
||||||
|
}
|
||||||
|
|
||||||
def save_cache(cache):
|
def save_cache(cache):
|
||||||
with open(CACHE_FILE, "w") as f:
|
with open(CACHE_FILE, "w") as f:
|
||||||
json.dump(cache, f, indent=2)
|
json.dump(cache, f, indent=2)
|
||||||
|
|
||||||
|
|
|
||||||
73
plex_helpers.py
Normal file
73
plex_helpers.py
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
# plex_helpers.py
|
||||||
|
import requests
|
||||||
|
from config import PLEX_URL, PLEX_TOKEN
|
||||||
|
from lastfm_helpers import get_top_tracks, lf_request
|
||||||
|
|
||||||
|
HEADERS = {
|
||||||
|
"X-Plex-Token": PLEX_TOKEN
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_artist_name_from_mbid(mbid):
|
||||||
|
js = lf_request("artist.getInfo", mbid=mbid)
|
||||||
|
if js and "artist" in js:
|
||||||
|
return js["artist"]["name"]
|
||||||
|
return None
|
||||||
|
|
||||||
|
def search_track(artist, track):
|
||||||
|
query = f"{artist} {track}"
|
||||||
|
params = {
|
||||||
|
"type": "10", # track
|
||||||
|
"query": query
|
||||||
|
}
|
||||||
|
res = requests.get(f"{PLEX_URL}/search", params=params, headers=HEADERS)
|
||||||
|
res.raise_for_status()
|
||||||
|
return res.json()
|
||||||
|
|
||||||
|
def get_top_tracks_keys(artist_names, top_n=3, already_added=None):
|
||||||
|
if already_added is None:
|
||||||
|
already_added = []
|
||||||
|
|
||||||
|
keys = []
|
||||||
|
for artist in artist_names:
|
||||||
|
top_tracks = get_top_tracks(artist, limit=top_n)
|
||||||
|
for track in top_tracks:
|
||||||
|
try:
|
||||||
|
result = search_track(artist, track)
|
||||||
|
items = result.get("MediaContainer", {}).get("Metadata", [])
|
||||||
|
for item in items:
|
||||||
|
key = item.get("ratingKey")
|
||||||
|
if key and key not in already_added:
|
||||||
|
keys.append(key)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
return keys
|
||||||
|
|
||||||
|
def create_or_update_playlist(name, mbid_list, top_n=3, already_added=None):
|
||||||
|
artist_names = []
|
||||||
|
for mbid in mbid_list:
|
||||||
|
name = get_artist_name_from_mbid(mbid)
|
||||||
|
if name:
|
||||||
|
artist_names.append(name)
|
||||||
|
|
||||||
|
track_keys = get_top_tracks_keys(artist_names, top_n=top_n, already_added=already_added)
|
||||||
|
|
||||||
|
if not track_keys:
|
||||||
|
print("[PLEX] Inga nya spår hittades för de angivna artisterna.")
|
||||||
|
return False, []
|
||||||
|
|
||||||
|
keys_csv = ",".join(track_keys)
|
||||||
|
url = f"{PLEX_URL}/playlists"
|
||||||
|
payload = {
|
||||||
|
"type": "audio",
|
||||||
|
"title": name,
|
||||||
|
"smart": "0",
|
||||||
|
"uri": f"server://{PLEX_TOKEN}/com.plexapp.plugins.library/library/metadata/{keys_csv}"
|
||||||
|
}
|
||||||
|
r = requests.post(url, headers=HEADERS, params=payload)
|
||||||
|
if r.status_code == 201:
|
||||||
|
print(f"[PLEX] ✅ Spellistan '{name}' skapades med {len(track_keys)} spår.")
|
||||||
|
return True, track_keys
|
||||||
|
else:
|
||||||
|
print(f"[PLEX] ❌ Misslyckades med att skapa spellista: {r.text}")
|
||||||
|
return False, []
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue