diff --git a/docs/api.rst b/docs/api.rst index 6a09eb95..71367a1d 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -6,9 +6,10 @@ This is an incomplete reference of the relevant Streamlink APIs. .. toctree:: api/streamlink - api/options api/session api/plugin + api/options + api/cache api/validate api/stream api/webbrowser diff --git a/docs/api/cache.rst b/docs/api/cache.rst new file mode 100644 index 00000000..1bfa3e26 --- /dev/null +++ b/docs/api/cache.rst @@ -0,0 +1,6 @@ +Cache +----- + +.. module:: streamlink.cache + +.. autoclass:: Cache diff --git a/src/streamlink/cache.py b/src/streamlink/cache.py index c4ce6720..b4e38a3d 100644 --- a/src/streamlink/cache.py +++ b/src/streamlink/cache.py @@ -26,9 +26,18 @@ CACHE_DIR = Path(xdg_cache) / "streamlink" # - add JSON schema information # - add translation logic, to keep backwards compatibility class Cache: - """Caches Python values as JSON and prunes expired entries.""" + def __init__( + self, + filename: Union[str, Path], + key_prefix: str = "", + ): + """ + Caches Python values as JSON and prunes expired entries. + + :param filename: A file name or :class:`Path` object, relative to the cache directory + :param key_prefix: Optional prefix for each key to be retrieved from or stored in the cache + """ - def __init__(self, filename: Union[str, Path], key_prefix: str = ""): self.key_prefix = key_prefix self.filename = CACHE_DIR / Path(filename) @@ -74,7 +83,24 @@ class Cache: with suppress(Exception): os.remove(tempname) - def set(self, key: str, value: Any, expires: float = 60 * 60 * 24 * 7, expires_at: Optional[datetime] = None): + def set( + self, + key: str, + value: Any, + expires: float = 60 * 60 * 24 * 7, + expires_at: Optional[datetime] = None, + ) -> None: + """ + Store the given value using the key name and expiration time. + + Prunes the cache of all expired key-value pairs before setting the new key-value pair. + + :param key: A specific key name + :param value: Any kind of value that can be JSON-serialized + :param expires: Expiration time in seconds, with the default being one week + :param expires_at: Optional expiration date, which overrides the expiration time + """ + self._load() self._prune() @@ -92,7 +118,21 @@ class Cache: self._cache[key] = dict(value=value, expires=expires) self._save() - def get(self, key: str, default: Optional[Any] = None): + def get( + self, + key: str, + default: Optional[Any] = None, + ) -> Any: + """ + Attempt to retrieve the given key from the cache. + + Prunes the cache of all expired key-value pairs before retrieving the key's value. + + :param key: A specific key name + :param default: An optional default value if no key was stored, or if it has expired + :return: The retrieved value or optional default value + """ + self._load() if self._prune(): @@ -106,7 +146,15 @@ class Cache: else: return default - def get_all(self): + def get_all(self) -> Dict[str, Any]: + """ + Retrieve all cached key-value pairs. + + Prunes the cache of all expired key-value pairs first. + + :return: A dictionary of all cached key-value pairs. + """ + ret = {} self._load() diff --git a/src/streamlink/plugin/plugin.py b/src/streamlink/plugin/plugin.py index 712bd41b..d9b7b77b 100644 --- a/src/streamlink/plugin/plugin.py +++ b/src/streamlink/plugin/plugin.py @@ -251,6 +251,9 @@ class Plugin: options: Options """Plugin options, initialized with the user-set values of the plugin's arguments""" + cache: Cache + """Plugin cache object, used to store plugin-specific data other than HTTP session cookies""" + # plugin metadata attributes id: Optional[str] = None """Metadata 'id' attribute: unique stream ID, etc."""