plugin: clean the runtime/storage API

This commit is contained in:
dece 2022-09-09 17:45:21 +02:00
parent 8d9ccd8dc9
commit 255cdcaac2

View file

@ -46,9 +46,21 @@ class Plugin:
can disable itself by setting its own `is_ready` flag to false.
A plugin can access its config once the base `__init__` has been called.
The configuration is valid only is `is_ready` is True, else accessing its
The configuration is valid only if `is_ready` is True, else accessing its
content is undefined behaviour.
Plugins may use two types of special values, stored in two dicts: runtime
values and storage values. Runtime values can be accessed by other plugins
to get information about the runtime state of the bot. Currently it is used
to store if the bot is asleep or awake by the sleep plugin, and its current
mood by the mood plugin. They are lost when the bot shuts down. Storage
values on the other hand are written in a storage file everytime the object
is modified during runtime and also when the bot shuts down. Storage values
are stored as JSON, so values must be JSON-encodable. Storage values should
be used everytime information needs to persist over restarts instead of
external files. Access here means read and write, for both runtime and
storage values.
Plugins can have priorities and calling their callbacks will respect it.
For now these levels are used:
- 0: default
@ -108,32 +120,49 @@ class Plugin:
return not missing
def get_runtime_value(
self, key: str, default: Any = None, ns: str = None
self,
key: str,
default: Any = None,
ns: Optional[str] = None,
) -> Any:
"""Get a value from the plugin runtime dict.
This will get the value from the plugin namespace, but it is possible
to get runtime values from other plugins using their name as `ns`.
"""
if ns is None:
ns = self.name
return self.bot.values[ns].get(key, default)
name = ns or self.name
return self.bot.values[name].get(key, default)
def set_runtime_value(self, key: str, value: Any) -> Any:
def set_runtime_value(
self,
key: str,
value: Any,
ns: Optional[str] = None,
) -> None:
"""Set a value in the plugin runtime dict."""
self.bot.values[self.name][key] = value
name = ns or self.name
self.bot.values[name][key] = value
def get_storage_value(self, key: str, default=None, ns: str = None) -> Any:
def get_storage_value(
self,
key: str,
default: Any = None,
ns: Optional[str] = None,
) -> Any:
"""Get a value from the plugin persistent storage.
This will get the value from the plugin namespace, but it is possible
to get storage values from other plugins using their name as `ns`.
"""
if ns is None:
ns = self.name
return self.bot.storage.get(ns, {}).get(key, default)
name = ns or self.name
return self.bot.storage.get(name, {}).get(key, default)
def set_storage_value(self, key: str, value: Any, ns: str = None) -> None:
def set_storage_value(
self,
key: str,
value: Any,
ns: Optional[str] = None,
) -> None:
"""Set a value in the plugin persistent storage."""
name = ns or self.name
if name not in self.bot.storage:
@ -142,23 +171,32 @@ class Plugin:
self.bot.storage[name][key] = value
self.bot.save_storage()
def append_storage_list_value(self, key: str, value: Any) -> None:
def append_storage_list_value(
self,
key: str,
value: Any,
ns: str = None,
) -> None:
"""Append a value to a list in the plugin persistent storage."""
if self.name not in self.bot.storage:
self.bot.storage[self.name] = {key: [value]}
elif key not in self.bot.storage[self.name]:
self.bot.storage[self.name][key] = [value]
name = ns or self.name
if name not in self.bot.storage:
self.bot.storage[name] = {key: [value]}
elif key not in self.bot.storage[name]:
self.bot.storage[name][key] = [value]
else:
self.bot.storage[self.name][key].append(value)
self.bot.storage[name][key].append(value)
self.bot.save_storage()
def remove_storage_list_value(self, key: str, value: Any) -> None:
def remove_storage_list_value(
self,
key: str,
value: Any,
ns: Optional[str] = None,
) -> None:
"""Remove a value from a persistent storage list."""
if (
self.name in self.bot.storage
and key in self.bot.storage[self.name]
):
self.bot.storage[self.name][key].remove(value)
name = ns or self.name
if name in self.bot.storage and key in self.bot.storage[name]:
self.bot.storage[name][key].remove(value)
self.bot.save_storage()
def should_read_message(self, message: str) -> Optional[str]: