From eae2c558486f872262a1263e503d9a98fd88a691 Mon Sep 17 00:00:00 2001 From: aschamberger Date: Sat, 18 May 2019 17:22:28 +0200 Subject: [PATCH 1/4] changes for Python 3 --- LMSTools/artworkresolver.py | 2 +- LMSTools/discovery.py | 6 +++--- LMSTools/menu.py | 2 +- LMSTools/player.py | 6 +++--- LMSTools/server.py | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/LMSTools/artworkresolver.py b/LMSTools/artworkresolver.py index 0efe16c..84f59ca 100644 --- a/LMSTools/artworkresolver.py +++ b/LMSTools/artworkresolver.py @@ -1,4 +1,4 @@ -from urllib import urlencode +from urllib.parse import urlencode class LMSArtworkResolver(object): """ diff --git a/LMSTools/discovery.py b/LMSTools/discovery.py index 3f5091a..f4fa527 100644 --- a/LMSTools/discovery.py +++ b/LMSTools/discovery.py @@ -72,14 +72,14 @@ def update(self): sock.bind(('', 0)) try: - sock.sendto(lms_msg, (lms_ip, lms_port)) + sock.sendto(lms_msg.encode(), (lms_ip, lms_port)) while True: try: data, server = sock.recvfrom(1024) - host, _ = server + host, _ = server if data.startswith(b'E'): - port = data.split("\x04")[1] + port = data.split("\x04".encode())[1] entries.append({'port': int(port), 'data': data, 'from': server, diff --git a/LMSTools/menu.py b/LMSTools/menu.py index 29aa4cf..fa0d2ea 100644 --- a/LMSTools/menu.py +++ b/LMSTools/menu.py @@ -1,6 +1,6 @@ import json -from menuitems import (NextMenuItem, +from .menuitems import (NextMenuItem, PlaylistMenuItem, SearchMenuItem, AudioMenuItem) diff --git a/LMSTools/player.py b/LMSTools/player.py index 0f53c4b..cd74e99 100644 --- a/LMSTools/player.py +++ b/LMSTools/player.py @@ -4,9 +4,9 @@ # # This set of tools was inspired by the PyLMS library. -from artworkresolver import LMSArtworkResolver -from tags import LMSTags as tags -from utils import LMSUtils +from .artworkresolver import LMSArtworkResolver +from .tags import LMSTags as tags +from .utils import LMSUtils DETAILED_TAGS = [tags.ARTIST, diff --git a/LMSTools/server.py b/LMSTools/server.py index 71d0686..88fadc7 100644 --- a/LMSTools/server.py +++ b/LMSTools/server.py @@ -2,7 +2,7 @@ Simple python class definitions for interacting with Logitech Media Server. This code uses the JSON interface. """ -import urllib2 +import urllib.request, urllib.error import json from .player import LMSPlayer @@ -40,7 +40,7 @@ def request(self, player="-", params=None): :param params: Request command """ - req = urllib2.Request(self.url) + req = urllib.request.Request(self.url) req.add_header('Content-Type', 'application/json') if type(params) == str: @@ -53,11 +53,11 @@ def request(self, player="-", params=None): "params": cmd} try: - response = urllib2.urlopen(req, json.dumps(data)) + response = urllib.request.urlopen(req, json.dumps(data).encode()) self.id += 1 return json.loads(response.read())["result"] - except urllib2.URLError: + except urllib.error.URLError: raise LMSConnectionError("Could not connect to server.") except: From 9fe71b61f46e076e752932acbb11bb32fac1ac45 Mon Sep 17 00:00:00 2001 From: aschamberger Date: Thu, 11 Feb 2021 20:47:21 +0100 Subject: [PATCH 2/4] Add files for pip packaging --- pyproject.toml | 6 ++++++ setup.py | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 pyproject.toml create mode 100644 setup.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b5a3c46 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,6 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel" +] +build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..b5099ad --- /dev/null +++ b/setup.py @@ -0,0 +1,22 @@ +import setuptools + +with open("README.md", "r", encoding="utf-8") as fh: + long_description = fh.read() + +setuptools.setup( + name="LMSTools", + version="0.0.1", + author="Andreas Schamberger", + author_email="mail@andreass.net", + description="A python library for iteracting with your Logitech Media Server", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/aschamberger/LMSTools", + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: OS Independent", + ], + packages=setuptools.find_packages(), + python_requires='>=3.6', +) \ No newline at end of file From 7c8cd12037eb9eef398cc12ad02540056ce8f281 Mon Sep 17 00:00:00 2001 From: torianironfist Date: Fri, 11 Feb 2022 21:30:07 -0500 Subject: [PATCH 3/4] Added option for authentication --- LMSTools/server.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/LMSTools/server.py b/LMSTools/server.py index 88fadc7..4c16d59 100644 --- a/LMSTools/server.py +++ b/LMSTools/server.py @@ -4,6 +4,7 @@ """ import urllib.request, urllib.error import json +import base64 from .player import LMSPlayer @@ -24,13 +25,16 @@ class LMSServer(object): """ - def __init__(self, host="localhost", port=9000): + def __init__(self, host="localhost", port=9000, username=None, password=None): self.host = host self.port = port self._version = None self.id = 1 self.web = "http://{h}:{p}/".format(h=host, p=port) self.url = "http://{h}:{p}/jsonrpc.js".format(h=host, p=port) + if username and password: + self.auth = base64.b64encode(bytes('{u}:{p}'.format(u=username, p=password),'ascii')) + else: self.auth = None def request(self, player="-", params=None): """ @@ -43,6 +47,9 @@ def request(self, player="-", params=None): req = urllib.request.Request(self.url) req.add_header('Content-Type', 'application/json') + if self.auth: + req.add_header("Authorization", "Basic {}".format(self.auth.decode('utf-8'))) + if type(params) == str: params = params.split() From 3befa6eb2e21afa7b99059fa07499342a29cb19c Mon Sep 17 00:00:00 2001 From: torianironfist Date: Fri, 11 Feb 2022 21:38:38 -0500 Subject: [PATCH 4/4] Updated docs --- LMSTools/server.py | 4 ++++ doc/examples/start.rst | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/LMSTools/server.py b/LMSTools/server.py index 4c16d59..37fcd64 100644 --- a/LMSTools/server.py +++ b/LMSTools/server.py @@ -19,6 +19,10 @@ class LMSServer(object): :param host: address of LMS server (default "localhost") :type port: int :param port: port for the web interface (default 9000) + :type username: str + :param username: username for accessing the server + :type password: str + :param password: password for accessing the server Class for Logitech Media Server. Provides access via JSON interface. As the class uses the JSON interface, no active connections are maintained. diff --git a/doc/examples/start.rst b/doc/examples/start.rst index 41f615b..a01b8c8 100644 --- a/doc/examples/start.rst +++ b/doc/examples/start.rst @@ -51,3 +51,13 @@ Pretty unexciting though, isn't it? That's because you know it's not the server that really matters, it's the \ players. So let's see how they work in the next section: :ref:`player-example`. + +Authentication +-------------- + +If your server requires authentication, you can add that into your initial \ +server request. + +:: + + >>>server = LMSServer(SERVER_IP, username='username', password='password')