예제 #1
0
    async def load_dev(self,
                       ctx: commands.Context,
                       replace_mock: Optional[str] = None):
        """
        Dynamically loads dev cog

        `[replace_mock]` the replacement command name for `[p]mock`
        If nothing is provided this will not replace `[p]mock`.
        """
        dev = Dev()
        # log.debug(dir(dev))
        # return
        if not replace_mock:
            replace_mock = await self.config.replace_mock()
        if replace_mock:
            for command in dev.walk_commands():
                if command.name == "mock":
                    del dev.all_commands[str(command)]
                    command.name = replace_mock
                    dev.all_commands[replace_mock] = command
                    log.debug(command.name)
        self.bot.remove_cog("Dev")
        # remove currently existing dev cog if it's loaded
        self.bot.add_cog(dev)
        await ctx.send(
            _("The following package was loaded: `{pack}`").format(pack="dev"))
예제 #2
0
 async def initialize(self):
     replace_mock = await self.config.replace_mock()
     if await self.config.auto_load_dev():
         dev = Dev()
         if replace_mock:
             for command in dev.walk_commands():
                 if command.name == "mock":
                     del dev.all_commands[str(command)]
                     command.name = replace_mock
                     dev.all_commands[replace_mock] = command
                     log.debug("Replaced Mock command")
         self.bot.remove_cog("Dev")
         self.bot.add_cog(dev)
예제 #3
0
파일: cog.py 프로젝트: aikaterna/sitcogsv3
    async def on_command_error(self, ctx, error, unhandled_by_cog=False):
        if isinstance(error, commands.CommandInvokeError):
            # let me know if you want that generate error ticket ID feature here
            # logging and stuff is straight out of events.py to make sure those
            # still occur for this error type
            cmd = ctx.command

            log.exception(f"Exception in command '{cmd.qualified_name}'", exc_info=error.original)
            exception_log = f"Exception in command '{cmd.qualified_name}'\n"
            exception_log += "".join(
                traceback.format_exception(type(error), error, error.__traceback__)
            )
            ctx.bot._last_exception = exception_log

            eh_cog = ctx.bot.get_cog("ErrorHandler")
            if eh_cog._eval_string is None:
                eh_cog._eval_string = await eh_cog.config.response()

            # redbot.core.dev_commands L186 helped a bunch here
            # also could probably use locals() here but don't care
            env = {
                'ctx': ctx,
                'error': error,
                'discord': discord,
                'cf': cf
            }

            to_compile = "async def func():\n%s" % textwrap.indent(eh_cog._eval_string, "  ")
            try:
                compiled = Dev.async_compile(to_compile, "<string>", "exec")
                exec(compiled, env)
            except SyntaxError as e:
                return await ctx.send(Dev.get_syntax_error(e))

            func = env["func"]
            await func()
            return
        await self._old_handler(ctx, error, unhandled_by_cog)
예제 #4
0
파일: cog.py 프로젝트: aikaterna/sitcogsv3
    async def set_handler(self, ctx, *, code):
        """
        Set the string to evaluate, use a python code block.

        Environment variables:
            cf      - redbot.core.utils.chat_formatting module
            ctx     - context of invokation
            error   - the error that was raised
            discord - discord.py library
        """
        body = Dev.cleanup_code(code)
        await self.config.response.set(value=body)
        await ctx.send(f"Handler code set to\n```py\n{body}\n```\nIt's recommended that you test the handler by running `{ctx.prefix}errorhandler test`")
        self._eval_string = body
예제 #5
0
def main():
    description = "Bot Base - Version {}".format(__version__)
    cli_flags = parse_cli_flags(sys.argv[1:])
    if cli_flags.list_instances:
        list_instances()
    elif cli_flags.version:
        print(description)
        sys.exit(0)
    elif not cli_flags.instance_name and not cli_flags.no_instance:
        print("Error: No instance name was provided!")
        sys.exit(1)
    if cli_flags.no_instance:
        print(
            "\033[1m"
            "Warning: The data will be placed in a temporary folder and removed on next system "
            "reboot."
            "\033[0m")
        cli_flags.instance_name = "temporary_red"
        create_temp_config()
    load_basic_configuration(cli_flags.instance_name)
    log = init_loggers(cli_flags)
    loop = asyncio.get_event_loop()
    red = Red(cli_flags=cli_flags, description=description, pm_help=None)
    init_global_checks(red)
    init_events(red, cli_flags)
    loop.run_until_complete(red.cog_mgr.initialize())
    red.add_cog(Core(red))
    red.add_cog(CogManagerUI())
    if cli_flags.dev:
        red.add_cog(Dev())
    # noinspection PyProtectedMember
    modlog._init()
    # noinspection PyProtectedMember
    bank._init()
    if os.name == "posix":
        loop.add_signal_handler(
            SIGTERM, lambda: asyncio.ensure_future(sigterm_handler(red, log)))
    tmp_data = {}
    loop.run_until_complete(_get_prefix_and_token(red, tmp_data))
    token = os.environ.get("RED_TOKEN", tmp_data["token"])
    if cli_flags.token:
        token = cli_flags.token
    prefix = cli_flags.prefix or tmp_data["prefix"]
    if not (token and prefix):
        if cli_flags.no_prompt is False:
            new_token = interactive_config(red,
                                           token_set=bool(token),
                                           prefix_set=bool(prefix))
            if new_token:
                token = new_token
        else:
            log.critical("Token and prefix must be set in order to login.")
            sys.exit(1)
    loop.run_until_complete(_get_prefix_and_token(red, tmp_data))

    if cli_flags.dry_run:
        loop.run_until_complete(red.http.close())
        sys.exit(0)
    try:
        loop.run_until_complete(red.start(token, bot=True))
    except discord.LoginFailure:
        log.critical("This token doesn't seem to be valid.")
        db_token = loop.run_until_complete(red.db.token())
        if db_token and not cli_flags.no_prompt:
            print("\nDo you want to reset the token? (y/n)")
            if confirm("> "):
                loop.run_until_complete(red.db.token.set(""))
                print("Token has been reset.")
    except KeyboardInterrupt:
        log.info("Keyboard interrupt detected. Quitting...")
        loop.run_until_complete(red.logout())
        red._shutdown_mode = ExitCodes.SHUTDOWN
    except Exception as e:
        log.critical("Fatal exception", exc_info=e)
        loop.run_until_complete(red.logout())
    finally:
        pending = asyncio.Task.all_tasks(loop=red.loop)
        gathered = asyncio.gather(*pending,
                                  loop=red.loop,
                                  return_exceptions=True)
        gathered.cancel()
        try:
            loop.run_until_complete(red.rpc.close())
        except AttributeError:
            pass

        sys.exit(red._shutdown_mode.value)