Esempio n. 1
0
def on_message(client: discord.Client, message: discord.Message):
    """ Perform lambda commands. """
    args = utils.split(message.content)

    # Check if the command is a lambda command and is not disabled (in the blacklist)
    if args[0] in lambdas.data and args[0] not in lambda_config.data["blacklist"]:
        def say(msg, m=message):
            asyncio.async(client.say(m, msg))

        def arg(i, default=0):
            if len(args) > i:
                return args[i]
            else:
                return default

        code_globals.update(dict(arg=arg, say=say, args=args, message=message, client=client))

        # Execute the command
        try:
            exec(lambdas.data[args[0]], code_globals)
        except Exception as e:
            if utils.is_owner(message.author):
                say("```" + utils.format_exception(e) + "```")
            else:
                logging.warn("An exception occurred when parsing lambda command:"
                             "\n{}".format(utils.format_exception(e)))

        return True
Esempio n. 2
0
async def on_message(message: discord.Message):
    """ Perform lambda commands. """
    args = utils.split(message.content)

    # Check if the command is a lambda command and is not disabled (in the blacklist)
    if args[0] in lambdas.data and args[0] not in lambda_config.data[
            "blacklist"]:

        def arg(i, default=0):
            if len(args) > i:
                return args[i]
            else:
                return default

        code_globals.update(
            dict(arg=arg,
                 args=args,
                 message=message,
                 client=client,
                 author=message.author,
                 server=message.server,
                 channel=message.channel))
        python_code = lambdas.data[args[0]]

        # Create an async function so that we can await it using the result of eval
        python_code = "async def lambda_session():\n    " + "\n    ".join(
            line for line in python_code.split("\n"))
        try:
            exec(python_code, code_globals)
        except SyntaxError as e:
            if plugins.is_owner(message.author):
                await client.say(message,
                                 "```" + utils.format_syntax_error(e) + "```")
            else:
                logging.warning(
                    "An exception occurred when parsing lambda command:"
                    "\n{}".format(utils.format_syntax_error(e)))
            return True

        # Execute the command
        try:
            await eval("lambda_session()", code_globals)
        except AssertionError as e:  # Send assertion errors to the core module
            raise AssertionError(e)
        except Exception as e:
            if plugins.is_owner(message.author):
                await client.say(message,
                                 "```" + utils.format_exception(e) + "```")
            else:
                logging.warning(
                    "An exception occurred when parsing lambda command:"
                    "\n{}".format(utils.format_exception(e)))

        return True
Esempio n. 3
0
async def do(message: discord.Message, python_code: Annotate.Code):
    """ Execute python code. """
    code_globals.update(
        dict(message=message,
             client=client,
             author=message.author,
             server=message.server,
             channel=message.channel))

    # Create an async function so that we can await it using the result of eval
    python_code = "async def do_session():\n    " + "\n    ".join(
        line for line in python_code.split("\n"))
    try:
        exec(python_code, code_globals)
    except SyntaxError as e:
        await client.say(message, "```" + utils.format_syntax_error(e) + "```")
        return

    before = datetime.now()
    try:
        result = await eval("do_session()", code_globals)
    except Exception as e:
        await client.say(message, "```" + utils.format_exception(e) + "```")
    else:
        if result:
            await send_result(message.channel, result, datetime.now() - before)
Esempio n. 4
0
def load_plugin(name: str, package: str = "plugins"):
    """ Load a plugin with the name name. If package isn't specified, this
    looks for plugin with specified name in /plugins/

    Any loaded plugin is imported and stored in the self.plugins dictionary. """
    if not name.startswith("__") or not name.endswith("__"):
        try:
            plugin = importlib.import_module("{package}.{plugin}".format(
                plugin=name, package=package))
        except ImportError as e:
            logging.error(
                "An error occurred when loading plugin {}:\n{}".format(
                    name, format_exception(e)))
            return False
        except:
            logging.error(
                "An error occurred when loading plugin {}:\n{}".format(
                    name, format_exc()))
            return False

        plugins[name] = plugin
        logging.debug("LOADED PLUGIN " + name)
        return True

    return False
Esempio n. 5
0
def eval_(client: discord.Client, message: discord.Message, python_code: Annotate.Code):
    """ Evaluate a python expression. Can be any python code on one line that returns something. """
    code_globals.update(dict(message=message, client=client))

    try:
        result = eval(python_code, code_globals)
    except Exception as e:
        result = utils.format_exception(e)

    yield from client.say(message, "**Result:** \n```{}\n```".format(result))
Esempio n. 6
0
async def on_message(message: discord.Message):
    """ Perform lambda commands. """
    args = utils.split(message.content)

    # Check if the command is a lambda command and is not disabled (in the blacklist)
    if args[0] in lambdas.data and args[0] not in lambda_config.data["blacklist"]:
        def arg(i, default=0):
            if len(args) > i:
                return args[i]
            else:
                return default

        code_globals.update(dict(arg=arg, args=args, message=message, client=client,
                                 author=message.author, server=message.server, channel=message.channel))
        python_code = lambdas.data[args[0]]

        # Create an async function so that we can await it using the result of eval
        python_code = "async def lambda_session():\n    " + "\n    ".join(line for line in python_code.split("\n"))
        try:
            exec(python_code, code_globals)
        except SyntaxError as e:
            if utils.is_owner(message.author):
                await client.say(message, "```" + utils.format_syntax_error(e) + "```")
            else:
                logging.warn("An exception occurred when parsing lambda command:"
                             "\n{}".format(utils.format_syntax_error(e)))
            return True

        # Execute the command
        try:
            await eval("lambda_session()", code_globals)
        except AssertionError as e:  # Send assertion errors to the core module
            raise AssertionError(e)
        except Exception as e:
            if utils.is_owner(message.author):
                await client.say(message, "```" + utils.format_exception(e) + "```")
            else:
                logging.warn("An exception occurred when parsing lambda command:"
                             "\n{}".format(utils.format_exception(e)))
        finally:
            return True
Esempio n. 7
0
def do(client: discord.Client, message: discord.Message, python_code: Annotate.Code):
    """ Execute python code. Coroutines do not work, although you can run `say(msg, c=message.channel)`
        to send a message, optionally to a channel. Eg: `say("Hello!")`. """
    def say(msg, m=message):
        asyncio.async(client.say(m, msg))

    code_globals.update(dict(say=say, message=message, client=client))

    try:
        exec(python_code, code_globals)
    except Exception as e:
        say("```" + utils.format_exception(e) + "```")
Esempio n. 8
0
File: bot.py Progetto: Jeglet/pcbot
def main():
    """ The main function. Parses command line arguments, sets up logging,
    gets the user's login info, sets up any background task and starts the bot. """
    # Setup logger with level specified in start_args or logging.INFO
    logging.basicConfig(
        filename=start_args.log_file,
        level=start_args.log_level,
        format="%(levelname)s %(asctime)s [%(module)s / %(name)s]: %(message)s"
    )

    # Always keep the websockets.protocol logger at INFO as a minimum unless --enable-protocol-logging is set
    if not start_args.enable_protocol_logging:
        discord_logger = logging.getLogger("websockets.protocol")
        discord_logger.setLevel(start_args.log_level if start_args.
                                log_level >= logging.INFO else logging.INFO)

    # Setup some config for more customization
    bot_meta = config.Config(
        "bot_meta",
        pretty=True,
        data=dict(
            name="PCBOT",
            command_prefix=config.default_command_prefix,
            case_sensitive_commands=config.default_case_sensitive_commands,
            display_owner_error_in_chat=False))
    config.name = bot_meta.data["name"]
    config.default_command_prefix = bot_meta.data["command_prefix"]
    config.default_case_sensitive_commands = bot_meta.data[
        "case_sensitive_commands"]
    config.owner_error = bot_meta.data["display_owner_error_in_chat"]

    # Set the client for the plugins to use
    plugins.set_client(client)
    utils.set_client(client)

    # Load plugin for builtin commands
    plugins.load_plugin("builtin", "pcbot")

    # Load all dynamic plugins
    plugins.load_plugins()

    # Login with the specified token if specified
    token = start_args.token or input("Token: ")

    login = [token]

    # Setup background tasks
    client.loop.create_task(add_tasks())

    try:
        client.run(*login)
    except discord.errors.LoginFailure as e:
        logging.error(utils.format_exception(e))
