Merge branch 'master' of git://github.com/jodal/mopidy

This commit is contained in:
Johannes Knutsen 2010-08-05 18:49:37 +02:00
commit dc7353694b
6 changed files with 61 additions and 23 deletions

View File

@ -1,4 +1,5 @@
include COPYING include COPYING pylintrc *.rst *.txt
include *.rst recursive-include docs *
include requirements*.txt prune docs/_build
recursive-include docs *.rst recursive-include tests *.py
recursive-include tests/data *

View File

@ -4,10 +4,30 @@ Changes
This change log is used to track all major changes to Mopidy. This change log is used to track all major changes to Mopidy.
0.1.0a3 (unreleased)
0.1.0a4 (in development)
========================
Another great release.
**Changes**
- Exit early if not Python >= 2.6, < 3.
- Include Sphinx scripts for building docs, pylintrc, tests and test data in
the packages created by ``setup.py`` for i.e. PyPI.
0.1.0a3 (2010-08-03)
==================== ====================
We got an updated :doc:`release roadmap <development/roadmap>`! In the last two months, Mopidy's MPD frontend has gotten lots of stability
fixes and error handling improvements, proper support for having the same track
multiple times in a playlist, and support for IPv6. We have also fixed the
choppy playback on the libspotify backend. For the road ahead of us, we got an
updated :doc:`release roadmap <development/roadmap>` with our goals for the 0.1
to 0.3 releases.
Enjoy the best alpha relase of Mopidy ever :-)
**Changes** **Changes**

View File

@ -1,7 +1,11 @@
import sys
if not (2, 6) <= sys.version_info < (3,):
sys.exit(u'Mopidy requires Python >= 2.6, < 3')
from mopidy import settings as raw_settings from mopidy import settings as raw_settings
def get_version(): def get_version():
return u'0.1.0a3' return u'0.1.0a4'
def get_mpd_protocol_version(): def get_mpd_protocol_version():
return u'0.16.0' return u'0.16.0'

View File

@ -312,19 +312,19 @@ class MpdFrontend(object):
end = int(end) end = int(end)
else: else:
end = len(self.backend.current_playlist.tracks) end = len(self.backend.current_playlist.tracks)
tracks = self.backend.current_playlist.tracks[start:end] cp_tracks = self.backend.current_playlist.cp_tracks[start:end]
if not tracks: if not cp_tracks:
raise MpdArgError(u'Bad song index', command=u'delete') raise MpdArgError(u'Bad song index', command=u'delete')
for track in tracks: for (cpid, track) in cp_tracks:
self.backend.current_playlist.remove(id=track.id) self.backend.current_playlist.remove(cpid=cpid)
@handle_pattern(r'^delete "(?P<songpos>\d+)"$') @handle_pattern(r'^delete "(?P<songpos>\d+)"$')
def _current_playlist_delete_songpos(self, songpos): def _current_playlist_delete_songpos(self, songpos):
"""See :meth:`_current_playlist_delete_range`""" """See :meth:`_current_playlist_delete_range`"""
try: try:
songpos = int(songpos) songpos = int(songpos)
track = self.backend.current_playlist.tracks[songpos] (cpid, track) = self.backend.current_playlist.cp_tracks[songpos]
self.backend.current_playlist.remove(id=track.id) self.backend.current_playlist.remove(cpid=cpid)
except IndexError: except IndexError:
raise MpdArgError(u'Bad song index', command=u'delete') raise MpdArgError(u'Bad song index', command=u'delete')
@ -496,6 +496,7 @@ class MpdFrontend(object):
return self.backend.current_playlist.mpd_format(start, end) return self.backend.current_playlist.mpd_format(start, end)
@handle_pattern(r'^playlistsearch "(?P<tag>[^"]+)" "(?P<needle>[^"]+)"$') @handle_pattern(r'^playlistsearch "(?P<tag>[^"]+)" "(?P<needle>[^"]+)"$')
@handle_pattern(r'^playlistsearch (?P<tag>\S+) "(?P<needle>[^"]+)"$')
def _current_playlist_playlistsearch(self, tag, needle): def _current_playlist_playlistsearch(self, tag, needle):
""" """
*musicpd.org, current playlist section:* *musicpd.org, current playlist section:*
@ -504,6 +505,11 @@ class MpdFrontend(object):
Searches case-sensitively for partial matches in the current Searches case-sensitively for partial matches in the current
playlist. playlist.
*GMPC:*
- does not add quotes around the tag
- uses ``filename`` and ``any`` as tags
""" """
raise MpdNotImplemented # TODO raise MpdNotImplemented # TODO
@ -540,10 +546,10 @@ class MpdFrontend(object):
# XXX Naive implementation that returns all tracks as changed # XXX Naive implementation that returns all tracks as changed
if int(version) != self.backend.current_playlist.version: if int(version) != self.backend.current_playlist.version:
result = [] result = []
for position, track in enumerate( for (position, (cpid, track)) in enumerate(
self.backend.current_playlist.tracks): self.backend.current_playlist.cp_tracks):
result.append((u'cpos', position)) result.append((u'cpos', position))
result.append((u'Id', track.id)) result.append((u'Id', cpid))
return result return result
@handle_pattern(r'^shuffle$') @handle_pattern(r'^shuffle$')

