Source code for erin.core.utils

import importlib
import logging
import os
import pkgutil
import sys
from pathlib import Path
from typing import List

from erin.core.exceptions import EnvironmentVariableError, PluginNotFoundError

logger = logging.getLogger(__name__)


[docs]def find_plugins(package) -> List[str]: """ Finds all top level subpackages in a package and presents them in the format required by :meth:`discord.ext.cli.Bot.load_extension`. This is useful when you need to load cogs from multiple areas of your bot. Simply convert your cogs directory into a package and run this method on it. Parameters ----------- package : package Your package as a python package or a path to one. Note: All packages are modules, all modules are not packages. Returns -------- list or None A list of strings of format `foo.bar` as required by :meth:`discord.ext.cli.Bot.load_extension`. If package passed is not valid then `None` is returned instead. """ # Check if parameter is a package if hasattr(package, "__path__"): plugins = pkgutil.walk_packages(package.__path__) package_name = os.path.basename(package.__path__[0]) elif isinstance(package, str): if os.path.exists(package): plugins = pkgutil.walk_packages([package]) package_name = os.path.basename(package) else: raise PluginNotFoundError(package) elif isinstance(package, Path): if package.exists(): plugins = pkgutil.walk_packages([str(package)]) package_name = os.path.basename(str(package)) else: raise PluginNotFoundError(package) else: raise TypeError( f"expected package, str, pathlib.Path or os.PathLike " f"object, not {type(package).__name__}" ) # Create plugin import list plugins = [f"{package_name}.{i.name}" for i in plugins] return plugins
[docs]def get_plugin_data(plugin): """ Retrieve the plugin_data dictionary defined in a plugin. Parameters ----------- plugin : path to a plugin in module import format Returns -------- dict or None The plugin_data dict defined in a plugin or None if the dict is not defined. """ logger.debug(f"Attempting Plugin Import: {plugin}") plugin = importlib.import_module(plugin) plugin_data = None try: plugin_data = plugin.plugin_data except AttributeError: plugin_data = None finally: del sys.modules[plugin.__name__] return plugin_data
[docs]def config_loader(mappings, optional_envs): for category, settings in mappings.items(): for setting, value in settings.items(): if value.startswith("ERIN_"): if value in os.environ: mappings[category][setting] = os.environ[value] elif value in optional_envs: mappings[category][setting] = None else: raise EnvironmentVariableError( f"{value} is not optional.\n" "Set this in your TOML config file or use 'export " f"{value}=YOUR_CUSTOM_VALUE'!" ) return mappings