mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
parent
85b0f34395
commit
f78c33445c
@ -10,20 +10,15 @@ from core import checks
|
|||||||
from core.config import Config
|
from core.config import Config
|
||||||
from core.utils.chat_formatting import box
|
from core.utils.chat_formatting import box
|
||||||
|
|
||||||
|
__all__ = ["CogManager"]
|
||||||
class CogManagerException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidPath(CogManagerException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class NoModuleFound(CogManagerException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CogManager:
|
class CogManager:
|
||||||
|
"""
|
||||||
|
This module allows you to load cogs from multiple directories and even from outside the bot
|
||||||
|
directory. You may also set a directory for downloader to install new cogs to, the default
|
||||||
|
being the :code:`cogs/` folder in the root bot directory.
|
||||||
|
"""
|
||||||
def __init__(self, paths: Tuple[str]=(), bot_dir: Path=Path.cwd()):
|
def __init__(self, paths: Tuple[str]=(), bot_dir: Path=Path.cwd()):
|
||||||
self.conf = Config.get_conf(self, 2938473984732, True)
|
self.conf = Config.get_conf(self, 2938473984732, True)
|
||||||
self.conf.register_global(
|
self.conf.register_global(
|
||||||
@ -35,8 +30,7 @@ class CogManager:
|
|||||||
|
|
||||||
async def paths(self) -> Tuple[Path, ...]:
|
async def paths(self) -> Tuple[Path, ...]:
|
||||||
"""
|
"""
|
||||||
This will return all currently valid path directories.
|
All currently valid path directories.
|
||||||
:return:
|
|
||||||
"""
|
"""
|
||||||
conf_paths = await self.conf.paths()
|
conf_paths = await self.conf.paths()
|
||||||
other_paths = self._paths
|
other_paths = self._paths
|
||||||
@ -50,8 +44,7 @@ class CogManager:
|
|||||||
|
|
||||||
async def install_path(self) -> Path:
|
async def install_path(self) -> Path:
|
||||||
"""
|
"""
|
||||||
Returns the install path for 3rd party cogs.
|
The install path for 3rd party cogs.
|
||||||
:return:
|
|
||||||
"""
|
"""
|
||||||
p = Path(await self.conf.install_path())
|
p = Path(await self.conf.install_path())
|
||||||
return p.resolve()
|
return p.resolve()
|
||||||
@ -59,9 +52,17 @@ class CogManager:
|
|||||||
async def set_install_path(self, path: Path) -> Path:
|
async def set_install_path(self, path: Path) -> Path:
|
||||||
"""
|
"""
|
||||||
Install path setter, will return the absolute path to
|
Install path setter, will return the absolute path to
|
||||||
the given path.
|
the given path.
|
||||||
:param path:
|
|
||||||
:return:
|
.. note::
|
||||||
|
|
||||||
|
The bot will not remember your old cog install path which means
|
||||||
|
that ALL PREVIOUSLY INSTALLED COGS will now be unfindable.
|
||||||
|
|
||||||
|
:param pathlib.Path path:
|
||||||
|
The new directory for cog installs.
|
||||||
|
:raises ValueError:
|
||||||
|
If :code:`path` is not an existing directory.
|
||||||
"""
|
"""
|
||||||
if not path.is_dir():
|
if not path.is_dir():
|
||||||
raise ValueError("The install path must be an existing directory.")
|
raise ValueError("The install path must be an existing directory.")
|
||||||
@ -73,8 +74,12 @@ class CogManager:
|
|||||||
def _ensure_path_obj(path: Union[Path, str]) -> Path:
|
def _ensure_path_obj(path: Union[Path, str]) -> Path:
|
||||||
"""
|
"""
|
||||||
Guarantees an object will be a path object.
|
Guarantees an object will be a path object.
|
||||||
|
|
||||||
:param path:
|
:param path:
|
||||||
:return:
|
:type path:
|
||||||
|
pathlib.Path or str
|
||||||
|
:rtype:
|
||||||
|
pathlib.Path
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
path.exists()
|
path.exists()
|
||||||
@ -85,13 +90,15 @@ class CogManager:
|
|||||||
async def add_path(self, path: Union[Path, str]):
|
async def add_path(self, path: Union[Path, str]):
|
||||||
"""
|
"""
|
||||||
Adds a cog path to current list, will ignore duplicates. Does have
|
Adds a cog path to current list, will ignore duplicates. Does have
|
||||||
a side effect of removing all invalid paths from the saved path
|
a side effect of removing all invalid paths from the saved path
|
||||||
list.
|
list.
|
||||||
|
|
||||||
Will raise InvalidPath if given anything that does not resolve to
|
|
||||||
a directory.
|
|
||||||
:param path:
|
:param path:
|
||||||
:return:
|
Path to add.
|
||||||
|
:type path:
|
||||||
|
pathlib.Path or str
|
||||||
|
:raises ValueError:
|
||||||
|
If :code:`path` does not resolve to an existing directory.
|
||||||
"""
|
"""
|
||||||
path = self._ensure_path_obj(path)
|
path = self._ensure_path_obj(path)
|
||||||
|
|
||||||
@ -100,7 +107,7 @@ class CogManager:
|
|||||||
path = path.resolve()
|
path = path.resolve()
|
||||||
|
|
||||||
if not path.is_dir():
|
if not path.is_dir():
|
||||||
raise InvalidPath("'{}' is not a valid directory.".format(path))
|
raise ValueError("'{}' is not a valid directory.".format(path))
|
||||||
|
|
||||||
if path == await self.install_path():
|
if path == await self.install_path():
|
||||||
raise ValueError("Cannot add the install path as an additional path.")
|
raise ValueError("Cannot add the install path as an additional path.")
|
||||||
@ -112,8 +119,13 @@ class CogManager:
|
|||||||
async def remove_path(self, path: Union[Path, str]) -> Tuple[Path, ...]:
|
async def remove_path(self, path: Union[Path, str]) -> Tuple[Path, ...]:
|
||||||
"""
|
"""
|
||||||
Removes a path from the current paths list.
|
Removes a path from the current paths list.
|
||||||
:param path:
|
|
||||||
|
:param path: Path to remove.
|
||||||
|
:type path:
|
||||||
|
pathlib.Path or str
|
||||||
:return:
|
:return:
|
||||||
|
Tuple of new valid paths.
|
||||||
|
:rtype: tuple
|
||||||
"""
|
"""
|
||||||
path = self._ensure_path_obj(path)
|
path = self._ensure_path_obj(path)
|
||||||
all_paths = list(await self.paths())
|
all_paths = list(await self.paths())
|
||||||
@ -125,19 +137,25 @@ class CogManager:
|
|||||||
async def set_paths(self, paths_: List[Path]):
|
async def set_paths(self, paths_: List[Path]):
|
||||||
"""
|
"""
|
||||||
Sets the current paths list.
|
Sets the current paths list.
|
||||||
:param paths_:
|
|
||||||
:return:
|
:param List[pathlib.Path] paths_:
|
||||||
|
List of paths to set.
|
||||||
"""
|
"""
|
||||||
str_paths = [str(p) for p in paths_]
|
str_paths = [str(p) for p in paths_]
|
||||||
await self.conf.paths.set(str_paths)
|
await self.conf.paths.set(str_paths)
|
||||||
|
|
||||||
async def find_cog(self, name: str) -> ModuleSpec:
|
async def find_cog(self, name: str) -> ModuleSpec:
|
||||||
"""
|
"""
|
||||||
Finds a cog in the list of available path.
|
Finds a cog in the list of available paths.
|
||||||
|
|
||||||
Raises NoModuleFound if unavailable.
|
|
||||||
:param name:
|
:param name:
|
||||||
|
Name of the cog to find.
|
||||||
|
:raises RuntimeError:
|
||||||
|
If there is no cog with the given name.
|
||||||
:return:
|
:return:
|
||||||
|
A module spec to be used for specialized cog loading.
|
||||||
|
:rtype:
|
||||||
|
importlib.machinery.ModuleSpec
|
||||||
"""
|
"""
|
||||||
resolved_paths = [str(p.resolve()) for p in await self.paths()]
|
resolved_paths = [str(p.resolve()) for p in await self.paths()]
|
||||||
for finder, module_name, _ in pkgutil.iter_modules(resolved_paths):
|
for finder, module_name, _ in pkgutil.iter_modules(resolved_paths):
|
||||||
@ -146,17 +164,16 @@ class CogManager:
|
|||||||
if spec:
|
if spec:
|
||||||
return spec
|
return spec
|
||||||
|
|
||||||
raise NoModuleFound("No module by the name of '{}' was found"
|
raise RuntimeError("No module by the name of '{}' was found"
|
||||||
" in any available path.".format(name))
|
" in any available path.".format(name))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def invalidate_caches():
|
def invalidate_caches():
|
||||||
"""
|
"""
|
||||||
This is an alias for an importlib internal and should be called
|
This is an alias for an importlib internal and should be called
|
||||||
any time that a new module has been installed to a cog directory.
|
any time that a new module has been installed to a cog directory.
|
||||||
|
|
||||||
*I think.*
|
*I think.*
|
||||||
:return:
|
|
||||||
"""
|
"""
|
||||||
invalidate_caches()
|
invalidate_caches()
|
||||||
|
|
||||||
|
|||||||
@ -11,8 +11,6 @@ import discord
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from core.cog_manager import NoModuleFound
|
|
||||||
|
|
||||||
log = logging.getLogger("red")
|
log = logging.getLogger("red")
|
||||||
|
|
||||||
OWNER_DISCLAIMER = ("⚠ **Only** the person who is hosting Red should be "
|
OWNER_DISCLAIMER = ("⚠ **Only** the person who is hosting Red should be "
|
||||||
@ -30,7 +28,7 @@ class Core:
|
|||||||
"""Loads a package"""
|
"""Loads a package"""
|
||||||
try:
|
try:
|
||||||
spec = await ctx.bot.cog_mgr.find_cog(cog_name)
|
spec = await ctx.bot.cog_mgr.find_cog(cog_name)
|
||||||
except NoModuleFound:
|
except RuntimeError:
|
||||||
await ctx.send("No module by that name was found in any"
|
await ctx.send("No module by that name was found in any"
|
||||||
" cog path.")
|
" cog path.")
|
||||||
return
|
return
|
||||||
|
|||||||
8
docs/framework_cogmanager.rst
Normal file
8
docs/framework_cogmanager.rst
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.. cog manager docs
|
||||||
|
|
||||||
|
===========
|
||||||
|
Cog Manager
|
||||||
|
===========
|
||||||
|
|
||||||
|
.. automodule:: core.cog_manager
|
||||||
|
:members:
|
||||||
@ -17,6 +17,7 @@ Welcome to Red - Discord Bot's documentation!
|
|||||||
:caption: Red Development Framework Reference:
|
:caption: Red Development Framework Reference:
|
||||||
|
|
||||||
framework_bank
|
framework_bank
|
||||||
|
framework_cogmanager
|
||||||
framework_config
|
framework_config
|
||||||
framework_downloader
|
framework_downloader
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user