Some reorganising

This commit is contained in:
Gnarwhal 2024-09-14 16:56:57 +00:00
parent babba91ca2
commit 552146551c
Signed by: Gnarwhal
GPG key ID: 0989A73D8C421174
3 changed files with 73 additions and 49 deletions

View file

@ -16,11 +16,15 @@ import os
from pathlib import Path from pathlib import Path
LOCATION = Path(os.environ.get("XDG_CONFIG_DIR", f"{os.environ["HOME"]}/.config")) / "sshare" _LOCATION = Path(os.environ.get("XDG_CONFIG_DIR", f"{os.environ["HOME"]}/.config")) / "sshare"
def default_config():
return _LOCATION / "config.toml"
def plugins(): def plugins():
return [ return [
path for path for
path in path in
(LOCATION / "plugins").iterdir() (_LOCATION / "plugins").iterdir()
if path.is_file() and path.suffix == ".py" if path.is_file() and path.suffix == ".py"
] ]

View file

@ -38,7 +38,7 @@ def main():
help="Specify location of config file to use" help="Specify location of config file to use"
) )
arguments, _ = arg_parser.parse_known_args() arguments, _ = arg_parser.parse_known_args()
with open(arguments.config or (config_directory.LOCATION / "config.toml"), mode="rb") as file: with open(arguments.config or config_directory.default_config(), mode="rb") as file:
config = tomllib.load(file) config = tomllib.load(file)
config["config"] = config.get("config", {}) config["config"] = config.get("config", {})
config["flags" ] = config.get("flags", {}) config["flags" ] = config.get("flags", {})
@ -56,41 +56,23 @@ def main():
version=f"%(prog)s version {version}", version=f"%(prog)s version {version}",
) )
INTERNAL_PLUGIN_LOCATION = "sshare.plugins"
# Load command line early and set it as the active logger # Load command line early and set it as the active logger
# so that it can be used to report errors while loading and # so that it can be used to report errors while loading and
# configuring other loggers # configuring other loggers
logger = Logger()
command_line = Plugin.internal( command_line = Plugin.internal(
INTERNAL_PLUGIN_LOCATION,
"command_line", "command_line",
logger,
config["config"], config["config"],
config["flags"], config["flags"],
) )
logger = Logger(command_line) logger.add(command_line)
plugin_types = [ "logger", "source", "name", "upload", "location", "feedback" ]
plugins = PluginManager( plugins = PluginManager(
plugin_types,
logger, logger,
config["config"], config["config"],
config["flags"], config["flags"],
arg_parser, arg_parser,
) )
plugins.add_from(
Plugin.internal(INTERNAL_PLUGIN_LOCATION),
"file",
"stdin",
"current_time",
"append_type",
"ssh",
"uri",
"print_location",
)
sys.dont_write_bytecode = True
plugins.add_from(
Plugin.external,
*config_directory.plugins(),
)
sys.dont_write_bytecode = False
plugins.activate("logger") plugins.activate("logger")
logger.add(*plugins.logger.active) logger.add(*plugins.logger.active)
plugins.activate() plugins.activate()

View file

