init
This commit is contained in:
commit
3a770365c5
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
env/
|
38
README.md
Normal file
38
README.md
Normal file
|
@ -0,0 +1,38 @@
|
|||
slskd-musicsearch
|
||||
=================
|
||||
|
||||
A small library to query for a release ID from musicbrainz, then locate and queue downloads for the tracks in that release on an instance of slskd
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
* Install `musicbrainzngs` and `slskd-api` from pypi with `pip3 install 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.
|
||||
|
||||
tl;dr
|
||||
-----
|
||||
|
||||
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)
|
||||
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.
|
||||
|
||||
```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
|
||||
```
|
74
slskdsearch.py
Normal file
74
slskdsearch.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/env python3
|
||||
import musicbrainzngs
|
||||
from slskd_api import SlskdClient
|
||||
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",""))
|
||||
|
||||
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"]
|
||||
tracks = []
|
||||
for medium in result["medium-list"]:
|
||||
for track in medium["track-list"]:
|
||||
tracks.append({
|
||||
"title": track["recording"]["title"],
|
||||
"alttitle": track["recording"].get("work-relation-list",[{}])[0].get("work",{}).get("title"),
|
||||
"length": track["length"]
|
||||
})
|
||||
return {
|
||||
"title": result["title"],
|
||||
"artist": result["artist-credit-phrase"],
|
||||
"tracks": tracks
|
||||
}
|
||||
|
||||
def san(inp):
|
||||
return inp.replace("\u2019","").replace(",","").replace("'","") if inp else None
|
||||
|
||||
def search(album):
|
||||
search = None
|
||||
query = f"{album['artist']} - {album['title']} flac"
|
||||
previous_searches = slskd.searches.get_all()
|
||||
for s in previous_searches:
|
||||
if s["searchText"] == query:
|
||||
print(query, s)
|
||||
search = s
|
||||
if not search:
|
||||
search = slskd.searches.search_text(f"{album['artist']} - {album['title']} flac")
|
||||
try:
|
||||
while not slskd.searches.state(search["id"])["isComplete"]:
|
||||
sleep(0.5)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
results = slskd.searches.search_responses(search["id"])
|
||||
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)
|
||||
matches = 0
|
||||
resp = {"username": result["username"], "files": []}
|
||||
for f in result["files"]:
|
||||
fn = (f["filename"].split("\\")[-1])
|
||||
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):
|
||||
del track_names[n]
|
||||
resp["files"].append(f)
|
||||
matches += 1
|
||||
if not track_names:
|
||||
break
|
||||
if matches == len([track["title"] for track in album["tracks"]]):
|
||||
slskd.transfers.enqueue(**resp)
|
||||
slskd.searches.delete(search["id"])
|
||||
return True
|
||||
if not matches:
|
||||
continue
|
||||
resp["matches"] = matches
|
||||
lookup.append(resp)
|
||||
return search["id"]
|
Loading…
Reference in a new issue