pax_global_header00006660000000000000000000000064143066602630014520gustar00rootroot0000000000000052 comment=7a9d6751316ca70ec9999e38802290d746a26cea uvjustin-pylibrespot-java-7a9d675/000077500000000000000000000000001430666026300172505ustar00rootroot00000000000000uvjustin-pylibrespot-java-7a9d675/CHANGES.txt000066400000000000000000000002361430666026300210620ustar00rootroot00000000000000v0.1.0, 2020-04-15 -- Initial release. v0.1.1, 2022-09-09 -- Remove LibrespotJavaData Fix typing Add py.typed uvjustin-pylibrespot-java-7a9d675/LICENSE.txt000066400000000000000000000020771430666026300211010ustar00rootroot00000000000000MIT License Copyright (c) 2020 Justin Wong Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.uvjustin-pylibrespot-java-7a9d675/README.md000066400000000000000000000007551430666026300205360ustar00rootroot00000000000000pylibrespot-java Python Library =============================== version number: 0.1.0 author: Justin Wong Overview -------- A simple library to interface with a librespot-java server. Installation / Usage -------------------- To install use pip: $ pip install pylibrespot-java Or clone the repo: $ git clone https://github.com/uvjustin/pylibrespot-java.git $ python setup.py install Contributing ------------ TBD Example ------- TBDuvjustin-pylibrespot-java-7a9d675/pylibrespot_java/000077500000000000000000000000001430666026300226255ustar00rootroot00000000000000uvjustin-pylibrespot-java-7a9d675/pylibrespot_java/__init__.py000066400000000000000000000155441430666026300247470ustar00rootroot00000000000000"""This library wraps the librespot-java API for use with Home Assistant.""" from __future__ import annotations __version__ = "0.1.1" import asyncio import logging from typing import Any, Callable, Coroutine, Mapping import aiohttp _LOGGER = logging.getLogger(__name__) def _debug_string(string_base: str, status: int) -> str: """Helper for logger debug strings.""" if status == 204: return string_base + " No active session" if status == 500: return string_base + " Invalid session" if status == 503: return string_base + " Session is reconnecting" return "" class LibrespotJavaAPI: """Class for interfacing with librespot-java API.""" def __init__( self, websession: aiohttp.ClientSession, ip_address: str, api_port: int ): self._ip_address = ip_address self._api_port = api_port self._websession = websession async def post_request( self, endpoint: str, data: Mapping[str, Any] | None = None ) -> aiohttp.ClientResponse: """Helper function to put to endpoint.""" url = f"http://{self._ip_address}:{self._api_port}/{endpoint}" _LOGGER.debug("POST request to %s with payload %s.", url, data) response = await self._websession.post(url=url, data=data) return response async def start_websocket_handler( self, update_callback: Callable[[Mapping[str, Any]], Coroutine[Any, Any, None]], websocket_reconnect_time: float, ) -> None: """Websocket handler daemon.""" _LOGGER.debug("Starting websocket handler") url = f"http://{self._ip_address}:{self._api_port}/events" while True: try: async with self._websession.ws_connect(url) as ws: async for msg in ws: json = msg.json() _LOGGER.debug("Message received: %s", json) await update_callback(json) _LOGGER.debug( "WebSocket disconnected, will retry in %s seconds.", websocket_reconnect_time, ) await asyncio.sleep(websocket_reconnect_time) except (asyncio.TimeoutError, aiohttp.ClientError): _LOGGER.error( "Can not connect to WebSocket at %s, will retry in %s seconds.", url, websocket_reconnect_time, ) await asyncio.sleep(websocket_reconnect_time) continue async def player_load(self, uri: str, play: bool) -> int: """Load track from URI.""" resp = await self.post_request( endpoint="player/load", data={"uri": uri, "play": play} ) if resp.status in [204, 500, 503]: _LOGGER.debug(_debug_string("Unable to load track.", resp.status)) return resp.status async def player_pause(self) -> int: """Pause playback.""" resp = await self.post_request(endpoint="player/pause") if resp.status in [204, 500, 503]: _LOGGER.debug(_debug_string("Unable to pause player.", resp.status)) return resp.status async def player_resume(self) -> int: """Resume playback.""" resp = await self.post_request(endpoint="player/resume") if resp.status in [204, 500, 503]: _LOGGER.debug(_debug_string("Unable to resume player.", resp.status)) return resp.status async def player_next(self) -> int: """Skip to next track.""" resp = await self.post_request(endpoint="player/next") if resp.status in [204, 500, 503]: _LOGGER.debug( _debug_string("Unable to skip to the next track.", resp.status) ) return resp.status async def player_prev(self) -> int: """Skip to previous track.""" resp = await self.post_request(endpoint="player/prev") if resp.status in [204, 500, 503]: _LOGGER.debug( _debug_string("Unable to skip to the previous track.", resp.status) ) return resp.status async def player_set_volume(self, volume: int) -> int: """Set volume to a given volume between 0 and 65536.""" resp = await self.post_request( endpoint="player/set-volume", data={"volume": volume} ) if resp.status in [204, 500, 503]: _LOGGER.debug(_debug_string("Unable to set the volume.", resp.status)) return resp.status async def player_volume_up(self) -> int: """Turn up the volume a little bit.""" resp = await self.post_request(endpoint="player/volume-up") if resp.status in [204, 500, 503]: _LOGGER.debug(_debug_string("Unable to turn the volume up.", resp.status)) return resp.status async def player_volume_down(self) -> int: """Turn down the volume a little bit.""" resp = await self.post_request(endpoint="player/volume-down") if resp.status in [204, 500, 503]: _LOGGER.debug(_debug_string("Unable to turn the volume down.", resp.status)) return resp.status async def player_current(self) -> dict: """Retrieve information about the current track.""" resp = await self.post_request(endpoint="player/current") if resp.status in [204, 500, 503]: _LOGGER.debug( _debug_string( "Unable to retrieve information about the current track.", resp.status, ) ) json = await resp.json(content_type=None) return json async def metadata(self, uri: str) -> dict: """Retrieve metadata.""" resp = await self.post_request(endpoint=f"metadata/{uri}") if resp.status in [204, 500, 503]: _LOGGER.debug( _debug_string(f"Unable to get metadata for {uri}.", resp.status) ) json = await resp.json(content_type=None) return json async def search(self, query: str) -> dict: """Make a search.""" resp = await self.post_request(endpoint=f"search/{query}") if resp.status in [204, 500, 503]: _LOGGER.debug(_debug_string(f"Unable to search for {query}.", resp.status)) json = await resp.json(content_type=None) return json async def token(self, scope: str) -> dict: """Request an access token for a specific scope.""" resp = await self.post_request(endpoint=f"token/{scope}") if resp.status in [204, 500, 503]: _LOGGER.debug( _debug_string(f"Unable to get token for {scope}.", resp.status) ) json = await resp.json(content_type=None) return json uvjustin-pylibrespot-java-7a9d675/requirements.txt000066400000000000000000000000111430666026300225240ustar00rootroot00000000000000aiohttp uvjustin-pylibrespot-java-7a9d675/setup.py000066400000000000000000000026231430666026300207650ustar00rootroot00000000000000from __future__ import print_function import io from setuptools import setup import pylibrespot_java def read(*filenames, **kwargs): encoding = kwargs.get("encoding", "utf-8") sep = kwargs.get("sep", "\n") buf = [] for filename in filenames: with io.open(filename, encoding=encoding) as file: buf.append(file.read()) return sep.join(buf) LONG_DESCRIPTION = read("README.md") setup( name="pylibrespot-java", version=pylibrespot_java.__version__, url="http://github.com/uvjustin/pylibrespot-java/", author="Justin Wong", install_requires=['aiohttp'], author_email="46082645+uvjustin@users.noreply.github.com", description="Python Interface for librespot-java", long_description=LONG_DESCRIPTION, long_description_content_type="text/markdown", package_data={"pyforked_daapd": ["py.typed"]}, zip_safe=False, packages=["pylibrespot_java"], include_package_data=True, platforms="any", classifiers=[ "Programming Language :: Python", "Development Status :: 4 - Beta", "Natural Language :: English", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Topic :: Software Development :: Libraries :: Python Modules", ], )