"""Python Music Player Daemon client library"""
-import socket
+import logging
import os
+import socket
from functools import wraps
SUCCESS = "OK"
NEXT = "list_OK"
#: Module version
-VERSION = '0.9.0b0'
+VERSION = '0.9.0b1'
#: Seconds before a connection attempt times out
#: (overriden by :envvar:`MPD_TIMEOUT` env. var.)
CONNECTION_TIMEOUT = 30
-#: Socket timeout in second (Default is None for no timeout)
+#: Socket timeout in second > 0 (Default is :py:obj:`None` for no timeout)
SOCKET_TIMEOUT = None
+log = logging.getLogger(__name__)
+
def iterator_wrapper(func):
"""Decorator handling iterate option"""
mpd_host_env = _host.split('@', 1)
if mpd_host_env[0]:
# A password is actually set
+ log.debug('password detected in MPD_HOST, set client pwd attribute')
self.pwd = mpd_host_env[0]
if mpd_host_env[1]:
self.host = mpd_host_env[1]
+ log.debug('host detected in MPD_HOST: %s', self.host)
elif mpd_host_env[1]:
# No password set but leading @ is an abstract socket
self.host = '@'+mpd_host_env[1]
+ log.debug('host detected in MPD_HOST: %s (abstract socket)', self.host)
else:
# MPD_HOST is a plain host
self.host = _host
+ log.debug('host detected in MPD_HOST: @%s', self.host)
else:
# Is socket there
xdg_runtime_dir = os.getenv('XDG_RUNTIME_DIR', '/run')
rundir = os.path.join(xdg_runtime_dir, 'mpd/socket')
if os.path.exists(rundir):
self.host = rundir
+ log.debug('host detected in ${XDG_RUNTIME_DIR}/run: %s (unix socket)', self.host)
_mpd_timeout = os.getenv('MPD_TIMEOUT', '')
if _mpd_timeout.isdigit():
self.mpd_timeout = int(_mpd_timeout)
+ log.debug('timeout detected in MPD_TIMEOUT: %d', self.mpd_timeout)
else: # Use CONNECTION_TIMEOUT as default even if MPD_TIMEOUT carries gargage
self.mpd_timeout = CONNECTION_TIMEOUT
if self._sock is not None:
raise ConnectionError("Already connected")
if host[0] in ['/', '@']:
+ log.debug('Connecting unix socket %s', host)
self._sock = self._connect_unix(host)
else:
+ log.debug('Connecting tcp socket %s:%s (timeout: %ss)', host, port, self.mpd_timeout)
self._sock = self._connect_tcp(host, port)
self._rfile = self._sock.makefile("r", encoding='utf-8', errors='surrogateescape')
self._rbfile = self._sock.makefile("rb")
except:
self.disconnect()
raise
+ log.debug('Connected')
@property
def socket_timeout(self):
"""Socket timeout in second (defaults to :py:obj:`SOCKET_TIMEOUT`).
- Use None to disable socket timout."""
+ Use :py:obj:`None` to disable socket timout.
+
+ :setter: Set the socket timeout
+ :type: int or None (integer > 0)
+ """
return self._socket_timeout
@socket_timeout.setter
def socket_timeout(self, timeout):
- self._socket_timeout = timeout
+ if timeout is not None:
+ if int(timeout) <= 0:
+ raise ValueError('socket_timeout expects a non zero positive integer')
+ self._socket_timeout = int(timeout)
+ else:
+ self._socket_timeout = timeout
if getattr(self._sock, 'settimeout', False):
self._sock.settimeout(self._socket_timeout)
+
def disconnect(self):
"""Closes the MPD connection.
The client closes the actual socket, it does not use the