change search to use kwargs with value lists as search queries
This commit is contained in:
parent
b9a7ed5ec6
commit
9d628eefb7
@ -312,14 +312,18 @@ class BaseLibraryController(object):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def search(self, query):
|
||||
def search(self, **query):
|
||||
"""
|
||||
Search the library for tracks where ``field`` contains ``query``.
|
||||
Search the library for tracks where ``field`` contains ``values``.
|
||||
|
||||
:param field: 'track', 'artist', 'album', 'uri', and 'any'
|
||||
:type field: string
|
||||
:param query: the search query
|
||||
:type query: string
|
||||
Examples::
|
||||
|
||||
search(any=['a']) # Returns results matching 'a'
|
||||
search(artist=['xyz']) # Returns results matching artist 'xyz'
|
||||
search(any=['a', 'b'], artist=['xyz']) # Returns results matching 'a' and 'b' and artist 'xyz'
|
||||
|
||||
:param query: one or more queries to search for
|
||||
:type query: dict
|
||||
:rtype: :class:`mopidy.models.Playlist`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@ -58,15 +58,18 @@ class DespotifyLibraryController(BaseLibraryController):
|
||||
track = self.backend.spotify.lookup(uri.encode(ENCODING))
|
||||
return DespotifyTranslator.to_mopidy_track(track)
|
||||
|
||||
def search(self, query):
|
||||
def search(self, **query):
|
||||
spotify_query = []
|
||||
for (field, what) in query:
|
||||
if field == u'track':
|
||||
field = u'title'
|
||||
if field is u'any':
|
||||
spotify_query.append(what)
|
||||
else:
|
||||
spotify_query.append(u'%s:"%s"' % (field, what))
|
||||
for (field, values) in query.iteritems():
|
||||
if not hasattr(values, '__iter__'):
|
||||
values = [values]
|
||||
for value in values:
|
||||
if field == u'track':
|
||||
field = u'title'
|
||||
if field is u'any':
|
||||
spotify_query.append(value)
|
||||
else:
|
||||
spotify_query.append(u'%s:"%s"' % (field, value))
|
||||
spotify_query = u' '.join(query)
|
||||
result = self.backend.spotify.search(spotify_query.encode(ENCODING))
|
||||
if (result is None or result.playlist.tracks[0].get_uri() ==
|
||||
|
||||
@ -30,7 +30,7 @@ class DummyLibraryController(BaseLibraryController):
|
||||
if matches:
|
||||
return matches[0]
|
||||
|
||||
def search(self, query):
|
||||
def search(self, **query):
|
||||
return Playlist()
|
||||
|
||||
find_exact = search
|
||||
|
||||
@ -236,35 +236,34 @@ class GStreamerLibraryController(BaseLibraryController):
|
||||
result_tracks = filter(filter_func, result_tracks)
|
||||
return Playlist(tracks=result_tracks)
|
||||
|
||||
def search(self, query):
|
||||
for (field, what) in query:
|
||||
if not what:
|
||||
raise LookupError('Missing query')
|
||||
|
||||
def search(self, **query):
|
||||
result_tracks = self._uri_mapping.values()
|
||||
for (field, what) in query:
|
||||
q = what.strip().lower()
|
||||
for (field, values) in query:
|
||||
if not hasattr(values, '__iter__'):
|
||||
values = [values]
|
||||
for value in values:
|
||||
q = value.strip().lower()
|
||||
|
||||
# FIXME this is bound to be slow for large libraries
|
||||
track_filter = lambda t: q in t.name.lower()
|
||||
album_filter = lambda t: q in getattr(t, 'album', Album()).name.lower()
|
||||
artist_filter = lambda t: filter(lambda a: q in a.name.lower(),
|
||||
t.artists)
|
||||
uri_filter = lambda t: q in t.uri.lower()
|
||||
any_filter = lambda t: track_filter(t) or album_filter(t) or \
|
||||
artist_filter(t) or uri_filter(t)
|
||||
# FIXME this is bound to be slow for large libraries
|
||||
track_filter = lambda t: q in t.name.lower()
|
||||
album_filter = lambda t: q in getattr(t, 'album', Album()).name.lower()
|
||||
artist_filter = lambda t: filter(lambda a: q in a.name.lower(),
|
||||
t.artists)
|
||||
uri_filter = lambda t: q in t.uri.lower()
|
||||
any_filter = lambda t: track_filter(t) or album_filter(t) or \
|
||||
artist_filter(t) or uri_filter(t)
|
||||
|
||||
if field == 'track':
|
||||
result_tracks = filter(track_filter, result_tracks)
|
||||
elif field == 'album':
|
||||
result_tracks = filter(album_filter, result_tracks)
|
||||
elif field == 'artist':
|
||||
result_tracks = filter(artist_filter, result_tracks)
|
||||
elif field == 'uri':
|
||||
result_tracks = filter(uri_filter, result_tracks)
|
||||
elif field == 'any':
|
||||
result_tracks = filter(any_filter, result_tracks)
|
||||
else:
|
||||
raise LookupError('Invalid lookup field: %s' % field)
|
||||
if field == 'track':
|
||||
result_tracks = filter(track_filter, result_tracks)
|
||||
elif field == 'album':
|
||||
result_tracks = filter(album_filter, result_tracks)
|
||||
elif field == 'artist':
|
||||
result_tracks = filter(artist_filter, result_tracks)
|
||||
elif field == 'uri':
|
||||
result_tracks = filter(uri_filter, result_tracks)
|
||||
elif field == 'any':
|
||||
result_tracks = filter(any_filter, result_tracks)
|
||||
else:
|
||||
raise LookupError('Invalid lookup field: %s' % field)
|
||||
|
||||
return Playlist(tracks=result_tracks)
|
||||
|
||||
@ -69,13 +69,18 @@ class LibspotifyLibraryController(BaseLibraryController):
|
||||
spotify_track = Link.from_string(uri).as_track()
|
||||
return LibspotifyTranslator.to_mopidy_track(spotify_track)
|
||||
|
||||
def search(self, query):
|
||||
def search(self, **query):
|
||||
spotify_query = []
|
||||
for (field, what) in query:
|
||||
if field is u'any':
|
||||
spotify_query.append(what)
|
||||
else:
|
||||
spotify_query.append(u'%s:"%s"' % (field, what))
|
||||
for (field, values) in query.iteritems():
|
||||
if not hasattr(values, '__iter__'):
|
||||
values = [values]
|
||||
for value in values:
|
||||
if field == u'track':
|
||||
field = u'title'
|
||||
if field is u'any':
|
||||
spotify_query.append(value)
|
||||
else:
|
||||
spotify_query.append(u'%s:"%s"' % (field, value))
|
||||
spotify_query = u' '.join(spotify_query)
|
||||
logger.debug(u'In search method, search for: %s' % spotify_query)
|
||||
my_end, other_end = multiprocessing.Pipe()
|
||||
|
||||
@ -118,14 +118,17 @@ class MpdFrontend(object):
|
||||
query_part_pattern = (
|
||||
r'"?(?P<field>([Aa]lbum|[Aa]rtist|[Ff]ilename|[Tt]itle|[Aa]ny))"?\s'
|
||||
r'"(?P<what>[^"]+)"')
|
||||
query = []
|
||||
query = {}
|
||||
for query_part in query_parts:
|
||||
m = re.match(query_part_pattern, query_part)
|
||||
field = m.groupdict()['field'].lower()
|
||||
if field == u'title':
|
||||
field = u'track'
|
||||
what = m.groupdict()['what'].lower()
|
||||
query.append((field, what))
|
||||
if field in query:
|
||||
query[field].append(what)
|
||||
else:
|
||||
query[field] = [what]
|
||||
return query
|
||||
|
||||
@handle_pattern(r'^disableoutput "(?P<outputid>\d+)"$')
|
||||
@ -646,7 +649,7 @@ class MpdFrontend(object):
|
||||
- capitalizes the type argument.
|
||||
"""
|
||||
query = self._build_query(mpd_query)
|
||||
return self.backend.library.find_exact(query).mpd_format()
|
||||
return self.backend.library.find_exact(**query).mpd_format()
|
||||
|
||||
@handle_pattern(r'^findadd '
|
||||
r'(?P<query>("?([Aa]lbum|[Aa]rtist|[Ff]ilename|[Tt]itle|[Aa]ny)"? "[^"]+"\s?)+)$')
|
||||
@ -722,7 +725,7 @@ class MpdFrontend(object):
|
||||
return artists
|
||||
|
||||
def __music_db_list_album_artist(self, artist):
|
||||
playlist = self.backend.library.find_exact([(u'artist', artist)])
|
||||
playlist = self.backend.library.find_exact(artist=[artist])
|
||||
albums = set()
|
||||
for track in playlist.tracks:
|
||||
albums.add((u'Album', track.album.name))
|
||||
@ -810,7 +813,7 @@ class MpdFrontend(object):
|
||||
- capitalizes the field argument.
|
||||
"""
|
||||
query = self._build_query(mpd_query)
|
||||
return self.backend.library.search(query).mpd_format()
|
||||
return self.backend.library.search(**query).mpd_format()
|
||||
|
||||
@handle_pattern(r'^update( "(?P<uri>[^"]+)")*$')
|
||||
def _music_db_update(self, uri=None, rescan_unmodified_files=False):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user