Esempio n. 9
0
async def eval_(message: discord.Message, python_code: Annotate.Code):
    """ Evaluate a python expression. Can be any python code on one
    line that returns something. Coroutine generators will by awaited. """
    code_globals.update(dict(message=message, client=client,
                             author=message.author, server=message.server, channel=message.channel))

    try:
        result = eval(python_code, code_globals)
        if inspect.isawaitable(result):
            result = await result
    except SyntaxError as e:
        result = utils.format_syntax_error(e)
    except Exception as e:
        result = utils.format_exception(e)

    await client.say(message, "**Result:** \n```{}\n```".format(result))
Esempio n. 10
0
async def eval_(message: discord.Message, python_code: Annotate.Code):
    """ Evaluate a python expression. Can be any python code on one
    line that returns something. Coroutine generators will by awaited. """
    code_globals.update(dict(message=message, client=client,
                             author=message.author, server=message.server, channel=message.channel))

    before = datetime.now()
    try:
        result = eval(python_code, code_globals)
        if inspect.isawaitable(result):
            result = await result
    except SyntaxError as e:
        result = utils.format_syntax_error(e)
    except Exception as e:
        result = utils.format_exception(e)

    await send_result(message.channel, result, datetime.now() - before)
Esempio n. 11
0
async def do(message: discord.Message, python_code: Annotate.Code):
    """ Execute python code. """
    code_globals.update(dict(message=message, client=client,
                             author=message.author, server=message.server, channel=message.channel))

    # Create an async function so that we can await it using the result of eval
    python_code = "async def do_session():\n    " + "\n    ".join(line for line in python_code.split("\n"))
    try:
        exec(python_code, code_globals)
    except SyntaxError as e:
        await client.say(message, "```" + utils.format_syntax_error(e) + "```")
        return

    try:
        result = await eval("do_session()", code_globals)
    except Exception as e:
        await client.say(message, "```" + utils.format_exception(e) + "```")
    else:
        if result:
            await client.say(message, "**Result:** \n```{}\n```".format(result))
Esempio n. 12
0
File: bot.py Progetto: stoz/PCBOT
def main():
    """ The main function. Parses command line arguments, sets up logging,
    gets the user's login info, sets up any background task and starts the bot. """
    # Add all command-line arguments
    parser = ArgumentParser(description="Run PCBOT.")
    parser.add_argument("--version",
                        "-V",
                        help="Return the current version.",
                        action="version",
                        version=__version__)

    # Setup a login group for handling only token or email, but not both
    login_group = parser.add_mutually_exclusive_group()
    login_group.add_argument(
        "--token", "-t", help="The token to login with. Prompts if omitted.")
    login_group.add_argument("--email",
                             "-e",
                             help="Alternative email to login with.")

    parser.add_argument("--new-pass",
                        "-n",
                        help="Always prompts for password.",
                        action="store_true")
    parser.add_argument(
        "--log-level",
        "-l",
        help=
        "Use the specified logging level (see the docs on logging for values).",
        type=lambda s: getattr(logging, s.upper()),
        default=logging.INFO,
        metavar="LEVEL")
    start_args = parser.parse_args()

    # Setup logger with level specified in start_args or logging.INFO
    logging.basicConfig(
        level=start_args.log_level,
        format="%(levelname)s %(asctime)s [%(module)s / %(name)s]: %(message)s"
    )

    # Always keep discord.py logger at INFO as a minimum
    discord_logger = logging.getLogger("discord")
    discord_logger.setLevel(start_args.log_level if start_args.
                            log_level >= logging.INFO else logging.INFO)

    # Setup some config for more customization
    bot_meta = config.Config(
        "bot_meta",
        pretty=True,
        data=dict(
            name="PCBOT",
            command_prefix=config.default_command_prefix,
            case_sensitive_commands=config.default_case_sensitive_commands,
            display_owner_error_in_chat=False))
    config.name = bot_meta.data["name"]
    config.default_command_prefix = bot_meta.data["command_prefix"]
    config.default_case_sensitive_commands = bot_meta.data[
        "case_sensitive_commands"]
    config.owner_error = bot_meta.data["display_owner_error_in_chat"]

    # Set the client for the plugins to use
    plugins.set_client(client)
    utils.set_client(client)

    # Load plugin for builtin commands
    plugins.load_plugin("builtin", "pcbot")

    # Load all dynamic plugins
    plugins.load_plugins()

    # Handle login
    if not start_args.email:
        # Login with the specified token if specified
        token = start_args.token or input("Token: ")

        login = [token]
    else:
        # Get the email from commandline argument
        email = start_args.email

        password = ""
        cached_path = client._get_cache_filename(
            email)  # Get the name of the would-be cached email

        # If the --new-pass command-line argument is specified, remove the cached password
        # Useful for when you have changed the password
        if start_args.new_pass:
            if os.path.exists(cached_path):
                os.remove(cached_path)

        # Prompt for password if the cached file does not exist (the user has not logged in before or
        # they they entered the --new-pass argument)
        if not os.path.exists(cached_path):
            password = getpass()

        login = [email, password]

    # Setup background tasks
    client.loop.create_task(add_tasks())

    try:
        client.run(*login)
    except discord.errors.LoginFailure as e:
        logging.error(utils.format_exception(e))
