diff --git a/mopidy/frontends/mpd/__init__.py b/mopidy/frontends/mpd/__init__.py index e5bafcf1..b90f7c86 100644 --- a/mopidy/frontends/mpd/__init__.py +++ b/mopidy/frontends/mpd/__init__.py @@ -4,8 +4,8 @@ import sys from pykka import registry, actor from mopidy import core, settings -from mopidy.frontends.mpd import dispatcher, protocol -from mopidy.utils import locale_decode, log, network, process +from mopidy.frontends.mpd import session +from mopidy.utils import locale_decode, network, process logger = logging.getLogger('mopidy.frontends.mpd') @@ -33,7 +33,7 @@ class MpdFrontend(actor.ThreadingActor, core.CoreListener): try: network.Server( hostname, port, - protocol=MpdSession, protocol_kwargs={'core': core}, + protocol=session.MpdSession, protocol_kwargs={'core': core}, max_connections=settings.MPD_SERVER_MAX_CONNECTIONS) except IOError as error: logger.error( @@ -43,7 +43,7 @@ class MpdFrontend(actor.ThreadingActor, core.CoreListener): logger.info(u'MPD server running at [%s]:%s', hostname, port) def on_stop(self): - process.stop_actors_by_class(MpdSession) + process.stop_actors_by_class(session.MpdSession) def send_idle(self, subsystem): # FIXME this should be updated once pykka supports non-blocking calls @@ -53,7 +53,7 @@ class MpdFrontend(actor.ThreadingActor, core.CoreListener): 'attr_path': ('on_idle',), 'args': [subsystem], 'kwargs': {}, - }, target_class=MpdSession) + }, target_class=session.MpdSession) def playback_state_changed(self, old_state, new_state): self.send_idle('player') @@ -66,53 +66,3 @@ class MpdFrontend(actor.ThreadingActor, core.CoreListener): def volume_changed(self): self.send_idle('mixer') - - -class MpdSession(network.LineProtocol): - """ - The MPD client session. Keeps track of a single client session. Any - requests from the client is passed on to the MPD request dispatcher. - """ - - terminator = protocol.LINE_TERMINATOR - encoding = protocol.ENCODING - delimiter = r'\r?\n' - - def __init__(self, connection, core=None): - super(MpdSession, self).__init__(connection) - self.dispatcher = dispatcher.MpdDispatcher(session=self, core=core) - - def on_start(self): - logger.info(u'New MPD connection from [%s]:%s', self.host, self.port) - self.send_lines([u'OK MPD %s' % protocol.VERSION]) - - def on_line_received(self, line): - logger.debug( - u'Request from [%s]:%s to %s: %s', - self.host, self.port, self.actor_urn, line) - - response = self.dispatcher.handle_request(line) - if not response: - return - - logger.debug( - u'Response to [%s]:%s from %s: %s', - self.host, self.port, self.actor_urn, - log.indent(self.terminator.join(response))) - - self.send_lines(response) - - def on_idle(self, subsystem): - self.dispatcher.handle_idle(subsystem) - - def decode(self, line): - try: - return super(MpdSession, self).decode(line.decode('string_escape')) - except ValueError: - logger.warning( - u'Stopping actor due to unescaping error, data ' - u'supplied by client was not valid.') - self.stop() - - def close(self): - self.stop() diff --git a/mopidy/frontends/mpd/session.py b/mopidy/frontends/mpd/session.py new file mode 100644 index 00000000..b4531c83 --- /dev/null +++ b/mopidy/frontends/mpd/session.py @@ -0,0 +1,56 @@ +import logging + +from mopidy.frontends.mpd import dispatcher, protocol +from mopidy.utils import log, network + +logger = logging.getLogger('mopidy.frontends.mpd') + + +class MpdSession(network.LineProtocol): + """ + The MPD client session. Keeps track of a single client session. Any + requests from the client is passed on to the MPD request dispatcher. + """ + + terminator = protocol.LINE_TERMINATOR + encoding = protocol.ENCODING + delimiter = r'\r?\n' + + def __init__(self, connection, core=None): + super(MpdSession, self).__init__(connection) + self.dispatcher = dispatcher.MpdDispatcher(session=self, core=core) + + def on_start(self): + logger.info(u'New MPD connection from [%s]:%s', self.host, self.port) + self.send_lines([u'OK MPD %s' % protocol.VERSION]) + + def on_line_received(self, line): + logger.debug( + u'Request from [%s]:%s to %s: %s', + self.host, self.port, self.actor_urn, line) + + response = self.dispatcher.handle_request(line) + if not response: + return + + logger.debug( + u'Response to [%s]:%s from %s: %s', + self.host, self.port, self.actor_urn, + log.indent(self.terminator.join(response))) + + self.send_lines(response) + + def on_idle(self, subsystem): + self.dispatcher.handle_idle(subsystem) + + def decode(self, line): + try: + return super(MpdSession, self).decode(line.decode('string_escape')) + except ValueError: + logger.warning( + u'Stopping actor due to unescaping error, data ' + u'supplied by client was not valid.') + self.stop() + + def close(self): + self.stop() diff --git a/tests/frontends/mpd/protocol/__init__.py b/tests/frontends/mpd/protocol/__init__.py index 63c253d9..34557513 100644 --- a/tests/frontends/mpd/protocol/__init__.py +++ b/tests/frontends/mpd/protocol/__init__.py @@ -4,7 +4,7 @@ from pykka.registry import ActorRegistry from mopidy import core, settings from mopidy.backends import dummy -from mopidy.frontends import mpd +from mopidy.frontends.mpd import session from tests import unittest @@ -27,7 +27,7 @@ class BaseTestCase(unittest.TestCase): self.core = core.Core.start(backend=self.backend).proxy() self.connection = MockConnection() - self.session = mpd.MpdSession(self.connection, core=self.core) + self.session = session.MpdSession(self.connection, core=self.core) self.dispatcher = self.session.dispatcher self.context = self.dispatcher.context