@ -17,28 +17,65 @@ import importlib.util
from sshare.plugin.config import Flag from sshare.plugin.config import Flag
from sshare.plugin.config import NoDefault from sshare.plugin.config import NoDefault
from sshare import config_directory
class PluginLoader:
@staticmethod
def all(command_line=False, logger=None, config=None, flags=None):
return PluginLoader.internal(command_line, logger, config, flags) + PluginLoader.external(logger, config, flags)
@staticmethod
def internal(command_line=False, logger=None, config=None, flags=None):
return [
Plugin.internal(plugin, logger, config, flags)
for plugin
in ([ "command_line" ] if command_line else []) + [
"file",
"stdin",
"current_time",
"append_type",
"ssh",
"uri",
"print_location",
]
]
@staticmethod
def external(logger=None, config=None, flags=None):
return [
Plugin.external(plugin, logger, config, flags)
for plugin
in config_directory.plugins()
]
@staticmethod
def at(logger=None, config=None, flags=None, *args):
return [
Plugin.external(plugin, logger, config, flags)
for plugin
in args
]
class PluginManager: class PluginManager:
def __init__(self, types, logger, config, flags, arg_parser): def __init__(self, logger, config, flags, arg_parser):
self._uninitialized = []
self._logger = logger self._logger = logger
self._config = config
self._flags = flags
self._arg_parser = arg_parser self._arg_parser = arg_parser
class PluginState: class PluginState:
def __init__(self): def __init__(self):
self.active = [] self.active = []
self.inactive = [] self.inactive = []
for type in types: for type in Plugin.types():
setattr(self, type, PluginState()) setattr(self, type, PluginState())
def add_from(self, location, *args, **kwargs): self._uninitialized = PluginLoader.all(
for plugin in args: command_line=False,
plugin = location(plugin, self._config, self._flags) logger=logger,
plugin.set_logger(self._logger) config=config,
plugin.add_args(self._arg_parser) flags=flags,
self._uninitialized.append(plugin) )
for plugin in self._uninitialized:
plugin.add_args(arg_parser)
def activate(self, activate_type=None): def activate(self, activate_type=None):
args = self._arg_parser.parse_args() args = self._arg_parser.parse_args()
@ -53,10 +90,19 @@ class PluginManager:
).append(plugin) ).append(plugin)
class Plugin: class Plugin:
def __init__(self, name, module, external_config, external_flags): @staticmethod
def types():
return [ "logger", "source", "name", "upload", "location", "feedback" ]
def __init__(self, name, module, logger, external_config, external_flags):
self.__dict__ = module.__dict__ self.__dict__ = module.__dict__
self.name = name self.name = name
if logger == None:
return
self.logger = logger
if not isinstance(self.plugin_type, set): if not isinstance(self.plugin_type, set):
self.plugin_type = { self.plugin_type } self.plugin_type = { self.plugin_type }
@ -84,7 +130,7 @@ class Plugin:
if hasattr(self, "args"): if hasattr(self, "args"):
for arg in self.args.items(): for arg in self.args.items():
arg[1].bind(self, arg[0]) arg[1].bind(self, arg[0])
flags = external_flags.get(arg[0], {}) flags = external_flags.get(arg[0], dict())
arg[1].set_flags(flags.get("short"), flags.get("long")) arg[1].set_flags(flags.get("short"), flags.get("long"))
value = arg[1].default() value = arg[1].default()
if value != NoDefault: if value != NoDefault:
@ -98,9 +144,6 @@ class Plugin:
flat_config.__dict__ = config flat_config.__dict__ = config
self.config = flat_config self.config = flat_config
def set_logger(self, logger):
self.logger = logger
def add_args(self, arg_parser): def add_args(self, arg_parser):
for arg in self.args.values(): for arg in self.args.values():
arg.add(arg_parser) arg.add(arg_parser)
@ -126,20 +169,15 @@ class Plugin:
return activate return activate
@staticmethod @staticmethod
def internal(location, name=None, config=None, flags=None): def internal(name=None, logger=None, config=None, flags=None):
def _load_internal(_name, _config, _flags): return Plugin(name, importlib.import_module(f"sshare.plugins.{name}"), logger, config.get(name, dict()), flags.get(name, dict()))
return Plugin(_name, importlib.import_module(f"{location}.{_name}"), _config.get(_name, dict()), _flags.get(_name, dict()))
if name == None:
return _load_internal
else:
return _load_internal(name, config, flags)
@staticmethod @staticmethod
def external(path, config, flags): def external(path, logger=None, config=None, flags=None):
module_spec = importlib.util.spec_from_file_location( module_spec = importlib.util.spec_from_file_location(
path.stem, path.stem,
path.as_posix(), path.as_posix(),
) )
module = importlib.util.module_from_spec(module_spec) module = importlib.util.module_from_spec(module_spec)
module_spec.loader.exec_module(module) module_spec.loader.exec_module(module)
return Plugin(path.stem, module, config.get(path.stem, dict()), flags.get(path.stem, dict())) return Plugin(path.stem, module, logger, config.get(path.stem, dict()), flags.get(path.stem, dict()))