diff --git a/README.rst b/README.rst
index 4f31fb59..c063de79 100644
--- a/README.rst
+++ b/README.rst
@@ -6,14 +6,15 @@ 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.
+platforms, including Windows, Mac OS X, Linux, Android and iOS.
To install Mopidy, check out
`the installation docs `_.
-* `Documentation (latest release) `_
-* `Documentation (development version) `_
-* `Source code `_
-* `Issue tracker `_
-* IRC: ``#mopidy`` at `irc.freenode.net `_
-* `Download development snapshot `_
+- `Documentation for the latest release `_
+- `Documentation for the development version
+ `_
+- `Source code `_
+- `Issue tracker `_
+- IRC: ``#mopidy`` at `irc.freenode.net `_
+- `Download development snapshot `_
diff --git a/docs/_static/mopidy.png b/docs/_static/mopidy.png
new file mode 100644
index 00000000..7d6ce5af
Binary files /dev/null and b/docs/_static/mopidy.png differ
diff --git a/docs/changes.rst b/docs/changes.rst
index ddb46bb8..326ae4af 100644
--- a/docs/changes.rst
+++ b/docs/changes.rst
@@ -8,8 +8,18 @@ This change log is used to track all major changes to Mopidy.
0.3.0 (in development)
======================
+.. warning:: Known bug in Spotify playlist loading
+
+ There is a known bug in the loading of Spotify playlists. This bug affects
+ both Mopidy 0.2.1 and 0.3.0, given that you use libspotify 0.0.6. To avoid
+ the bug, either use Mopidy 0.2.1 with libspotify 0.0.4, or use either
+ Mopidy version with libspotify 0.0.6 and follow the simple workaround
+ described at :issue:`59`.
+
+
No description yet.
+
**Important changes**
- Spotify backend:
@@ -36,6 +46,8 @@ No description yet.
- Update to use Last.fm's new Scrobbling 2.0 API, as the old Submissions
Protocol 1.2.1 is deprecated. (Fixes: :issue:`33`)
+ - Fix crash when track object does not contain all the expected meta data.
+
**Changes**
@@ -71,6 +83,11 @@ No description yet.
any help from the original MPD server.
- Support UTF-8 encoded tag caches with non-ASCII characters.
+- Mixers:
+
+ - Support use of unicode strings for :mod:`mopidy.mixers.nad` specific
+ settings.
+
- Models:
- Rename and generalize ``Playlist._with(**kwargs)`` to
diff --git a/docs/clients/mpd.rst b/docs/clients/mpd.rst
index de54dfcb..6ecfded5 100644
--- a/docs/clients/mpd.rst
+++ b/docs/clients/mpd.rst
@@ -16,11 +16,14 @@ mpc
A command line client. Version 0.14 had some issues with Mopidy (see
:issue:`5`), but 0.16 seems to work nicely.
+
ncmpc
-----
A console client. Uses the ``idle`` command heavily, which Mopidy doesn't
-support yet. If you want a console client, use ncmpcpp instead.
+support yet (see :issue:`32`). If you want a console client, use ncmpcpp
+instead.
+
ncmpcpp
-------
@@ -40,59 +43,262 @@ If you run Ubuntu 10.04 or older, you can fetch an updated version of ncmpcpp
from `Launchpad `_.
-
Graphical clients
=================
GMPC
----
-A GTK+ client which works well with Mopidy, and is regularly used by Mopidy
-developers.
+`GMPC `_ is a graphical MPD client (GTK+) which works
+well with Mopidy, and is regularly used by Mopidy developers.
+
+GMPC may sometimes requests a lot of meta data of related albums, artists, etc.
+This takes more time with Mopidy, which needs to query Spotify for the data,
+than with a normal MPD server, which has a local cache of meta data. Thus, GMPC
+may sometimes feel frozen, but usually you just need to give it a bit of slack
+before it will catch up.
+
Sonata
------
-A GTK+ client. Generally works well with Mopidy.
+`Sonata `_ is a graphical MPD client (GTK+).
+It generally works well with Mopidy, except for search.
-Search does not work, because they do most of the search on the client side.
-See :issue:`1` for details.
+When you search in Sonata, it only sends the first to letters of the search
+query to Mopidy, and then does the rest of the filtering itself on the client
+side. Since Spotify has a collection of millions of tracks and they only return
+the first 100 hits for any search query, searching for two-letter combinations
+seldom returns any useful results. See :issue:`1` and the matching `Sonata
+bug`_ for details.
+
+.. _Sonata bug: http://developer.berlios.de/feature/?func=detailfeature&feature_id=5038&group_id=7323
+
+
+Theremin
+--------
+
+`Theremin `_ is a graphical MPD client for OS X.
+It generally works well with Mopidy.
Android clients
===============
+We've tested all six MPD clients we could find for Android with Mopidy 0.3 on a
+HTC Hero with Android 2.1, using the following test procedure:
+
+#. Connect to Mopidy
+#. Search for ``foo``, with search type "any" if it can be selected
+#. Add "The Pretender" from the search results to the current playlist
+#. Start playback
+#. Pause and resume playback
+#. Adjust volume
+#. Find a playlist and append it to the current playlist
+#. Skip to next track
+#. Skip to previous track
+#. Select the last track from the current playlist
+#. Turn on repeat mode
+#. Seek to 10 seconds or so before the end of the track
+#. Wait for the end of the track and confirm that playback continues at the
+ start of the playlist
+#. Turn off repeat mode
+#. Turn on random mode
+#. Skip to next track and confirm that it random mode works
+#. Turn off random mode
+#. Stop playback
+#. Check if the app got support for single mode and consume mode
+#. Kill Mopidy and confirm that the app handles it without crashing
+
+In summary:
+
+- BitMPC lacks finishing touches on its user interface but supports all
+ features tested.
+- Droid MPD Client works well, but got a couple of bugs one can live with and
+ does not expose stored playlist anywhere.
+- IcyBeats is not usable yet.
+- MPDroid is working well and looking good, but does not have search
+ functionality.
+- PMix is just a lesser MPDroid, so use MPDroid instead.
+- ThreeMPD is too buggy to even get connected to Mopidy.
+
+Our recommendation:
+
+- If you do not care about looks, use BitMPC.
+- If you do not care about stored playlists, use Droid MPD Client.
+- If you do not care about searching, use MPDroid.
+
+
BitMPC
------
-Works well with Mopidy.
+We tested version 1.0.0, which at the time had 1k-5k downloads, <100 ratings,
+3.5 stars.
-Droid MPD
----------
+The user interface lacks some finishing touches. E.g. you can't enter a
+hostname for the server. Only IPv4 addresses are allowed.
+
+All features exercised in the test procedure works. BitMPC lacks support for
+single mode and consume mode. BitMPC crashes if Mopidy is killed or crash.
+
+
+Droid MPD Client
+----------------
+
+We tested version 0.4.0, which at the time had 5k-10k downloads, >200 ratings,
+4 stars.
+
+To find the search functionality, you have to select the menu, then "Playlist
+manager", then the search tab. I do not understand why search is hidden inside
+"Playlist manager".
+
+The user interface have some French remnants, like "Rechercher" in the search
+field.
+
+When selecting the artist tab, it issues the ``list Artist`` command and
+becomes stuck waiting for the results. Same thing happens for the album tab,
+which issues ``list Album``, and the folder tab, which issues ``lsinfo``.
+Mopidy returned zero hits immediately on all three commands. If Mopidy has
+loaded your stored playlists and returns more than zero hits on these commands,
+they artist and album tabs do not hang. The folder tab still freezes when
+``lsinfo`` returns a list of stored playlists, though zero files. Thus, we've
+discovered a couple of bugs in Droid MPD Client.
+
+The volume control is very slick, with a turn knob, just like on an amplifier.
+It lends itself to showing off to friends when combined with Mopidy's external
+amplifier mixers. Everybody loves turning a knob on a touch screen and see the
+physical knob on the amplifier turn as well ;-)
+
+Even though ``lsinfo`` returns the stored playlists for the folder tab, they
+are not displayed anywhere. Thus, we had to select an album in the album tab to
+complete the test procedure.
+
+At one point, I had problems turning off repeat mode. After I adjusted the
+volume and tried again, it worked.
+
+Droid MPD client does not support single mode or consume mode. It does not
+detect that the server is killed/crashed. You'll only notice it by no actions
+having any effect, e.g. you can't turn the volume knob any more.
+
+In conclusion, some bugs and caveats, but most of the test procedure was
+possible to perform.
+
+
+IcyBeats
+--------
+
+We tested version 0.2, which at the time had 50-100 downloads, no ratings.
+The app was still in beta when we tried it.
+
+IcyBeats successfully connected to Mopidy and I was able to adjust volume. When
+I was searching for some tracks, I could not figure out how to actually start
+the search, as there was no search button and pressing enter in the input field
+just added a new line. I was stuck. In other words, IcyBeats 0.2 is not usable
+with Mopidy.
+
+IcyBeats does have something going for it: IcyBeats uses IPv6 to connect to
+Mopidy. The future is just around the corner!
-Works well with Mopidy.
MPDroid
-------
-Works well with Mopidy, and is regularly used by Mopidy developers.
+We tested version 0.6.9, which at the time had 5k-10k downloads, <200 ratings,
+4.5 stars. MPDroid started out as a fork of PMix.
+
+First of all, MPDroid's user interface looks nice.
+
+I couldn't find any search functionality, so I added the initial track using
+another client. Other than the missing search functionality, everything in the
+test procedure worked out flawlessly. Like all other Android clients, MPDroid
+does not support single mode or consume mode. When Mopidy is killed, MPDroid
+handles it gracefully and asks if you want to try to reconnect.
+
+All in all, MPDroid is a good MPD client without search support.
+
PMix
----
-Works well with Mopidy.
+We tested version 0.4.0, which at the time had 10k-50k downloads, >200 ratings,
+4 stars.
+
+Add MPDroid is a fork from PMix, it is no surprise that PMix does not support
+search either. In addition, I could not find stored playlists. Other than that,
+I was able to complete the test procedure. PMix crashed once during testing,
+but handled the killing of Mopidy just as nicely as MPDroid. It does not
+support single mode or consume mode.
+
+All in all, PMix works but can do less than MPDroid. Use MPDroid instead.
+
ThreeMPD
--------
-Does not work well with Mopidy, because we haven't implemented ``listallinfo``
-yet.
+We tested version 0.3.0, which at the time had 1k-5k downloads, <25 ratings,
+2.5 average. The developer request users to use MPDroid instead, due to limited
+time for maintenance. Does not support password authentication.
+
+ThreeMPD froze during startup, so we were not able to test it.
iPhone/iPod Touch clients
=========================
+impdclient
+----------
+
+There's an open source MPD client for iOS called `impdclient
+`_ which has not seen any updates since
+August 2008. So far, we've not heard of users trying it with Mopidy. Please
+notify us of your successes and/or problems if you do try it out.
+
+
MPod
----
-Works well with Mopidy as far as we've heard from users.
+The `MPoD `_ client can be
+installed from the `iTunes Store
+`_.
+
+Users have reported varying success in using MPoD together with Mopidy. Thus,
+we've tested a fresh install of MPoD 1.5.1 with Mopidy as of revision e7ed28d
+(pre-0.3) on an iPod Touch 3rd generation. The following are our findings:
+
+- **Works:** Playback control generally works, including stop, play, pause,
+ previous, next, repeat, random, seek, and volume control.
+
+- **Bug:** Search does not work, neither in the artist, album, or song
+ tabs. Mopidy gets no requests at all from MPoD when executing searches. Seems
+ like MPoD only searches in local cache, even if "Use local cache" is turned
+ off in MPoD's settings. Until this is fixed by the MPoD developer, MPoD will
+ be much less useful with Mopidy.
+
+- **Bug:** When adding another playlist to the current playlist in MPoD,
+ the currently playing track restarts at the beginning. I do not currently
+ know enough about this bug, because I'm not sure if MPoD was in the "add to
+ active playlist" or "replace active playlist" mode when I tested it. I only
+ later learned what that button was for. Anyway, what I experienced was:
+
+ #. I play a track
+ #. I select a new playlist
+ #. MPoD reconnects to Mopidy for unknown reason
+ #. MPoD issues MPD command ``load "a playlist name"``
+ #. MPoD issues MPD command ``play "-1"``
+ #. MPoD issues MPD command ``playlistinfo "-1"``
+ #. I hear that the currently playing tracks restarts playback
+
+- **Tips:** MPoD seems to cache stored playlists, but they won't work if the
+ server hasn't loaded stored playlists from e.g. Spotify yet. A trick to force
+ refetching of playlists from Mopidy is to add a new empty playlist in MPoD.
+
+- **Wishlist:** Modifying the current playlists is not supported by MPoD it
+ seems.
+
+- **Wishlist:** MPoD supports playback of Last.fm radio streams through the MPD
+ server. Mopidy does not currently support this, but there is a wishlist bug
+ at :issue:`38`.
+
+- **Wishlist:** MPoD supports autodetection/-configuration of MPD servers
+ through the use of Bonjour. Mopidy does not currently support this, but there
+ is a wishlist bug at :issue:`39`.
diff --git a/docs/conf.py b/docs/conf.py
index 9e7ff1fb..4587c16d 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -43,7 +43,7 @@ master_doc = 'index'
# General information about the project.
project = u'Mopidy'
-copyright = u'2010, Stein Magnus Jodal and contributors'
+copyright = u'2010-2011, Stein Magnus Jodal and contributors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -116,7 +116,7 @@ html_theme_path = ['_themes']
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
-#html_logo = None
+html_logo = '_static/mopidy.png'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
@@ -153,7 +153,7 @@ html_last_updated_fmt = '%b %d, %Y'
#html_split_index = False
# If true, links to the reST sources are added to the pages.
-html_show_sourcelink = False
+#html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
diff --git a/docs/development/roadmap.rst b/docs/development/roadmap.rst
index 9db74a4d..cec8e9c7 100644
--- a/docs/development/roadmap.rst
+++ b/docs/development/roadmap.rst
@@ -2,88 +2,33 @@
Roadmap
*******
-This is the current roadmap and collection of wild ideas for future Mopidy
-development. This is intended to be a living document and may change at any
-time.
-We intend to have about one timeboxed release every month. Thus, the roadmap is
-oriented around "soon" and "later" instead of mapping each feature to a future
-release.
+Release schedule
+================
+
+We intend to have about one timeboxed feature release every month
+in periods of active development. The feature releases are numbered 0.x.0. The
+features added is a mix of what we feel is most important/requested of the
+missing features, and features we develop just because we find them fun to
+make, even though they may be useful for very few users or for a limited use
+case.
+
+Bugfix releases, numbered 0.x.y, will be released whenever we discover bugs
+that are too serious to wait for the next feature release. We will only release
+bugfix releases for the last feature release. E.g. when 0.3.0 is released, we
+will no longer provide bugfix releases for the 0.2 series. In other words,
+there will be just a single supported release at any point in time.
-Possible targets for the next version
-=====================================
+Feature wishlist
+================
-- Reintroduce support for OS X. See :issue:`25` for details.
-- **[WIP: feature/multi-backend]** Support for using multiple Mopidy backends
- simultaneously. Should make it possible to have both Spotify tracks and local
- tracks in the same playlist.
-- MPD frontend:
-
- - **[WIP: feature/mpd-password]** Password authentication.
- - ``idle`` support.
-
-- Spotify backend:
-
- - Write-support for Spotify, i.e. playlist management.
- - Virtual directories with e.g. starred tracks from Spotify.
- - **[DONE: v0.3]** Support for 320 kbps audio.
-
-- Local backend:
-
- - Better music library support.
- - **[DONE: v0.3]** A script for creating a tag cache.
- - An alternative to tag cache for caching metadata, i.e. Sqlite.
-
-- **[DONE: v0.2]** Last.fm scrobbling.
-
-
-Stuff we want to do, but not right now, and maybe never
-=======================================================
-
-- Packaging and distribution:
-
- - **[BLOCKED]** Create `Homebrew `_
- recipies for all our dependencies and Mopidy itself to make OS X
- installation a breeze. See `Homebrew's issue #1612
- `_.
- - **[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.
-
-- Compatability:
-
- - **[WIP: feature/blackbox-testing]** Run frontend tests against a real MPD
- server to ensure we are in sync.
-
-- Backends:
-
- - `Last.fm `_
- - `WIMP `_
- - DNLA/UPnP so Mopidy can play music from other DNLA MediaServers.
-
-- Frontends:
-
- - Publish the server's presence to the network using `Zeroconf
- `_/Avahi.
- - **[WIP: feature/mpris-frontend]** D-Bus/`MPRIS `_
- - **[WIP: feature/http-frontend]** REST/JSON web service with a jQuery client
- as example application. Maybe based upon `Tornado
- `_ and `jQuery
- Mobile `_.
- - DNLA/UPnP so Mopidy can be controlled from i.e. TVs.
- - `XMMS2 `_
- - LIRC frontend for controlling Mopidy with a remote.
-
-- Mixers:
-
- - LIRC mixer for controlling arbitrary amplifiers remotely.
-
-- Audio streaming:
-
- - Ogg Vorbis/MP3 audio stream over HTTP, to MPD clients, `Squeezeboxes
- `_, etc.
- - Feed audio to an `Icecast `_ server.
- - Stream to AirPort Express using `RAOP
- `_.
+We maintain our collection of sane or less sane ideas for future Mopidy
+features as `issues `_ at GitHub
+labeled with `the "wishlist" label
+`_. Feel free to vote
+up any feature you would love to see in Mopidy, but please refrain from adding
+a comment just to say "I want this too!". You are of course free to add
+comments if you have suggestions for how the feature should work or be
+implemented, and you may add new wishlist issues if your ideas are not already
+represented.
diff --git a/docs/index.rst b/docs/index.rst
index 09029a4f..0af45835 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,4 +1,31 @@
-.. include:: ../README.rst
+******
+Mopidy
+******
+
+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, Android, and iOS.
+
+To install Mopidy, start out by reading :ref:`installation`.
+
+If you get stuck, we usually hang around at ``#mopidy`` at `irc.freenode.net
+`_. If you stumble into a bug or got a feature request,
+please create an issue in the `issue tracker
+`_.
+
+
+Project resources
+=================
+
+- `Documentation for the latest release `_
+- `Documentation for the development version
+ `_
+- `Source code `_
+- `Issue tracker `_
+- IRC: ``#mopidy`` at `irc.freenode.net `_
+
User documentation
==================
diff --git a/docs/installation/index.rst b/docs/installation/index.rst
index 26b50994..56f0015b 100644
--- a/docs/installation/index.rst
+++ b/docs/installation/index.rst
@@ -1,3 +1,5 @@
+.. _installation:
+
************
Installation
************
diff --git a/docs/licenses.rst b/docs/licenses.rst
index c3a13904..7f4ed0ce 100644
--- a/docs/licenses.rst
+++ b/docs/licenses.rst
@@ -8,7 +8,7 @@ contributed what, please refer to our git repository.
Source code license
===================
-Copyright 2009-2010 Stein Magnus Jodal and contributors
+Copyright 2009-2011 Stein Magnus Jodal and contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ limitations under the License.
Documentation license
=====================
-Copyright 2010 Stein Magnus Jodal and contributors
+Copyright 2010-2011 Stein Magnus Jodal and contributors
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0
Unported License. To view a copy of this license, visit
diff --git a/mopidy/frontends/lastfm.py b/mopidy/frontends/lastfm.py
index 60c2d708..69d1c8bc 100644
--- a/mopidy/frontends/lastfm.py
+++ b/mopidy/frontends/lastfm.py
@@ -92,23 +92,23 @@ class LastfmFrontendThread(BaseThread):
def started_playing(self, track):
artists = ', '.join([a.name for a in track.artists])
- duration = track.length // 1000
+ duration = track.length and track.length // 1000 or 0
self.last_start_time = int(time.time())
logger.debug(u'Now playing track: %s - %s', artists, track.name)
try:
self.lastfm.update_now_playing(
artists,
- track.name,
- album=track.album.name,
+ (track.name or ''),
+ album=(track.album and track.album.name or ''),
duration=str(duration),
track_number=str(track.track_no),
mbid=(track.musicbrainz_id or ''))
- except (pylast.ScrobblingError, socket.error) as e:
+ except (pylast.ScrobblingError, pylast.WSError, socket.error) as e:
logger.warning(u'Last.fm now playing error: %s', e)
def stopped_playing(self, track, stop_position):
artists = ', '.join([a.name for a in track.artists])
- duration = track.length // 1000
+ duration = track.length and track.length // 1000 or 0
stop_position = stop_position // 1000
if duration < 30:
logger.debug(u'Track too short to scrobble. (30s)')
@@ -123,11 +123,11 @@ class LastfmFrontendThread(BaseThread):
try:
self.lastfm.scrobble(
artists,
- track.name,
+ (track.name or ''),
str(self.last_start_time),
- album=track.album.name,
+ album=(track.album and track.album.name or ''),
track_number=str(track.track_no),
duration=str(duration),
mbid=(track.musicbrainz_id or ''))
- except (pylast.ScrobblingError, socket.error) as e:
+ except (pylast.ScrobblingError, pylast.WSError, socket.error) as e:
logger.warning(u'Last.fm scrobbling error: %s', e)
diff --git a/mopidy/mixers/nad.py b/mopidy/mixers/nad.py
index 3215a761..5cf92826 100644
--- a/mopidy/mixers/nad.py
+++ b/mopidy/mixers/nad.py
@@ -147,6 +147,8 @@ class NadTalker(BaseThread):
return self._readline().replace('%s=' % key, '')
def _command_device(self, key, value):
+ if type(value) == unicode:
+ value = value.encode('utf-8')
self._write('%s=%s' % (key, value))
self._readline()