libspotify: Move all data translation into pyspotify thread. Rewrite search.
This commit is contained in:
parent
0c5c88e04f
commit
e8d4f01382
@ -1,5 +1,6 @@
|
|||||||
import datetime as dt
|
import datetime as dt
|
||||||
import logging
|
import logging
|
||||||
|
import multiprocessing
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from spotify import Link
|
from spotify import Link
|
||||||
@ -44,7 +45,6 @@ class LibspotifyBackend(BaseBackend):
|
|||||||
self.stored_playlists = LibspotifyStoredPlaylistsController(
|
self.stored_playlists = LibspotifyStoredPlaylistsController(
|
||||||
backend=self)
|
backend=self)
|
||||||
self.uri_handlers = [u'spotify:', u'http://open.spotify.com/']
|
self.uri_handlers = [u'spotify:', u'http://open.spotify.com/']
|
||||||
self.translate = LibspotifyTranslator()
|
|
||||||
self.spotify = self._connect()
|
self.spotify = self._connect()
|
||||||
|
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
@ -61,27 +61,19 @@ class LibspotifyCurrentPlaylistController(BaseCurrentPlaylistController):
|
|||||||
|
|
||||||
|
|
||||||
class LibspotifyLibraryController(BaseLibraryController):
|
class LibspotifyLibraryController(BaseLibraryController):
|
||||||
_search_results = None
|
|
||||||
_search_results_received = threading.Event()
|
|
||||||
|
|
||||||
def search(self, type, what):
|
def search(self, type, what):
|
||||||
# FIXME When searching while playing music, this is really slow, like
|
|
||||||
# 12-14s between querying and getting results.
|
|
||||||
self._search_results_received.clear()
|
|
||||||
if type is u'any':
|
if type is u'any':
|
||||||
query = what
|
query = what
|
||||||
else:
|
else:
|
||||||
query = u'%s:%s' % (type, what)
|
query = u'%s:%s' % (type, what)
|
||||||
def callback(results, userdata):
|
my_end, other_end = multiprocessing.Pipe()
|
||||||
logger.debug(u'Search results received')
|
self.backend.spotify.search(query.encode(ENCODING), other_end)
|
||||||
self._search_results = results
|
my_end.poll(None)
|
||||||
self._search_results_received.set()
|
logger.debug(u'In search method, receiving search results')
|
||||||
self.backend.spotify.search(query.encode(ENCODING), callback)
|
playlist = my_end.recv()
|
||||||
self._search_results_received.wait()
|
logger.debug(u'In search method, done receiving search results')
|
||||||
result = Playlist(tracks=[self.backend.translate.to_mopidy_track(t)
|
logger.debug(['%s' % t.name for t in playlist.tracks])
|
||||||
for t in self._search_results.tracks()])
|
return playlist
|
||||||
self._search_results = None
|
|
||||||
return result
|
|
||||||
|
|
||||||
find_exact = search
|
find_exact = search
|
||||||
|
|
||||||
@ -111,16 +103,7 @@ class LibspotifyPlaybackController(BasePlaybackController):
|
|||||||
|
|
||||||
|
|
||||||
class LibspotifyStoredPlaylistsController(BaseStoredPlaylistsController):
|
class LibspotifyStoredPlaylistsController(BaseStoredPlaylistsController):
|
||||||
def refresh(self):
|
pass
|
||||||
logger.info(u'Refreshing stored playlists')
|
|
||||||
playlists = []
|
|
||||||
for spotify_playlist in self.backend.spotify.playlists:
|
|
||||||
playlists.append(
|
|
||||||
self.backend.translate.to_mopidy_playlist(spotify_playlist))
|
|
||||||
self._playlists = playlists
|
|
||||||
logger.debug(u'Available playlists: %s',
|
|
||||||
u', '.join([u'<%s>' % p.name for p in self.playlists]))
|
|
||||||
logger.info(u'Done refreshing stored playlists')
|
|
||||||
|
|
||||||
|
|
||||||
class LibspotifyTranslator(object):
|
class LibspotifyTranslator(object):
|
||||||
@ -180,6 +163,7 @@ class LibspotifySessionManager(SpotifySessionManager, threading.Thread):
|
|||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.core_queue = core_queue
|
self.core_queue = core_queue
|
||||||
self.connected = threading.Event()
|
self.connected = threading.Event()
|
||||||
|
self.translate = LibspotifyTranslator()
|
||||||
self.audio = AlsaController()
|
self.audio = AlsaController()
|
||||||
self.playlists = []
|
self.playlists = []
|
||||||
|
|
||||||
@ -187,6 +171,7 @@ class LibspotifySessionManager(SpotifySessionManager, threading.Thread):
|
|||||||
self.connect()
|
self.connect()
|
||||||
|
|
||||||
def logged_in(self, session, error):
|
def logged_in(self, session, error):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
logger.info('Logged in')
|
logger.info('Logged in')
|
||||||
self.session = session
|
self.session = session
|
||||||
try:
|
try:
|
||||||
@ -197,35 +182,62 @@ class LibspotifySessionManager(SpotifySessionManager, threading.Thread):
|
|||||||
self.connected.set()
|
self.connected.set()
|
||||||
|
|
||||||
def logged_out(self, session):
|
def logged_out(self, session):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
logger.info('Logged out')
|
logger.info('Logged out')
|
||||||
|
|
||||||
def metadata_updated(self, session):
|
def metadata_updated(self, session):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
logger.debug('Metadata updated')
|
logger.debug('Metadata updated')
|
||||||
self.core_queue.put({'command': 'stored_playlists_updated'})
|
playlists = []
|
||||||
|
for spotify_playlist in session.playlist_container():
|
||||||
|
playlists.append(
|
||||||
|
self.translate.to_mopidy_playlist(spotify_playlist))
|
||||||
|
self.core_queue.put({
|
||||||
|
'command': 'set_stored_playlists',
|
||||||
|
'playlists': playlists,
|
||||||
|
})
|
||||||
|
|
||||||
def connection_error(self, session, error):
|
def connection_error(self, session, error):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
logger.error('Connection error: %s', error)
|
logger.error('Connection error: %s', error)
|
||||||
|
|
||||||
def message_to_user(self, session, message):
|
def message_to_user(self, session, message):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
logger.info(message)
|
logger.info(message)
|
||||||
|
|
||||||
def notify_main_thread(self, session):
|
def notify_main_thread(self, session):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
logger.debug('Notify main thread')
|
logger.debug('Notify main thread')
|
||||||
|
|
||||||
def music_delivery(self, *args, **kwargs):
|
def music_delivery(self, *args, **kwargs):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
self.audio.music_delivery(*args, **kwargs)
|
self.audio.music_delivery(*args, **kwargs)
|
||||||
|
|
||||||
def play_token_lost(self, session):
|
def play_token_lost(self, session):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
logger.debug('Play token lost')
|
logger.debug('Play token lost')
|
||||||
self.core_queue.put({'command': 'stop_playback'})
|
self.core_queue.put({'command': 'stop_playback'})
|
||||||
|
|
||||||
def log_message(self, session, data):
|
def log_message(self, session, data):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
logger.debug(data)
|
logger.debug(data)
|
||||||
|
|
||||||
def end_of_track(self, session):
|
def end_of_track(self, session):
|
||||||
|
"""Callback used by pyspotify"""
|
||||||
logger.debug('End of track')
|
logger.debug('End of track')
|
||||||
self.core_queue.put({'command': 'end_of_track'})
|
self.core_queue.put({'command': 'end_of_track'})
|
||||||
|
|
||||||
def search(self, query, callback):
|
def search(self, query, connection):
|
||||||
|
"""Search method used by Mopidy backend"""
|
||||||
self.connected.wait()
|
self.connected.wait()
|
||||||
|
def callback(results, userdata):
|
||||||
|
logger.debug(u'In search callback, translating search results')
|
||||||
|
logger.debug(results.tracks())
|
||||||
|
# TODO Include results from results.albums(), etc. too
|
||||||
|
playlist = Playlist(tracks=[
|
||||||
|
self.translate.to_mopidy_track(t)
|
||||||
|
for t in results.tracks()])
|
||||||
|
logger.debug(u'In search callback, sending search results')
|
||||||
|
logger.debug(['%s' % t.name for t in playlist.tracks])
|
||||||
|
connection.send(playlist)
|
||||||
self.session.search(query, callback)
|
self.session.search(query, callback)
|
||||||
|
|||||||
@ -44,7 +44,7 @@ class CoreProcess(BaseProcess):
|
|||||||
self._backend.playback.end_of_track_callback()
|
self._backend.playback.end_of_track_callback()
|
||||||
elif message['command'] == 'stop_playback':
|
elif message['command'] == 'stop_playback':
|
||||||
self._backend.playback.stop()
|
self._backend.playback.stop()
|
||||||
elif message['command'] == 'stored_playlists_updated':
|
elif message['command'] == 'set_stored_playlists':
|
||||||
self._backend.stored_playlists.refresh()
|
self._backend.stored_playlists.playlists = message['playlists']
|
||||||
else:
|
else:
|
||||||
logger.warning(u'Cannot handle message: %s', message)
|
logger.warning(u'Cannot handle message: %s', message)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user