From 1c48c7ab2f758836358bd8b05f2cebec76ce49ce Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Nov 2010 01:31:49 +0100 Subject: [PATCH 01/35] Show 320kbit bitrate in MPD if SPOTIFY_HIGH_BITRATE=True --- mopidy/backends/libspotify/translator.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mopidy/backends/libspotify/translator.py b/mopidy/backends/libspotify/translator.py index ff8f3c5c..09303eda 100644 --- a/mopidy/backends/libspotify/translator.py +++ b/mopidy/backends/libspotify/translator.py @@ -2,8 +2,9 @@ import datetime as dt from spotify import Link -from mopidy.models import Artist, Album, Track, Playlist +from mopidy import settings from mopidy.backends.libspotify import ENCODING +from mopidy.models import Artist, Album, Track, Playlist class LibspotifyTranslator(object): @classmethod @@ -39,7 +40,7 @@ class LibspotifyTranslator(object): track_no=spotify_track.index(), date=date, length=spotify_track.duration(), - bitrate=160, + bitrate=(settings.SPOTIFY_HIGH_BITRATE and 320 or 160), ) @classmethod From 0b9d7bbd3f3a172d6d5acf83184568c074088fe9 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Nov 2010 09:01:44 +0100 Subject: [PATCH 02/35] Switch main GitHub repo from jodal/mopidy to mopidy/mopidy --- README.rst | 6 +++--- docs/changes.rst | 2 +- docs/conf.py | 2 +- docs/installation/index.rst | 2 +- mopidy/backends/libspotify/__init__.py | 3 ++- mopidy/backends/local/__init__.py | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index c6187119..4f31fb59 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,7 @@ To install Mopidy, check out * `Documentation (latest release) `_ * `Documentation (development version) `_ -* `Source code `_ -* `Issue tracker `_ +* `Source code `_ +* `Issue tracker `_ * IRC: ``#mopidy`` at `irc.freenode.net `_ -* `Download development snapshot `_ +* `Download development snapshot `_ diff --git a/docs/changes.rst b/docs/changes.rst index 3a030145..1c97ed68 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -426,7 +426,7 @@ Mopidy is working and usable. 0.1.0a0 is an alpha release, which basicly means we will still change APIs, add features, etc. before the final 0.1.0 release. But the software is usable as is, so we release it. Please give it a try and give us feedback, either at our IRC channel or through the `issue tracker -`_. Thanks! +`_. Thanks! **Changes** diff --git a/docs/conf.py b/docs/conf.py index 16a85975..9e7ff1fb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -202,4 +202,4 @@ latex_documents = [ needs_sphinx = '1.0' -extlinks = {'issue': ('http://github.com/jodal/mopidy/issues#issue/%s', 'GH-')} +extlinks = {'issue': ('http://github.com/mopidy/mopidy/issues#issue/%s', 'GH-')} diff --git a/docs/installation/index.rst b/docs/installation/index.rst index 580ecd6d..3f0600f4 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -103,7 +103,7 @@ ckeckout:: sudo aptitude install git-core # On Ubuntu/Debian sudo brew install git # On OS X - git clone git://github.com/jodal/mopidy.git + git clone git://github.com/mopidy/mopidy.git cd mopidy/ python mopidy # Yes, 'mopidy' is a dir diff --git a/mopidy/backends/libspotify/__init__.py b/mopidy/backends/libspotify/__init__.py index 4d8b67d5..ad2926c7 100644 --- a/mopidy/backends/libspotify/__init__.py +++ b/mopidy/backends/libspotify/__init__.py @@ -15,7 +15,8 @@ class LibspotifyBackend(Backend): library and the `pyspotify `_ Python bindings for libspotify. - **Issues:** http://github.com/jodal/mopidy/issues/labels/backend-libspotify + **Issues:** + http://github.com/mopidy/mopidy/issues/labels/backend-libspotify **Settings:** diff --git a/mopidy/backends/local/__init__.py b/mopidy/backends/local/__init__.py index 532c3976..e3e1d5dc 100644 --- a/mopidy/backends/local/__init__.py +++ b/mopidy/backends/local/__init__.py @@ -20,7 +20,7 @@ class LocalBackend(Backend): """ A backend for playing music from a local music archive. - **Issues:** http://github.com/jodal/mopidy/issues/labels/backend-local + **Issues:** http://github.com/mopidy/mopidy/issues/labels/backend-local **Settings:** From 2d7ac225673279421b1dcd86acc5e2ea28867870 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Nov 2010 09:38:47 +0100 Subject: [PATCH 03/35] docs: Update all Git repo references --- README.rst | 6 +++--- docs/changes.rst | 2 +- docs/conf.py | 2 +- docs/development/contributing.rst | 2 +- docs/installation/index.rst | 2 +- mopidy/backends/libspotify/__init__.py | 3 ++- mopidy/backends/local/__init__.py | 2 +- tests/frontends/mpd/regression_test.py | 6 +++--- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/README.rst b/README.rst index c6187119..4f31fb59 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,7 @@ To install Mopidy, check out * `Documentation (latest release) `_ * `Documentation (development version) `_ -* `Source code `_ -* `Issue tracker `_ +* `Source code `_ +* `Issue tracker `_ * IRC: ``#mopidy`` at `irc.freenode.net `_ -* `Download development snapshot `_ +* `Download development snapshot `_ diff --git a/docs/changes.rst b/docs/changes.rst index eadf8e75..9e895419 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -351,7 +351,7 @@ Mopidy is working and usable. 0.1.0a0 is an alpha release, which basicly means we will still change APIs, add features, etc. before the final 0.1.0 release. But the software is usable as is, so we release it. Please give it a try and give us feedback, either at our IRC channel or through the `issue tracker -`_. Thanks! +`_. Thanks! **Changes** diff --git a/docs/conf.py b/docs/conf.py index d0d8f3af..bb9eb3ba 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -202,4 +202,4 @@ latex_documents = [ needs_sphinx = '1.0' -extlinks = {'issue': ('http://github.com/jodal/mopidy/issues#issue/%s', 'GH-')} +extlinks = {'issue': ('http://github.com/mopidy/mopidy/issues#issue/%s', 'GH-')} diff --git a/docs/development/contributing.rst b/docs/development/contributing.rst index 4adde637..a9cd8dc3 100644 --- a/docs/development/contributing.rst +++ b/docs/development/contributing.rst @@ -137,7 +137,7 @@ Then, to generate docs:: .. note:: The documentation at http://www.mopidy.com/ is automatically updated when a - documentation update is pushed to ``jodal/mopidy`` at GitHub. + documentation update is pushed to ``mopidy/mopidy`` at GitHub. Documentation generated from the ``master`` branch is published at http://www.mopidy.com/docs/master/, and will always be valid for the latest diff --git a/docs/installation/index.rst b/docs/installation/index.rst index 9577c383..c3bbddce 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -88,7 +88,7 @@ development version of Mopidy:: sudo aptitude install git-core # On Ubuntu/Debian sudo brew install git # On OS X - git clone git://github.com/jodal/mopidy.git + git clone git://github.com/mopidy/mopidy.git cd mopidy/ sudo python setup.py install diff --git a/mopidy/backends/libspotify/__init__.py b/mopidy/backends/libspotify/__init__.py index 223d9968..f4087043 100644 --- a/mopidy/backends/libspotify/__init__.py +++ b/mopidy/backends/libspotify/__init__.py @@ -14,7 +14,8 @@ class LibspotifyBackend(BaseBackend): library and the `pyspotify `_ Python bindings for libspotify. - **Issues:** http://github.com/jodal/mopidy/issues/labels/backend-libspotify + **Issues:** + http://github.com/mopidy/mopidy/issues/labels/backend-libspotify **Settings:** diff --git a/mopidy/backends/local/__init__.py b/mopidy/backends/local/__init__.py index e5bfe8f8..bb5e6a5e 100644 --- a/mopidy/backends/local/__init__.py +++ b/mopidy/backends/local/__init__.py @@ -17,7 +17,7 @@ class LocalBackend(BaseBackend): """ A backend for playing music from a local music archive. - **Issues:** http://github.com/jodal/mopidy/issues/labels/backend-local + **Issues:** http://github.com/mopidy/mopidy/issues/labels/backend-local **Settings:** diff --git a/tests/frontends/mpd/regression_test.py b/tests/frontends/mpd/regression_test.py index 3cfdb855..7e7163d8 100644 --- a/tests/frontends/mpd/regression_test.py +++ b/tests/frontends/mpd/regression_test.py @@ -8,7 +8,7 @@ from mopidy.models import Track class IssueGH17RegressionTest(unittest.TestCase): """ - The issue: http://github.com/jodal/mopidy/issues#issue/17 + The issue: http://github.com/mopidy/mopidy/issues#issue/17 How to reproduce: @@ -42,7 +42,7 @@ class IssueGH17RegressionTest(unittest.TestCase): class IssueGH18RegressionTest(unittest.TestCase): """ - The issue: http://github.com/jodal/mopidy/issues#issue/18 + The issue: http://github.com/mopidy/mopidy/issues#issue/18 How to reproduce: @@ -79,7 +79,7 @@ class IssueGH18RegressionTest(unittest.TestCase): class IssueGH22RegressionTest(unittest.TestCase): """ - The issue: http://github.com/jodal/mopidy/issues/#issue/22 + The issue: http://github.com/mopidy/mopidy/issues/#issue/22 How to reproduce: From 827940a97785af2c8232c3a1997d90909be4c7a9 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Nov 2010 09:39:40 +0100 Subject: [PATCH 04/35] Update Git repo references in tests --- tests/frontends/mpd/regression_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/frontends/mpd/regression_test.py b/tests/frontends/mpd/regression_test.py index 3cfdb855..7e7163d8 100644 --- a/tests/frontends/mpd/regression_test.py +++ b/tests/frontends/mpd/regression_test.py @@ -8,7 +8,7 @@ from mopidy.models import Track class IssueGH17RegressionTest(unittest.TestCase): """ - The issue: http://github.com/jodal/mopidy/issues#issue/17 + The issue: http://github.com/mopidy/mopidy/issues#issue/17 How to reproduce: @@ -42,7 +42,7 @@ class IssueGH17RegressionTest(unittest.TestCase): class IssueGH18RegressionTest(unittest.TestCase): """ - The issue: http://github.com/jodal/mopidy/issues#issue/18 + The issue: http://github.com/mopidy/mopidy/issues#issue/18 How to reproduce: @@ -79,7 +79,7 @@ class IssueGH18RegressionTest(unittest.TestCase): class IssueGH22RegressionTest(unittest.TestCase): """ - The issue: http://github.com/jodal/mopidy/issues/#issue/22 + The issue: http://github.com/mopidy/mopidy/issues/#issue/22 How to reproduce: From 6d21f86a9e351abbae6fe9fb1b030ec6a4fa734c Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 28 Dec 2010 14:27:09 +0100 Subject: [PATCH 05/35] Fix broken link --- docs/changes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changes.rst b/docs/changes.rst index 1c97ed68..bd4f08ae 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -14,7 +14,7 @@ No description yet. - If you use the Spotify backend, you need to upgrade to libspotify 0.0.6 and the latest pyspotify from the Mopidy developers. Follow the instructions at - :ref:`/installation/libspotify/`. + :doc:`/installation/libspotify/`. **Changes** From f7b4f65e31640393bda643999e0e67f1e390b195 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 28 Dec 2010 14:30:36 +0100 Subject: [PATCH 06/35] Move 320k support to the important section of the changelog --- docs/changes.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index bd4f08ae..7bf1ebba 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -12,9 +12,15 @@ No description yet. **Important changes** -- If you use the Spotify backend, you need to upgrade to libspotify 0.0.6 and - the latest pyspotify from the Mopidy developers. Follow the instructions at - :doc:`/installation/libspotify/`. +- Spotify backend: + + - If you use the Spotify backend, you need to upgrade to libspotify 0.0.6 and + the latest pyspotify from the Mopidy developers. Follow the instructions at + :doc:`/installation/libspotify/`. + + - Support high bitrate (320k) audio. See + :attr:`mopidy.settings.SPOTIFY_HIGH_BITRATE` for details. + **Changes** @@ -37,11 +43,6 @@ No description yet. application menus. - Create infrastructure for creating Debian packages of Mopidy. -- Spotify backend: - - - Support high bitrate (320k). See - :attr:`mopidy.settings.SPOTIFY_HIGH_BITRATE` for details. - - Local backend: - Add :command:`mopidy-scan` command to generate ``tag_cache`` files without From 2379e772c7c39b47c314c774d4b59aff4d4a56fe Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 28 Dec 2010 14:34:34 +0100 Subject: [PATCH 07/35] Remove warning that is not needed when we don't pull pyspotify from Git --- docs/installation/libspotify.rst | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/installation/libspotify.rst b/docs/installation/libspotify.rst index 9dc91066..692bda36 100644 --- a/docs/installation/libspotify.rst +++ b/docs/installation/libspotify.rst @@ -77,12 +77,4 @@ Check out the pyspotify code, and install it:: wget --no-check-certificate -O pyspotify.tar.gz https://github.com/mopidy/pyspotify/tarball/mopidy tar zxfv pyspotify.tar.gz cd pyspotify/pyspotify/ - sudo rm -rf build/ # If you are upgrading pyspotify sudo python setup.py install - -.. note:: - - The ``sudo rm -rf build/`` step is needed if you are upgrading pyspotify. - Simply running ``python setup.py clean`` will *not* clean out the C parts - of the ``build/`` directory, and you will thus not get any changes to the C - code included in your installation. From 62af31cbcae57fa2717942a86f0c63ab347fd041 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 28 Dec 2010 15:00:23 +0100 Subject: [PATCH 08/35] Doc how to install dev snapshot using pip --- docs/installation/index.rst | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/installation/index.rst b/docs/installation/index.rst index 3f0600f4..96ba6027 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -61,18 +61,16 @@ Make sure you got the required dependencies installed. - pylast >= 4.3.0 -Install latest release -====================== +Install latest stable release +============================= -To install the currently latest release of Mopidy using ``pip``:: +To install the currently latest stable release of Mopidy using ``pip``:: sudo aptitude install python-setuptools python-pip # On Ubuntu/Debian sudo brew install pip # On OS X - sudo pip install mopidy + sudo pip install -U Mopidy -To later upgrade to the latest release:: - - sudo pip install -U mopidy +To later upgrade to the latest release, just rerun the last command. If you for some reason can't use ``pip``, try ``easy_install``. @@ -94,20 +92,21 @@ Next, you need to set a couple of :doc:`settings `, and then you're ready to :doc:`run Mopidy `. -Run from source code checkout -============================= +Track development using Git +=========================== -If you may want to contribute to Mopidy, and want access to other branches as -well, you can checkout the Mopidy source from Git and run it directly from the -ckeckout:: +If you want to contribute to Mopidy, you should install Mopidy using Git:: sudo aptitude install git-core # On Ubuntu/Debian sudo brew install git # On OS X git clone git://github.com/mopidy/mopidy.git - cd mopidy/ - python mopidy # Yes, 'mopidy' is a dir -To later update to the very latest version:: +You can then run Mopidy directly from the Git repository:: + + cd mopidy/ # Move into the Git repo dir + python mopidy # Run python on the mopidy source code dir + +To get the latest changes to Mopidy:: cd mopidy/ git pull From 18caae4b18a4e20d58aad8329b64be00ead94e9a Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 28 Dec 2010 15:12:04 +0100 Subject: [PATCH 09/35] Simplify dependency list --- docs/installation/index.rst | 40 ++++++++++--------------------------- mopidy/mixers/alsa.py | 4 ++++ mopidy/mixers/osa.py | 13 +++++++++++- 3 files changed, 26 insertions(+), 31 deletions(-) diff --git a/docs/installation/index.rst b/docs/installation/index.rst index 96ba6027..142c5d84 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -20,45 +20,25 @@ Install dependencies Make sure you got the required dependencies installed. - Python >= 2.6, < 3 -- :doc:`GStreamer ` >= 0.10, with Python bindings -- Dependencies for at least one Mopidy mixer: - - :mod:`mopidy.mixers.alsa` (Linux only) +- GStreamer >= 0.10, with Python bindings. See :doc:`gstreamer`. - - pyalsaaudio >= 0.2 (Debian/Ubuntu package: python-alsaaudio) - - - :mod:`mopidy.mixers.denon` (Linux, OS X, and Windows) - - - pyserial (Debian/Ubuntu package: python-serial) - - - *Default:* :mod:`mopidy.mixers.gstreamer_software` (Linux, OS X, and - Windows) - - - No additional dependencies. - - - :mod:`mopidy.mixers.nad` (Linux, OS X, and Windows) - - - pyserial (Debian/Ubuntu package: python-serial) - - - :mod:`mopidy.mixers.osa` (OS X only) - - - No additional dependencies. +- Mixer dependencies: The default mixer does not require any additional + dependencies. If you use another mixer, see the mixer's docs for any + additional requirements. - Dependencies for at least one Mopidy backend: - - *Default:* :mod:`mopidy.backends.libspotify` (Linux, OS X, and Windows) + - The default backend, :mod:`mopidy.backends.libspotify`, requires libspotify + and pyspotify. See :doc:`libspotify`. - - :doc:`libspotify and pyspotify ` - - - :mod:`mopidy.backends.local` (Linux, OS X, and Windows) - - - No additional dependencies. + - The local backend, :mod:`mopidy.backends.local`, requires no additional + dependencies. - Optional dependencies: - - :mod:`mopidy.frontends.lastfm` - - - pylast >= 4.3.0 + - To use the Last.FM scrobbler, see :mod:`mopidy.frontends.lastfm` for + additional requirements. Install latest stable release diff --git a/mopidy/mixers/alsa.py b/mopidy/mixers/alsa.py index f90060ce..4aa5952f 100644 --- a/mopidy/mixers/alsa.py +++ b/mopidy/mixers/alsa.py @@ -11,6 +11,10 @@ class AlsaMixer(BaseMixer): Mixer which uses the Advanced Linux Sound Architecture (ALSA) to control volume. + **Dependencies:** + + - pyalsaaudio >= 0.2 (python-alsaaudio on Debian/Ubuntu) + **Settings:** - :attr:`mopidy.settings.MIXER_ALSA_CONTROL` diff --git a/mopidy/mixers/osa.py b/mopidy/mixers/osa.py index 8d69eb47..2ea04cf2 100644 --- a/mopidy/mixers/osa.py +++ b/mopidy/mixers/osa.py @@ -4,7 +4,18 @@ import time from mopidy.mixers.base import BaseMixer class OsaMixer(BaseMixer): - """Mixer which uses ``osascript`` on OS X to control volume.""" + """ + Mixer which uses ``osascript`` on OS X to control volume. + + **Dependencies:** + + - None + + **Settings:** + + - None + + """ CACHE_TTL = 30 From ab6dbbb8fe41df9bc8e45feafe028ab7b65cea10 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 28 Dec 2010 15:19:15 +0100 Subject: [PATCH 10/35] Add note on the importancy of using pyspotify from the correct repo --- docs/installation/libspotify.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/installation/libspotify.rst b/docs/installation/libspotify.rst index 692bda36..b511e9c9 100644 --- a/docs/installation/libspotify.rst +++ b/docs/installation/libspotify.rst @@ -7,9 +7,9 @@ Mopidy uses `libspotify the Spotify music service. To use :mod:`mopidy.backends.libspotify` you must install libspotify and `pyspotify `_. -.. warning:: +.. note:: - This backend requires a `Spotify premium account + This backend requires a paid `Spotify premium account `_. .. note:: @@ -78,3 +78,8 @@ Check out the pyspotify code, and install it:: tar zxfv pyspotify.tar.gz cd pyspotify/pyspotify/ sudo python setup.py install + +It is important that you install pyspotify from the ``mopidy`` branch of the +``mopidy/pyspotify`` repository, as the upstream repository at +``winjer/pyspotify`` is not updated with changes needed to support e.g. +libspotify 0.0.6 and high bitrate audio. From 7743fa372b91e111abd2019e1260ce33cc753228 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 28 Dec 2010 15:31:10 +0100 Subject: [PATCH 11/35] Doc gst-launch test step. Fixes GH#35. --- docs/installation/gstreamer.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/installation/gstreamer.rst b/docs/installation/gstreamer.rst index ef66c673..ad2761a3 100644 --- a/docs/installation/gstreamer.rst +++ b/docs/installation/gstreamer.rst @@ -46,3 +46,19 @@ you should see a long listing of installed plugins, ending in a summary line:: $ gst-inspect-0.10 ... long list of installed plugins ... Total count: 218 plugins (1 blacklist entry not shown), 1031 features + +You should be able to produce a audible tone by running:: + + gst-launch-0.10 audiotestsrc ! autoaudiosink + +If you cannot hear any sound when running this command, you won't hear any +sound from Mopidy either, as Mopidy uses GStreamer's ``autoaudiosink`` to play +audio. Thus, make this work before you continue installing Mopidy. + + +Using a custom audio sink +========================= + +If you for some reason want to use some other GStreamer audio sink than +``autoaudiosink``, you can change :attr:`mopidy.settings.GSTREAMER_AUDIO_SINK` +in your ``settings.py`` file. From 71ede1a37b2f17f42d292096b124d846a7908905 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 28 Dec 2010 15:41:22 +0100 Subject: [PATCH 12/35] Update 0.2.0 docs to recommend libspotify 0.0.6 and mopidy/pyspotify over 0.0.4 and jodal/pyspotify --- docs/installation/libspotify.rst | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/docs/installation/libspotify.rst b/docs/installation/libspotify.rst index b3ea06fa..4860fc4b 100644 --- a/docs/installation/libspotify.rst +++ b/docs/installation/libspotify.rst @@ -22,14 +22,14 @@ install libspotify and `pyspotify `_. Installing libspotify on Linux ============================== -Download and install libspotify 0.0.4 for your OS and CPU architecture from +Download and install libspotify 0.0.6 for your OS and CPU architecture from https://developer.spotify.com/en/libspotify/. For 64-bit Linux the process is as follows:: - wget http://developer.spotify.com/download/libspotify/libspotify-0.0.4-linux6-x86_64.tar.gz - tar zxfv libspotify-0.0.4-linux6-x86_64.tar.gz - cd libspotify-0.0.4-linux6-x86_64/ + wget http://developer.spotify.com/download/libspotify/libspotify-0.0.6-linux6-x86_64.tar.gz + tar zxfv libspotify-0.0.6-linux6-x86_64.tar.gz + cd libspotify-0.0.6-linux6-x86_64/ sudo make install prefix=/usr/local sudo ldconfig @@ -67,16 +67,14 @@ Install pyspotify's dependencies. At Debian/Ubuntu systems:: In OS X no additional dependencies are needed. -Check out the pyspotify code, and install it:: +Get the pyspotify code, and install it:: - git clone git://github.com/jodal/pyspotify.git + wget --no-check-certificate -O pyspotify.tar.gz https://github.com/mopidy/pyspotify/tarball/mopidy + tar zxfv pyspotify.tar.gz cd pyspotify/pyspotify/ - sudo rm -rf build/ # If you are upgrading pyspotify sudo python setup.py install -.. note:: - - The ``sudo rm -rf build/`` step is needed if you are upgrading pyspotify. - Simply running ``python setup.py clean`` will *not* clean out the C parts - of the ``build/`` directory, and you will thus not get any changes to the C - code included in your installation. +It is important that you install pyspotify from the ``mopidy`` branch of the +``mopidy/pyspotify`` repository, as the upstream repository at +``winjer/pyspotify`` is not updated with changes needed to support e.g. +libspotify 0.0.6 and high bitrate audio. From 27f6e95e1f268439e8e6d700d1980810f32a4a42 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 28 Dec 2010 15:42:52 +0100 Subject: [PATCH 13/35] Minimize diff with master branch --- docs/installation/libspotify.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation/libspotify.rst b/docs/installation/libspotify.rst index b511e9c9..afb54d16 100644 --- a/docs/installation/libspotify.rst +++ b/docs/installation/libspotify.rst @@ -72,7 +72,7 @@ Install pyspotify's dependencies. At Debian/Ubuntu systems:: In OS X no additional dependencies are needed. -Check out the pyspotify code, and install it:: +Get the pyspotify code, and install it:: wget --no-check-certificate -O pyspotify.tar.gz https://github.com/mopidy/pyspotify/tarball/mopidy tar zxfv pyspotify.tar.gz From 19683539ea30e2c20900299ff609c028c3666df9 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 31 Dec 2010 17:25:25 +0100 Subject: [PATCH 14/35] Make mopidy.desktop pass desktop-file-validate validation --- data/mopidy.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/mopidy.desktop b/data/mopidy.desktop index f5ca43bb..70257d58 100644 --- a/data/mopidy.desktop +++ b/data/mopidy.desktop @@ -7,4 +7,4 @@ Icon=audio-x-generic TryExec=mopidy Exec=mopidy Terminal=true -Categories=AudioVideo;Audio;Player;ConsoleOnly +Categories=AudioVideo;Audio;Player;ConsoleOnly; From e8aaefa5cb8e9b4c50df2d475edd04919555ac70 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 7 Jan 2011 19:04:41 +0100 Subject: [PATCH 15/35] Debian packaging has moved to its own repo --- debian/TODO | 14 -------------- debian/changelog | 5 ----- debian/compat | 1 - debian/control | 22 ---------------------- debian/copyright | 38 -------------------------------------- debian/docs | 2 -- debian/menu | 2 -- debian/pyversions | 1 - debian/rules | 27 --------------------------- debian/source/format | 1 - debian/watch | 2 -- 11 files changed, 115 deletions(-) delete mode 100644 debian/TODO delete mode 100644 debian/changelog delete mode 100644 debian/compat delete mode 100644 debian/control delete mode 100644 debian/copyright delete mode 100644 debian/docs delete mode 100644 debian/menu delete mode 100644 debian/pyversions delete mode 100755 debian/rules delete mode 100644 debian/source/format delete mode 100644 debian/watch diff --git a/debian/TODO b/debian/TODO deleted file mode 100644 index 4551dc55..00000000 --- a/debian/TODO +++ /dev/null @@ -1,14 +0,0 @@ -To do for Mopidy's Debian packaging -=================================== - -- Install data/mopidy.desktop into /usr/share/applications/ -- Add manpages for all commands. Build the manpages with Sphinx -- Make init script run Mopidy as a daemon -- Make init script run Mopidy with its own user -- Add support for reading settings from /etc/mopidy/settings.py -- Log to /var/log -- Cache files in /var/cache -- Package pyspotify and add it to Recommends -- Package pylast and add it to Recommends -- Create GPG key for signing the package -- Host the packages at PPA or apt.mopidy.com diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index a04f2e78..00000000 --- a/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -mopidy (0.2.0-1) unstable; urgency=low - - * Initial release - - -- Stein Magnus Jodal Sun, 31 Oct 2010 13:07:04 +0100 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index 7f8f011e..00000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/debian/control b/debian/control deleted file mode 100644 index c2755717..00000000 --- a/debian/control +++ /dev/null @@ -1,22 +0,0 @@ -Source: mopidy -Section: sound -Priority: optional -Maintainer: Stein Magnus Jodal -Build-Depends: debhelper (>= 7.0.50~), python-support, python (>= 2.6), - python-sphinx (>= 1.0), python-pygraphviz -Standards-Version: 3.9.1 -Homepage: http://www.mopidy.com/ -Vcs-Git: git://github.com/jodal/mopidy.git -Vcs-Browser: http://github.com/jodal/mopidy - -Package: mopidy -Architecture: all -Depends: ${misc:Depends}, ${python:Depends}, python-gst0.10 -Recommends: gstreamer0.10-plugins-good, gstreamer0.10-plugins-ugly -Suggests: python-alsaaudio (>= 0.2), python-serial -Description: music server with MPD client support - Mopidy is a music server which can play music from Spotify or from your - local hard drive. To search for music in Spotify’s vast archive, manage - playlists, and play music, you can use most MPD clients. MPD clients are - available for most platforms, including Windows, Mac OS X, Linux, and - iPhone and Android phones. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index c29416d6..00000000 --- a/debian/copyright +++ /dev/null @@ -1,38 +0,0 @@ -This work was packaged for Debian by: - - Stein Magnus Jodal on Sun, 31 Oct 2010 09:50:28 +0100 - -It was downloaded from: - - http://pypi.python.org/packages/source/M/Mopidy/Mopidy-0.2.0.tar.gz - -Upstream Author(s): - - Stein Magnus Jodal - -Copyright: - - Copyright 2009-2010 Stein Magnus Jodal and contributors - -License: - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied. See the License for the specific language governing - permissions and limitations under the License. - -On Debian systems, the complete text of the Apache version 2.0 license -can be found in "/usr/share/common-licenses/Apache-2.0". - -The Debian packaging is: - - Copyright 2010 Stein Magnus Jodal - -and is licensed under the Apache License, Version 2.0, see above. diff --git a/debian/docs b/debian/docs deleted file mode 100644 index a4b46448..00000000 --- a/debian/docs +++ /dev/null @@ -1,2 +0,0 @@ -README.rst -docs/_build/html/ diff --git a/debian/menu b/debian/menu deleted file mode 100644 index 6376a81e..00000000 --- a/debian/menu +++ /dev/null @@ -1,2 +0,0 @@ -?package(mopidy):needs="text" section="Applications/Sound"\ - title="Mopidy" command="/usr/bin/mopidy" diff --git a/debian/pyversions b/debian/pyversions deleted file mode 100644 index 0c043f18..00000000 --- a/debian/pyversions +++ /dev/null @@ -1 +0,0 @@ -2.6- diff --git a/debian/rules b/debian/rules deleted file mode 100755 index 926a81b1..00000000 --- a/debian/rules +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -%: - dh $@ - -override_dh_clean: - make -C docs/ clean - dh_clean - -override_dh_installchangelogs: - dh_installchangelogs docs/changes.rst - -override_dh_installdocs: - make -C docs/ clean html - dh_installdocs - -.PHONY: override_dh_clean override_dh_installchangelogs \ - override_dh_installdocs override_dh_installinit diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 163aaf8d..00000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/debian/watch b/debian/watch deleted file mode 100644 index 3d4d3a41..00000000 --- a/debian/watch +++ /dev/null @@ -1,2 +0,0 @@ -version=3 -http://pypi.python.org/packages/source/M/Mopidy/Mopidy-(.*)\.tar\.gz From 7dce103d9056d38a6500859a26f54069122db4fc Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 7 Jan 2011 20:18:40 +0100 Subject: [PATCH 16/35] Fix crash in Last.fm frontend if pylast was not installed or frontend not configured --- mopidy/frontends/lastfm.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mopidy/frontends/lastfm.py b/mopidy/frontends/lastfm.py index e91dd272..c4ea73c4 100644 --- a/mopidy/frontends/lastfm.py +++ b/mopidy/frontends/lastfm.py @@ -54,7 +54,8 @@ class LastfmFrontend(BaseFrontend): self.thread.destroy() def process_message(self, message): - self.connection.send(message) + if self.thread.is_alive(): + self.connection.send(message) class LastfmFrontendThread(BaseThread): @@ -68,7 +69,7 @@ class LastfmFrontendThread(BaseThread): def run_inside_try(self): self.setup() - while True: + while self.scrobbler is not None: self.connection.poll(None) message = self.connection.recv() self.process_message(message) From d32d4b2cad7750c5021428ac958da5025bfd00c1 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 7 Jan 2011 20:38:48 +0100 Subject: [PATCH 17/35] Release v0.2.1 --- docs/changes.rst | 13 +++++++++++++ mopidy/__init__.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/changes.rst b/docs/changes.rst index 9e895419..3232cfcc 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -5,6 +5,19 @@ Changes This change log is used to track all major changes to Mopidy. +0.2.1 (2011-01-07) +================== + +This is a maintenance release without any new features. + +**Bugfixes** + +- Fix crash in :mod:`mopidy.frontends.lastfm` which occurred at playback if + either :mod:`pylast` was not installed or the Last.fm scrobbling was not + correctly configured. The scrobbling thread now shuts properly down at + failure. + + 0.2.0 (2010-10-24) ================== diff --git a/mopidy/__init__.py b/mopidy/__init__.py index 5e1b26de..350fc8d7 100644 --- a/mopidy/__init__.py +++ b/mopidy/__init__.py @@ -3,7 +3,7 @@ if not (2, 6) <= sys.version_info < (3,): sys.exit(u'Mopidy requires Python >= 2.6, < 3') def get_version(): - return u'0.2.0' + return u'0.2.1' class MopidyException(Exception): def __init__(self, message, *args, **kwargs): From 2161e6cb94840e5d1345ab6ad63847aa5963e7ee Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 7 Jan 2011 22:52:11 +0100 Subject: [PATCH 18/35] docs: Remove empty section on installing libspotify on Windows --- docs/installation/libspotify.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/installation/libspotify.rst b/docs/installation/libspotify.rst index afb54d16..cb352b8c 100644 --- a/docs/installation/libspotify.rst +++ b/docs/installation/libspotify.rst @@ -55,12 +55,6 @@ When libspotify has been installed, continue with :ref:`pyspotify_installation`. -Install libspotify on Windows -============================= - -**TODO** Test and document installation on Windows. - - .. _pyspotify_installation: Installing pyspotify From 0212e7181b8de646d75e7d532e6178508d114e74 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 8 Jan 2011 01:10:49 +0100 Subject: [PATCH 19/35] docs: Darker background on pre tags --- docs/_themes/nature/static/nature.css_t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_themes/nature/static/nature.css_t b/docs/_themes/nature/static/nature.css_t index 63ef80d6..b6c0f22e 100644 --- a/docs/_themes/nature/static/nature.css_t +++ b/docs/_themes/nature/static/nature.css_t @@ -214,7 +214,7 @@ p.admonition-title:after { pre { padding: 10px; - background-color: #fafafa; + background-color: #eeeeee; color: #222222; line-height: 1.5em; font-size: 1.1em; From 7e0047a8b5d77f877a3d0bc5a16169d94a6bd357 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 8 Jan 2011 01:25:13 +0100 Subject: [PATCH 20/35] docs: Rewrite installation docs and include the APT archive alternative --- docs/installation/gstreamer.rst | 29 +++++-- docs/installation/index.rst | 136 ++++++++++++++++++++++++------- docs/installation/libspotify.rst | 53 ++++++++++-- 3 files changed, 173 insertions(+), 45 deletions(-) diff --git a/docs/installation/gstreamer.rst b/docs/installation/gstreamer.rst index ad2761a3..72d55908 100644 --- a/docs/installation/gstreamer.rst +++ b/docs/installation/gstreamer.rst @@ -5,23 +5,32 @@ GStreamer installation To use the Mopidy, you first need to install GStreamer and its Python bindings. -Installing GStreamer on Linux -============================= +Installing GStreamer +==================== -GStreamer is packaged for most popular Linux distributions. If you use -Debian/Ubuntu you can install GStreamer with Aptitude:: +On Linux +-------- - sudo aptitude install python-gst0.10 gstreamer0.10-plugins-good \ +GStreamer is packaged for most popular Linux distributions. Search for +GStreamer in your package manager, and make sure to install the Python +bindings, and the "good" and "ugly" plugin sets. + +If you use Debian/Ubuntu you can install GStreamer like this:: + + sudo apt-get install python-gst0.10 gstreamer0.10-plugins-good \ gstreamer0.10-plugins-ugly +If you install Mopidy from our APT archive, you don't need to install GStreamer +yourself. The Mopidy Debian package will handle it for you. -Installing GStreamer on OS X -============================ + +On OS X from Homebrew +--------------------- .. note:: We have created GStreamer formulas for Homebrew to make the GStreamer - installation easy for you, but our formulas has not been merged into + installation easy for you, but not all our formulas have been merged into Homebrew's master branch yet. You should either fetch the formula files from `Homebrew's issue #1612 `_ yourself, or fall @@ -31,6 +40,10 @@ To install GStreamer on OS X using Homebrew:: brew install gst-python gst-plugins-good gst-plugins-ugly + +On OS X from MacPorts +--------------------- + To install GStreamer on OS X using MacPorts:: sudo port install py26-gst-python gstreamer-plugins-good \ diff --git a/docs/installation/index.rst b/docs/installation/index.rst index 142c5d84..d45ac1c9 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -2,10 +2,9 @@ Installation ************ -To get a basic version of Mopidy running, you need Python and the -:doc:`GStreamer library `. To use Spotify with Mopidy, you also need -:doc:`libspotify and pyspotify `. Mopidy itself can either be -installed from the Python package index, PyPI, or from git. +There are several ways to install Mopidy. What way is best depends upon your +setup and whether you want to use stable releases or less stable development +versions. Install dependencies @@ -17,7 +16,10 @@ Install dependencies gstreamer libspotify -Make sure you got the required dependencies installed. +If you install Mopidy from the APT archive, as described below, you can skip +the dependency installation part. + +Otherwise, make sure you got the required dependencies installed. - Python >= 2.6, < 3 @@ -44,49 +46,125 @@ Make sure you got the required dependencies installed. Install latest stable release ============================= -To install the currently latest stable release of Mopidy using ``pip``:: - sudo aptitude install python-setuptools python-pip # On Ubuntu/Debian - sudo brew install pip # On OS X - sudo pip install -U Mopidy +From APT archive +---------------- -To later upgrade to the latest release, just rerun the last command. +If you run a Debian based Linux distribution, like Ubuntu, the easiest way to +install Mopidy is from the Mopidy APT archive. When installing from the APT +archive, you will automatically get updates to Mopidy in the same way as you +get updates to the rest of your distribution. -If you for some reason can't use ``pip``, try ``easy_install``. +#. Add the archive's GPG key:: -Next, you need to set a couple of :doc:`settings `, and then you're -ready to :doc:`run Mopidy `. + wget -q -O - http://apt.mopidy.com/mopidy.gpg | sudo apt-key add - + +#. Add the following to ``/etc/apt/sources.list``, or if you have the directory + ``/etc/apt/sources.list.d/``, add it to a file called ``mopidy.list`` in + that directory:: + + # Mopidy APT archive + deb http://apt.mopidy.com/ stable main contrib non-free + deb-src http://apt.mopidy.com/ stable main contrib non-free + +#. Install Mopidy and all dependencies:: + + sudo apt-get update + sudo apt-get install mopidy + +#. Next, you need to set a couple of :doc:`settings `, and then + you're ready to :doc:`run Mopidy `. + +When a new release is out, and you can't wait for you system to figure it out +for itself, run the following to force an upgrade:: + + sudo apt-get update + sudo apt-get dist-upgrade -Install development snapshot -============================ +From PyPI using Pip +------------------- -If you want to follow Mopidy development closer, you may install a snapshot of -Mopidy's ``develop`` branch:: +If you are on OS X or on Linux, but can't install from the APT archive, you can +install Mopidy from PyPI using Pip. - sudo aptitude install python-setuptools python-pip # On Ubuntu/Debian - sudo brew install pip # On OS X - sudo pip install mopidy==dev +#. When you install using Pip, you first need to ensure that all of Mopidy's + dependencies have been installed. See the section on dependencies above. -Next, you need to set a couple of :doc:`settings `, and then you're -ready to :doc:`run Mopidy `. +#. Then, you need to install Pip:: + + sudo aptitude install python-setuptools python-pip # On Ubuntu/Debian + sudo brew install pip # On OS X + +#. To install the currently latest stable release of Mopidy:: + + sudo pip install -U Mopidy + + To upgrade Mopidy to future releases, just rerun this command. + +#. Next, you need to set a couple of :doc:`settings `, and then + you're ready to :doc:`run Mopidy `. + +If you for some reason can't use Pip, try ``easy_install`` instead. -Track development using Git +Install development version =========================== -If you want to contribute to Mopidy, you should install Mopidy using Git:: +If you want to follow the development of Mopidy closer, you may install a +development version of Mopidy. These are not as stable as the releases, but +you'll get access to new features earlier and may help us by reporting issues. - sudo aptitude install git-core # On Ubuntu/Debian - sudo brew install git # On OS X - git clone git://github.com/mopidy/mopidy.git -You can then run Mopidy directly from the Git repository:: +From snapshot +------------- + +If you want to follow Mopidy development closer, you may install a snapshot of +Mopidy's ``develop`` branch. + +#. When you install using Pip, you first need to ensure that all of Mopidy's + dependencies have been installed. See the section on dependencies above. + +#. Then, you need to install Pip:: + + sudo aptitude install python-setuptools python-pip # On Ubuntu/Debian + sudo brew install pip # On OS X + +#. To install the latest snapshot of Mopidy, run:: + + sudo pip install mopidy==dev + + To upgrade Mopidy to future releases, just rerun this command. + +#. Next, you need to set a couple of :doc:`settings `, and then + you're ready to :doc:`run Mopidy `. + + +From Git +-------- + +If you want to contribute to Mopidy, you should install Mopidy using Git. + +#. When you install from Git, you first need to ensure that all of Mopidy's + dependencies have been installed. See the section on dependencies above. + +#. Then install Git, if haven't already:: + + sudo aptitude install git-core # On Ubuntu/Debian + sudo brew install git # On OS X + +#. Clone the official Mopidy repository, or your own fork of it:: + + git clone git://github.com/mopidy/mopidy.git + +#. Next, you need to set a couple of :doc:`settings `. + +#. You can then run Mopidy directly from the Git repository:: cd mopidy/ # Move into the Git repo dir python mopidy # Run python on the mopidy source code dir -To get the latest changes to Mopidy:: +#. Later, to get the latest changes to Mopidy:: cd mopidy/ git pull diff --git a/docs/installation/libspotify.rst b/docs/installation/libspotify.rst index cb352b8c..5d278fe2 100644 --- a/docs/installation/libspotify.rst +++ b/docs/installation/libspotify.rst @@ -19,8 +19,25 @@ install libspotify and `pyspotify `_. Spotify Group. -Installing libspotify on Linux -============================== +Installing libspotify +===================== + + +On Linux from APT archive +------------------------- + +If you run a Debian based Linux distribution, like Ubuntu, see +http://apt.mopidy.com/ for how to the Mopidy APT archive as a software source +on your installation. Then, simply run:: + + sudo apt-get install libspotify6 + +When libspotify has been installed, continue with +:ref:`pyspotify_installation`. + + +On Linux from source +-------------------- Download and install libspotify 0.0.6 for your OS and CPU architecture from https://developer.spotify.com/en/libspotify/. @@ -37,8 +54,8 @@ When libspotify has been installed, continue with :ref:`pyspotify_installation`. -Installing libspotify on OS X -============================= +On OS X from Homebrew +--------------------- In OS X you need to have `XCode `_ and `Homebrew `_ installed. Then, to install @@ -60,17 +77,37 @@ When libspotify has been installed, continue with Installing pyspotify ==================== -Install pyspotify's dependencies. At Debian/Ubuntu systems:: +When you've installed libspotify, it's time for making it available from Python +by installing pyspotify. - sudo aptitude install python-dev -In OS X no additional dependencies are needed. +On Linux from APT archive +------------------------- + +Assuming that you've already set up http://apt.mopidy.com/ as a software +source, run:: + + sudo apt-get install python-spotify + +If you haven't already installed libspotify, this command will install both +libspotify and pyspotify for you. + + +On Linux/OS X from source +------------------------- + +On Linux, you need to get the Python development files installed. On +Debian/Ubuntu systems run:: + + sudo apt-get install python-dev + +On OS X no additional dependencies are needed. Get the pyspotify code, and install it:: wget --no-check-certificate -O pyspotify.tar.gz https://github.com/mopidy/pyspotify/tarball/mopidy tar zxfv pyspotify.tar.gz - cd pyspotify/pyspotify/ + cd pyspotify/ sudo python setup.py install It is important that you install pyspotify from the ``mopidy`` branch of the From bb57ad9f60abfaf2e31b187c7644ac5341f842c7 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 8 Jan 2011 01:33:45 +0100 Subject: [PATCH 21/35] docs: Add note ArchLinux AUR package --- docs/installation/index.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/installation/index.rst b/docs/installation/index.rst index d45ac1c9..df41f521 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -116,8 +116,8 @@ development version of Mopidy. These are not as stable as the releases, but you'll get access to new features earlier and may help us by reporting issues. -From snapshot -------------- +From snapshot using Pip +----------------------- If you want to follow Mopidy development closer, you may install a snapshot of Mopidy's ``develop`` branch. @@ -172,3 +172,10 @@ If you want to contribute to Mopidy, you should install Mopidy using Git. For an introduction to ``git``, please visit `git-scm.com `_. Also, please read our :doc:`developer documentation `. + + +From AUR on ArchLinux +--------------------- + +If you are running ArchLinux, you can install a development snapshot of Mopidy +using the package found at http://aur.archlinux.org/packages.php?ID=44026. From 35e35054f0aa041d5a570fada0a51a91010a00e2 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 8 Jan 2011 01:42:33 +0100 Subject: [PATCH 22/35] docs: Update development roadmap --- docs/development/roadmap.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/development/roadmap.rst b/docs/development/roadmap.rst index 175c62ac..9db74a4d 100644 --- a/docs/development/roadmap.rst +++ b/docs/development/roadmap.rst @@ -27,7 +27,7 @@ Possible targets for the next version - Write-support for Spotify, i.e. playlist management. - Virtual directories with e.g. starred tracks from Spotify. - - **[WIP: possibly v0.3]** Support for 320 kbps audio. + - **[DONE: v0.3]** Support for 320 kbps audio. - Local backend: @@ -47,7 +47,7 @@ Stuff we want to do, but not right now, and maybe never recipies for all our dependencies and Mopidy itself to make OS X installation a breeze. See `Homebrew's issue #1612 `_. - - **[WIP]** Create `Debian packages + - **[DONE]** Create `Debian packages `_ of all our dependencies and Mopidy itself (hosted in our own Debian repo until we get stuff into the various distros) to make Debian/Ubuntu installation a breeze. From 3989891de5d17fe91b7a7d4bcffa8350826e5e16 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 8 Jan 2011 02:47:16 +0100 Subject: [PATCH 23/35] docs: Better instructions for ArchLinux (thanks to sandsmark) --- docs/installation/index.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/installation/index.rst b/docs/installation/index.rst index df41f521..746648f4 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -179,3 +179,12 @@ From AUR on ArchLinux If you are running ArchLinux, you can install a development snapshot of Mopidy using the package found at http://aur.archlinux.org/packages.php?ID=44026. + +To install it, you can use ``packer``, ``yaourt``, or do it by hand like this:: + + wget http://aur.archlinux.org/packages/mopidy-git/mopidy-git.tar.gz + tar xf mopidy-git.tar.gz + cd mopidy-git/ + makepkg -si + +To upgrade Mopidy to future releases, just rerun ``makepkg``. From 6a29222751468ccc81dd8bdec6349382be83da7b Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 8 Jan 2011 02:58:50 +0100 Subject: [PATCH 24/35] docs: Split ArchLinux instructions into several steps, like the others --- docs/installation/index.rst | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/installation/index.rst b/docs/installation/index.rst index 746648f4..f6754371 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -180,11 +180,18 @@ From AUR on ArchLinux If you are running ArchLinux, you can install a development snapshot of Mopidy using the package found at http://aur.archlinux.org/packages.php?ID=44026. -To install it, you can use ``packer``, ``yaourt``, or do it by hand like this:: +#. First, you should consider installing any optional dependencies not included + by the AUR package, like required for e.g. Last.fm scrobbling. - wget http://aur.archlinux.org/packages/mopidy-git/mopidy-git.tar.gz - tar xf mopidy-git.tar.gz - cd mopidy-git/ - makepkg -si +#. To install Mopidy with GStreamer, libspotify and pyspotify, you can use + ``packer``, ``yaourt``, or do it by hand like this:: -To upgrade Mopidy to future releases, just rerun ``makepkg``. + wget http://aur.archlinux.org/packages/mopidy-git/mopidy-git.tar.gz + tar xf mopidy-git.tar.gz + cd mopidy-git/ + makepkg -si + + To upgrade Mopidy to future releases, just rerun ``makepkg``. + +#. Next, you need to set a couple of :doc:`settings `, and then + you're ready to :doc:`run Mopidy `. From dbbde5fdd6f685a7cfdf17c2f7c7328f296795e1 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 8 Jan 2011 03:48:16 +0100 Subject: [PATCH 25/35] Update Last.fm frontend to use pylast>=0.5 and the new Scrobbling 2.0 API --- docs/changes.rst | 7 +++++++ mopidy/frontends/lastfm.py | 32 +++++++++++++++----------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index 4a8548bf..624f7ef4 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -21,6 +21,13 @@ No description yet. - Support high bitrate (320k) audio. See :attr:`mopidy.settings.SPOTIFY_HIGH_BITRATE` for details. +- Last.fm frontend: + + - If you use the Last.fm frontend, you need to upgrade to pylast 0.5. + + - Update to use Last.fm's new Scrobbling 2.0 API, as the old Submissions + Protocol 1.2.1 is deprecated. (Fixes: :issue:`33`) + **Changes** diff --git a/mopidy/frontends/lastfm.py b/mopidy/frontends/lastfm.py index ddd621f8..8d912f64 100644 --- a/mopidy/frontends/lastfm.py +++ b/mopidy/frontends/lastfm.py @@ -15,8 +15,8 @@ from mopidy.utils.process import BaseThread logger = logging.getLogger('mopidy.frontends.lastfm') -CLIENT_ID = u'mop' -CLIENT_VERSION = get_version() +API_KEY = '2236babefa8ebb3d93ea467560d00d04' +API_SECRET = '94d9a09c0cd5be955c4afaeaffcaefcd' # pylast raises UnicodeEncodeError on conversion from unicode objects to # ascii-encoded bytestrings, so we explicitly encode as utf-8 before passing @@ -34,7 +34,7 @@ class LastfmFrontend(BaseFrontend): **Dependencies:** - - `pylast `_ >= 0.4.30 + - `pylast `_ >= 0.5 **Settings:** @@ -64,12 +64,11 @@ class LastfmFrontendThread(BaseThread): self.name = u'LastfmFrontendThread' self.connection = connection self.lastfm = None - self.scrobbler = None self.last_start_time = None def run_inside_try(self): self.setup() - while self.scrobbler is not None: + while self.lastfm is not None: self.connection.poll(None) message = self.connection.recv() self.process_message(message) @@ -78,10 +77,9 @@ class LastfmFrontendThread(BaseThread): try: username = settings.LASTFM_USERNAME password_hash = pylast.md5(settings.LASTFM_PASSWORD) - self.lastfm = pylast.get_lastfm_network( + self.lastfm = pylast.LastFMNetwork( + api_key=API_KEY, api_secret=API_SECRET, username=username, password_hash=password_hash) - self.scrobbler = self.lastfm.get_scrobbler( - CLIENT_ID, CLIENT_VERSION) logger.info(u'Connected to Last.fm') except SettingsError as e: logger.info(u'Last.fm scrobbler not started') @@ -103,12 +101,13 @@ class LastfmFrontendThread(BaseThread): self.last_start_time = int(time.time()) logger.debug(u'Now playing track: %s - %s', artists, track.name) try: - self.scrobbler.report_now_playing( + self.lastfm.update_now_playing( artists.encode(ENCODING), track.name.encode(ENCODING), album=track.album.name.encode(ENCODING), - duration=duration, - track_number=track.track_no) + duration=str(duration), + track_number=str(track.track_no), + mbid=(track.musicbrainz_id or '').encode(ENCODING)) except (pylast.ScrobblingError, socket.error) as e: logger.warning(u'Last.fm now playing error: %s', e) @@ -127,14 +126,13 @@ class LastfmFrontendThread(BaseThread): self.last_start_time = int(time.time()) - duration logger.debug(u'Scrobbling track: %s - %s', artists, track.name) try: - self.scrobbler.scrobble( + self.lastfm.scrobble( artists.encode(ENCODING), track.name.encode(ENCODING), - time_started=self.last_start_time, - source=pylast.SCROBBLE_SOURCE_USER, - mode=pylast.SCROBBLE_MODE_PLAYED, - duration=duration, + str(self.last_start_time), album=track.album.name.encode(ENCODING), - track_number=track.track_no) + track_number=str(track.track_no), + duration=str(duration), + mbid=(track.musicbrainz_id or '').encode(ENCODING)) except (pylast.ScrobblingError, socket.error) as e: logger.warning(u'Last.fm scrobbling error: %s', e) From 85d4dde338c6b8b02bf52952fa24ed781e7c3079 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sun, 9 Jan 2011 13:04:28 +0100 Subject: [PATCH 26/35] Forgot to update pylast version in requirements file --- requirements/lastfm.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/lastfm.txt b/requirements/lastfm.txt index 642735be..887a0f0d 100644 --- a/requirements/lastfm.txt +++ b/requirements/lastfm.txt @@ -1 +1 @@ -pylast >= 0.4.30 +pylast >= 0.5 From a14f114d2aed2f45a41ca8809da095f684b6ca2d Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sun, 9 Jan 2011 22:54:18 +0100 Subject: [PATCH 27/35] Fix crash for Spotify users with playlist folders --- docs/changes.rst | 4 ++++ mopidy/backends/libspotify/session_manager.py | 1 + mopidy/backends/libspotify/translator.py | 22 ++++++++++++++----- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index 624f7ef4..72e9217b 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -21,6 +21,10 @@ No description yet. - Support high bitrate (320k) audio. See :attr:`mopidy.settings.SPOTIFY_HIGH_BITRATE` for details. + - Catch and log error caused by playlist folder boundaries being threated as + normal playlists. More permanent fix requires support for checking playlist + types in pyspotify. + - Last.fm frontend: - If you use the Last.fm frontend, you need to upgrade to pylast 0.5. diff --git a/mopidy/backends/libspotify/session_manager.py b/mopidy/backends/libspotify/session_manager.py index 8a79088f..f736a40e 100644 --- a/mopidy/backends/libspotify/session_manager.py +++ b/mopidy/backends/libspotify/session_manager.py @@ -54,6 +54,7 @@ class LibspotifySessionManager(SpotifySessionManager, BaseThread): for spotify_playlist in session.playlist_container(): playlists.append( LibspotifyTranslator.to_mopidy_playlist(spotify_playlist)) + playlists = filter(None, playlists) self.core_queue.put({ 'command': 'set_stored_playlists', 'playlists': playlists, diff --git a/mopidy/backends/libspotify/translator.py b/mopidy/backends/libspotify/translator.py index 09303eda..4a42cf97 100644 --- a/mopidy/backends/libspotify/translator.py +++ b/mopidy/backends/libspotify/translator.py @@ -1,11 +1,14 @@ import datetime as dt +import logging -from spotify import Link +from spotify import Link, SpotifyError from mopidy import settings from mopidy.backends.libspotify import ENCODING from mopidy.models import Artist, Album, Track, Playlist +logger = logging.getLogger('mopidy.backends.libspotify.translator') + class LibspotifyTranslator(object): @classmethod def to_mopidy_artist(cls, spotify_artist): @@ -47,8 +50,15 @@ class LibspotifyTranslator(object): def to_mopidy_playlist(cls, spotify_playlist): if not spotify_playlist.is_loaded(): return Playlist(name=u'[loading...]') - return Playlist( - uri=str(Link.from_playlist(spotify_playlist)), - name=spotify_playlist.name().decode(ENCODING), - tracks=[cls.to_mopidy_track(t) for t in spotify_playlist], - ) + # FIXME Replace this try-except with a check on the playlist type, + # which is currently not supported by pyspotify, to avoid handling + # playlist folder boundaries like normal playlists. + try: + return Playlist( + uri=str(Link.from_playlist(spotify_playlist)), + name=spotify_playlist.name().decode(ENCODING), + tracks=[cls.to_mopidy_track(t) for t in spotify_playlist], + ) + except SpotifyError, e: + logger.warning(u'Failed translating Spotify playlist ' + '(probably a playlist folder boundary): %s', e) From 469e5fa189774b87e711b6480375175576c85eeb Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sun, 9 Jan 2011 23:38:46 +0100 Subject: [PATCH 28/35] Fix volume setting for Droid MPD --- docs/changes.rst | 5 +++++ mopidy/frontends/mpd/protocol/playback.py | 5 +++++ tests/frontends/mpd/playback_test.py | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/docs/changes.rst b/docs/changes.rst index 72e9217b..931e99cf 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -54,6 +54,11 @@ No description yet. application menus. - Create infrastructure for creating Debian packages of Mopidy. +- MPD frontend: + + - Support ``setvol 50`` without quotes around the argument. Fixes volume + control in Droid MPD. + - Local backend: - Add :command:`mopidy-scan` command to generate ``tag_cache`` files without diff --git a/mopidy/frontends/mpd/protocol/playback.py b/mopidy/frontends/mpd/protocol/playback.py index 2f5dd29e..13f7d2a8 100644 --- a/mopidy/frontends/mpd/protocol/playback.py +++ b/mopidy/frontends/mpd/protocol/playback.py @@ -320,6 +320,7 @@ def seekid(frontend, cpid, seconds): playid(frontend, cpid) frontend.backend.playback.seek(int(seconds) * 1000) +@handle_pattern(r'^setvol (?P[-+]*\d+)$') @handle_pattern(r'^setvol "(?P[-+]*\d+)"$') def setvol(frontend, volume): """ @@ -328,6 +329,10 @@ def setvol(frontend, volume): ``setvol {VOL}`` Sets volume to ``VOL``, the range of volume is 0-100. + + *Droid MPD:* + + - issues ``setvol 50`` without quotes around the argument. """ volume = int(volume) if volume < 0: diff --git a/tests/frontends/mpd/playback_test.py b/tests/frontends/mpd/playback_test.py index 4e60546d..f6e22641 100644 --- a/tests/frontends/mpd/playback_test.py +++ b/tests/frontends/mpd/playback_test.py @@ -104,6 +104,11 @@ class PlaybackOptionsHandlerTest(unittest.TestCase): self.assert_(u'OK' in result) self.assertEqual(10, self.b.mixer.volume) + def test_setvol_without_quotes(self): + result = self.h.handle_request(u'setvol 50') + self.assert_(u'OK' in result) + self.assertEqual(50, self.b.mixer.volume) + def test_single_off(self): result = self.h.handle_request(u'single "0"') self.assertFalse(self.b.playback.single) From 3eb1d477651ef92c13da21995279c4ad1ae856ad Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sun, 9 Jan 2011 23:46:03 +0100 Subject: [PATCH 29/35] Fix seek for Droid MPD --- docs/changes.rst | 2 ++ mopidy/frontends/mpd/protocol/playback.py | 5 +++++ tests/frontends/mpd/playback_test.py | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/docs/changes.rst b/docs/changes.rst index 931e99cf..03044731 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -58,6 +58,8 @@ No description yet. - Support ``setvol 50`` without quotes around the argument. Fixes volume control in Droid MPD. + - Support ``seek 1 120`` without quotes around the arguments. Fixes seek in + Droid MPD. - Local backend: diff --git a/mopidy/frontends/mpd/protocol/playback.py b/mopidy/frontends/mpd/protocol/playback.py index 13f7d2a8..19922bc3 100644 --- a/mopidy/frontends/mpd/protocol/playback.py +++ b/mopidy/frontends/mpd/protocol/playback.py @@ -293,6 +293,7 @@ def replay_gain_status(frontend): """ return u'off' # TODO +@handle_pattern(r'^seek (?P\d+) (?P\d+)$') @handle_pattern(r'^seek "(?P\d+)" "(?P\d+)"$') def seek(frontend, songpos, seconds): """ @@ -302,6 +303,10 @@ def seek(frontend, songpos, seconds): Seeks to the position ``TIME`` (in seconds) of entry ``SONGPOS`` in the playlist. + + *Droid MPD:* + + - issues ``seek 1 120`` without quotes around the arguments. """ if frontend.backend.playback.current_playlist_position != songpos: playpos(frontend, songpos) diff --git a/tests/frontends/mpd/playback_test.py b/tests/frontends/mpd/playback_test.py index f6e22641..43614173 100644 --- a/tests/frontends/mpd/playback_test.py +++ b/tests/frontends/mpd/playback_test.py @@ -325,6 +325,13 @@ class PlaybackControlHandlerTest(unittest.TestCase): result = self.h.handle_request(u'seek "1" "30"') self.assertEqual(self.b.playback.current_track, seek_track) + def test_seek_without_quotes(self): + self.b.current_playlist.append([Track(length=40000)]) + self.h.handle_request(u'seek 0') + result = self.h.handle_request(u'seek 0 30') + self.assert_(u'OK' in result) + self.assert_(self.b.playback.time_position >= 30000) + def test_seekid(self): self.b.current_playlist.append([Track(length=40000)]) result = self.h.handle_request(u'seekid "0" "30"') From 8503fe7b9e32210eedf39cbc674c447be1f795ab Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 10 Jan 2011 16:08:05 +0100 Subject: [PATCH 30/35] pylast 0.5 seems to prefer unicode over utf-8 encoded bytestrings --- mopidy/frontends/lastfm.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/mopidy/frontends/lastfm.py b/mopidy/frontends/lastfm.py index 8d912f64..60c2d708 100644 --- a/mopidy/frontends/lastfm.py +++ b/mopidy/frontends/lastfm.py @@ -18,11 +18,6 @@ logger = logging.getLogger('mopidy.frontends.lastfm') API_KEY = '2236babefa8ebb3d93ea467560d00d04' API_SECRET = '94d9a09c0cd5be955c4afaeaffcaefcd' -# pylast raises UnicodeEncodeError on conversion from unicode objects to -# ascii-encoded bytestrings, so we explicitly encode as utf-8 before passing -# strings to pylast. -ENCODING = u'utf-8' - class LastfmFrontend(BaseFrontend): """ Frontend which scrobbles the music you play to your `Last.fm @@ -102,12 +97,12 @@ class LastfmFrontendThread(BaseThread): logger.debug(u'Now playing track: %s - %s', artists, track.name) try: self.lastfm.update_now_playing( - artists.encode(ENCODING), - track.name.encode(ENCODING), - album=track.album.name.encode(ENCODING), + artists, + track.name, + album=track.album.name, duration=str(duration), track_number=str(track.track_no), - mbid=(track.musicbrainz_id or '').encode(ENCODING)) + mbid=(track.musicbrainz_id or '')) except (pylast.ScrobblingError, socket.error) as e: logger.warning(u'Last.fm now playing error: %s', e) @@ -127,12 +122,12 @@ class LastfmFrontendThread(BaseThread): logger.debug(u'Scrobbling track: %s - %s', artists, track.name) try: self.lastfm.scrobble( - artists.encode(ENCODING), - track.name.encode(ENCODING), + artists, + track.name, str(self.last_start_time), - album=track.album.name.encode(ENCODING), + album=track.album.name, track_number=str(track.track_no), duration=str(duration), - mbid=(track.musicbrainz_id or '').encode(ENCODING)) + mbid=(track.musicbrainz_id or '')) except (pylast.ScrobblingError, socket.error) as e: logger.warning(u'Last.fm scrobbling error: %s', e) From 099544d9158c709fe051cb9b04ec6a7382d968b3 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 10 Jan 2011 16:45:44 +0100 Subject: [PATCH 31/35] Rename libspotify backend to simply 'spotify', as suggested by adamcik and knutz3n half a year ago --- docs/api/backends/providers.rst | 2 +- docs/changes.rst | 4 ++ docs/installation/index.rst | 2 +- docs/modules/backends/libspotify.rst | 7 --- docs/modules/backends/spotify.rst | 7 +++ .../{libspotify => spotify}/__init__.py | 49 +++++++++--------- .../{libspotify => spotify}/library.py | 10 ++-- .../{libspotify => spotify}/playback.py | 4 +- .../session_manager.py | 19 +++---- .../spotify_appkey.key | Bin .../stored_playlists.py | 2 +- .../{libspotify => spotify}/translator.py | 6 +-- mopidy/settings.py | 16 +++--- 13 files changed, 67 insertions(+), 61 deletions(-) delete mode 100644 docs/modules/backends/libspotify.rst create mode 100644 docs/modules/backends/spotify.rst rename mopidy/backends/{libspotify => spotify}/__init__.py (61%) rename mopidy/backends/{libspotify => spotify}/library.py (87%) rename mopidy/backends/{libspotify => spotify}/playback.py (91%) rename mopidy/backends/{libspotify => spotify}/session_manager.py (87%) rename mopidy/backends/{libspotify => spotify}/spotify_appkey.key (100%) rename mopidy/backends/{libspotify => spotify}/stored_playlists.py (84%) rename mopidy/backends/{libspotify => spotify}/translator.py (93%) diff --git a/docs/api/backends/providers.rst b/docs/api/backends/providers.rst index 9289dd06..903e220b 100644 --- a/docs/api/backends/providers.rst +++ b/docs/api/backends/providers.rst @@ -37,5 +37,5 @@ Backend provider implementations ================================ * :mod:`mopidy.backends.dummy` -* :mod:`mopidy.backends.libspotify` +* :mod:`mopidy.backends.spotify` * :mod:`mopidy.backends.local` diff --git a/docs/changes.rst b/docs/changes.rst index 03044731..ddb46bb8 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -21,6 +21,10 @@ No description yet. - Support high bitrate (320k) audio. See :attr:`mopidy.settings.SPOTIFY_HIGH_BITRATE` for details. + - Rename :mod:`mopidy.backends.libspotify` to :mod:`mopidy.backends.spotify`. + If you have set :attr:`mopidy.settings.BACKENDS` explicitly, you may need + to update the setting's value. + - Catch and log error caused by playlist folder boundaries being threated as normal playlists. More permanent fix requires support for checking playlist types in pyspotify. diff --git a/docs/installation/index.rst b/docs/installation/index.rst index f6754371..26b50994 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -31,7 +31,7 @@ Otherwise, make sure you got the required dependencies installed. - Dependencies for at least one Mopidy backend: - - The default backend, :mod:`mopidy.backends.libspotify`, requires libspotify + - The default backend, :mod:`mopidy.backends.spotify`, requires libspotify and pyspotify. See :doc:`libspotify`. - The local backend, :mod:`mopidy.backends.local`, requires no additional diff --git a/docs/modules/backends/libspotify.rst b/docs/modules/backends/libspotify.rst deleted file mode 100644 index e7528757..00000000 --- a/docs/modules/backends/libspotify.rst +++ /dev/null @@ -1,7 +0,0 @@ -******************************************************* -:mod:`mopidy.backends.libspotify` -- Libspotify backend -******************************************************* - -.. automodule:: mopidy.backends.libspotify - :synopsis: Spotify backend using the libspotify library - :members: diff --git a/docs/modules/backends/spotify.rst b/docs/modules/backends/spotify.rst new file mode 100644 index 00000000..938d6337 --- /dev/null +++ b/docs/modules/backends/spotify.rst @@ -0,0 +1,7 @@ +************************************************* +:mod:`mopidy.backends.spotify` -- Spotify backend +************************************************* + +.. automodule:: mopidy.backends.spotify + :synopsis: Backend for the Spotify music streaming service + :members: diff --git a/mopidy/backends/libspotify/__init__.py b/mopidy/backends/spotify/__init__.py similarity index 61% rename from mopidy/backends/libspotify/__init__.py rename to mopidy/backends/spotify/__init__.py index ad2926c7..d36f6250 100644 --- a/mopidy/backends/libspotify/__init__.py +++ b/mopidy/backends/spotify/__init__.py @@ -4,54 +4,55 @@ from mopidy import settings from mopidy.backends.base import (Backend, CurrentPlaylistController, LibraryController, PlaybackController, StoredPlaylistsController) -logger = logging.getLogger('mopidy.backends.libspotify') +logger = logging.getLogger('mopidy.backends.spotify') ENCODING = 'utf-8' -class LibspotifyBackend(Backend): +class SpotifyBackend(Backend): """ - A `Spotify `_ backend which uses the official - `libspotify `_ - library and the `pyspotify `_ Python - bindings for libspotify. - - **Issues:** - http://github.com/mopidy/mopidy/issues/labels/backend-libspotify - - **Settings:** - - - :attr:`mopidy.settings.SPOTIFY_CACHE_PATH` - - :attr:`mopidy.settings.SPOTIFY_USERNAME` - - :attr:`mopidy.settings.SPOTIFY_PASSWORD` + A backend for playing music from the `Spotify `_ + music streaming service. The backend uses the official `libspotify + `_ library and the + `pyspotify `_ Python bindings for + libspotify. .. note:: This product uses SPOTIFY(R) CORE but is not endorsed, certified or otherwise approved in any way by Spotify. Spotify is the registered trade mark of the Spotify Group. + + **Issues:** + http://github.com/mopidy/mopidy/issues/labels/backend-spotify + + **Settings:** + + - :attr:`mopidy.settings.SPOTIFY_CACHE_PATH` + - :attr:`mopidy.settings.SPOTIFY_USERNAME` + - :attr:`mopidy.settings.SPOTIFY_PASSWORD` """ # Imports inside methods are to prevent loading of __init__.py to fail on # missing spotify dependencies. def __init__(self, *args, **kwargs): - from .library import LibspotifyLibraryProvider - from .playback import LibspotifyPlaybackProvider - from .stored_playlists import LibspotifyStoredPlaylistsProvider + from .library import SpotifyLibraryProvider + from .playback import SpotifyPlaybackProvider + from .stored_playlists import SpotifyStoredPlaylistsProvider - super(LibspotifyBackend, self).__init__(*args, **kwargs) + super(SpotifyBackend, self).__init__(*args, **kwargs) self.current_playlist = CurrentPlaylistController(backend=self) - library_provider = LibspotifyLibraryProvider(backend=self) + library_provider = SpotifyLibraryProvider(backend=self) self.library = LibraryController(backend=self, provider=library_provider) - playback_provider = LibspotifyPlaybackProvider(backend=self) + playback_provider = SpotifyPlaybackProvider(backend=self) self.playback = PlaybackController(backend=self, provider=playback_provider) - stored_playlists_provider = LibspotifyStoredPlaylistsProvider( + stored_playlists_provider = SpotifyStoredPlaylistsProvider( backend=self) self.stored_playlists = StoredPlaylistsController(backend=self, provider=stored_playlists_provider) @@ -61,11 +62,11 @@ class LibspotifyBackend(Backend): self.spotify = self._connect() def _connect(self): - from .session_manager import LibspotifySessionManager + from .session_manager import SpotifySessionManager logger.info(u'Mopidy uses SPOTIFY(R) CORE') logger.debug(u'Connecting to Spotify') - spotify = LibspotifySessionManager( + spotify = SpotifySessionManager( settings.SPOTIFY_USERNAME, settings.SPOTIFY_PASSWORD, core_queue=self.core_queue, output=self.output) diff --git a/mopidy/backends/libspotify/library.py b/mopidy/backends/spotify/library.py similarity index 87% rename from mopidy/backends/libspotify/library.py rename to mopidy/backends/spotify/library.py index 948c69b2..16391473 100644 --- a/mopidy/backends/libspotify/library.py +++ b/mopidy/backends/spotify/library.py @@ -4,13 +4,13 @@ import multiprocessing from spotify import Link, SpotifyError from mopidy.backends.base import BaseLibraryProvider -from mopidy.backends.libspotify import ENCODING -from mopidy.backends.libspotify.translator import LibspotifyTranslator +from mopidy.backends.spotify import ENCODING +from mopidy.backends.spotify.translator import SpotifyTranslator from mopidy.models import Playlist -logger = logging.getLogger('mopidy.backends.libspotify.library') +logger = logging.getLogger('mopidy.backends.spotify.library') -class LibspotifyLibraryProvider(BaseLibraryProvider): +class SpotifyLibraryProvider(BaseLibraryProvider): def find_exact(self, **query): return self.search(**query) @@ -20,7 +20,7 @@ class LibspotifyLibraryProvider(BaseLibraryProvider): # TODO Block until metadata_updated callback is called. Before that # the track will be unloaded, unless it's already in the stored # playlists. - return LibspotifyTranslator.to_mopidy_track(spotify_track) + return SpotifyTranslator.to_mopidy_track(spotify_track) except SpotifyError as e: logger.warning(u'Failed to lookup: %s', uri, e) return None diff --git a/mopidy/backends/libspotify/playback.py b/mopidy/backends/spotify/playback.py similarity index 91% rename from mopidy/backends/libspotify/playback.py rename to mopidy/backends/spotify/playback.py index 29409ff4..a066d90e 100644 --- a/mopidy/backends/libspotify/playback.py +++ b/mopidy/backends/spotify/playback.py @@ -4,9 +4,9 @@ from spotify import Link, SpotifyError from mopidy.backends.base import BasePlaybackProvider -logger = logging.getLogger('mopidy.backends.libspotify.playback') +logger = logging.getLogger('mopidy.backends.spotify.playback') -class LibspotifyPlaybackProvider(BasePlaybackProvider): +class SpotifyPlaybackProvider(BasePlaybackProvider): def pause(self): return self.backend.output.set_state('PAUSED') diff --git a/mopidy/backends/libspotify/session_manager.py b/mopidy/backends/spotify/session_manager.py similarity index 87% rename from mopidy/backends/libspotify/session_manager.py rename to mopidy/backends/spotify/session_manager.py index f736a40e..6ec6b4c9 100644 --- a/mopidy/backends/libspotify/session_manager.py +++ b/mopidy/backends/spotify/session_manager.py @@ -2,28 +2,29 @@ import logging import os import threading -from spotify.manager import SpotifySessionManager +import spotify.manager from mopidy import get_version, settings -from mopidy.backends.libspotify.translator import LibspotifyTranslator +from mopidy.backends.spotify.translator import SpotifyTranslator from mopidy.models import Playlist from mopidy.utils.process import BaseThread -logger = logging.getLogger('mopidy.backends.libspotify.session_manager') +logger = logging.getLogger('mopidy.backends.spotify.session_manager') # pylint: disable = R0901 -# LibspotifySessionManager: Too many ancestors (9/7) +# SpotifySessionManager: Too many ancestors (9/7) -class LibspotifySessionManager(SpotifySessionManager, BaseThread): +class SpotifySessionManager(spotify.manager.SpotifySessionManager, BaseThread): cache_location = settings.SPOTIFY_CACHE_PATH settings_location = settings.SPOTIFY_CACHE_PATH appkey_file = os.path.join(os.path.dirname(__file__), 'spotify_appkey.key') user_agent = 'Mopidy %s' % get_version() def __init__(self, username, password, core_queue, output): - SpotifySessionManager.__init__(self, username, password) + spotify.manager.SpotifySessionManager.__init__( + self, username, password) BaseThread.__init__(self, core_queue) - self.name = 'LibspotifySMThread' + self.name = 'SpotifySMThread' self.output = output self.connected = threading.Event() self.session = None @@ -53,7 +54,7 @@ class LibspotifySessionManager(SpotifySessionManager, BaseThread): playlists = [] for spotify_playlist in session.playlist_container(): playlists.append( - LibspotifyTranslator.to_mopidy_playlist(spotify_playlist)) + SpotifyTranslator.to_mopidy_playlist(spotify_playlist)) playlists = filter(None, playlists) self.core_queue.put({ 'command': 'set_stored_playlists', @@ -111,7 +112,7 @@ class LibspotifySessionManager(SpotifySessionManager, BaseThread): def callback(results, userdata=None): # TODO Include results from results.albums(), etc. too playlist = Playlist(tracks=[ - LibspotifyTranslator.to_mopidy_track(t) + SpotifyTranslator.to_mopidy_track(t) for t in results.tracks()]) connection.send(playlist) self.connected.wait() diff --git a/mopidy/backends/libspotify/spotify_appkey.key b/mopidy/backends/spotify/spotify_appkey.key similarity index 100% rename from mopidy/backends/libspotify/spotify_appkey.key rename to mopidy/backends/spotify/spotify_appkey.key diff --git a/mopidy/backends/libspotify/stored_playlists.py b/mopidy/backends/spotify/stored_playlists.py similarity index 84% rename from mopidy/backends/libspotify/stored_playlists.py rename to mopidy/backends/spotify/stored_playlists.py index 6f2a7aad..054e2bd1 100644 --- a/mopidy/backends/libspotify/stored_playlists.py +++ b/mopidy/backends/spotify/stored_playlists.py @@ -1,6 +1,6 @@ from mopidy.backends.base import BaseStoredPlaylistsProvider -class LibspotifyStoredPlaylistsProvider(BaseStoredPlaylistsProvider): +class SpotifyStoredPlaylistsProvider(BaseStoredPlaylistsProvider): def create(self, name): pass # TODO diff --git a/mopidy/backends/libspotify/translator.py b/mopidy/backends/spotify/translator.py similarity index 93% rename from mopidy/backends/libspotify/translator.py rename to mopidy/backends/spotify/translator.py index 4a42cf97..50ee07d1 100644 --- a/mopidy/backends/libspotify/translator.py +++ b/mopidy/backends/spotify/translator.py @@ -4,12 +4,12 @@ import logging from spotify import Link, SpotifyError from mopidy import settings -from mopidy.backends.libspotify import ENCODING +from mopidy.backends.spotify import ENCODING from mopidy.models import Artist, Album, Track, Playlist -logger = logging.getLogger('mopidy.backends.libspotify.translator') +logger = logging.getLogger('mopidy.backends.spotify.translator') -class LibspotifyTranslator(object): +class SpotifyTranslator(object): @classmethod def to_mopidy_artist(cls, spotify_artist): if not spotify_artist.is_loaded(): diff --git a/mopidy/settings.py b/mopidy/settings.py index 1aaa4318..23aa7cb6 100644 --- a/mopidy/settings.py +++ b/mopidy/settings.py @@ -12,12 +12,12 @@ Available settings and their default values. #: #: Default:: #: -#: BACKENDS = (u'mopidy.backends.libspotify.LibspotifyBackend',) +#: BACKENDS = (u'mopidy.backends.spotify.SpotifyBackend',) #: #: .. note:: #: Currently only the first backend in the list is used. BACKENDS = ( - u'mopidy.backends.libspotify.LibspotifyBackend', + u'mopidy.backends.spotify.SpotifyBackend', ) #: The log format used for informational logging. @@ -169,24 +169,24 @@ MPD_SERVER_HOSTNAME = u'127.0.0.1' #: Default: 6600 MPD_SERVER_PORT = 6600 -#: Path to the libspotify cache. +#: Path to the Spotify cache. #: -#: Used by :mod:`mopidy.backends.libspotify`. -SPOTIFY_CACHE_PATH = u'~/.mopidy/libspotify_cache' +#: Used by :mod:`mopidy.backends.spotify`. +SPOTIFY_CACHE_PATH = u'~/.mopidy/spotify_cache' #: Your Spotify Premium username. #: -#: Used by :mod:`mopidy.backends.libspotify`. +#: Used by :mod:`mopidy.backends.spotify`. SPOTIFY_USERNAME = u'' #: Your Spotify Premium password. #: -#: Used by :mod:`mopidy.backends.libspotify`. +#: Used by :mod:`mopidy.backends.spotify`. SPOTIFY_PASSWORD = u'' #: Do you prefer high bitrate (320k)? #: -#: Used by :mod:`mopidy.backends.libspotify`. +#: Used by :mod:`mopidy.backends.spotify`. # #: Default:: #: From c2c39acbe87735954d7591a8b1e676f8994b6942 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 10 Jan 2011 17:03:54 +0100 Subject: [PATCH 32/35] Tweak log messages --- mopidy/backends/spotify/session_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mopidy/backends/spotify/session_manager.py b/mopidy/backends/spotify/session_manager.py index 6ec6b4c9..c32148c3 100644 --- a/mopidy/backends/spotify/session_manager.py +++ b/mopidy/backends/spotify/session_manager.py @@ -37,10 +37,10 @@ class SpotifySessionManager(spotify.manager.SpotifySessionManager, BaseThread): logger.info(u'Connected to Spotify') self.session = session if settings.SPOTIFY_HIGH_BITRATE: - logger.debug(u'Prefer high bitrate') + logger.debug(u'Preferring high bitrate from Spotify') self.session.set_preferred_bitrate(1) else: - logger.debug(u'Prefer normal bitrate') + logger.debug(u'Preferring normal bitrate from Spotify') self.session.set_preferred_bitrate(0) self.connected.set() From feead97b5bf1fef8e1de6929538f0482eaef346e Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 10 Jan 2011 22:13:06 +0100 Subject: [PATCH 33/35] Update reference to Spotify application key --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d77be3cd..d9d6af42 100644 --- a/setup.py +++ b/setup.py @@ -77,7 +77,7 @@ setup( author='Stein Magnus Jodal', author_email='stein.magnus@jodal.no', packages=packages, - package_data={'mopidy': ['backends/libspotify/spotify_appkey.key']}, + package_data={'mopidy': ['backends/spotify/spotify_appkey.key']}, cmdclass=cmdclasses, data_files=data_files, scripts=['bin/mopidy', 'bin/mopidy-scan'], From 9f5e97d14be6b0063357e96e301318eabcf2cd09 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 10 Jan 2011 23:18:12 +0100 Subject: [PATCH 34/35] Make all tests pass without having pyserial installed --- mopidy/mixers/denon.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mopidy/mixers/denon.py b/mopidy/mixers/denon.py index e6d752b6..f0712f95 100644 --- a/mopidy/mixers/denon.py +++ b/mopidy/mixers/denon.py @@ -1,8 +1,6 @@ import logging from threading import Lock -from serial import Serial - from mopidy import settings from mopidy.mixers.base import BaseMixer @@ -33,8 +31,11 @@ class DenonMixer(BaseMixer): """ super(DenonMixer, self).__init__(*args, **kwargs) device = kwargs.get('device', None) - self._device = device or Serial(port=settings.MIXER_EXT_PORT, - timeout=0.2) + if device: + self._device = device + else: + from serial import Serial + self._device = Serial(port=settings.MIXER_EXT_PORT, timeout=0.2) self._levels = ['99'] + ["%(#)02d" % {'#': v} for v in range(0, 99)] self._volume = 0 self._lock = Lock() From 65f8acb2873424ffee019ab546b2ebe0754b496e Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 11 Jan 2011 22:09:51 +0100 Subject: [PATCH 35/35] Split Spotify playlist refreshing out of metadata updated callback --- mopidy/backends/spotify/session_manager.py | 26 +++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/mopidy/backends/spotify/session_manager.py b/mopidy/backends/spotify/session_manager.py index c32148c3..9736f2eb 100644 --- a/mopidy/backends/spotify/session_manager.py +++ b/mopidy/backends/spotify/session_manager.py @@ -50,16 +50,8 @@ class SpotifySessionManager(spotify.manager.SpotifySessionManager, BaseThread): def metadata_updated(self, session): """Callback used by pyspotify""" - logger.debug(u'Metadata updated, refreshing stored playlists') - playlists = [] - for spotify_playlist in session.playlist_container(): - playlists.append( - SpotifyTranslator.to_mopidy_playlist(spotify_playlist)) - playlists = filter(None, playlists) - self.core_queue.put({ - 'command': 'set_stored_playlists', - 'playlists': playlists, - }) + logger.debug(u'Metadata updated') + self.refresh_stored_playlists() def connection_error(self, session, error): """Callback used by pyspotify""" @@ -107,6 +99,20 @@ class SpotifySessionManager(spotify.manager.SpotifySessionManager, BaseThread): logger.debug(u'End of data stream reached') self.output.end_of_data_stream() + def refresh_stored_playlists(self): + """Refresh the stored playlists in the backend with fresh meta data + from Spotify""" + playlists = [] + for spotify_playlist in self.session.playlist_container(): + playlists.append( + SpotifyTranslator.to_mopidy_playlist(spotify_playlist)) + playlists = filter(None, playlists) + self.core_queue.put({ + 'command': 'set_stored_playlists', + 'playlists': playlists, + }) + logger.debug(u'Refreshed %d stored playlist(s)', len(playlists)) + def search(self, query, connection): """Search method used by Mopidy backend""" def callback(results, userdata=None):