Skip to content

Commit

Permalink
Updates for sxm==0.2.5
Browse files Browse the repository at this point in the history
  • Loading branch information
AngellusMortis committed Jul 16, 2021
1 parent 69c2500 commit 112b265
Show file tree
Hide file tree
Showing 17 changed files with 112 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM python:3.9.6-slim-buster

RUN apt-get update \
&& apt-get install -y git ffmpeg build-essential vim \
&& apt-get install -y git ffmpeg build-essential vim procps curl \
# cleaning up unused files
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -rf /var/lib/apt/lists/*
Expand Down
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ History
* Replaces requests with httpx
* Replaces click with typer
* Adds Pydantic `PlayerState`, `Song` and `Episode` models
* Updates for `sxm==0.2.5` client

0.1.0 (2018-12-25)
------------------
Expand Down
9 changes: 5 additions & 4 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ bandit==1.7.0
# via sxm_player (pyproject.toml)
beautifulsoup4==4.9.3
# via furo
black==21.6b0
black==21.7b0
# via sxm_player (pyproject.toml)
certifi==2021.5.30
# via
# httpx
# requests
chardet==4.0.0
# via aiohttp
charset-normalizer==2.0.2
charset-normalizer==2.0.3
# via requests
click==7.1.2
# via
Expand Down Expand Up @@ -304,15 +304,14 @@ sqlalchemy-stubs==0.4
# via sxm_player (pyproject.toml)
stevedore==3.3.0
# via bandit
sxm==0.2.4
sxm==0.2.5
# via sxm_player (pyproject.toml)
tenacity==8.0.1
# via sxm
termcolor==1.1.0
# via pytest-sugar
toml==0.10.2
# via
# black
# flit
# flit-core
# mypy
Expand All @@ -323,6 +322,8 @@ toml==0.10.2
# pytest-cov
# snooty-lextudio
# tox
tomli==1.0.4
# via black
tox==3.24.0
# via sxm_player (pyproject.toml)
traitlets==5.0.5
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ requires=[
'pydantic',
'pyyaml',
'sqlalchemy',
'sxm>=0.2.4',
'sxm>=0.2.5',
'typer',
]

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ sniffio==1.2.0
# httpx
sqlalchemy==1.4.21
# via sxm_player (pyproject.toml)
sxm==0.2.4
sxm==0.2.5
# via sxm_player (pyproject.toml)
tenacity==8.0.1
# via sxm
Expand Down
9 changes: 7 additions & 2 deletions sxm_player/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

import psutil
import typer
from sxm import QualitySize, RegionChoice
from sxm.cli import (
OPTION_HOST,
OPTION_PASSWORD,
OPTION_PORT,
OPTION_QUALITY,
OPTION_REGION,
OPTION_USERNAME,
OPTION_VERBOSE,
Expand Down Expand Up @@ -77,7 +79,8 @@ def main(
verbose: bool = OPTION_VERBOSE,
username: str = OPTION_USERNAME,
password: str = OPTION_PASSWORD,
region: str = OPTION_REGION,
region: RegionChoice = OPTION_REGION,
quality: QualitySize = OPTION_QUALITY,
port: int = OPTION_PORT,
host: str = OPTION_HOST,
output_folder: Optional[Path] = OPTION_OUTPUT_FOLDER,
Expand Down Expand Up @@ -124,7 +127,8 @@ def spawn_sxm_worker(
port: int,
username: str,
password: str,
region: str,
region: RegionChoice,
quality: QualitySize,
**kwargs,
):
runner.create_worker(
Expand All @@ -135,6 +139,7 @@ def spawn_sxm_worker(
username=username,
password=password,
region=region,
quality=quality,
)


Expand Down
2 changes: 1 addition & 1 deletion sxm_player/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def handle_update_metadata_event(
):
"""event.msg == (state.get_raw_live())"""

state.stream_channel = event.msg["channelId"]
state.stream_channel = event.msg["moduleResponse"]["liveChannelData"]["channelId"]
state.update_live(event.msg)
hls_metadata_event(runner, state.get_raw_live(), src=event.msg_src)

Expand Down
31 changes: 15 additions & 16 deletions sxm_player/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import time
from datetime import datetime, timezone
from datetime import datetime, timedelta, timezone
from typing import List, Optional, Tuple, Union

from pydantic import BaseModel, PrivateAttr # pylint: disable=no-name-in-module
Expand Down Expand Up @@ -153,8 +153,8 @@ class PlayerState(BaseModel):
_failures: int = PrivateAttr(0)
_cooldown: float = PrivateAttr(0)
_last_failure: float = PrivateAttr(0)
_start_time: Optional[float] = PrivateAttr(None)
_time_offset: Optional[float] = PrivateAttr(None)
_start_time: Optional[datetime] = PrivateAttr(None)
_time_offset: Optional[timedelta] = PrivateAttr(None)

@property
def stream_data(self) -> Tuple[Optional[str], Optional[str]]:
Expand Down Expand Up @@ -208,7 +208,7 @@ def live(self) -> Union[XMLiveChannel, None]:
def update_live(self, value: dict) -> None:
"""Sets live key in internal `_raw_live`."""

now = int(time.time() * 1000)
now = datetime.now(timezone.utc)
self._live = None
self._raw_live = value

Expand All @@ -229,12 +229,12 @@ def update_live(self, value: dict) -> None:

def get_raw_live(
self,
) -> Tuple[Optional[float], Optional[float], Optional[dict]]:
) -> Tuple[Optional[datetime], Optional[timedelta], Optional[dict]]:
return (self._start_time, self._time_offset, self._raw_live)

def set_raw_live(
self,
live_data: Tuple[Optional[float], Optional[float], Optional[dict]],
live_data: Tuple[Optional[datetime], Optional[timedelta], Optional[dict]],
):
self._start_time = live_data[0]
self._time_offset = live_data[1]
Expand All @@ -244,20 +244,19 @@ def set_raw_live(
self._live = XMLiveChannel.from_dict(self._raw_live)

@property
def radio_time(self) -> Union[int, None]:
def radio_time(self) -> Union[datetime, None]:
"""Returns current time for the radio"""

if self.live is None:
return None

now = int(time.time() * 1000)
# Does not seem to be accurate
# if self._time_offset is not None:
# return now - int(self._time_offset)
now = datetime.now(timezone.utc)
if self._time_offset is not None:
return now - self._time_offset
return now

@property
def start_time(self) -> Union[float, None]:
def start_time(self) -> Optional[datetime]:
"""Returns the start time for the current SiriusXM channel"""

if self.live is None:
Expand All @@ -267,13 +266,13 @@ def start_time(self) -> Union[float, None]:
@property
def is_connected(self) -> bool:
is_connected = self._raw_channels is not None
if is_connected and time.time() - self._last_failure > 300:
if is_connected and time.monotonic() - self._last_failure > 300:
self._failures = 0
return is_connected

@property
def can_connect(self) -> bool:
return time.time() > self._cooldown
return time.monotonic() > self._cooldown

def mark_attempt(self, logger: logging.Logger) -> float:
if self.can_connect:
Expand All @@ -295,13 +294,13 @@ def increase_cooldown(self) -> float:
else:
extra_seconds = COOLDOWN_LONG

self._cooldown = time.time() + extra_seconds
self._cooldown = time.monotonic() + extra_seconds

return extra_seconds

def mark_failure(self) -> float:
self._failures += 1
self._last_failure = time.time()
self._last_failure = time.monotonic()
return self._cooldown

def get_channel(self, name: str) -> Union[XMChannel, None]:
Expand Down
2 changes: 1 addition & 1 deletion sxm_player/queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class EventMessage:
msg: Any

def __init__(self, msg_src, msg_type, msg, msg_relay=None):
self.id = time.time()
self.id = time.monotonic()
self.msg_src = msg_src
self.msg_relay = msg_relay
self.msg_type = msg_type
Expand Down
4 changes: 2 additions & 2 deletions sxm_player/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

def _sleep_secs(max_sleep, end_time=999_999_999_999_999.9):
# Calculate time left to sleep, no less than 0
return max(0.0, min(end_time - time.time(), max_sleep))
return max(0.0, min(end_time - time.monotonic(), max_sleep))


def worker_wrapper(
Expand Down Expand Up @@ -195,7 +195,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):

def stop_workers(self) -> Tuple[int, int]:
self.shutdown_event.set()
end_time = time.time() + STOP_WAIT_SECS
end_time = time.monotonic() + STOP_WAIT_SECS
num_terminated = 0
num_failed = 0

Expand Down
25 changes: 11 additions & 14 deletions sxm_player/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import datetime
import logging
import os
import select
import shlex
import subprocess # nosec
from datetime import datetime
from pathlib import Path
from typing import List, Optional, Union

Expand All @@ -12,7 +12,7 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm.session import Session
from sxm.models import XMArt, XMImage, XMMarker
from sxm.models import XMArt, XMImage

from sxm_player.models import DBEpisode, DBSong

Expand All @@ -21,6 +21,7 @@
psutil.STATUS_SLEEPING,
psutil.STATUS_DISK_SLEEP,
]
FS_DATETIME_FORMAT = "%Y%m%d-%H%M%S%z"


unrelated_loggers = [
Expand Down Expand Up @@ -75,18 +76,6 @@ def init_db(
return db_session


def get_air_time(cut: XMMarker) -> datetime.datetime:
"""Dates UTC datetime object for the air
date of a `XMMarker` to the hour"""

air_time = datetime.datetime.fromtimestamp(
int(cut.time / 1000), tz=datetime.timezone.utc
)
air_time = air_time.replace(minute=0, second=0, microsecond=0)

return air_time


def get_art_url_by_size(arts: List[XMArt], size: str) -> Optional[str]:
for art in arts:
if isinstance(art, XMImage) and art.size is not None and art.size == size:
Expand Down Expand Up @@ -152,6 +141,14 @@ def splice_file(
return output_file


def create_fs_datetime(dt):
return dt.strftime(FS_DATETIME_FORMAT)


def from_fs_datetime(dt_string):
return datetime.strptime(dt_string, FS_DATETIME_FORMAT)


def configure_root_logger(level: str, log_file: Optional[Path] = None):
root_logger = logging.getLogger()
if len(root_logger.handlers) == 0:
Expand Down
Loading

0 comments on commit 112b265

Please sign in to comment.