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