Fix config updating and make plugin dbs somewhat configurable

This commit is contained in:
Tulir Asokan 2018-10-22 01:57:29 +03:00
parent 485040e687
commit 894c5df07b
6 changed files with 24 additions and 9 deletions

View File

@ -5,6 +5,9 @@
# Postgres: postgres://username:password@hostname/dbname # Postgres: postgres://username:password@hostname/dbname
database: sqlite:///maubot.db database: sqlite:///maubot.db
# The directory where plugin databases should be stored.
plugin_db_directory: ./plugins
# If multiple directories have a plugin with the same name, the first directory is used. # If multiple directories have a plugin with the same name, the first directory is used.
plugin_directories: plugin_directories:
- ./plugins - ./plugins

View File

@ -27,7 +27,7 @@ from .db import Base, init as init_db
from .server import MaubotServer from .server import MaubotServer
from .client import Client, init as init_client from .client import Client, init as init_client
from .loader import ZippedPluginLoader from .loader import ZippedPluginLoader
from .plugin import PluginInstance from .plugin import PluginInstance, init as init_plugin_instance_class
from .__meta__ import __version__ from .__meta__ import __version__
parser = argparse.ArgumentParser(description="A plugin-based Matrix bot system.", parser = argparse.ArgumentParser(description="A plugin-based Matrix bot system.",
@ -57,6 +57,7 @@ loop = asyncio.get_event_loop()
init_db(db_session) init_db(db_session)
init_client(loop) init_client(loop)
init_plugin_instance_class(config)
server = MaubotServer(config, loop) server = MaubotServer(config, loop)
ZippedPluginLoader.load_all(*config["plugin_directories"]) ZippedPluginLoader.load_all(*config["plugin_directories"])
plugins = PluginInstance.all() plugins = PluginInstance.all()

View File

@ -1 +1 @@
__version__ = "0.1.0.dev3" __version__ = "0.1.0.dev4"

View File

@ -16,7 +16,7 @@
import random import random
import string import string
from mautrix.util import BaseFileConfig from mautrix.util import BaseFileConfig, ConfigUpdateHelper
class Config(BaseFileConfig): class Config(BaseFileConfig):
@ -24,10 +24,11 @@ class Config(BaseFileConfig):
def _new_token() -> str: def _new_token() -> str:
return "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(64)) return "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(64))
def update(self): def do_update(self, helper: ConfigUpdateHelper) -> None:
base, copy, copy_dict = self._pre_update() base, copy, _ = helper
copy("database") copy("database")
copy("plugin_directories") copy("plugin_directories")
copy("plugin_db_directory")
copy("server.hostname") copy("server.hostname")
copy("server.port") copy("server.port")
copy("server.listen") copy("server.listen")
@ -37,4 +38,5 @@ class Config(BaseFileConfig):
base["server.shared_secret"] = self._new_token() base["server.shared_secret"] = self._new_token()
else: else:
base["server.shared_secret"] = shared_secret base["server.shared_secret"] = shared_secret
copy("admins")
copy("logging") copy("logging")

View File

@ -23,6 +23,7 @@ from mautrix.util import BaseProxyConfig, RecursiveDict
from mautrix.types import UserID from mautrix.types import UserID
from .db import DBPlugin from .db import DBPlugin
from .config import Config
from .client import Client from .client import Client
from .loader import PluginLoader from .loader import PluginLoader
from .plugin_base import Plugin from .plugin_base import Plugin
@ -34,6 +35,7 @@ yaml.indent(4)
class PluginInstance: class PluginInstance:
mb_config: Config = None
cache: Dict[str, 'PluginInstance'] = {} cache: Dict[str, 'PluginInstance'] = {}
plugin_directories: List[str] = [] plugin_directories: List[str] = []
@ -68,7 +70,7 @@ class PluginInstance:
def load_config_base(self) -> Optional[RecursiveDict[CommentedMap]]: def load_config_base(self) -> Optional[RecursiveDict[CommentedMap]]:
try: try:
base = self.loader.read_file("base-config.yaml") base = self.loader.read_file("base-config.yaml")
return yaml.load(base.decode("utf-8")) return RecursiveDict(yaml.load(base.decode("utf-8")), CommentedMap)
except (FileNotFoundError, KeyError): except (FileNotFoundError, KeyError):
return None return None
@ -86,7 +88,8 @@ class PluginInstance:
if config_class: if config_class:
self.config = config_class(self.load_config, self.load_config_base, self.config = config_class(self.load_config, self.load_config_base,
self.save_config) self.save_config)
self.plugin = cls(self.client.client, self.id, self.log, self.config) self.plugin = cls(self.client.client, self.id, self.log, self.config,
self.mb_config["plugin_db_directory"])
self.loader.references |= {self} self.loader.references |= {self}
await self.plugin.start() await self.plugin.start()
self.log.info(f"Started instance of {self.loader.id} v{self.loader.version} " self.log.info(f"Started instance of {self.loader.id} v{self.loader.version} "
@ -148,3 +151,7 @@ class PluginInstance:
self.db_instance.primary_user = value self.db_instance.primary_user = value
# endregion # endregion
def init(config: Config):
PluginInstance.mb_config = config

View File

@ -16,6 +16,7 @@
from typing import Type, Optional, TYPE_CHECKING from typing import Type, Optional, TYPE_CHECKING
from logging import Logger from logging import Logger
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
import os.path
from sqlalchemy.engine.base import Engine from sqlalchemy.engine.base import Engine
import sqlalchemy as sql import sqlalchemy as sql
@ -33,14 +34,15 @@ class Plugin(ABC):
config: Optional['BaseProxyConfig'] config: Optional['BaseProxyConfig']
def __init__(self, client: 'MaubotMatrixClient', plugin_instance_id: str, log: Logger, def __init__(self, client: 'MaubotMatrixClient', plugin_instance_id: str, log: Logger,
config: Optional['BaseProxyConfig']) -> None: config: Optional['BaseProxyConfig'], db_base_path: str) -> None:
self.client = client self.client = client
self.id = plugin_instance_id self.id = plugin_instance_id
self.log = log self.log = log
self.config = config self.config = config
self.__db_base_path = db_base_path
def request_db_engine(self) -> Engine: def request_db_engine(self) -> Engine:
return sql.create_engine(f"sqlite:///{self.id}.db") return sql.create_engine(f"sqlite:///{os.path.join(self.__db_base_path, self.id)}.db")
def set_command_spec(self, spec: 'CommandSpec') -> None: def set_command_spec(self, spec: 'CommandSpec') -> None:
self.client.set_command_spec(self.id, spec) self.client.set_command_spec(self.id, spec)