Create new MpdContext object which is passed to command handlers
This commit is contained in:
parent
76d0314eff
commit
d57727282e
@ -26,16 +26,9 @@ class MpdDispatcher(object):
|
||||
# XXX Consider merging MpdDispatcher into MpdSession
|
||||
|
||||
def __init__(self):
|
||||
backend_refs = ActorRegistry.get_by_class(Backend)
|
||||
assert len(backend_refs) == 1, 'Expected exactly one running backend.'
|
||||
self.backend = backend_refs[0].proxy()
|
||||
|
||||
mixer_refs = ActorRegistry.get_by_class(BaseMixer)
|
||||
assert len(mixer_refs) == 1, 'Expected exactly one running mixer.'
|
||||
self.mixer = mixer_refs[0].proxy()
|
||||
|
||||
self.command_list = False
|
||||
self.command_list_ok = False
|
||||
self.context = MpdContext(self)
|
||||
|
||||
def handle_request(self, request, command_list_index=None):
|
||||
"""Dispatch incoming requests to the correct handler."""
|
||||
@ -44,7 +37,7 @@ class MpdDispatcher(object):
|
||||
return None
|
||||
try:
|
||||
(handler, kwargs) = self.find_handler(request)
|
||||
result = handler(self, **kwargs)
|
||||
result = handler(self.context, **kwargs)
|
||||
except MpdAckError as e:
|
||||
if command_list_index is not None:
|
||||
e.index = command_list_index
|
||||
@ -87,3 +80,34 @@ class MpdDispatcher(object):
|
||||
if add_ok and (not response or not response[-1].startswith(u'ACK')):
|
||||
response.append(u'OK')
|
||||
return response
|
||||
|
||||
|
||||
class MpdContext(object):
|
||||
"""
|
||||
This object is passed as the first argument to all MPD command handlers to
|
||||
give the command handlers access to important parts of Mopidy.
|
||||
"""
|
||||
|
||||
#: The current :class:`MpdDispatcher`.
|
||||
dispatcher = None
|
||||
|
||||
#: The backend. An instance of :class:`mopidy.backends.base.Backend`.
|
||||
backend = None
|
||||
|
||||
#: The mixer. An instance of :class:`mopidy.mixers.base.BaseMixer`.
|
||||
mixer = None
|
||||
|
||||
def __init__(self, dispatcher):
|
||||
self.dispatcher = dispatcher
|
||||
self.backend = self._get_backend()
|
||||
self.mixer = self._get_mixer()
|
||||
|
||||
def _get_backend(self):
|
||||
backend_refs = ActorRegistry.get_by_class(Backend)
|
||||
assert len(backend_refs) == 1, 'Expected exactly one running backend.'
|
||||
return backend_refs[0].proxy()
|
||||
|
||||
def _get_mixer(self):
|
||||
mixer_refs = ActorRegistry.get_by_class(BaseMixer)
|
||||
assert len(mixer_refs) == 1, 'Expected exactly one running mixer.'
|
||||
return mixer_refs[0].proxy()
|
||||
|
||||
@ -18,21 +18,23 @@ def command_list_begin(context):
|
||||
returned. If ``command_list_ok_begin`` is used, ``list_OK`` is
|
||||
returned for each successful command executed in the command list.
|
||||
"""
|
||||
context.command_list = []
|
||||
context.command_list_ok = False
|
||||
context.dispatcher.command_list = []
|
||||
context.dispatcher.command_list_ok = False
|
||||
|
||||
@handle_pattern(r'^command_list_end$')
|
||||
def command_list_end(context):
|
||||
"""See :meth:`command_list_begin()`."""
|
||||
if context.command_list is False:
|
||||
if context.dispatcher.command_list is False:
|
||||
# Test for False exactly, and not e.g. empty list
|
||||
raise MpdUnknownCommand(command='command_list_end')
|
||||
(command_list, context.command_list) = (context.command_list, False)
|
||||
(command_list_ok, context.command_list_ok) = (
|
||||
context.command_list_ok, False)
|
||||
(command_list, context.dispatcher.command_list) = (
|
||||
context.dispatcher.command_list, False)
|
||||
(command_list_ok, context.dispatcher.command_list_ok) = (
|
||||
context.dispatcher.command_list_ok, False)
|
||||
result = []
|
||||
for i, command in enumerate(command_list):
|
||||
response = context.handle_request(command, command_list_index=i)
|
||||
response = context.dispatcher.handle_request(
|
||||
command, command_list_index=i)
|
||||
if response is not None:
|
||||
result.append(response)
|
||||
if response and response[-1].startswith(u'ACK'):
|
||||
@ -44,5 +46,5 @@ def command_list_end(context):
|
||||
@handle_pattern(r'^command_list_ok_begin$')
|
||||
def command_list_ok_begin(context):
|
||||
"""See :meth:`command_list_begin()`."""
|
||||
context.command_list = []
|
||||
context.command_list_ok = True
|
||||
context.dispatcher.command_list = []
|
||||
context.dispatcher.command_list_ok = True
|
||||
|
||||
@ -8,55 +8,55 @@ class CommandListsTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.b = DummyBackend.start().proxy()
|
||||
self.mixer = DummyMixer.start().proxy()
|
||||
self.h = dispatcher.MpdDispatcher()
|
||||
self.dispatcher = dispatcher.MpdDispatcher()
|
||||
|
||||
def tearDown(self):
|
||||
self.b.stop().get()
|
||||
self.mixer.stop().get()
|
||||
|
||||
def test_command_list_begin(self):
|
||||
result = self.h.handle_request(u'command_list_begin')
|
||||
result = self.dispatcher.handle_request(u'command_list_begin')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_command_list_end(self):
|
||||
self.h.handle_request(u'command_list_begin')
|
||||
result = self.h.handle_request(u'command_list_end')
|
||||
self.dispatcher.handle_request(u'command_list_begin')
|
||||
result = self.dispatcher.handle_request(u'command_list_end')
|
||||
self.assert_(u'OK' in result)
|
||||
|
||||
def test_command_list_end_without_start_first_is_an_unknown_command(self):
|
||||
result = self.h.handle_request(u'command_list_end')
|
||||
result = self.dispatcher.handle_request(u'command_list_end')
|
||||
self.assertEquals(result[0],
|
||||
u'ACK [5@0] {} unknown command "command_list_end"')
|
||||
|
||||
def test_command_list_with_ping(self):
|
||||
self.h.handle_request(u'command_list_begin')
|
||||
self.assertEqual([], self.h.command_list)
|
||||
self.assertEqual(False, self.h.command_list_ok)
|
||||
self.h.handle_request(u'ping')
|
||||
self.assert_(u'ping' in self.h.command_list)
|
||||
result = self.h.handle_request(u'command_list_end')
|
||||
self.dispatcher.handle_request(u'command_list_begin')
|
||||
self.assertEqual([], self.dispatcher.command_list)
|
||||
self.assertEqual(False, self.dispatcher.command_list_ok)
|
||||
self.dispatcher.handle_request(u'ping')
|
||||
self.assert_(u'ping' in self.dispatcher.command_list)
|
||||
result = self.dispatcher.handle_request(u'command_list_end')
|
||||
self.assert_(u'OK' in result)
|
||||
self.assertEqual(False, self.h.command_list)
|
||||
self.assertEqual(False, self.dispatcher.command_list)
|
||||
|
||||
def test_command_list_with_error_returns_ack_with_correct_index(self):
|
||||
self.h.handle_request(u'command_list_begin')
|
||||
self.h.handle_request(u'play') # Known command
|
||||
self.h.handle_request(u'paly') # Unknown command
|
||||
result = self.h.handle_request(u'command_list_end')
|
||||
self.dispatcher.handle_request(u'command_list_begin')
|
||||
self.dispatcher.handle_request(u'play') # Known command
|
||||
self.dispatcher.handle_request(u'paly') # Unknown command
|
||||
result = self.dispatcher.handle_request(u'command_list_end')
|
||||
self.assertEqual(result[0], u'ACK [5@1] {} unknown command "paly"')
|
||||
|
||||
def test_command_list_ok_begin(self):
|
||||
result = self.h.handle_request(u'command_list_ok_begin')
|
||||
result = self.dispatcher.handle_request(u'command_list_ok_begin')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_command_list_ok_with_ping(self):
|
||||
self.h.handle_request(u'command_list_ok_begin')
|
||||
self.assertEqual([], self.h.command_list)
|
||||
self.assertEqual(True, self.h.command_list_ok)
|
||||
self.h.handle_request(u'ping')
|
||||
self.assert_(u'ping' in self.h.command_list)
|
||||
result = self.h.handle_request(u'command_list_end')
|
||||
self.dispatcher.handle_request(u'command_list_ok_begin')
|
||||
self.assertEqual([], self.dispatcher.command_list)
|
||||
self.assertEqual(True, self.dispatcher.command_list_ok)
|
||||
self.dispatcher.handle_request(u'ping')
|
||||
self.assert_(u'ping' in self.dispatcher.command_list)
|
||||
result = self.dispatcher.handle_request(u'command_list_end')
|
||||
self.assert_(u'list_OK' in result)
|
||||
self.assert_(u'OK' in result)
|
||||
self.assertEqual(False, self.h.command_list)
|
||||
self.assertEqual(False, self.h.command_list_ok)
|
||||
self.assertEqual(False, self.dispatcher.command_list)
|
||||
self.assertEqual(False, self.dispatcher.command_list_ok)
|
||||
|
||||
@ -2,7 +2,8 @@ import unittest
|
||||
|
||||
from mopidy.backends.base import PlaybackController
|
||||
from mopidy.backends.dummy import DummyBackend
|
||||
from mopidy.frontends.mpd import dispatcher
|
||||
from mopidy.frontends.mpd.dispatcher import MpdDispatcher
|
||||
from mopidy.frontends.mpd.protocol import status
|
||||
from mopidy.mixers.dummy import DummyMixer
|
||||
from mopidy.models import Track
|
||||
|
||||
@ -14,21 +15,22 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.b = DummyBackend.start().proxy()
|
||||
self.mixer = DummyMixer.start().proxy()
|
||||
self.h = dispatcher.MpdDispatcher()
|
||||
self.dispatcher = MpdDispatcher()
|
||||
self.context = self.dispatcher.context
|
||||
|
||||
def tearDown(self):
|
||||
self.b.stop().get()
|
||||
self.mixer.stop().get()
|
||||
|
||||
def test_clearerror(self):
|
||||
result = self.h.handle_request(u'clearerror')
|
||||
result = self.dispatcher.handle_request(u'clearerror')
|
||||
self.assert_(u'ACK [0@0] {} Not implemented' in result)
|
||||
|
||||
def test_currentsong(self):
|
||||
track = Track()
|
||||
self.b.current_playlist.append([track])
|
||||
self.b.playback.play()
|
||||
result = self.h.handle_request(u'currentsong')
|
||||
result = self.dispatcher.handle_request(u'currentsong')
|
||||
self.assert_(u'file: ' in result)
|
||||
self.assert_(u'Time: 0' in result)
|
||||
self.assert_(u'Artist: ' in result)
|
||||
@ -41,27 +43,27 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
self.assert_(u'OK' in result)
|
||||
|
||||
def test_currentsong_without_song(self):
|
||||
result = self.h.handle_request(u'currentsong')
|
||||
result = self.dispatcher.handle_request(u'currentsong')
|
||||
self.assert_(u'OK' in result)
|
||||
|
||||
def test_idle_without_subsystems(self):
|
||||
result = self.h.handle_request(u'idle')
|
||||
result = self.dispatcher.handle_request(u'idle')
|
||||
self.assert_(u'OK' in result)
|
||||
|
||||
def test_idle_with_subsystems(self):
|
||||
result = self.h.handle_request(u'idle database playlist')
|
||||
result = self.dispatcher.handle_request(u'idle database playlist')
|
||||
self.assert_(u'OK' in result)
|
||||
|
||||
def test_noidle(self):
|
||||
result = self.h.handle_request(u'noidle')
|
||||
result = self.dispatcher.handle_request(u'noidle')
|
||||
self.assert_(u'OK' in result)
|
||||
|
||||
def test_stats_command(self):
|
||||
result = self.h.handle_request(u'stats')
|
||||
result = self.dispatcher.handle_request(u'stats')
|
||||
self.assert_(u'OK' in result)
|
||||
|
||||
def test_stats_method(self):
|
||||
result = dispatcher.status.stats(self.h)
|
||||
result = status.stats(self.context)
|
||||
self.assert_('artists' in result)
|
||||
self.assert_(int(result['artists']) >= 0)
|
||||
self.assert_('albums' in result)
|
||||
@ -78,110 +80,110 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
self.assert_(int(result['playtime']) >= 0)
|
||||
|
||||
def test_status_command(self):
|
||||
result = self.h.handle_request(u'status')
|
||||
result = self.dispatcher.handle_request(u'status')
|
||||
self.assert_(u'OK' in result)
|
||||
|
||||
def test_status_method_contains_volume_which_defaults_to_0(self):
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('volume' in result)
|
||||
self.assertEqual(int(result['volume']), 0)
|
||||
|
||||
def test_status_method_contains_volume(self):
|
||||
self.mixer.volume = 17
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('volume' in result)
|
||||
self.assertEqual(int(result['volume']), 17)
|
||||
|
||||
def test_status_method_contains_repeat_is_0(self):
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('repeat' in result)
|
||||
self.assertEqual(int(result['repeat']), 0)
|
||||
|
||||
def test_status_method_contains_repeat_is_1(self):
|
||||
self.b.playback.repeat = 1
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('repeat' in result)
|
||||
self.assertEqual(int(result['repeat']), 1)
|
||||
|
||||
def test_status_method_contains_random_is_0(self):
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('random' in result)
|
||||
self.assertEqual(int(result['random']), 0)
|
||||
|
||||
def test_status_method_contains_random_is_1(self):
|
||||
self.b.playback.random = 1
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('random' in result)
|
||||
self.assertEqual(int(result['random']), 1)
|
||||
|
||||
def test_status_method_contains_single(self):
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('single' in result)
|
||||
self.assert_(int(result['single']) in (0, 1))
|
||||
|
||||
def test_status_method_contains_consume_is_0(self):
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('consume' in result)
|
||||
self.assertEqual(int(result['consume']), 0)
|
||||
|
||||
def test_status_method_contains_consume_is_1(self):
|
||||
self.b.playback.consume = 1
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('consume' in result)
|
||||
self.assertEqual(int(result['consume']), 1)
|
||||
|
||||
def test_status_method_contains_playlist(self):
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('playlist' in result)
|
||||
self.assert_(int(result['playlist']) in xrange(0, 2**31 - 1))
|
||||
|
||||
def test_status_method_contains_playlistlength(self):
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('playlistlength' in result)
|
||||
self.assert_(int(result['playlistlength']) >= 0)
|
||||
|
||||
def test_status_method_contains_xfade(self):
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('xfade' in result)
|
||||
self.assert_(int(result['xfade']) >= 0)
|
||||
|
||||
def test_status_method_contains_state_is_play(self):
|
||||
self.b.playback.state = PLAYING
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('state' in result)
|
||||
self.assertEqual(result['state'], 'play')
|
||||
|
||||
def test_status_method_contains_state_is_stop(self):
|
||||
self.b.playback.state = STOPPED
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('state' in result)
|
||||
self.assertEqual(result['state'], 'stop')
|
||||
|
||||
def test_status_method_contains_state_is_pause(self):
|
||||
self.b.playback.state = PLAYING
|
||||
self.b.playback.state = PAUSED
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('state' in result)
|
||||
self.assertEqual(result['state'], 'pause')
|
||||
|
||||
def test_status_method_when_playlist_loaded_contains_song(self):
|
||||
self.b.current_playlist.append([Track()])
|
||||
self.b.playback.play()
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('song' in result)
|
||||
self.assert_(int(result['song']) >= 0)
|
||||
|
||||
def test_status_method_when_playlist_loaded_contains_cpid_as_songid(self):
|
||||
self.b.current_playlist.append([Track()])
|
||||
self.b.playback.play()
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('songid' in result)
|
||||
self.assertEqual(int(result['songid']), 0)
|
||||
|
||||
def test_status_method_when_playing_contains_time_with_no_length(self):
|
||||
self.b.current_playlist.append([Track(length=None)])
|
||||
self.b.playback.play()
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('time' in result)
|
||||
(position, total) = result['time'].split(':')
|
||||
position = int(position)
|
||||
@ -191,7 +193,7 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
def test_status_method_when_playing_contains_time_with_length(self):
|
||||
self.b.current_playlist.append([Track(length=10000)])
|
||||
self.b.playback.play()
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('time' in result)
|
||||
(position, total) = result['time'].split(':')
|
||||
position = int(position)
|
||||
@ -201,13 +203,13 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
def test_status_method_when_playing_contains_elapsed(self):
|
||||
self.b.playback.state = PAUSED
|
||||
self.b.playback.play_time_accumulated = 59123
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('elapsed' in result)
|
||||
self.assertEqual(int(result['elapsed']), 59123)
|
||||
|
||||
def test_status_method_when_playing_contains_bitrate(self):
|
||||
self.b.current_playlist.append([Track(bitrate=320)])
|
||||
self.b.playback.play()
|
||||
result = dict(dispatcher.status.status(self.h))
|
||||
result = dict(status.status(self.context))
|
||||
self.assert_('bitrate' in result)
|
||||
self.assertEqual(int(result['bitrate']), 320)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user