From c5ad0639ad5120f2b36b45744d927c253e913bfc Mon Sep 17 00:00:00 2001 From: kaliko Date: Fri, 24 Apr 2015 10:47:06 +0200 Subject: [PATCH] Plain POC of an MPDClient object --- musicpdasio.py | 70 +++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/musicpdasio.py b/musicpdasio.py index 3848ecd..b52a3e3 100644 --- a/musicpdasio.py +++ b/musicpdasio.py @@ -27,6 +27,7 @@ HELLO_PREFIX = "OK MPD " ERROR_PREFIX = "ACK " SUCCESS = "OK" NEXT = "list_OK" +VERSION = '0.0.1b' class MPDError(Exception): @@ -50,7 +51,6 @@ class PendingCommandError(MPDError): class IteratingError(MPDError): pass -loop = asyncio.get_event_loop() class Response: def __init__(self): @@ -59,7 +59,10 @@ class Response: self.err = None def __repr__(self): - return '{0}, {1}… ({2})'.format(self.err, self.resp[:15], self.version) + return 'err:{0}, "{1}…" ({2})'.format( + self.err, + ' '.join(self.resp.split('\n')[:2]), + self.version) class MPDProto(asyncio.Protocol): def __init__(self, future, payload): @@ -74,9 +77,9 @@ class MPDProto(asyncio.Protocol): def data_received(self, data): rcv = data.decode('utf-8') if '\n' not in rcv: - self.sess.err = 'Connection lost while reading line' + self.sess.err = ConnectionError('Connection lost while reading line') self.future.set_result(self.sess) - raise ConnectionError("Connection lost while reading line") + raise ConnectionError('Connection lost while reading line') rcv = rcv.strip('\n') @@ -85,7 +88,7 @@ class MPDProto(asyncio.Protocol): return self.transport.close() - # set the result on the Future so that the main() coroutine can + # set the result on the Future so that the coroutine can # resume if rcv.startswith(ERROR_PREFIX): self.sess.err = rcv[len(ERROR_PREFIX):].strip() @@ -95,28 +98,37 @@ class MPDProto(asyncio.Protocol): self.sess.resp = rcv self.future.set_result(self.sess) -def command(payload): - future = asyncio.Future() - if payload: - cli = MPDProto(future, payload) +class MPDClient: + loop = asyncio.get_event_loop() + + def __init__(self, host='localhost', port=6600): + self._host = host + self._port = port + self._commands = { + 'currentsong', + 'stats', + } + + def __getattr__(self, attr): + command = attr + wrapper = self._command + if command not in self._commands: + command = command.replace("_", " ") + if command not in self._commands: + raise AttributeError("'%s' object has no attribute '%s'" % + (self.__class__.__name__, attr)) + return lambda *args: wrapper(command, args) + + def _command(self, command, args): + # TODO: deal with encoding + payload = '{} {}'.format(command ,''.join(args)) + future = asyncio.Future() # kick off a task to create the connection to MPD. - asyncio.async(loop.create_connection(lambda: cli, host='192.168.0.20', port=6600)) - else: - future.set_result((None, None, None)) - - # return the future for the main() coroutine to wait on. - return future - - -def main(): - """main""" - import logging - logging.basicConfig(level=logging.DEBUG) - res = yield from command('currentsongt') - if res.err: - raise CommandError(res.err) - print(res) - print(res.resp) - -if __name__ == '__main__': - loop.run_until_complete(main()) + asyncio.async(MPDClient.loop.create_connection( + lambda: MPDProto(future, payload), + host=self._host, + port=self._port)) + MPDClient.loop.run_until_complete(future) + # return the future once completed. + return future.result() + -- 2.39.2