Skip to content

Commit

Permalink
Fix seeking, enable icon caching, ensure that user data dirs are crea…
Browse files Browse the repository at this point in the history
…ted if they don't exist before trying to create the user data
  • Loading branch information
alexdelorenzo committed Jun 24, 2021
1 parent 36ada53 commit 13b6dae
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 32 deletions.
2 changes: 1 addition & 1 deletion cast_control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
__license__: Final[str] = 'AGPL-3.0'
__copyright__: Final[str] = \
f'Copyright 2021 {__author__}. Licensed under terms of the {__license__}.'
__version__: Final[str] = '0.11.2'
__version__: Final[str] = '0.11.3'

NAME: Final[str] = 'cast_control'
SHORT_NAME: Final[str] = 'castctl'
Expand Down
46 changes: 28 additions & 18 deletions cast_control/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from __future__ import annotations
from typing import Optional, Union, NamedTuple
from typing import Optional, Union, NamedTuple, Callable
from pathlib import Path
from uuid import UUID
from enum import auto
from os import stat_result
from functools import lru_cache
from functools import lru_cache, wraps
from asyncio import gather, run
from weakref import finalize
import logging
Expand Down Expand Up @@ -129,6 +129,31 @@ def set_log_level(
)


async def _create_user_dirs():
paths = map(AsyncPath, USER_DIRS)

coros = (
path.mkdir(parents=True, exist_ok=True)
for path in paths
)

await gather(*coros)


@lru_cache(LRU_MAX_SIZE)
def create_user_dirs():
run(_create_user_dirs())


def ensure_user_dirs_exist(func: Callable) -> Callable:
@wraps(func)
def new_func(*args, **kwargs):
create_user_dirs()
return func(*args, **kwargs)

return new_func


def get_stat(file: Path) -> stat_result:
return file.stat()

Expand Down Expand Up @@ -174,6 +199,7 @@ def new_file_from_template(file: Path, icon_path: Path):


@lru_cache(LRU_MAX_SIZE)
@ensure_user_dirs_exist
def create_desktop_file(light_icon: bool = True) -> Path:
icon, file = get_paths(light_icon)

Expand All @@ -183,22 +209,6 @@ def create_desktop_file(light_icon: bool = True) -> Path:
return file


async def _create_user_dirs():
paths = map(AsyncPath, USER_DIRS)

coros = (
path.mkdir(parents=True, exist_ok=True)
for path in paths
)

await gather(*coros)


@lru_cache(LRU_MAX_SIZE)
def create_user_dirs():
run(_create_user_dirs())


def get_device_via_host(
host: str,
retry_wait: Optional[float] = DEFAULT_RETRY_WAIT,
Expand Down
76 changes: 66 additions & 10 deletions cast_control/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from .base import DEFAULT_THUMB, LIGHT_THUMB, NO_DURATION, NO_DELTA, \
US_IN_SEC, DEFAULT_DISC_NO, MediaType, NO_DESKTOP_FILE, LRU_MAX_SIZE, \
NAME, create_desktop_file, DEFAULT_ICON, create_user_dirs, \
Device
Device, ensure_user_dirs_exist


RESOLUTION: Final[int] = 1
Expand All @@ -56,8 +56,8 @@ class Titles(NamedTuple):


class Controllers(NamedTuple):
yt: YouTubeController
spotify: SpotifyController
yt: YouTubeController = None
spotify: SpotifyController = None
# dash: DashCastController
# bbc_ip: BbcIplayerController
# bbc_sound: BbcSoundsController
Expand All @@ -73,6 +73,7 @@ class Controllers(NamedTuple):
class Wrapper(Protocol):
dev: Device
ctls: Controllers
cached_icon: Optional[CachedIcon] = None
light_icon: bool = DEFAULT_ICON

@property
Expand Down Expand Up @@ -131,7 +132,7 @@ def __init__(self):
def _setup_controllers(self):
self.ctls = Controllers(
YouTubeController(),
SpotifyController(),
# SpotifyController(),
# DashCastController(),
# BbcIplayerController(),
# BbcSoundsController(),
Expand All @@ -144,6 +145,9 @@ def _setup_controllers(self):
)

for ctl in self.ctls:
if not ctl:
continue

self._register(ctl)

def _register(self, controller: BaseController):
Expand Down Expand Up @@ -213,6 +217,12 @@ def titles(self) -> Titles:
if title:
titles.append(title)

if self.media_status:
series_title = self.media_status.series_title

if series_title:
titles.append(series_title)

subtitle = self.get_subtitle()

if subtitle:
Expand Down Expand Up @@ -324,24 +334,70 @@ def set_rate(self, val: RateDecimal):
pass


class CachedIcon(NamedTuple):
url: str
app_id: str
title: str


class IconsMixin(Wrapper):
def set_icon(self, lighter: bool = False):
self.light_icon: bool = lighter

def get_art_url(self, track: Optional[int] = None) -> str:
thumb = self.media_controller.thumbnail
def _set_cached_icon(self, url: Optional[str] = None):
if not url:
self.cached_icon = None
return

app_id = self.dev.app_id
title, *_ = self.titles
self.cached_icon = CachedIcon(url, app_id, title)

def _can_use_cache(self) -> bool:
cache = self.cached_icon

if thumb:
return thumb
if not cache or not cache.url:
return False

app_id = self.dev.app_id
title, *_ = self.titles

icon: Optional[str] = None
if cache.app_id != app_id or cache.title != title:
return False

return True

def _get_icon_from_device(self) -> Optional[str]:
images = self.media_status.images

if images:
first, *_ = images
url, *_ = first

self._set_cached_icon(url)
return url

url: Optional[str] = None

if self.cast_status:
icon = self.cast_status.icon_url
url = self.cast_status.icon_url

if url:
self._set_cached_icon(url)
return url

if not self._can_use_cache():
return None

return self.cached_icon.url

def get_art_url(self, track: Optional[int] = None) -> str:
icon = self._get_icon_from_device()

if icon:
return icon

# use default icon files if there's no thumbnails
create_user_dirs()

if self.light_icon:
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

[project]
name = "cast_control"
version = "0.11.2"
version = "0.11.3"
description = "📺 Control Chromecasts from Linux and D-Bus"
license = "AGPL-3.0"
homepage = "https://github.com/alexdelorenzo/cast_control"
Expand All @@ -20,7 +20,7 @@
aiopath = ">=0.5.6"
click = "==8.0.1"
daemons = "==1.3.2"
mpris-server = ">=0.3.3, <0.4.0"
mpris-server = ">=0.3.4, <0.4.0"
pychromecast = "==9.2.0"
pydbus = ">=0.6.0"
pygobject = ">=3.34.0"
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ typing-extensions>=3.10.0.0; python_version < '3.10'

aiopath>=0.5.8; python_version <= '3.9'
aiopath>=0.6.8; python_version >= '3.10'
mpris_server>=0.3.3, <0.4.0
mpris_server>=0.3.4, <0.4.0

0 comments on commit 13b6dae

Please sign in to comment.