Restrict search to specific backend in ncmpcpp


#1

I’m using mopidy on arch linux with the spotify and youtube backends(possibly intending to add more later), and the ncmpcpp client. Both backends seem to work okay.

However, I can’t figure out how to restrict a search to only one of the backends. In probably 95% cases I only want to search spotify, because most of the music I listen to can be found there. Also, there’s a significant slowdown from searching youtube, as well a large amount of irrelevant search results.

From reading the mopidy documentation, and also the source code, it seems to me that the uri field in the search protocol command serves this function. ncmpcpp has no uri field for search, but it does have a “filename” field, which sends “file” to mopidy. Which, according to the code is an alias for “uri”.

However, when I make a search in my client for, say, artist: pink floyd, filename: spotify, I get no results.

Judging from the debug logs, it seems that mopidy, instead of dispatching to the right backend, simply attempts to search spotify, and complains about not finding a URI. Here is an excerpt from the logs:

https://hastebin.com/sinoxojeka.py

This makes no sense to me. What am I missing?


#2

AFAIK, the MPD protocol provides no way to limit search scope. The “filename” is just a search key, which allows you to search for (local) files by name.


#3

That doesn’t seem to agree with the mopidy API documentation:

If uris is given, the search is limited to results from within the URI roots. For example passing uris=[‘file:’] will limit the search to the local backend.

Examples:

Returns results matching ‘a’ in any backend

search({‘any’: [‘a’]})

Returns results matching artist ‘xyz’ in any backend

search({‘artist’: [‘xyz’]})

Returns results matching ‘a’ and ‘b’ and artist ‘xyz’ in any

backend

search({‘any’: [‘a’, ‘b’], ‘artist’: [‘xyz’]})

Returns results matching ‘a’ if within the given URI roots

“file:///media/music” and “spotify:”

search({‘any’: [‘a’]}, uris=[‘file:///media/music’, ‘spotify:’])

Returns results matching artist ‘xyz’ and ‘abc’ in any backend

search({‘artist’: [‘xyz’, ‘abc’]})


#4

You are quoting the Mopidy core API. The MPD frontend uses Mopidy core to implement the MPD protocol (to some extent) but they are not the same and you’ll find many ways they differ. Mopidy core is directly exposed via the http frontend and you’d have to use that to perform those example queries.

Sounds like maybe you want support for MPD’s base argument:

base restricts the search to songs in the given directory (also relative to the music directory)

(From https://www.musicpd.org/doc/protocol/database.html)

Which I’m pretty sure we have not implemented. While our MPD frontend does have support for file, that must match the full path, so it isn’t what you want (https://docs.mopidy.com/en/latest/modules/mpd/#mopidy.mpd.protocol.music_db.find)


#5

@mtl: I think you’re confusing the uri (singular) query field (which is similar to album, artist, etc.) with the uris (plural) search method parameter, which can be used to limit the scope of the search.


#6

I see, that’s made things clearer, thanks. I’d rather not use the http frontend, since me that would defeat the purpose of using mopidy in the first place(as opposed to spotify web player/youtube.com).

I suppose I can just modify the mpd frontend code to behave the way I want. Seems like it should be simple enough, given that the mopidy core API supports it. I don’t have any need for file/filename/uri, so I’m not worried about breaking the existing behaviour for my own purposes.

Thanks for the help.


#7

Well, it looks like I’ve got it doing what I want it to now. I won’t send a pull request, because this obviously breaks existing behaviour, and is only tended to serve my personal needs. However, in case someone has the same problem as I did, here’s my solution(in mopidy/mpd/protocol/music-db.py):

https://hastebin.com/iqexacezex.py

Other protocol calls might also have to be modified accordingly, depending on use case.