From 3a949c076873a90eb02ff71f71f9df58b08854cf Mon Sep 17 00:00:00 2001 From: Kaliko Jack Date: Wed, 17 Feb 2021 21:17:03 +0100 Subject: [PATCH] Add abstract unix socket support Closes #12 and #13 --- CHANGES.txt | 1 + musicpd.py | 28 ++++++++++++++++++---------- test.py | 11 +++++++++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 110b69d..c72e7eb 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -10,6 +10,7 @@ Changes in 0.6.0 UNRELEASED * Add getvol command * Honor MPD_TIMEOUT environment variables * Default connection timeout is now 30s (previously 5s) +* Add abstract unix socket support Changes in 0.5.1 diff --git a/musicpd.py b/musicpd.py index 1a64271..47eb7b5 100644 --- a/musicpd.py +++ b/musicpd.py @@ -300,15 +300,20 @@ class MPDClient: self.host = 'localhost' self.pwd = None self.port = os.getenv('MPD_PORT', '6600') - mpd_host_env = os.getenv('MPD_HOST') - if mpd_host_env: - # If password is set: - # mpd_host_env = ['pass', 'host'] because MPD_HOST=pass@host - mpd_host_env = mpd_host_env.split('@') - mpd_host_env.reverse() - self.host = mpd_host_env[0] - if len(mpd_host_env) > 1 and mpd_host_env[1]: - self.pwd = mpd_host_env[1] + if os.getenv('MPD_HOST'): + # If password is set: MPD_HOST=pass@host + if '@' in os.getenv('MPD_HOST'): + mpd_host_env = os.getenv('MPD_HOST').split('@', 1) + if mpd_host_env[0]: + # A password is actually set + self.pwd = mpd_host_env[0] + self.host = mpd_host_env[1] + else: + # No password set but leading @ is an abstract socket + self.host = '@'+mpd_host_env[1] + else: + # MPD_HOST is a plain host + self.host = os.getenv('MPD_HOST') else: # Is socket there xdg_runtime_dir = os.getenv('XDG_RUNTIME_DIR', '/run') @@ -599,6 +604,9 @@ class MPDClient: if not hasattr(socket, "AF_UNIX"): raise ConnectionError( "Unix domain sockets not supported on this platform") + # abstract socket + if path.startswith('@'): + path = '\0'+path[1:] sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(path) return sock @@ -671,7 +679,7 @@ class MPDClient: self.port = port if self._sock is not None: raise ConnectionError("Already connected") - if host.startswith("/"): + if host[0] in ['/', '@']: self._sock = self._connect_unix(host) else: self._sock = self._connect_tcp(host, port) diff --git a/test.py b/test.py index ad3d471..449101b 100755 --- a/test.py +++ b/test.py @@ -66,6 +66,17 @@ class testEnvVar(unittest.TestCase): client = musicpd.MPDClient() self.assertEqual(client.host, '/unix/sock') + # Test plain abstract socket extraction + os.environ['MPD_HOST'] = '@abstract' + client = musicpd.MPDClient() + self.assertEqual(client.host, '@abstract') + + # Test password and abstract socket extraction + os.environ['MPD_HOST'] = 'pass@@abstract' + client = musicpd.MPDClient() + self.assertEqual(client.pwd, 'pass') + self.assertEqual(client.host, '@abstract') + # Test unix socket fallback os.environ.pop('MPD_HOST', None) os.environ.pop('MPD_PORT', None) -- 2.39.2