]> kaliko git repositories - python-musicpdaio.git/commitdiff
Add binary read for albumart/readpicture and protocol version
authorkaliko <kaliko@azylum.org>
Sun, 3 Mar 2024 20:33:06 +0000 (21:33 +0100)
committerkaliko <kaliko@azylum.org>
Sun, 3 Mar 2024 20:33:06 +0000 (21:33 +0100)
mpdaio/client.py
mpdaio/connection.py

index a8ae0cd8d0819275e96c7614c872594d31ee96f0..bde752f6d4d8305c7936b132d8a79694617d50ef 100644 (file)
@@ -26,10 +26,8 @@ class MPDClient:
         self.password = password or self.server_discovery[2]
         #: port used with the current connection (:py:obj:`int`, :py:obj:`str`)
         self.port = port or self.server_discovery[1]
-        log.info('logger : "%s"', __name__)
-        #: Protocol version
-        self.version: [None, str] = None
         self.mpd_timeout = CONNECTION_TIMEOUT
+        log.info('Using %s:%s to connect', self.host, self.port)
 
     def _get_envvars(self):
         """
@@ -87,13 +85,23 @@ class MPDClient:
                     f"'CmdHandler' object has no attribute '{attr}'")
         return lambda *args: wrapper(command, args)
 
+    @property
+    def version(self):
+        """MPD protocol version"""
+        host = (self.host, self.port)
+        version = {_.version for _ in self._pool._connections.get(host, [])}
+        if not version:
+            log.warning('No connections yet in the connections pool for %s', host)
+            return ''
+        if len(version) > 1:
+            log.warning('More than one version in the connections pool for %s', host)
+        return version.pop()
+
     async def close(self):
         await self._pool.close()
 
 
 class CmdHandler:
-    #TODO: CmdHandler to intanciate in place of MPDClient._execute
-    # The MPDClient.__getattr__ wrapper should instanciate an CmdHandler object
 
     def __init__(self, pool, server, port, password, timeout):
         self._commands = {
@@ -272,12 +280,12 @@ class CmdHandler:
         log.debug(' '.join(parts))
         await self._write_line(' '.join(parts))
 
-    def _read_binary(self, amount):
+    async def _read_binary(self, amount):
         chunk = bytearray()
         while amount > 0:
-            result = self._rbfile.read(amount)
+            result = await self.connection.read(amount)
             if len(result) == 0:
-                self.disconnect()
+                await self.connection.close()
                 raise ConnectionError(
                     "Connection lost while reading binary content")
             chunk.extend(result)
@@ -285,13 +293,10 @@ class CmdHandler:
         return bytes(chunk)
 
     async def _read_line(self, binary=False):
-        if binary:
-            line = self._rbfile.readline().decode('utf-8')
-        else:
-            line = await self.connection.readline()
+        line = await self.connection.readline()
         line = line.decode('utf-8')
         if not line.endswith('\n'):
-            await self.close()
+            await self.connection.close()
             raise MPDConnectionError("Connection lost while reading line")
         line = line.rstrip('\n')
         if line.startswith(ERROR_PREFIX):
@@ -316,7 +321,6 @@ class CmdHandler:
         return pair
 
     async def _read_pairs(self, separator=": ", binary=False):
-        """OK"""
         pair = await self._read_pair(separator, binary=binary)
         while pair:
             yield pair
@@ -419,7 +423,7 @@ class CmdHandler:
 
     async def _fetch_composite(self):
         obj = {}
-        for key, value in self._read_pairs(binary=True):
+        async for key, value in self._read_pairs(binary=True):
             key = key.lower()
             obj[key] = value
             if key == 'binary':
@@ -430,7 +434,7 @@ class CmdHandler:
             return obj
         amount = int(obj['binary'])
         try:
-            obj['data'] = self._read_binary(amount)
+            obj['data'] = await self._read_binary(amount)
         except IOError as err:
             raise ConnectionError(
                 f'Error reading binary content: {err}') from err
@@ -440,8 +444,10 @@ class CmdHandler:
                                   f'Expects {amount}B, got {data_bytes}')
         # Fetches trailing new line
         await self._read_line(binary=True)
+        #ALT: await self.connection.readuntil(b'\n')
         # Fetches SUCCESS code
         await self._read_line(binary=True)
+        #ALT: await self.connection.readuntil(b'OK\n')
         return obj
 
     async def _fetch_command_list(self):
index f4a97de09039f3220ce81ea6971ef99155bf5f5d..5da292c0eae5a209cacd598537e852eb8397c954 100644 (file)
@@ -172,7 +172,6 @@ class Connection(base):
         self.version = rcv.split('\n')[0][len(HELLO_PREFIX):]
         log.info('protocol version: %s', self.version)
 
-
     def __getattr__(self, name: str) -> Any:
         """All unknown attributes are delegated to the reader and writer"""
         if self._closed or not self.in_use: