ERROR_PREFIX = "ACK "
SUCCESS = "OK"
NEXT = "list_OK"
+VERSION = '0.0.1b'
class MPDError(Exception):
class IteratingError(MPDError):
pass
-loop = asyncio.get_event_loop()
class Response:
def __init__(self):
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):
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')
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()
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()
+