diff --git a/docs/changes.rst b/docs/changes.rst index 57224300..082ad136 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -68,6 +68,9 @@ v0.8 (in development) cleanup code would wait for an response that would never come inside the event loop, blocking everything else. +- Created a Spotify track proxy that will switch to using loaded data as soon + as it becomes available. Fixes :issue:`72`. + v0.7.3 (2012-08-11) =================== diff --git a/mopidy/backends/spotify/library.py b/mopidy/backends/spotify/library.py index a080c7bd..18276ecd 100644 --- a/mopidy/backends/spotify/library.py +++ b/mopidy/backends/spotify/library.py @@ -5,21 +5,55 @@ from spotify import Link, SpotifyError from mopidy.backends.base import BaseLibraryProvider from mopidy.backends.spotify.translator import SpotifyTranslator -from mopidy.models import Playlist +from mopidy.models import Track, Playlist logger = logging.getLogger('mopidy.backends.spotify.library') + +class SpotifyTrack(Track): + """Proxy object for unloaded Spotify tracks.""" + def __init__(self, uri): + self._spotify_track = Link.from_string(uri).as_track() + self._unloaded_track = Track(uri=uri, name=u'[loading...]') + self._track = None + + @property + def _proxy(self): + if self._track: + return self._track + elif self._spotify_track.is_loaded(): + self._track = SpotifyTranslator.to_mopidy_track(self._spotify_track) + return self._track + else: + return self._unloaded_track + + def __getattribute__(self, name): + if name.startswith('_'): + return super(SpotifyTrack, self).__getattribute__(name) + return self._proxy.__getattribute__(name) + + def __repr__(self): + return self._proxy.__repr__() + + def __hash__(self): + return hash(self._proxy.uri) + + def __eq__(self, other): + if not isinstance(other, Track): + return False + return self._proxy.uri == other.uri + + def copy(self, **values): + return self._proxy.copy(**values) + + class SpotifyLibraryProvider(BaseLibraryProvider): def find_exact(self, **query): return self.search(**query) def lookup(self, uri): try: - spotify_track = Link.from_string(uri).as_track() - # TODO Block until metadata_updated callback is called. Before that - # the track will be unloaded, unless it's already in the stored - # playlists. - return SpotifyTranslator.to_mopidy_track(spotify_track) + return SpotifyTrack(uri) except SpotifyError as e: logger.debug(u'Failed to lookup "%s": %s', uri, e) return None