]> kaliko git repositories - mpd-sima.git/blobdiff - sima/mpdclient.py
ci: Fixed unittest
[mpd-sima.git] / sima / mpdclient.py
index 4e6af68f37ec2614b71f3114da9746d56ae85af8..d528b96bb25aa4dff2260e3475cf380ce050ac1a 100644 (file)
@@ -20,6 +20,7 @@
 from difflib import get_close_matches
 from functools import wraps
 from logging import getLogger
+from select import select
 
 # external module
 from musicpd import MPDClient, MPDError as PlayerError
@@ -106,6 +107,7 @@ class MPD(MPDClient):
 
     def __init__(self, config):
         super().__init__()
+        self.socket_timeout = 10
         self.use_mbid = True
         self.log = getLogger('sima')
         self.config = config
@@ -115,9 +117,12 @@ class MPD(MPDClient):
     def __getattr__(self, cmd):
         """Wrapper around MPDClient calls for abstract overriding"""
         track_wrapped = {'currentsong', 'find', 'playlistinfo', }
-        if cmd in track_wrapped:
-            return tracks_wrapper(super().__getattr__(cmd))
-        return super().__getattr__(cmd)
+        try:
+            if cmd in track_wrapped:
+                return tracks_wrapper(super().__getattr__(cmd))
+            return super().__getattr__(cmd)
+        except OSError as err:
+            raise PlayerError(err)
 
     def disconnect(self):
         """Overriding explicitly MPDClient.disconnect()"""
@@ -226,15 +231,22 @@ class MPD(MPDClient):
             * skipped   current track skipped
         """
         curr = self.current
-        try:
-            ret = self.idle('database', 'playlist', 'player', 'options')
-        except (PlayerError, OSError) as err:
-            raise PlayerError("Couldn't init idle: %s" % err)
-        if self._skipped_track(curr):
-            ret.append('skipped')
-        if 'database' in ret:
-            self._reset_cache()
-        return ret
+        select_timeout = 5
+        while True:
+            self.send_idle('database', 'playlist', 'player', 'options')
+            _read, _, _ = select([self], [], [], select_timeout)
+            if _read:  # tries to read response
+                ret = self.fetch_idle()
+                if self._skipped_track(curr):
+                    ret.append('skipped')
+                if 'database' in ret:
+                    self._reset_cache()
+                return ret
+            else:
+                try:  # noidle cmd does not go through __getattr__, need to catch OSError then
+                    self.noidle()
+                except OSError as err:
+                    raise PlayerError(err)
 
     def clean(self):
         """Clean blocking event (idle) and pending commands