Merge branch 'master' of git://github.com/jodal/mopidy
This commit is contained in:
commit
dc7353694b
@ -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 *
|
||||||
|
|||||||
@ -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**
|
||||||
|
|
||||||
|
|||||||
@ -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'
|
||||||
|
|||||||
@ -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$')
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
@ -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'))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user