change search to use kwargs with value lists as search queries

This commit is contained in:
Johannes Knutsen 2010-08-09 09:46:31 +02:00
parent b9a7ed5ec6
commit 9d628eefb7
6 changed files with 67 additions and 53 deletions

View File

@ -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

View File

@ -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() ==

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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):