From acd043719342f507ca92e9fb6d31605302cdad29 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Fri, 13 Aug 2010 20:44:24 +0200 Subject: [PATCH] Remove despotify backend as library is no longer maintained --- docs/api/backends.rst | 8 - docs/changes.rst | 2 + docs/development/roadmap.rst | 3 +- docs/installation/despotify.rst | 73 ------- docs/installation/index.rst | 7 +- docs/installation/libspotify.rst | 2 +- mopidy/backends/despotify/__init__.py | 209 -------------------- mopidy/settings.py | 5 +- tests/backends/despotify_integrationtest.py | 35 ---- 9 files changed, 7 insertions(+), 337 deletions(-) delete mode 100644 docs/installation/despotify.rst delete mode 100644 mopidy/backends/despotify/__init__.py delete mode 100644 tests/backends/despotify_integrationtest.py diff --git a/docs/api/backends.rst b/docs/api/backends.rst index adb87e56..f675541a 100644 --- a/docs/api/backends.rst +++ b/docs/api/backends.rst @@ -82,14 +82,6 @@ Manages the music library, e.g. searching for tracks to be added to a playlist. :undoc-members: -:mod:`mopidy.backends.despotify` -- Despotify backend -===================================================== - -.. automodule:: mopidy.backends.despotify - :synopsis: Spotify backend using the Despotify library - :members: - - :mod:`mopidy.backends.dummy` -- Dummy backend for testing ========================================================= diff --git a/docs/changes.rst b/docs/changes.rst index 460b7538..4e33125d 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -47,6 +47,8 @@ Another great release. - :meth:`mopidy.backends.base.BaseBackend()` now accepts an ``output_queue`` which it can use to send messages (i.e. audio data) to the output process. + - Remove Depsotify backend. + - Libspotify is now the default backend. diff --git a/docs/development/roadmap.rst b/docs/development/roadmap.rst index 7dc284df..5544a005 100644 --- a/docs/development/roadmap.rst +++ b/docs/development/roadmap.rst @@ -11,8 +11,7 @@ Version 0.1 - Core MPD server functionality working. Gracefully handle clients' use of non-supported functionality. -- Read-only support for Spotify through :mod:`mopidy.backends.despotify` and/or - :mod:`mopidy.backends.libspotify`. +- Read-only support for Spotify through :mod:`mopidy.backends.libspotify`. - Initial support for local file playback through :mod:`mopidy.backends.local`. The state of local file playback will not block the release of 0.1. diff --git a/docs/installation/despotify.rst b/docs/installation/despotify.rst deleted file mode 100644 index 6787070d..00000000 --- a/docs/installation/despotify.rst +++ /dev/null @@ -1,73 +0,0 @@ -********************** -Despotify installation -********************** - -To use the `Despotify `_ backend, you first need to -install Despotify and spytify. - -.. warning:: - - This backend requires a Spotify premium account. - - -Installing Despotify on Linux -============================= - -Install Despotify's dependencies. At Debian/Ubuntu systems:: - - sudo aptitude install libssl-dev zlib1g-dev libvorbis-dev \ - libtool libncursesw5-dev libao-dev python-dev - -Check out revision 508 of the Despotify source code:: - - svn checkout https://despotify.svn.sourceforge.net/svnroot/despotify@508 - -Build and install Despotify:: - - cd despotify/src/ - sudo make install - -When Despotify has been installed, continue with :ref:`spytify_installation`. - - -Installing Despotify on OS X -============================ - -In OS X you need to have `XCode `_ and -`Homebrew `_ installed. Then, to install -Despotify:: - - brew install despotify - -When Despotify has been installed, continue with :ref:`spytify_installation`. - - -.. _spytify_installation: - -Installing spytify -================== - -spytify's source comes bundled with despotify. If you haven't already checkout -out the despotify source, do it now:: - - svn checkout https://despotify.svn.sourceforge.net/svnroot/despotify@508 - -Build and install spytify:: - - cd despotify/src/bindings/python/ - export PKG_CONFIG_PATH=../../lib # Needed on OS X - sudo make install - - -Testing the installation -======================== - -To validate that everything is working, run the ``test.py`` script which is -distributed with spytify:: - - python test.py - -The test script should ask for your username and password (which must be for a -Spotify Premium account), ask for a search query, list all your playlists with -tracks, play 10s from a random song from the search result, pause for two -seconds, play for five more seconds, and quit. diff --git a/docs/installation/index.rst b/docs/installation/index.rst index 227ae8b9..044f2155 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -18,7 +18,6 @@ Install dependencies gstreamer libspotify - despotify Make sure you got the required dependencies installed. @@ -44,10 +43,6 @@ Make sure you got the required dependencies installed. - Dependencies for at least one Mopidy backend: - - :mod:`mopidy.backends.despotify` (Linux and OS X) - - - :doc:`Despotify and spytify ` - - :mod:`mopidy.backends.libspotify` (Linux, OS X, and Windows) - :doc:`libspotify and pyspotify ` @@ -106,7 +101,7 @@ username and password into the file, like this:: SPOTIFY_USERNAME = u'myusername' SPOTIFY_PASSWORD = u'mysecret' -Currently :mod:`mopidy.backends.despotify` is the default +Currently :mod:`mopidy.backends.libspotify` is the default backend. If you want to use :mod:`mopidy.backends.libspotify`, copy the Spotify diff --git a/docs/installation/libspotify.rst b/docs/installation/libspotify.rst index 3965162d..635c0495 100644 --- a/docs/installation/libspotify.rst +++ b/docs/installation/libspotify.rst @@ -2,7 +2,7 @@ libspotify installation *********************** -As an alternative to the despotify backend, we are working on a +We are working on a `libspotify `_ backend. To use the libspotify backend you must install libspotify and `pyspotify `_. diff --git a/mopidy/backends/despotify/__init__.py b/mopidy/backends/despotify/__init__.py deleted file mode 100644 index 78c7f774..00000000 --- a/mopidy/backends/despotify/__init__.py +++ /dev/null @@ -1,209 +0,0 @@ -import datetime as dt -import logging -import sys - -import spytify - -from mopidy import settings -from mopidy.backends.base import (BaseBackend, BaseCurrentPlaylistController, - BaseLibraryController, BasePlaybackController, - BaseStoredPlaylistsController) -from mopidy.models import Artist, Album, Track, Playlist - -logger = logging.getLogger('mopidy.backends.despotify') - -ENCODING = 'utf-8' - -class DespotifyBackend(BaseBackend): - """ - A Spotify backend which uses the open source `despotify library - `_. - - `spytify `_ - is the Python bindings for the despotify library. It got litle - documentation, but a couple of examples are available. - - **Issues:** http://github.com/jodal/mopidy/issues/labels/backend-despotify - """ - - def __init__(self, *args, **kwargs): - super(DespotifyBackend, self).__init__(*args, **kwargs) - self.current_playlist = DespotifyCurrentPlaylistController(backend=self) - self.library = DespotifyLibraryController(backend=self) - self.playback = DespotifyPlaybackController(backend=self) - self.stored_playlists = DespotifyStoredPlaylistsController(backend=self) - self.uri_handlers = [u'spotify:', u'http://open.spotify.com/'] - self.spotify = self._connect() - self.stored_playlists.refresh() - - def _connect(self): - logger.info(u'Connecting to Spotify') - try: - return DespotifySessionManager( - settings.SPOTIFY_USERNAME.encode(ENCODING), - settings.SPOTIFY_PASSWORD.encode(ENCODING), - core_queue=self.core_queue) - except spytify.SpytifyError as e: - logger.exception(e) - sys.exit(1) - - -class DespotifyCurrentPlaylistController(BaseCurrentPlaylistController): - pass - - -class DespotifyLibraryController(BaseLibraryController): - def find_exact(self, **query): - return self.search(**query) - - def lookup(self, uri): - track = self.backend.spotify.lookup(uri.encode(ENCODING)) - return DespotifyTranslator.to_mopidy_track(track) - - def refresh(self, uri=None): - pass # TODO - - def search(self, **query): - spotify_query = [] - for (field, values) in query.iteritems(): - if not hasattr(values, '__iter__'): - values = [values] - for value in values: - if field == u'track': - field = u'title' - if field == u'any': - spotify_query.append(value) - else: - spotify_query.append(u'%s:"%s"' % (field, value)) - spotify_query = u' '.join(spotify_query) - logger.debug(u'Spotify search query: %s', spotify_query) - result = self.backend.spotify.search(spotify_query.encode(ENCODING)) - if (result is None or result.playlist.tracks[0].get_uri() == - 'spotify:track:0000000000000000000000'): - return Playlist() - return DespotifyTranslator.to_mopidy_playlist(result.playlist) - - -class DespotifyPlaybackController(BasePlaybackController): - def _pause(self): - try: - self.backend.spotify.pause() - return True - except spytify.SpytifyError as e: - logger.error(e) - return False - - def _play(self, track): - try: - self.backend.spotify.play(self.backend.spotify.lookup(track.uri)) - return True - except spytify.SpytifyError as e: - logger.error(e) - return False - - def _resume(self): - try: - self.backend.spotify.resume() - return True - except spytify.SpytifyError as e: - logger.error(e) - return False - - def _seek(self, time_position): - pass # TODO - - def _stop(self): - try: - self.backend.spotify.stop() - return True - except spytify.SpytifyError as e: - logger.error(e) - return False - - -class DespotifyStoredPlaylistsController(BaseStoredPlaylistsController): - def create(self, name): - pass # TODO - - def delete(self, playlist): - pass # TODO - - def lookup(self, uri): - pass # TODO - - def refresh(self): - logger.info(u'Caching stored playlists') - playlists = [] - for spotify_playlist in self.backend.spotify.stored_playlists: - playlists.append( - DespotifyTranslator.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 caching stored playlists') - - def rename(self, playlist, new_name): - pass # TODO - - def save(self, playlist): - pass # TODO - - -class DespotifyTranslator(object): - @classmethod - def to_mopidy_artist(cls, spotify_artist): - return Artist( - uri=spotify_artist.get_uri(), - name=spotify_artist.name.decode(ENCODING) - ) - - @classmethod - def to_mopidy_album(cls, spotify_album_name): - return Album(name=spotify_album_name.decode(ENCODING)) - - @classmethod - def to_mopidy_track(cls, spotify_track): - if spotify_track is None or not spotify_track.has_meta_data(): - return None - if dt.MINYEAR <= int(spotify_track.year) <= dt.MAXYEAR: - date = dt.date(spotify_track.year, 1, 1) - else: - date = None - return Track( - uri=spotify_track.get_uri(), - name=spotify_track.title.decode(ENCODING), - artists=[cls.to_mopidy_artist(a) for a in spotify_track.artists], - album=cls.to_mopidy_album(spotify_track.album), - track_no=spotify_track.tracknumber, - date=date, - length=spotify_track.length, - bitrate=320, - ) - - @classmethod - def to_mopidy_playlist(cls, spotify_playlist): - return Playlist( - uri=spotify_playlist.get_uri(), - name=spotify_playlist.name.decode(ENCODING), - tracks=filter(None, - [cls.to_mopidy_track(t) for t in spotify_playlist.tracks]), - ) - - -class DespotifySessionManager(spytify.Spytify): - DESPOTIFY_NEW_TRACK = 1 - DESPOTIFY_TIME_TELL = 2 - DESPOTIFY_END_OF_PLAYLIST = 3 - DESPOTIFY_TRACK_PLAY_ERROR = 4 - - def __init__(self, *args, **kwargs): - kwargs['callback'] = self.callback - self.core_queue = kwargs.pop('core_queue') - super(DespotifySessionManager, self).__init__(*args, **kwargs) - - def callback(self, signal, data): - if signal == self.DESPOTIFY_END_OF_PLAYLIST: - logger.debug('Despotify signalled end of playlist') - self.core_queue.put({'command': 'end_of_track'}) - elif signal == self.DESPOTIFY_TRACK_PLAY_ERROR: - logger.error('Despotify signalled track play error') diff --git a/mopidy/settings.py b/mopidy/settings.py index 1be09511..d4321685 100644 --- a/mopidy/settings.py +++ b/mopidy/settings.py @@ -14,13 +14,12 @@ import sys #: List of playback backends to use. See :mod:`mopidy.backends` for all #: available backends. Default:: #: -#: BACKENDS = (u'mopidy.backends.despotify.DespotifyBackend',) +#: BACKENDS = (u'mopidy.backends.libspotify.LibspotifyBackend',) #: #: .. note:: #: Currently only the first backend in the list is used. BACKENDS = ( - u'mopidy.backends.despotify.DespotifyBackend', - #u'mopidy.backends.libspotify.LibspotifyBackend', + u'mopidy.backends.libspotify.LibspotifyBackend', ) #: The log format used on the console. See diff --git a/tests/backends/despotify_integrationtest.py b/tests/backends/despotify_integrationtest.py deleted file mode 100644 index 4192bf7b..00000000 --- a/tests/backends/despotify_integrationtest.py +++ /dev/null @@ -1,35 +0,0 @@ -# TODO This integration test is work in progress. - -import unittest - -from mopidy.backends.despotify import DespotifyBackend -from mopidy.models import Track - -from tests.backends.base import * - -uris = [ - 'spotify:track:6vqcpVcbI3Zu6sH3ieLDNt', - 'spotify:track:111sulhaZqgsnypz3MkiaW', - 'spotify:track:7t8oznvbeiAPMDRuK0R5ZT', -] - -class DespotifyCurrentPlaylistControllerTest( - BaseCurrentPlaylistControllerTest, unittest.TestCase): - tracks = [Track(uri=uri, length=4464) for i, uri in enumerate(uris)] - backend_class = DespotifyBackend - - -class DespotifyPlaybackControllerTest( - BasePlaybackControllerTest, unittest.TestCase): - tracks = [Track(uri=uri, length=4464) for i, uri in enumerate(uris)] - backend_class = DespotifyBackend - - -class DespotifyStoredPlaylistsControllerTest( - BaseStoredPlaylistsControllerTest, unittest.TestCase): - backend_class = DespotifyBackend - - -class DespotifyLibraryControllerTest( - BaseLibraryControllerTest, unittest.TestCase): - backend_class = DespotifyBackend