Merge branch 'develop' into feature/modularised-output

Conflicts:
	mopidy/gstreamer.py
This commit is contained in:
Thomas Adamcik 2011-05-01 23:50:23 +02:00
commit 865d62e6e1
34 changed files with 88 additions and 17 deletions

View File

@ -1,4 +1,4 @@
include LICENSE pylintrc *.rst data/mopidy.desktop
include LICENSE pylintrc *.rst *.ini data/mopidy.desktop
include mopidy/backends/spotify/spotify_appkey.key
recursive-include docs *
prune docs/_build

View File

@ -5,11 +5,35 @@ Changes
This change log is used to track all major changes to Mopidy.
0.4.0 (in development)
0.5.0 (in development)
======================
No description yet.
**Changes**
No changes yet.
0.4.0 (2011-04-27)
==================
Mopidy 0.4.0 is another release without major feature additions. In 0.4.0 we've
fixed a bunch of issues and bugs, with the help of several new contributors
who are credited in the changelog below. The major change of 0.4.0 is an
internal refactoring which clears way for future features, and which also make
Mopidy work on Python 2.7. In other words, Mopidy 0.4.0 works on Ubuntu 11.04
and Arch Linux.
Please note that 0.4.0 requires some updated dependencies, as listed under
*Important changes* below. Also, the known bug in the Spotify playlist
loading from Mopidy 0.3.0 is still present.
.. warning:: Known bug in Spotify playlist loading
There is a known bug in the loading of Spotify playlists. To avoid the bug,
follow the simple workaround described at :issue:`59`.
**Important changes**
@ -30,7 +54,7 @@ No description yet.
- Mopidy now use Pykka actors for thread management and inter-thread
communication. The immediate advantage of this is that Mopidy now works on
Python 2.7. (Fixes: :issue:`66`)
Python 2.7, which is the default on e.g. Ubuntu 11.04. (Fixes: :issue:`66`)
- Spotify backend:
@ -40,6 +64,11 @@ No description yet.
- Better error messages on wrong login or network problems. Thanks to Antoine
Pierlot-Garcin for patches to Mopidy and Pyspotify. (Fixes: :issue:`77`)
- Reduce log level for trivial log messages from warning to info. (Fixes:
:issue:`71`)
- Pause playback on network connection errors. (Fixes: :issue:`65`)
- Local backend:
- Fix crash in :command:`mopidy-scan` if a track has no artist name. Thanks
@ -61,11 +90,29 @@ No description yet.
- Fix bug where ``status`` returned ``song: None``, which caused MPDroid to
crash. (Fixes: :issue:`69`)
- Gracefully fallback to IPv4 sockets on systems that supports IPv6, but has
turned it off. (Fixes: :issue:`75`)
- GStreamer output:
- Use ``uridecodebin`` for playing audio from both Spotify and the local
backend. This contributes to support for multiple backends simultaneously.
- Settings:
- Fix crash on ``--list-settings`` on clean installation. Thanks to Martins
Grunskis for the bug report and patch. (Fixes: :issue:`63`)
- Packaging:
- Replace test data symlinks with real files to avoid symlink issues when
installing with pip. (Fixes: :issue:`68`)
- Debugging:
- Include platform, architecture, Linux distribution, and Python version in
the debug log, to ease debugging of issues with attached debug logs.
0.3.1 (2010-01-22)
==================

View File

@ -202,4 +202,4 @@ latex_documents = [
needs_sphinx = '1.0'
extlinks = {'issue': ('http://github.com/mopidy/mopidy/issues#issue/%s', 'GH-')}
extlinks = {'issue': ('http://github.com/mopidy/mopidy/issues/%s', 'GH-')}

View File

@ -5,7 +5,7 @@ if not (2, 6) <= sys.version_info < (3,):
from subprocess import PIPE, Popen
VERSION = (0, 4, 0)
VERSION = (0, 5, 0)
def get_version():
try:

View File

@ -24,7 +24,7 @@ class SpotifyPlaybackProvider(BasePlaybackProvider):
self.backend.gstreamer.set_metadata(track)
return True
except SpotifyError as e:
logger.warning('Play %s failed: %s', track.uri, e)
logger.info('Playback of %s failed: %s', track.uri, e)
return False
def resume(self):

View File

@ -74,7 +74,11 @@ class SpotifySessionManager(BaseThread, PyspotifySessionManager):
def connection_error(self, session, error):
"""Callback used by pyspotify"""
logger.error(u'Spotify connection error: %s', error)
if error is None:
logger.info(u'Spotify connection error resolved')
else:
logger.error(u'Spotify connection error: %s', error)
self.backend.playback.pause()
def message_to_user(self, session, message):
"""Callback used by pyspotify"""

View File

@ -62,5 +62,5 @@ class SpotifyTranslator(object):
if str(Link.from_track(t, 0))],
)
except SpotifyError, e:
logger.warning(u'Failed translating Spotify playlist '
logger.info(u'Failed translating Spotify playlist '
'(probably a playlist folder boundary): %s', e)

View File

@ -24,9 +24,11 @@ def main():
setup_backend()
setup_frontends()
try:
time.sleep(10000*24*60*60)
while ActorRegistry.get_all():
time.sleep(1)
logger.info(u'No actors left. Exiting...')
except KeyboardInterrupt:
logger.info(u'Exiting...')
logger.info(u'User interrupt. Exiting...')
ActorRegistry.stop_all()
def parse_options():

View File

@ -52,7 +52,7 @@ class MpdServer(asyncore.dispatcher):
self._format_hostname(settings.MPD_SERVER_HOSTNAME),
settings.MPD_SERVER_PORT)
except IOError, e:
logger.error('MPD server startup failed: %s' % e)
logger.error(u'MPD server startup failed: %s' % str(e).decode('utf-8'))
sys.exit(1)
def handle_accept(self):

