Added lidarr support

This commit is contained in:
alyssadev 2023-09-20 22:55:15 +10:00
parent 3a770365c5
commit 341da492bf
2 changed files with 70 additions and 20 deletions

View file

@ -6,33 +6,34 @@ A small library to query for a release ID from musicbrainz, then locate and queu
Installation
------------
* Install `musicbrainzngs` and `slskd-api` from pypi with `pip3 install musicbrainzngs slskd-api`
* Install `requests`, `musicbrainzngs`, `slskd-api` from pypi with `pip3 install requests musicbrainzngs slskd-api`
* Copy the functions in `slskdsearch.py`, or the file itself, into your project (it's MIT license).
* Set the environment variables `SLSKD_HOST` and `SLSKD_KEY` to the path to your slskd instance (`http://hostname:port`) and your [API key for slskd](https://github.com/slskd/slskd/blob/master/docs/config.md#authentication) respectively, or edit the values in the definition for the `slskd` variable.
* Set the environment variables `LIDARR_HOST` and `LIDARR_KEY` to the path to your lidarr instance (`http://hostname:port`) and your API key for lidarr respectively, or edit the values for the `lidarr` variable.
tl;dr
Usage
-----
do the above installation, then run `python3 -i slskdsearch.py`, then find the release ID for the album you want (not the release-group, one of the listed releases, probably the US CD release for western music) and run
```python
album = get_album(pasted_id)
release_id = "pasted_id"
album = get_album(release_id)
search(album)
```
check slskd/searches to see the search progress, if it's successful it'll queue the files under /downloads and delete the search, if it's unsuccessful it'll show the search ID and you'll have to manually select files because it couldn't do it automatically sorry
Usage
-----
Locate the release ID for the specific version of the album you want. One way you can do this is, go to https://musicbrainz.org/, in the top right search box search for the artist, find the correct artist from the search results, find the correct album in the list, then in the release group for that album you should probably find the release that says CD in the format column and says either US or your country in the country column. The release ID is after `/release/` in that url.
You can also now tell lidarr to create an entry for the album and artist with
```python
from slskdsearch import get_album, search # skip this if you've copied the functions into your project
MBID = "2e789ca4-020c-37ec-9f64-236c9ae1bd5f"
album = get_album(MBID)
search(album)
# while this is running, check the searches list on slskd, you should see the search progress
# if the search was successful, the function will return True, and the full album will be downloading in the download list in slskd
# if the search was not successful or was not entirely successful, the function will return the search ID, and you should go to /searches/<search ID> in slskd to manually select the files you want
lidarr_album = add_album_to_lidarr(release_id)
```
So far I haven't been able to get Lidarr to import the files from my unsorted folder automatically, you'll want to go to `/wanted/missing`, click Manual Import, and import it like that. But after that you can use
```python
lidarr_retag(lidarr_album["artist"]["id"])
```
to trigger Lidarr to update the metadata in the files. And then your music server should pick up the new files and all should be fine and/or dandy.

View file

@ -1,18 +1,22 @@
#!/usr/bin/env python3
import musicbrainzngs
from slskd_api import SlskdClient
from requests import get, post
from time import sleep
from os import environ
musicbrainzngs.set_useragent("slskd-musicsearch", "0.1", "https://github.com/alyssadev/slskd-musicsearch")
slskd = SlskdClient(environ.get("SLSKD_HOST","http://localhost:5030"), environ.get("SLSKD_KEY",""))
lidarr = environ.get("LIDARR_HOST","http://localhost:8686"), environ.get("LIDARR_KEY","")
def print_json(d):
from json import dumps
print(dumps(d,indent=4))
def get_album(mbid):
result = musicbrainzngs.get_release_by_id(mbid, includes=["artists", "recordings", "recording-level-rels", "work-rels", "work-level-rels"])["release"]
def get_album(release_id):
result = musicbrainzngs.get_release_by_id(release_id, includes=["artists", "recordings", "recording-level-rels", "work-rels", "work-level-rels"])["release"]
tracks = []
for medium in result["medium-list"]:
for track in medium["track-list"]:
@ -36,7 +40,7 @@ def search(album):
previous_searches = slskd.searches.get_all()
for s in previous_searches:
if s["searchText"] == query:
print(query, s)
# print(query, s)
search = s
if not search:
search = slskd.searches.search_text(f"{album['artist']} - {album['title']} flac")
@ -49,12 +53,12 @@ def search(album):
lookup = []
for result in results:
track_names = {n:(san(track["title"]),san(track["alttitle"])) for n,track in enumerate(album["tracks"])}
print_json(track_names)
# print_json(track_names)
matches = 0
resp = {"username": result["username"], "files": []}
for f in result["files"]:
fn = (f["filename"].split("\\")[-1])
print(fn)
# print(fn)
_track_names = dict(track_names)
for n,title in _track_names.items():
if f"{title[0]}.flac" in fn or (f"{title[1]}.flac" in fn if title[1] else False):
@ -64,11 +68,56 @@ def search(album):
if not track_names:
break
if matches == len([track["title"] for track in album["tracks"]]):
print(resp)
slskd.transfers.enqueue(**resp)
slskd.searches.delete(search["id"])
#slskd.searches.delete(search["id"])
return True
if not matches:
continue
resp["matches"] = matches
lookup.append(resp)
return search["id"]
def lidarr_get(endpoint, *args, **kwargs):
if not "headers" in kwargs:
kwargs["headers"] = {}
kwargs["headers"]["X-Api-Key"] = lidarr[1]
return get(lidarr[0] + endpoint, *args, **kwargs).json()
def lidarr_post(endpoint, *args, **kwargs):
if not "headers" in kwargs:
kwargs["headers"] = {}
kwargs["headers"]["X-Api-Key"] = lidarr[1]
return post(lidarr[0] + endpoint, *args, **kwargs).json()
def lidarr_get_root_folder(index: int=0):
root_folder = lidarr_get("/api/v1/rootFolder")
if type(root_folder) is list:
root_folder = root_folder[index]
return root_folder
def add_album_to_lidarr(release_id, root_folder_index: int=0):
release_group_id = musicbrainzngs.get_release_by_id(release_id,includes=["release-groups"])["release"]["release-group"]["id"]
lidarr_search = lidarr_get("/api/v1/search", params={"term": f"lidarr:{release_group_id}"})
lidarr_album = lidarr_search[0]["album"]
lidarr_album["monitored"] = True
lidarr_album["addOptions"] = {"searchForNewAlbum": False}
lidarr_album["artist"]["monitored"] = True
lidarr_album["artist"]["addOptions"] = {"monitor": "missing", "searchForMissingAlbums": False}
print_json(lidarr_album)
root_folder = lidarr_get_root_folder(root_folder_index)
print_json(root_folder)
# bring in values configured on root folder
lidarr_album["artist"]["metadataProfileId"] = root_folder["defaultMetadataProfileId"]
lidarr_album["artist"]["qualityProfileId"] = root_folder["defaultQualityProfileId"]
lidarr_album["artist"]["rootFolderPath"] = root_folder["path"]
return lidarr_post("/api/v1/album", json=lidarr_album)
def lidarr_import(root_folder):
# currently not working
return lidarr_post("/api/v1/command", json={"name": "DownloadedAlbumsScan", "path": root_folder["path"]})
def lidarr_retag(artist_id):
retag_list = lidarr_get("/api/v1/retag", params={"artistId": artist_id})
retag_data = {"artistId": artist_id, "files": [t["trackFileId"] for t in retag_list], "name": "RetagFiles"}
return lidarr_post("/api/v1/command", json=retag_data)