Exemplo n.º 1
0
async def _setup_driver():
    backend_type = _get_backend_type()
    storage_details = {}
    data_manager.storage_type = lambda: backend_type.value
    data_manager.storage_details = lambda: storage_details
    driver_cls = drivers.get_driver_class(backend_type)
    await driver_cls.initialize(**storage_details)
    yield
    await driver_cls.teardown()
Exemplo n.º 2
0
async def do_migration(current_backend: BackendType,
                       target_backend: BackendType) -> Dict[str, Any]:
    cur_driver_cls = drivers._get_driver_class_include_old(current_backend)
    new_driver_cls = drivers.get_driver_class(target_backend)
    cur_storage_details = data_manager.storage_details()
    new_storage_details = new_driver_cls.get_config_details()

    await cur_driver_cls.initialize(**cur_storage_details)
    await new_driver_cls.initialize(**new_storage_details)

    await config.migrate(cur_driver_cls, new_driver_cls)

    await cur_driver_cls.teardown()
    await new_driver_cls.teardown()

    return new_storage_details
Exemplo n.º 3
0
async def remove_instance(
    instance,
    interactive: bool = False,
    delete_data: Optional[bool] = None,
    _create_backup: Optional[bool] = None,
    drop_db: Optional[bool] = None,
    remove_datapath: Optional[bool] = None,
):
    data_manager.load_basic_configuration(instance)

    if interactive is True and delete_data is None:
        delete_data = click.confirm(
            "Would you like to delete this instance's data?", default=False)

    if interactive is True and _create_backup is None:
        _create_backup = click.confirm(
            "Would you like to make a backup of the data for this instance?",
            default=False)

    if _create_backup is True:
        await create_backup(instance)

    backend = get_current_backend(instance)
    driver_cls = drivers.get_driver_class(backend)
    await driver_cls.initialize(**data_manager.storage_details())
    try:
        if delete_data is True:
            await driver_cls.delete_all_data(interactive=interactive,
                                             drop_db=drop_db)

        if interactive is True and remove_datapath is None:
            remove_datapath = click.confirm(
                "Would you like to delete the instance's entire datapath?",
                default=False)

        if remove_datapath is True:
            data_path = data_manager.core_data_path().parent
            safe_delete(data_path)

        save_config(instance, {}, remove=True)
    finally:
        await driver_cls.teardown()
    print("The instance {} has been removed\n".format(instance))
Exemplo n.º 4
0
def basic_setup():
    """
    Creates the data storage folder.
    :return:
    """

    print(
        "Hello! Before we begin, we need to gather some initial information for the new instance."
    )
    name = get_name()

    default_data_dir = get_data_dir(name)

    default_dirs = deepcopy(data_manager.basic_config_default)
    default_dirs["DATA_PATH"] = default_data_dir

    storage = get_storage_type()

    storage_dict = {1: BackendType.JSON, 2: BackendType.POSTGRES}
    storage_type: BackendType = storage_dict.get(storage, BackendType.JSON)
    default_dirs["STORAGE_TYPE"] = storage_type.value
    driver_cls = drivers.get_driver_class(storage_type)
    default_dirs["STORAGE_DETAILS"] = driver_cls.get_config_details()

    if name in instance_data:
        print("WARNING: An instance already exists with this name. "
              "Continuing will overwrite the existing instance config.")
        if not click.confirm(
                "Are you absolutely certain you want to continue?",
                default=False):
            print("Not continuing")
            sys.exit(0)
    save_config(name, default_dirs)

    print()
    print(
        "Your basic configuration has been saved. Please run `beastbot <name>` to"
        " continue your setup process and to run the bot.\n\n"
        "First time? Read the quickstart guide:\n"
        "https://docs.discord.red/en/stable/getting_started.html")
Exemplo n.º 5
0
def handle_edit(cli_flags: Namespace):
    """
    This one exists to not log all the things like it's a full run of the bot.
    """
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    data_manager.load_basic_configuration(cli_flags.instance_name)
    red = Red(cli_flags=cli_flags, description="Red V3", dm_help=None)
    try:
        driver_cls = drivers.get_driver_class()
        loop.run_until_complete(
            driver_cls.initialize(**data_manager.storage_details()))
        loop.run_until_complete(edit_instance(red, cli_flags))
        loop.run_until_complete(driver_cls.teardown())
    except (KeyboardInterrupt, EOFError):
        print("Aborted!")
    finally:
        loop.run_until_complete(asyncio.sleep(1))
        asyncio.set_event_loop(None)
        loop.stop()
        loop.close()
        sys.exit(0)
Exemplo n.º 6
0
async def run_bot(red: Red, cli_flags: Namespace) -> None:
    """
    This runs the bot.

    Any shutdown which is a result of not being able to log in needs to raise
    a SystemExit exception.

    If the bot starts normally, the bot should be left to handle the exit case.
    It will raise SystemExit in a task, which will reach the event loop and
    interrupt running forever, then trigger our cleanup process, and does not
    need additional handling in this function.
    """

    driver_cls = drivers.get_driver_class()

    await driver_cls.initialize(**data_manager.storage_details())

    beastbot.logback.init_logging(
        level=cli_flags.logging_level,
        location=data_manager.core_data_path() / "logs",
        force_rich_logging=cli_flags.rich_logging,
    )

    log.debug("====Basic Config====")
    log.debug("Data Path: %s", data_manager._base_data_path())
    log.debug("Storage Type: %s", data_manager.storage_type())

    # lib folder has to be in sys.path before trying to load any 3rd-party cog (GH-3061)
    # We might want to change handling of requirements in Downloader at later date
    LIB_PATH = data_manager.cog_data_path(raw_name="Downloader") / "lib"
    LIB_PATH.mkdir(parents=True, exist_ok=True)
    if str(LIB_PATH) not in sys.path:
        sys.path.append(str(LIB_PATH))

        # "It's important to note that the global `working_set` object is initialized from
        # `sys.path` when `pkg_resources` is first imported, but is only updated if you do
        # all future `sys.path` manipulation via `pkg_resources` APIs. If you manually modify
        # `sys.path`, you must invoke the appropriate methods on the `working_set` instance
        # to keep it in sync."
        # Source: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#workingset-objects
        pkg_resources.working_set.add_entry(str(LIB_PATH))
    sys.meta_path.insert(0, SharedLibImportWarner())

    if cli_flags.token:
        token = cli_flags.token
    else:
        token = os.environ.get("RED_TOKEN", None)
        if not token:
            token = await red._config.token()

    prefix = cli_flags.prefix or await red._config.prefix()

    if not (token and prefix):
        if cli_flags.no_prompt is False:
            new_token = await 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)

    if cli_flags.dry_run:
        await red.http.close()
        sys.exit(0)
    try:
        await red.start(token, bot=True, cli_flags=cli_flags)
    except discord.LoginFailure:
        log.critical("This token doesn't seem to be valid.")
        db_token = await red._config.token()
        if db_token and not cli_flags.no_prompt:
            if confirm("\nDo you want to reset the token?"):
                await red._config.token.set("")
                print("Token has been reset.")
                sys.exit(0)
        sys.exit(1)
    except discord.PrivilegedIntentsRequired:
        print(
            "Red requires all Privileged Intents to be enabled.\n"
            "You can find out how to enable Privileged Intents with this guide:\n"
            "https://docs.discord.red/en/stable/bot_application_guide.html#enabling-privileged-intents"
        )
        sys.exit(1)

    return None