diff --git a/mopidy/backends/spotify/library.py b/mopidy/backends/spotify/library.py index df04058b..f451a93a 100644 --- a/mopidy/backends/spotify/library.py +++ b/mopidy/backends/spotify/library.py @@ -1,8 +1,8 @@ from __future__ import unicode_literals import logging -import Queue +import pykka from spotify import Link, SpotifyError from mopidy.backends import base @@ -67,14 +67,46 @@ class SpotifyLibraryProvider(base.BaseLibraryProvider): def search(self, **query): if not query: - # Since we can't search for the entire Spotify library, we return - # all tracks in the playlists when the query is empty. - tracks = [] - for playlist in self.backend.playlists.playlists: - tracks += playlist.tracks - return tracks + return self._get_all_tracks() + + spotify_query = self._translate_search_query(query) + logger.debug('Spotify search query: %s' % spotify_query) + + future = pykka.ThreadingFuture() + + def callback(results, userdata=None): + # TODO Include results from results.albums(), etc. too + # TODO Consider launching a second search if results.total_tracks() + # is larger than len(results.tracks()) + tracks = [ + translator.to_mopidy_track(t) for t in results.tracks()] + future.set(tracks) + + self.backend.spotify.connected.wait() + + self.backend.spotify.session.search( + spotify_query, callback, + track_count=100, album_count=0, artist_count=0) + + timeout = 10 # TODO Make this a setting + try: + return future.get(timeout=timeout) + except pykka.Timeout: + logger.debug( + 'Timeout: Spotify search did not return in %ds', timeout) + return [] + + def _get_all_tracks(self): + # Since we can't search for the entire Spotify library, we return + # all tracks in the playlists when the query is empty. + tracks = [] + for playlist in self.backend.playlists.playlists: + tracks += playlist.tracks + return tracks + + def _translate_search_query(self, mopidy_query): spotify_query = [] - for (field, values) in query.iteritems(): + for (field, values) in mopidy_query.iteritems(): if field == 'uri': tracks = [] for value in values: @@ -97,10 +129,4 @@ class SpotifyLibraryProvider(base.BaseLibraryProvider): else: spotify_query.append('%s:"%s"' % (field, value)) spotify_query = ' '.join(spotify_query) - logger.debug('Spotify search query: %s' % spotify_query) - queue = Queue.Queue() - self.backend.spotify.search(spotify_query, queue) - try: - return queue.get(timeout=3) # XXX What is an reasonable timeout? - except Queue.Empty: - return [] + return spotify_query diff --git a/mopidy/backends/spotify/session_manager.py b/mopidy/backends/spotify/session_manager.py index 288c61f2..f2631406 100644 --- a/mopidy/backends/spotify/session_manager.py +++ b/mopidy/backends/spotify/session_manager.py @@ -165,19 +165,6 @@ class SpotifySessionManager(process.BaseThread, PyspotifySessionManager): logger.info('Loaded %d Spotify playlist(s)', len(playlists)) BackendListener.send('playlists_loaded') - def search(self, query, queue): - """Search method used by Mopidy backend""" - def callback(results, userdata=None): - # TODO Include results from results.albums(), etc. too - # TODO Consider launching a second search if results.total_tracks() - # is larger than len(results.tracks()) - tracks = [ - translator.to_mopidy_track(t) for t in results.tracks()] - queue.put(tracks) - self.connected.wait() - self.session.search( - query, callback, track_count=100, album_count=0, artist_count=0) - def logout(self): """Log out from spotify""" logger.debug('Logging out from Spotify')