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