diff --git a/docs/changelog.rst b/docs/changelog.rst
index 38cde201..c4867a3c 100755
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -2,6 +2,18 @@
Changelog
*********
+
+v2.0.3 (2015-09-05)
+===================
+
+Bug fix release.
+
+- Make moving a playlist to its own location a no-op instead of causing an
+ error like libspotify does. (Fixes: :issue:`175`)
+
+- New better installation instructions. (Fixes: :issue:`174`)
+
+
v2.0.2 (2015-08-06)
===================
diff --git a/docs/conf.py b/docs/conf.py
index 94e83932..94255e13 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -96,7 +96,7 @@ def get_version(filename):
# -- Options for HTML output --------------------------------------------------
-html_theme = 'default'
+#html_theme = 'default'
html_static_path = ['_static']
html_use_modindex = True
diff --git a/docs/installation.rst b/docs/installation.rst
index df3c2a9f..1a8ed765 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -2,12 +2,107 @@
Installation
************
-Since pyspotify is a Python wrapper around the libspotify library, pyspotify
-necessarily depends on libspotify.
+pyspotify is packaged for various operating systems and in multiple Linux
+distributions. What way to install pyspotify is best for you depends upon your
+OS and/or distribution.
-Installing libspotify
-=====================
+.. _debian-install:
+
+Debian/Ubuntu: Install from apt.mopidy.com
+==========================================
+
+The `Mopidy `_ project runs its own APT archive which
+includes pyspotify built for:
+
+- Debian wheezy (oldstable), which also works for Ubuntu 12.04 LTS.
+- Debian jessie (stable), which also works for Ubuntu 14.04 LTS and newer.
+
+The packages are available for multiple CPU architectures: i386, amd64, armel,
+and armhf (compatible with Raspbian and Raspberry Pi 1).
+
+To install and receive future updates:
+
+1. Add the archive's GPG key::
+
+ wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add -
+
+2. If you run Debian wheezy or Ubuntu 12.04 LTS::
+
+ sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/wheezy.list
+
+ Or, if you run any newer Debian/Ubuntu distro::
+
+ sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/jessie.list
+
+3. Install pyspotify and all dependencies::
+
+ sudo apt-get update
+ sudo apt-get install python-spotify
+
+
+Arch Linux: Install from AUR
+============================
+
+If you are running Arch Linux, you can install Mopidy using the
+`python2-pyspotify package
+`_ found in AUR.
+
+1. To install pyspotify with all dependencies, run::
+
+ yaourt -S python2-pyspotify
+
+
+OS X: Install wheel package from PyPI with pip
+==============================================
+
+From PyPI, you can install precompiled wheel packages of pyspotify that bundle
+libspotify. The packages should work on all combinations of:
+
+- OS X 10.6 and newer
+- 32-bit and 64-bit
+- Apple-Python, Python.org-Python, Homebrew-Python
+
+1. Make sure you have a recent version of pip, which will default to installing
+ a wheel package if available::
+
+ pip install --upgrade pip
+
+2. Install pyspotify::
+
+ pip install pyspotify
+
+
+OS X: Install from Homebrew
+===========================
+
+The `Mopidy `__ project maintains its own `Homebrew
+tap `_ which includes pyspotify and
+its dependencies.
+
+1. Install `Homebrew `_.
+
+2. Make sure your installation is up to date::
+
+ brew update
+ brew upgrade --all
+
+3. Install pyspotify from the mopidy/mopidy tap::
+
+ brew install mopidy/mopidy/python-spotify
+
+
+Install from source
+===================
+
+If you are on Linux, but your distro don't package pyspotify, you can install
+pyspotify from PyPI using the pip installer. However, since pyspotify is a
+Python wrapper around the libspotify library, pyspotify necessarily depends on
+libspotify and it must be installed first.
+
+
+libspotify
+----------
libspotify is provided as a binary download for a selection of operating
systems and CPU architectures from the `libspotify site
@@ -19,25 +114,20 @@ To install libspotify, use one of the options below, or follow the instructions
on the libspotify site and in the README file of the libspotify tarball.
-Debian/Ubuntu/Raspbian
-----------------------
+Debian/Ubuntu
+~~~~~~~~~~~~~
-If you're running a Debian-based Linux distribution, like Ubuntu or Raspbian,
+If you're running a Debian-based Linux distribution, like Ubuntu,
you can get Debian packages of libspotify from `apt.mopidy.com
-`__. Follow the instructions on the site to add
-apt.mopidy.com as a software repository on your system. In summary::
-
- wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add -
- sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/mopidy.list
- sudo apt-get update
-
-Then install libspotify::
+`__. Follow the instructions :ref:`above
+` to make the apt.mopidy.com archive available on your system,
+then install libspotify::
sudo apt-get install libspotify-dev
Arch Linux
-----------
+~~~~~~~~~~
libspotify is packaged in `AUR
`_. To install libspotify,
@@ -47,7 +137,7 @@ run::
Fedora
-------
+~~~~~~
libspotify is packaged in `rpmfusion non-free `_.
Install the repository package, then run::
@@ -55,8 +145,8 @@ Install the repository package, then run::
yum -y install libspotify-devel
-Mac OS X
---------
+OS X
+~~~~
If you're using `Homebrew `_, it has a formula for
libspotify in the homebrew/binary tap::
@@ -81,34 +171,17 @@ libspotify in the homebrew/binary tap::
For details, or if you have a proper fix for this, see :issue:`130`.
-.. warning::
-
- It is currently unknown if pyspotify works with the Mac OS X download
- option from the libspotify web site. If you can provide any information
- either way, please open an issue.
-
-Installing pyspotify
-====================
+Build tools
+-----------
-You can install pyspotify from PyPI. PyPI may have a pyspotify package
-precompiled for your OS and architecture available as a wheel package. To
-install it run::
-
- pip install pyspotify
-
-If this fails, then pyspotify probably isn't available prebuilt for your OS and
-architecture. In that case, you'll need a C compiler, Python development
-headers, and libffi development headers to build pyspotify. When you got that
-in place, you can rerun the ``pip install pyspotify`` command to install
-pyspotify.
-
-Once you have pyspotify installed, you should head over to :doc:`quickstart`
-for a short introduction to pyspotify.
+To build pyspotify, you need a C compiler, Python development headers, and
+libffi development headers. All of this is easily installed using your system's
+package manager.
-Debian/Ubuntu/Raspbian
-----------------------
+Debian/Ubuntu
+~~~~~~~~~~~~~
If you're on a Debian-based system, you can install the pyspotify build
dependencies by running::
@@ -117,7 +190,7 @@ dependencies by running::
Arch Linux
-----------
+~~~~~~~~~~
If you're on Arch Linux, you can install the pyspotify build dependencies by
running::
@@ -125,27 +198,33 @@ running::
sudo pacman -S base-devel python2 python
-Mac OS X
---------
+OS X
+~~~~
-If you're on Mac OS X, you'll need to install the Xcode command line developer
+If you're on OS X, you'll need to install the Xcode command line developer
tools. Even if you've already installed Xcode from the App Store, e.g. to get
Homebrew working, you should run this command::
xcode-select --install
-If you get an error about ``ffi.h`` not being found when installing the cffi
-Python package, try running the above command.
+.. note::
-.. warning::
+ If you get an error about ``ffi.h`` not being found when installing the
+ cffi Python package, try running the above command.
- Due to a currently unresolved issue, the CFFI-generated C extension module
- in pyspotify is linked with libspotify without the ``.dylib`` file suffix.
- If ``pip install pyspotify`` fails with the message "Reason: image not
- found", then run the following command and rerun the pip command::
+pyspotify
+---------
- ln -s /usr/local/opt/libspotify/lib/libspotify.dylib \
- /usr/local/opt/libspotify/lib/libspotify
+With libspotify and the build tools in place, you can finally build pyspotify.
- If you know how to permanently fix this, please comment on :issue:`130`.
+To download and build pyspotify from PyPI, run::
+
+ pip install pyspotify
+
+Or, if you have a checkout of the pyspotify git repo, run::
+
+ pip install -e path/to/my/pyspotify/git/clone
+
+Once you have pyspotify installed, you should head over to :doc:`quickstart`
+for a short introduction to pyspotify.
diff --git a/spotify/__init__.py b/spotify/__init__.py
index a0fab8ce..62e0336f 100644
--- a/spotify/__init__.py
+++ b/spotify/__init__.py
@@ -3,7 +3,7 @@
import threading
-__version__ = '2.0.2'
+__version__ = '2.0.3'
# Global reentrant lock to be held whenever libspotify functions are called or
diff --git a/spotify/playlist_container.py b/spotify/playlist_container.py
index fbe9b32d..abf1d047 100644
--- a/spotify/playlist_container.py
+++ b/spotify/playlist_container.py
@@ -357,6 +357,8 @@ def move_playlist(self, from_index, to_index, dry_run=False):
If ``dry_run`` is :class:`True` the move isn't actually done. It is
only checked if the move is possible.
"""
+ if from_index == to_index:
+ return
spotify.Error.maybe_raise(lib.sp_playlistcontainer_move_playlist(
self._sp_playlistcontainer, from_index, to_index, int(dry_run)))
diff --git a/tests/test_playlist_container.py b/tests/test_playlist_container.py
index 1b0057ba..813e9928 100644
--- a/tests/test_playlist_container.py
+++ b/tests/test_playlist_container.py
@@ -1024,6 +1024,18 @@ def test_move_playlist_out_of_range_fails(self, lib_mock):
with self.assertRaises(spotify.Error):
playlist_container.move_playlist(5, 7)
+ def test_move_playlist_to_itself_is_a_noop(self, lib_mock):
+ lib_mock.sp_playlistcontainer_move_playlist.return_value = int(
+ spotify.ErrorType.INVALID_INDATA)
+ sp_playlistcontainer = spotify.ffi.cast('sp_playlistcontainer *', 42)
+ playlist_container = spotify.PlaylistContainer(
+ self.session, sp_playlistcontainer=sp_playlistcontainer)
+
+ playlist_container.move_playlist(5, 5)
+
+ self.assertEqual(
+ lib_mock.sp_playlistcontainer_move_playlist.call_count, 0)
+
@mock.patch('spotify.User', spec=spotify.User)
def test_owner(self, user_mock, lib_mock):
user_mock.return_value = mock.sentinel.user