From 0aeb11b22ebd94b0263e209a517afae46eb1c9da Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Fri, 7 Sep 2012 00:51:08 +0200 Subject: [PATCH 1/2] Create a Track proxy for spotify (Fixes #72) --- mopidy/backends/spotify/library.py | 45 ++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/mopidy/backends/spotify/library.py b/mopidy/backends/spotify/library.py index a080c7bd..181dc19d 100644 --- a/mopidy/backends/spotify/library.py +++ b/mopidy/backends/spotify/library.py @@ -5,21 +5,54 @@ 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): + 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): # hash on just uri for consistency? + return hash(self._proxy.uri) + + def __eq__(self, other): # compare on just uri for consistency? + if not isinstance(other, Track): + return False + return self._proxy.uri == other.uri + + def copy(self, **values): # is it okay to return a plain track? + 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 From ee599b6235aff2572604580e5ea0c57438571e29 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Sun, 9 Sep 2012 23:57:06 +0200 Subject: [PATCH 2/2] Add changelog entry for #72 and remove old comments. --- docs/changes.rst | 3 +++ mopidy/backends/spotify/library.py | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) 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 181dc19d..18276ecd 100644 --- a/mopidy/backends/spotify/library.py +++ b/mopidy/backends/spotify/library.py @@ -11,6 +11,7 @@ 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...]') @@ -34,15 +35,15 @@ class SpotifyTrack(Track): def __repr__(self): return self._proxy.__repr__() - def __hash__(self): # hash on just uri for consistency? + def __hash__(self): return hash(self._proxy.uri) - def __eq__(self, other): # compare on just uri for consistency? + def __eq__(self, other): if not isinstance(other, Track): return False return self._proxy.uri == other.uri - def copy(self, **values): # is it okay to return a plain track? + def copy(self, **values): return self._proxy.copy(**values)