Esempio n. 13
0
def main():
    """ The main function. Parses command line arguments, sets up logging,
    gets the user's login info, sets up any background task and starts the bot. """
    # Add all command-line arguments
    parser = ArgumentParser(description="Run PCBOT.")
    parser.add_argument("--version", "-V", help="Return the current version.",
                        action="version", version=__version__)

    # Setup a login group for handling only token or email, but not both
    login_group = parser.add_mutually_exclusive_group()
    login_group.add_argument("--token", "-t", help="The token to login with. Prompts if omitted.")
    login_group.add_argument("--email", "-e", help="The email to login to. Token prompt is default.")

    parser.add_argument("--new-pass", "-n", help="Always prompts for password.", action="store_true")
    parser.add_argument("--log-level", "-l",
                        help="Use the specified logging level (see the docs on logging for values).",
                        type=lambda s: getattr(logging, s.upper()), default=logging.INFO, metavar="LEVEL")
    start_args = parser.parse_args()

    # Setup logger with level specified in start_args or logging.INFO
    logging.basicConfig(level=start_args.log_level,
                        format="%(levelname)s %(asctime)s [%(module)s / %(name)s]: %(message)s")

    # Always keep discord.py logger at INFO as a minimum
    discord_logger = logging.getLogger("discord")
    discord_logger.setLevel(start_args.log_level if start_args.log_level >= logging.INFO else logging.INFO)

    # Setup some config for more customization
    bot_meta = config.Config("bot_meta", pretty=True, data=dict(
        name="PCBOT",
        command_prefix=config.command_prefix
    ))
    config.name = bot_meta.data["name"]
    config.command_prefix = bot_meta.data["command_prefix"]

    # Set the client for the plugins to use
    plugins.set_client(client)

    # Load plugin for builtin commands
    plugins.load_plugin("builtin", "pcbot")

    # Load all dynamic plugins
    plugins.load_plugins()

    # Handle login
    if not start_args.email:
        # Login with the specified token if specified
        token = start_args.token or input("Token: ")

        login = [token]
    else:
        # Get the email from commandline argument
        email = start_args.email

        password = ""
        cached_path = client._get_cache_filename(email)  # Get the name of the would-be cached email

        # If the --new-pass command-line argument is specified, remove the cached password
        # Useful for when you have changed the password
        if start_args.new_pass:
            if os.path.exists(cached_path):
                os.remove(cached_path)

        # Prompt for password if the cached file does not exist (the user has not logged in before or
        # they they entered the --new-pass argument)
        if not os.path.exists(cached_path):
            password = getpass()

        login = [email, password]

    # Setup background tasks
    client.loop.create_task(add_tasks())

    try:
        client.run(*login)
    except discord.errors.LoginFailure as e:
        logging.error(utils.format_exception(e))
Esempio n. 14
0
def load_plugin(name: str, package: str="plugins"):
    """ Load a plugin with the name name. If package isn't specified, this
    looks for plugin with specified name in /plugins/

    Any loaded plugin is imported and stored in the self.plugins dictionary. """
    if not name.startswith("__") or not name.endswith("__"):
        try:
            plugin = importlib.import_module("{package}.{plugin}".format(plugin=name, package=package))
        except ImportError as e:
            logging.error("An error occurred when loading plugin {}:\n{}".format(name, format_exception(e)))
            return False
        except:
            logging.error("An error occurred when loading plugin {}:\n{}".format(name, format_exc()))
            return False

        plugins[name] = plugin
        logging.debug("LOADED PLUGIN " + name)
        return True

    return False