librespot-python/librespot/player/state/DeviceStateHandler.py

119 lines
3.4 KiB
Python
Raw Normal View History

2021-02-25 00:07:17 +01:00
from __future__ import annotations
2021-04-10 01:16:20 +02:00
2021-02-25 00:07:17 +01:00
import base64
import concurrent.futures
import enum
import logging
import time
import typing
import urllib.parse
2021-04-10 01:16:20 +02:00
from librespot.common import Utils
from librespot.core import Session
from librespot.player import PlayerConfiguration
2021-05-22 03:26:35 +02:00
from librespot.proto import Connect, Player
2021-04-10 01:16:20 +02:00
2021-02-25 00:07:17 +01:00
class DeviceStateHandler:
_LOGGER: logging = logging.getLogger(__name__)
_session: Session = None
_deviceInfo: Connect.DeviceInfo = None
2021-04-24 12:17:02 +02:00
_listeners: typing.List[DeviceStateHandler.Listener] = []
2021-02-25 00:07:17 +01:00
_putState: Connect.PutStateRequest = None
2021-04-10 01:16:18 +02:00
_putStateWorker: concurrent.futures.ThreadPoolExecutor = (
2021-05-22 03:26:33 +02:00
concurrent.futures.ThreadPoolExecutor()
)
2021-02-25 00:07:17 +01:00
_connectionId: str = None
def __init__(self, session: Session, player, conf: PlayerConfiguration):
self._session = session
self._deviceInfo = None
self._putState = Connect.PutStateRequest()
def _update_connection_id(self, newer: str) -> None:
newer = urllib.parse.unquote(newer, "UTF-8")
2021-04-10 01:16:18 +02:00
if self._connectionId is None or self._connectionId != newer:
2021-02-25 00:07:17 +01:00
self._connectionId = newer
2021-05-22 03:26:33 +02:00
self._LOGGER.debug(
"Updated Spotify-Connection-Id: {}".format(self._connectionId)
)
2021-02-25 00:07:17 +01:00
self._notify_ready()
2021-02-25 10:22:28 +01:00
def add_listener(self, listener: DeviceStateHandler.Listener):
self._listeners.append(listener)
2021-02-25 00:07:17 +01:00
def _notify_ready(self) -> None:
for listener in self._listeners:
listener.ready()
2021-04-10 01:16:18 +02:00
def update_state(
self,
reason: Connect.PutStateReason,
player_time: int,
state: Player.PlayerState,
):
2021-02-25 00:07:17 +01:00
if self._connectionId is None:
raise TypeError()
if player_time == -1:
pass
else:
pass
self._putState.put_state_reason = reason
self._putState.client_side_timestamp = int(time.time() * 1000)
self._putState.device.device_info = self._deviceInfo
self._putState.device.player_state = state
self._putStateWorker.submit(self._put_connect_state, self._putState)
def _put_connect_state(self, req: Connect.PutStateRequest):
self._session.api().put_connect_state(self._connectionId, req)
2021-05-22 03:26:33 +02:00
self._LOGGER.info(
"Put state. ts: {}, connId: {}, reason: {}".format(
req.client_side_timestamp,
Utils.truncate_middle(self._connectionId, 10),
req.put_state_reason,
)
)
2021-02-25 00:07:17 +01:00
class Endpoint(enum.Enum):
Play: str = "play"
Pause: str = "pause"
Resume: str = "resume"
SeekTo: str = "seek_to"
SkipNext: str = "skip_next"
SkipPrev: str = "skip_prev"
class Listener:
def ready(self) -> None:
pass
2021-04-10 01:16:18 +02:00
def command(
self,
endpoint: DeviceStateHandler.Endpoint,
data: DeviceStateHandler.CommandBody,
) -> None:
2021-02-25 00:07:17 +01:00
pass
def volume_changed(self) -> None:
pass
def not_active(self) -> None:
pass
class CommandBody:
_obj: typing.Any = None
_data: bytes = None
_value: str = None
def __init__(self, obj: typing.Any):
self._obj = obj
if obj.get("data") is not None:
self._data = base64.b64decode(obj.get("data"))
if obj.get("value") is not None:
self._value = obj.get("value")