]> kaliko git repositories - python-musicpdaio.git/blobdiff - musicpdaio.py
Switch to async/await
[python-musicpdaio.git] / musicpdaio.py
index 1663b2727183235a74b65c9fe447b4ca414a0e5b..5e2c480bc991635a3da716496c547755ebb219f7 100644 (file)
@@ -27,6 +27,7 @@ import logging
 
 from os import environ
 if 'DEBUG' in environ or 'PYTHONASYNCIODEBUG' in environ:
+    # environ['PYTHONASYNCIODEBUG'] = '1'
     logging.basicConfig(level=logging.DEBUG)
 
 HELLO_PREFIX = "OK MPD "
@@ -48,15 +49,6 @@ class ProtocolError(MPDError):
 class CommandError(MPDError):
     pass
 
-class CommandListError(MPDError):
-    pass
-
-class PendingCommandError(MPDError):
-    pass
-
-class IteratingError(MPDError):
-    pass
-
 
 class Response:
     def __init__(self):
@@ -68,9 +60,10 @@ class Response:
                 ' '.join(self.resp.split('\n')[:2]),
                 self.version)
 
+
 class MPDProto(asyncio.Protocol):
-    def __init__(self, future, payload, pwd):
-        self.pwd = pwd
+    def __init__(self, future, payload):
+        logging.debug('payload: "%s"', payload)
         self.transport = None
         self.future = future
         self.payload = payload
@@ -110,6 +103,12 @@ class MPDProto(asyncio.Protocol):
         return rcv
 
 class MPDClient:
+    """MPD Client
+    :param string host: Server name or IP, default to 'localhost'
+    :param integer port: Server port, default to 6600
+    :param string passwd: Password, default to ``None``
+
+    """
 
     def __init__(self, host='localhost', port=6600, passwd=None):
         self._evloop = asyncio.get_event_loop()
@@ -117,11 +116,13 @@ class MPDClient:
         self.futures = []
         self._host = host
         self._port = port
-        self._pwd = passwd
+        #self._pwd = passwd  # TODO: authentication yet to implement
         self._commands = {
                 'currentsong',
                 'stats',
                 'playlistinfo',
+                'next',
+                'find',
         }
 
     def __getattr__(self, attr):
@@ -135,22 +136,23 @@ class MPDClient:
                                      (self.__class__.__name__, attr))
         return lambda *args: wrapper(command, args)
 
-    @asyncio.coroutine
-    def _connect(self, proto):
+    async def _connect(self, proto):
         # coroutine allowing Exception handling
         # src: http://comments.gmane.org/gmane.comp.python.tulip/1401
         try:
-            yield from self._evloop.create_connection(lambda: proto,
-                    host=self._host,
-                    port=self._port)
+            await self._evloop.create_connection(lambda: proto,
+                                                 host=self._host,
+                                                 port=self._port)
         except Exception as err:
             proto.future.set_exception(ConnectionError(err))
 
     def _command(self, command, args):
-        payload = '{} {}'.format(command, ''.join(args))
+        payload = command
+        for arg in args:
+            payload += ' "{}"'.format(escape(arg))
         future = asyncio.Future()
         # kick off a task to create the connection to MPD
-        coro = self._connect(MPDProto(future, payload, self._pwd))
+        coro = self._connect(MPDProto(future, payload))
         asyncio.async(coro)
         self.futures.append(future)
         if not self.asio:
@@ -167,7 +169,13 @@ class MPDClient:
         """Run event loop gathering tasks from self.futures
         """
         if self.futures:
-           self._evloop.run_until_complete(asyncio.gather(*self.futures))
-           self.futures = []
+            self._evloop.run_until_complete(asyncio.gather(*self.futures))
+            self.futures = []
         else:
             logging.info('No task found in queue, need to set self.asio?')
+
+
+def escape(text):
+    """Escapting quotes and backslash"""
+    return text.replace('\\', '\\\\').replace('"', '\\"')
+