Move idle code from dispatcher to protocol.status module

This commit is contained in:
Thomas Adamcik 2011-07-23 03:32:45 +02:00
parent e4ce31a438
commit 63dba5553f
4 changed files with 52 additions and 49 deletions

View File

@ -20,10 +20,6 @@ from mopidy.utils import flatten
logger = logging.getLogger('mopidy.frontends.mpd.dispatcher')
#: Subsystems that can be registered with idle command.
SUBSYSTEMS = ['database', 'mixer', 'options', 'output',
'player', 'playlist', 'stored_playlist', 'update', ]
class MpdDispatcher(object):
"""
The MPD session feeds the MPD dispatcher with requests. The dispatcher
@ -132,59 +128,40 @@ class MpdDispatcher(object):
### Filter: idle
def _idle_filter(self, request, response, filter_chain):
if re.match(r'^noidle$', request):
if not self.context.subscriptions:
return []
self.context.subscriptions = set()
self.context.events = set()
self.context.session.connection.enable_timeout()
return [u'OK']
if self.context.subscriptions:
if self._is_currently_idle() and not self._is_noidle(request):
logger.debug(u'Client send us %s, only %s is allowed while in '
'the idle state', repr(request), repr('noidle'))
self.context.session.close()
return []
if re.match(r'^idle( .+)?$', request):
for subsystem in self._extract_subsystems(request):
self.context.subscriptions.add(subsystem)
if not self._is_currently_idle() and self._is_noidle(request):
return []
subsystems = self.context.subscriptions.intersection(
self.context.events)
if subsystems:
for subsystem in subsystems:
response.append(u'changed: %s' % subsystem)
self.context.events = set()
self.context.subscriptions = set()
response.append(u'OK')
return response
else:
self.context.session.connection.disable_timeout()
return []
response = self._call_next_filter(request, response, filter_chain)
return self._call_next_filter(request, response, filter_chain)
if self._is_currently_idle():
return []
else:
return response
def _extract_subsystems(self, request):
match = re.match(r'^idle (?P<subsystems>.+)$', request)
if not match:
return SUBSYSTEMS
return match.groupdict()['subsystems'].split(' ')
def _is_currently_idle(self):
return bool(self.context.subscriptions)
def _is_noidle(self, request):
return re.match(r'^noidle$', request)
### Filter: add OK
def _add_ok_filter(self, request, response, filter_chain):
response = self._call_next_filter(request, response, filter_chain)
if not self._has_error(response) and not self._is_idle(request):
if not self._has_error(response):
response.append(u'OK')
return response
def _has_error(self, response):
return response and response[-1].startswith(u'ACK')
def _is_idle(self, request):
return request.startswith('idle')
### Filter: call handler
def _call_handler_filter(self, request, response, filter_chain):

View File

@ -27,10 +27,6 @@ def commands(context):
command_names.remove('command_list_ok_begin')
if 'command_list_end' in command_names:
command_names.remove('command_list_end')
if 'idle' in command_names:
command_names.remove('idle')
if 'noidle' in command_names:
command_names.remove('noidle')
if 'sticker' in command_names:
command_names.remove('sticker')

View File

@ -4,6 +4,10 @@ from mopidy.backends.base import PlaybackController
from mopidy.frontends.mpd.protocol import handle_request
from mopidy.frontends.mpd.exceptions import MpdNotImplemented
#: Subsystems that can be registered with idle command.
SUBSYSTEMS = ['database', 'mixer', 'options', 'output',
'player', 'playlist', 'stored_playlist', 'update', ]
@handle_request(r'^clearerror$')
def clearerror(context):
"""
@ -32,8 +36,8 @@ def currentsong(context):
position=context.backend.playback.current_playlist_position.get(),
cpid=current_cp_track.cpid)
#@handle_request(r'^idle$')
#@handle_request(r'^idle (?P<subsystems>.+)$')
@handle_request(r'^idle$')
@handle_request(r'^idle (?P<subsystems>.+)$')
def idle(context, subsystems=None):
"""
*musicpd.org, status section:*
@ -67,12 +71,38 @@ def idle(context, subsystems=None):
notifications when something changed in one of the specified
subsystems.
"""
pass # TODO
#@handle_request(r'^noidle$')
if subsystems:
subsystems = subsystems.split()
else:
subsystems = SUBSYSTEMS
for subsystem in subsystems:
context.subscriptions.add(subsystem)
active = context.subscriptions.intersection(context.events)
if not active:
context.session.connection.disable_timeout()
return
response = []
context.events = set()
context.subscriptions = set()
for subsystem in active:
response.append(u'changed: %s' % subsystem)
response.append(u'OK')
return response
@handle_request(r'^noidle$')
def noidle(context):
"""See :meth:`_status_idle`."""
pass # TODO
if not context.subscriptions:
return
context.subscriptions = set()
context.events = set()
context.session.connection.enable_timeout()
@handle_request(r'^stats$')
def stats(context):

View File

@ -1,6 +1,6 @@
from mock import patch
from mopidy.frontends.mpd.dispatcher import SUBSYSTEMS
from mopidy.frontends.mpd.protocol.status import SUBSYSTEMS
from mopidy.models import Track
from tests.frontends.mpd import protocol