[V3] Allow load, unload and reload to deal with multiple packages (#1441)

* [V3] Allow load, unload and reload to deal with multiple packages

This PR allows multiple packages to be loaded, unloaded or reloaded with the one command, the packages are delimited by the space character as suggested by Will
This is just the functionality, I'm sure the code could be better

* introduced helper function for getting package load strings

* missed characters

* forgotten import 👀

Forgot to include the import `inline` method from chat_formatting
This commit is contained in:
James 2018-03-21 13:32:54 +13:00 committed by palmtree5
parent 83471e0866
commit 153d710eb4

View File

@ -22,7 +22,7 @@ from redbot.core import i18n
from redbot.core import rpc
from redbot.core.context import RedContext
from .utils import TYPE_CHECKING
from .utils.chat_formatting import pagify, box
from .utils.chat_formatting import pagify, box, inline
if TYPE_CHECKING:
from redbot.core.bot import Red
@ -312,14 +312,28 @@ class Core:
@commands.command()
@checks.is_owner()
async def load(self, ctx, *, cog_name: str):
"""Loads a package"""
"""Loads packages"""
failed_packages = []
loaded_packages = []
notfound_packages = []
cognames = [c.strip() for c in cog_name.split(' ')]
cogspecs = []
for c in cognames:
try:
spec = await ctx.bot.cog_mgr.find_cog(cog_name)
spec = await ctx.bot.cog_mgr.find_cog(c)
cogspecs.append((spec, c))
except RuntimeError:
await ctx.send(_("No module by that name was found in any"
" cog path."))
notfound_packages.append(inline(c))
#await ctx.send(_("No module named '{}' was found in any"
# " cog path.").format(c))
if len(cogspecs) == 0:
return
for spec, name in cogspecs:
try:
await ctx.bot.load_extension(spec)
except Exception as e:
@ -330,40 +344,80 @@ class Core:
exception_log += "".join(traceback.format_exception(type(e),
e, e.__traceback__))
self.bot._last_exception = exception_log
await ctx.send(_("Failed to load package. Check your console or "
"logs for details."))
failed_packages.append(inline(name))
else:
await ctx.bot.add_loaded_package(cog_name)
await ctx.send(_("Done."))
await ctx.bot.add_loaded_package(name)
loaded_packages.append(inline(name))
if loaded_packages:
fmt = "Loaded {packs}"
formed = self.get_package_strings(loaded_packages, fmt)
await ctx.send(_(formed))
if failed_packages:
fmt = ("Failed to load package{plural} {packs}. Check your console or "
"logs for details.")
formed = self.get_package_strings(failed_packages, fmt)
await ctx.send(_(formed))
if notfound_packages:
fmt = 'The package{plural} {packs} {other} not found in any cog path.'
formed = self.get_package_strings(notfound_packages, fmt, ('was', 'were'))
await ctx.send(_(formed))
@commands.group()
@checks.is_owner()
async def unload(self, ctx, *, cog_name: str):
"""Unloads a package"""
if cog_name in ctx.bot.extensions:
ctx.bot.unload_extension(cog_name)
await ctx.bot.remove_loaded_package(cog_name)
await ctx.send(_("Done."))
"""Unloads packages"""
cognames = [c.strip() for c in cog_name.split(' ')]
failed_packages = []
unloaded_packages = []
for c in cognames:
if c in ctx.bot.extensions:
ctx.bot.unload_extension(c)
await ctx.bot.remove_loaded_package(c)
unloaded_packages.append(inline(c))
else:
await ctx.send(_("That extension is not loaded."))
failed_packages.append(inline(c))
if unloaded_packages:
fmt = "Package{plural} {packs} {other} unloaded."
formed = self.get_package_strings(unloaded_packages, fmt, ('was', 'were'))
await ctx.send(_(formed))
if failed_packages:
fmt = "The package{plural} {packs} {other} not loaded."
formed = self.get_package_strings(failed_packages, fmt, ('is', 'are'))
await ctx.send(_(formed))
@commands.command(name="reload")
@checks.is_owner()
async def _reload(self, ctx, *, cog_name: str):
"""Reloads a package"""
ctx.bot.unload_extension(cog_name)
"""Reloads packages"""
cognames = [c.strip() for c in cog_name.split(' ')]
for c in cognames:
ctx.bot.unload_extension(c)
cogspecs = []
failed_packages = []
loaded_packages = []
notfound_packages = []
for c in cognames:
try:
spec = await ctx.bot.cog_mgr.find_cog(cog_name)
spec = await ctx.bot.cog_mgr.find_cog(c)
cogspecs.append((spec, c))
except RuntimeError:
await ctx.send(_("No module by that name was found in any"
" cog path."))
return
notfound_packages.append(inline(c))
for spec, name in cogspecs:
try:
self.cleanup_and_refresh_modules(spec.name)
await ctx.bot.load_extension(spec)
loaded_packages.append(inline(name))
except Exception as e:
log.exception("Package reloading failed", exc_info=e)
@ -373,10 +427,40 @@ class Core:
e, e.__traceback__))
self.bot._last_exception = exception_log
await ctx.send(_("Failed to reload package. Check your console or "
"logs for details."))
else:
await ctx.send(_("Done."))
failed_packages.append(inline(name))
if loaded_packages:
fmt = "Package{plural} {packs} {other} reloaded."
formed = self.get_package_strings(loaded_packages, fmt, ('was', 'were'))
await ctx.send(_(formed))
if failed_packages:
fmt = ("Failed to reload package{plural} {packs}. Check your "
"logs for details")
formed = self.get_package_strings(failed_packages, fmt)
await ctx.send(_(formed))
if notfound_packages:
fmt = 'The package{plural} {packs} {other} not found in any cog path.'
formed = self.get_package_strings(notfound_packages, fmt, ('was', 'were'))
await ctx.send(_(formed))
def get_package_strings(self, packages: list, fmt: str, other: tuple=None):
"""
Gets the strings needed for the load, unload and reload commands
"""
if other is None:
other = ('', '')
plural = 's' if len(packages) > 1 else ''
use_and, other = ('', other[0]) if len(packages) == 1 else (' and ', other[1])
packages_string = ', '.join(packages[:-1]) + use_and + packages[-1]
form = {'plural': plural,
'packs' : packages_string,
'other' : other
}
final_string = fmt.format(**form)
return final_string
@commands.command(name="shutdown")
@checks.is_owner()