From 1fb65355de64ef044d0a7b3736a21bed6a6ae290 Mon Sep 17 00:00:00 2001 From: Kaliko Jack Date: Thu, 1 Nov 2018 17:47:06 +0100 Subject: [PATCH] Add suport for environment variables MPD_HOST/MPD_PORT/XDG_RUNTIME_DIR --- CHANGES.txt | 4 ++++ README.rst | 5 ++++- musicpd.py | 36 ++++++++++++++++++++++++++++++++++-- setup.py | 2 +- test.py | 38 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c0d5d50..ada6427 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,6 +5,10 @@ Changes in 0.4.3 UNRELEASED --------------------------- * Use setuptools +* Add sensible defaults and honor environment variables + Use MPD_HOST/MPD_PORT (honor password setting in MPD_HOST) + If MPD_HOST is not set, tries to find a socket in + ${XDG_RUNTIME_DIR:-/run}/mpd/socket Changes in 0.4.2 ---------------- diff --git a/README.rst b/README.rst index 61b305f..95e6ff5 100644 --- a/README.rst +++ b/README.rst @@ -35,7 +35,10 @@ Using the client library The client library can be used as follows:: client = musicpd.MPDClient() # create client object - client.connect('localhost', 6600) # connect to localhost:6600 + client.connect() # use MPD_HOST/MPD_PORT if set else + # test ${XDG_RUNTIME_DIR}/mpd/socket for existence + # fallback to localhost:6600 + # `connect` support host/port argument as well print client.mpd_version # print the mpd version print client.cmd('one', 2) # print result of the command "cmd one 2" client.close() # send the close command diff --git a/musicpd.py b/musicpd.py index 855ff5f..10b15cb 100644 --- a/musicpd.py +++ b/musicpd.py @@ -1,6 +1,6 @@ # python-musicpd: Python MPD client library # Copyright (C) 2008-2010 J. Alexander Treuman -# Copyright (C) 2012-2014 Kaliko Jack +# Copyright (C) 2012-2018 Kaliko Jack # # python-musicpd is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by @@ -18,6 +18,8 @@ # pylint: disable=missing-docstring import socket +import os + from functools import wraps @@ -219,6 +221,32 @@ class MPDClient: "readmessages": self._fetch_messages, "sendmessage": self._fetch_nothing, } + self._get_envvars() + + def _get_envvars(self): + """ + Retrieve MPD env. var. to overrides "localhost:6600" + Use MPD_HOST/MPD_PORT if set + else use MPD_HOST=${XDG_RUNTIME_DIR:-/run/}/mpd/socket if file exists + """ + self.host = 'localhost' + self.password = None + self.port = os.environ.get('MPD_PORT', '6600') + mpd_host_env = os.environ.get('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.password = mpd_host_env[1] + else: + # Is socket there + xdg_runtime_dir = os.environ.get('XDG_RUNTIME_DIR', '/run') + rundir = os.path.join(xdg_runtime_dir, 'mpd/socket') + if os.path.exists(rundir): + self.host = rundir def __getattr__(self, attr): if attr == 'send_noidle': # have send_noidle to cancel idle as well as noidle @@ -494,7 +522,11 @@ class MPDClient: self._write_command("noidle") return self._fetch_list() - def connect(self, host, port): + def connect(self, host=None, port=None): + if not host: + host = self.host + if not port: + port = self.port if self._sock is not None: raise ConnectionError("Already connected") if host.startswith("/"): diff --git a/setup.py b/setup.py index 8ed1c02..afcbf23 100755 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ CLASSIFIERS = [ LICENSE = """\ Copyright (C) 2008-2010 J. Alexander Treuman -Copyright (C) 2012-2015 Kaliko Jack +Copyright (C) 2012-2018 Kaliko Jack python-musicpd is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/test.py b/test.py index 7086bcd..4b08902 100755 --- a/test.py +++ b/test.py @@ -8,6 +8,7 @@ Test suite highly borrowed^Wsteal from python-mpd2 [0] project. import itertools +import os import sys import types import unittest @@ -31,6 +32,43 @@ warnings.simplefilter('default') TEST_MPD_HOST, TEST_MPD_PORT = ('example.com', 10000) +class testEnvVar(unittest.TestCase): + + def test_envvar(self): + os.environ.pop('MPD_HOST', None) + os.environ.pop('MPD_PORT', None) + client = musicpd.MPDClient() + self.assertEqual(client.host, 'localhost') + self.assertEqual(client.port, '6600') + + os.environ['MPD_HOST'] = 'pa55w04d@example.org' + client = musicpd.MPDClient() + self.assertEqual(client.password, 'pa55w04d') + self.assertEqual(client.host, 'example.org') + self.assertEqual(client.port, '6600') + + os.environ.pop('MPD_HOST', None) + os.environ['MPD_PORT'] = '6666' + client = musicpd.MPDClient() + self.assertEqual(client.password, None) + self.assertEqual(client.host, 'localhost') + self.assertEqual(client.port, '6666') + + # Test unix socket fallback + os.environ.pop('MPD_HOST', None) + os.environ.pop('MPD_PORT', None) + os.environ.pop('XDG_RUNTIME_DIR', None) + with mock.patch('os.path.exists', return_value=True): + client = musicpd.MPDClient() + self.assertEqual(client.host, '/run/mpd/socket') + + os.environ.pop('MPD_HOST', None) + os.environ.pop('MPD_PORT', None) + os.environ['XDG_RUNTIME_DIR'] = '/run/user/1000/' + with mock.patch('os.path.exists', return_value=True): + client = musicpd.MPDClient() + self.assertEqual(client.host, '/run/user/1000/mpd/socket') + class TestMPDClient(unittest.TestCase): longMessage = True -- 2.39.2