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