View File

@ -13,6 +13,15 @@ from mopidy.backends.base import Backend
logger = logging.getLogger('mopidy.gstreamer')
default_caps = gst.Caps("""
audio/x-raw-int,
endianness=(int)1234,
channels=(int)2,
width=(int)16,
depth=(int)16,
signed=(boolean)true,
rate=(int)44100""")
class BaseOutput(object):
def connect_bin(self, pipeline, element_to_link_to):
"""
@ -92,10 +101,11 @@ class GStreamer(ThreadingActor):
self.gst_volume = self.gst_pipeline.get_by_name('volume')
self.gst_taginject = self.gst_pipeline.get_by_name('tag')
self.gst_uridecodebin = gst.element_factory_make('uridecodebin', 'uri')
self.gst_uridecodebin.connect('pad-added', self._process_new_pad,
uridecodebin = gst.element_factory_make('uridecodebin', 'uri')
uridecodebin.connect('notify::source', self._process_new_source)
uridecodebin.connect('pad-added', self._process_new_pad,
self.gst_convert.get_pad('sink'))
self.gst_pipeline.add(self.gst_uridecodebin)
self.gst_pipeline.add(uridecodebin)
for output in settings.OUTPUTS:
output_cls = get_class(output)()
@ -106,6 +116,13 @@ class GStreamer(ThreadingActor):
gst_bus.add_signal_watch()
gst_bus.connect('message', self._process_gstreamer_message)
def _process_new_source(self, element, pad):
source = element.get_by_name('source')
try:
source.set_property('caps', default_caps)
except TypeError:
pass
def _process_new_pad(self, source, pad, target_pad):
pad.link(target_pad)

View File

@ -190,7 +190,7 @@ class NadTalker(ThreadingActor):
# trailing whitespace.
if not self._device.isOpen():
self._device.open()
result = self._device.readline(eol='\n').strip()
result = self._device.readline().strip()
if result:
logger.debug('Read: %s', result)
return result

View File

@ -1 +0,0 @@
../sample.mp3

Binary file not shown.

View File

@ -1 +0,0 @@
../sample.mp3

Binary file not shown.

View File

@ -1 +0,0 @@
../sample.mp3

Binary file not shown.

View File

@ -1 +0,0 @@
../../sample.mp3

Binary file not shown.

View File

@ -1 +0,0 @@
../../sample.mp3

Binary file not shown.

View File

@ -1 +0,0 @@
../../../sample.mp3

View File

@ -1 +0,0 @@
../../../sample.mp3

View File

@ -1 +0,0 @@
../../sample.mp3

Binary file not shown.

View File

@ -1 +0,0 @@
../../sample.mp3

Binary file not shown.

View File

@ -1 +0,0 @@
../sample.mp3

Binary file not shown.

View File

@ -1 +0,0 @@
blank.flac

BIN
tests/data/song1.flac Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.mp3

BIN
tests/data/song1.mp3 Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.ogg

BIN
tests/data/song1.ogg Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.wav

BIN
tests/data/song1.wav Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.flac

BIN
tests/data/song2.flac Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.mp3

BIN
tests/data/song2.mp3 Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.ogg

BIN
tests/data/song2.ogg Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.wav

BIN
tests/data/song2.wav Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.flac

BIN
tests/data/song3.flac Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.mp3

BIN
tests/data/song3.mp3 Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.ogg

BIN
tests/data/song3.ogg Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
blank.wav

BIN
tests/data/song3.wav Normal file

Binary file not shown.

View File

@ -17,8 +17,9 @@ class VersionTest(unittest.TestCase):
self.assert_(SV('0.1.0') < SV('1.0.0'))
self.assert_(SV('0.2.0') < SV('0.3.0'))
self.assert_(SV('0.3.0') < SV('0.3.1'))
self.assert_(SV('0.3.1') < SV(get_plain_version()))
self.assert_(SV(get_plain_version()) < SV('0.4.1'))
self.assert_(SV('0.3.1') < SV('0.4.0'))
self.assert_(SV('0.4.0') < SV(get_plain_version()))
self.assert_(SV(get_plain_version()) < SV('0.5.1'))
def test_get_platform_contains_platform(self):
self.assert_(platform.platform() in get_platform())