From 255cdcaac208fe3252f1598d5cbe892de057d644 Mon Sep 17 00:00:00 2001 From: dece Date: Fri, 9 Sep 2022 17:45:21 +0200 Subject: [PATCH] plugin: clean the runtime/storage API --- edmond/plugin.py | 86 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 24 deletions(-) diff --git a/edmond/plugin.py b/edmond/plugin.py index d31c428..1c9ce80 100644 --- a/edmond/plugin.py +++ b/edmond/plugin.py @@ -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]: