Fix tests broken by knutz3n's search improvements, and sync GstreamerBackend's find_exact() and search()

This commit is contained in:
Stein Magnus Jodal 2010-08-09 12:05:08 +02:00
parent 2897f8e5f6
commit 78f71794e1
4 changed files with 103 additions and 66 deletions

View File

@ -283,12 +283,21 @@ class BaseLibraryController(object):
"""Cleanup after component."""
pass
def find_exact(self, query):
def find_exact(self, **query):
"""
Find tracks in the library where ``field`` matches ``what`` exactly.
Search the library for tracks where ``field`` is ``values``.
:param query: Example: [(u'artist', u'anArtist'), (u'album', u'anAlbum')]
:type query: list of (field, what) tuples.
Examples::
# Returns results matching 'a'
find_exact(any=['a'])
# Returns results matching artist 'xyz'
find_exact(artist=['xyz'])
# Returns results matching 'a' and 'b' and artist 'xyz'
find_exact(any=['a', 'b'], artist=['xyz'])
:param query: one or more queries to search for
:type query: dict
:rtype: :class:`mopidy.models.Playlist`
"""
raise NotImplementedError
@ -318,9 +327,12 @@ class BaseLibraryController(object):
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'
# Returns results matching 'a'
search(any=['a'])
# Returns results matching artist 'xyz'
search(artist=['xyz'])
# Returns results matching 'a' and 'b' and artist 'xyz'
search(any=['a', 'b'], artist=['xyz'])
:param query: one or more queries to search for
:type query: dict

View File

@ -53,6 +53,9 @@ class DespotifyCurrentPlaylistController(BaseCurrentPlaylistController):
class DespotifyLibraryController(BaseLibraryController):
def find_exact(self, **query):
self.search(**query)
def lookup(self, uri):
track = self.backend.spotify.lookup(uri.encode(ENCODING))
return DespotifyTranslator.to_mopidy_track(track)
@ -76,8 +79,6 @@ class DespotifyLibraryController(BaseLibraryController):
return Playlist()
return DespotifyTranslator.to_mopidy_playlist(result.playlist)
find_exact = search
class DespotifyPlaybackController(BasePlaybackController):
def _pause(self):

View File

@ -217,38 +217,55 @@ class GStreamerLibraryController(BaseLibraryController):
except KeyError:
raise LookupError('%s not found.' % uri)
def find_exact(self, query):
for (field, what) in query:
if not what:
raise LookupError('Missing query')
def find_exact(self, **query):
self._validate_query(query)
result_tracks = self._uri_mapping.values()
for (field, what) in query:
if field == 'track':
filter_func = lambda t: t.name == what
elif field == 'album':
filter_func = lambda t: getattr(t, 'album', Album()).name == what
elif field == 'artist':
filter_func = lambda t: filter(lambda a: a.name == what, t.artists)
else:
raise LookupError('Invalid lookup field: %s' % field)
result_tracks = filter(filter_func, result_tracks)
for (field, values) in query.iteritems():
if not hasattr(values, '__iter__'):
values = [values]
# FIXME this is bound to be slow for large libraries
for value in values:
q = value.strip()
track_filter = lambda t: q == t.name
album_filter = lambda t: q == getattr(t, 'album', Album()).name
artist_filter = lambda t: filter(
lambda a: q == a.name, t.artists)
uri_filter = lambda t: q == t.uri
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)
return Playlist(tracks=result_tracks)
def search(self, **query):
self._validate_query(query)
result_tracks = self._uri_mapping.values()
for (field, values) in query:
for (field, values) in query.iteritems():
if not hasattr(values, '__iter__'):
values = [values]
# FIXME this is bound to be slow for large libraries
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)
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)
@ -265,5 +282,12 @@ class GStreamerLibraryController(BaseLibraryController):
result_tracks = filter(any_filter, result_tracks)
else:
raise LookupError('Invalid lookup field: %s' % field)
return Playlist(tracks=result_tracks)
def _validate_query(self, query):
for (field, values) in query.iteritems():
if not values:
raise LookupError('Missing query')
for value in values:
if not value:
raise LookupError('Missing query')

View File

@ -1079,120 +1079,120 @@ class BaseLibraryControllerTest(object):
self.assertRaises(LookupError, test)
def test_find_exact_no_hits(self):
result = self.library.find_exact([('track', 'unknown track')])
result = self.library.find_exact(track=['unknown track'])
self.assertEqual(result, Playlist())
result = self.library.find_exact([('artist', 'unknown artist')])
result = self.library.find_exact(artist=['unknown artist'])
self.assertEqual(result, Playlist())
result = self.library.find_exact([('album', 'unknown artist')])
result = self.library.find_exact(album=['unknown artist'])
self.assertEqual(result, Playlist())
def test_find_exact_artist(self):
result = self.library.find_exact([('artist', 'artist1')])
result = self.library.find_exact(artist=['artist1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.find_exact([('artist', 'artist2')])
result = self.library.find_exact(artist=['artist2'])
self.assertEqual(result, Playlist(tracks=self.tracks[1:2]))
def test_find_exact_track(self):
result = self.library.find_exact([('track', 'track1')])
result = self.library.find_exact(track=['track1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.find_exact([('track', 'track2')])
result = self.library.find_exact(track=['track2'])
self.assertEqual(result, Playlist(tracks=self.tracks[1:2]))
def test_find_exact_album(self):
result = self.library.find_exact([('album', 'album1')])
result = self.library.find_exact(album=['album1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.find_exact([('album', 'album2')])
result = self.library.find_exact(album=['album2'])
self.assertEqual(result, Playlist(tracks=self.tracks[1:2]))
def test_find_exact_wrong_type(self):
test = lambda: self.library.find_exact([('wrong', 'test')])
test = lambda: self.library.find_exact(wrong=['test'])
self.assertRaises(LookupError, test)
def test_find_exact_with_empty_query(self):
test = lambda: self.library.find_exact([('artist', '')])
test = lambda: self.library.find_exact(artist=[''])
self.assertRaises(LookupError, test)
test = lambda: self.library.find_exact([('track', '')])
test = lambda: self.library.find_exact(track=[''])
self.assertRaises(LookupError, test)
test = lambda: self.library.find_exact([('album', '')])
test = lambda: self.library.find_exact(album=[''])
self.assertRaises(LookupError, test)
def test_search_no_hits(self):
result = self.library.search([('track', 'unknown track')])
result = self.library.search(track=['unknown track'])
self.assertEqual(result, Playlist())
result = self.library.search([('artist', 'unknown artist')])
result = self.library.search(artist=['unknown artist'])
self.assertEqual(result, Playlist())
result = self.library.search([('album', 'unknown artist')])
result = self.library.search(album=['unknown artist'])
self.assertEqual(result, Playlist())
result = self.library.search([('uri', 'unknown')])
result = self.library.search(uri=['unknown'])
self.assertEqual(result, Playlist())
result = self.library.search([('any', 'unknown')])
result = self.library.search(any=['unknown'])
self.assertEqual(result, Playlist())
def test_search_artist(self):
result = self.library.search([('artist', 'Tist1')])
result = self.library.search(artist=['Tist1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.search([('artist', 'Tist2')])
result = self.library.search(artist=['Tist2'])
self.assertEqual(result, Playlist(tracks=self.tracks[1:2]))
def test_search_track(self):
result = self.library.search([('track', 'Rack1')])
result = self.library.search(track=['Rack1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.search([('track', 'Rack2')])
result = self.library.search(track=['Rack2'])
self.assertEqual(result, Playlist(tracks=self.tracks[1:2]))
def test_search_album(self):
result = self.library.search([('album', 'Bum1')])
result = self.library.search(album=['Bum1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.search([('album', 'Bum2')])
result = self.library.search(album=['Bum2'])
self.assertEqual(result, Playlist(tracks=self.tracks[1:2]))
def test_search_uri(self):
result = self.library.search([('uri', 'RI1')])
result = self.library.search(uri=['RI1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.search([('uri', 'RI2')])
result = self.library.search(uri=['RI2'])
self.assertEqual(result, Playlist(tracks=self.tracks[1:2]))
def test_search_any(self):
result = self.library.search([('any', 'Tist1')])
result = self.library.search(any=['Tist1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.search([('any', 'Rack1')])
result = self.library.search(any=['Rack1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.search([('any', 'Bum1')])
result = self.library.search(any=['Bum1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
result = self.library.search([('any', 'RI1')])
result = self.library.search(any=['RI1'])
self.assertEqual(result, Playlist(tracks=self.tracks[:1]))
def test_search_wrong_type(self):
test = lambda: self.library.search([('wrong', 'test')])
test = lambda: self.library.search(wrong=['test'])
self.assertRaises(LookupError, test)
def test_search_with_empty_query(self):
test = lambda: self.library.search([('artist', '')])
test = lambda: self.library.search(artist=[''])
self.assertRaises(LookupError, test)
test = lambda: self.library.search([('track', '')])
test = lambda: self.library.search(track=[''])
self.assertRaises(LookupError, test)
test = lambda: self.library.search([('album', '')])
test = lambda: self.library.search(album=[''])
self.assertRaises(LookupError, test)
test = lambda: self.library.search([('uri', '')])
test = lambda: self.library.search(uri=[''])
self.assertRaises(LookupError, test)
test = lambda: self.library.search([('any', '')])
test = lambda: self.library.search(any=[''])
self.assertRaises(LookupError, test)