View File

@ -304,7 +304,11 @@ class CurrentPlaylistHandlerTest(unittest.TestCase):
self.assert_(u'OK' in result) self.assert_(u'OK' in result)
def test_playlistsearch(self): def test_playlistsearch(self):
result = self.h.handle_request(u'playlistsearch "tag" "needle"') result = self.h.handle_request(u'playlistsearch "any" "needle"')
self.assert_(u'ACK [0@0] {} Not implemented' in result)
def test_playlistsearch_without_quotes(self):
result = self.h.handle_request(u'playlistsearch any "needle"')
self.assert_(u'ACK [0@0] {} Not implemented' in result) self.assert_(u'ACK [0@0] {} Not implemented' in result)
def test_plchanges(self): def test_plchanges(self):
@ -317,15 +321,17 @@ class CurrentPlaylistHandlerTest(unittest.TestCase):
self.assert_(u'OK' in result) self.assert_(u'OK' in result)
def test_plchangesposid(self): def test_plchangesposid(self):
self.b.current_playlist.load( self.b.current_playlist.load([Track(), Track(), Track()])
[Track(id=11), Track(id=12), Track(id=13)])
result = self.h.handle_request(u'plchangesposid "0"') result = self.h.handle_request(u'plchangesposid "0"')
self.assert_(u'cpos: 0' in result) self.assert_(u'cpos: 0' in result)
self.assert_(u'Id: 11' in result) self.assert_(u'Id: %d' % self.b.current_playlist.cp_tracks[0][0]
in result)
self.assert_(u'cpos: 2' in result) self.assert_(u'cpos: 2' in result)
self.assert_(u'Id: 12' in result) self.assert_(u'Id: %d' % self.b.current_playlist.cp_tracks[1][0]
in result)
self.assert_(u'cpos: 2' in result) self.assert_(u'cpos: 2' in result)
self.assert_(u'Id: 13' in result) self.assert_(u'Id: %d' % self.b.current_playlist.cp_tracks[2][0]
in result)
self.assert_(u'OK' in result) self.assert_(u'OK' in result)
def test_shuffle_without_range(self): def test_shuffle_without_range(self):

View File

@ -10,7 +10,8 @@ class VersionTest(unittest.TestCase):
def test_versions_can_be_strictly_ordered(self): def test_versions_can_be_strictly_ordered(self):
self.assert_(SV('0.1.0a0') < SV('0.1.0a1')) self.assert_(SV('0.1.0a0') < SV('0.1.0a1'))
self.assert_(SV('0.1.0a2') < SV(get_version())) self.assert_(SV('0.1.0a2') < SV(get_version()))
self.assert_(SV(get_version()) < SV('0.1.0a4')) self.assert_(SV('0.1.0a3') < SV(get_version()))
self.assert_(SV(get_version()) < SV('0.1.0a5'))
self.assert_(SV('0.1.0a0') < SV('0.1.0')) self.assert_(SV('0.1.0a0') < SV('0.1.0'))
self.assert_(SV('0.1.0') < SV('0.1.1')) self.assert_(SV('0.1.0') < SV('0.1.1'))
self.assert_(SV('0.1.1') < SV('0.2.0')) self.assert_(SV('0.1.1') < SV('0.2.0'))