示例#1
0
async def reset_red():
    instances = load_existing_config()

    if not instances:
        print("No instance to delete.\n")
        return
    print(
        "WARNING: You are about to remove ALL bot instances on this computer.")
    print("If you want to reset data of only one instance, "
          "please select option 5 in the launcher.")
    await asyncio.sleep(2)
    print("\nIf you continue you will remove these instanes.\n")
    for instance in list(instances.keys()):
        print("    - {}".format(instance))
    await asyncio.sleep(3)
    print('\nIf you want to reset all instances, type "I agree".')
    response = input("> ").strip()
    if response != "I agree":
        print("Cancelling...")
        return

    if confirm("\nDo you want to create a backup for an instance? (y/n) "):
        for index, instance in instances.items():
            print("\nRemoving {}...".format(index))
            await create_backup(index, instance)
            await remove_instance(index, instance)
    else:
        for index, instance in instances.items():
            await remove_instance(index, instance)
    print("All instances have been removed.")
示例#2
0
def save_config(name, data, remove=False):
    config = load_existing_config()
    if remove and name in config:
        config.pop(name)
    else:
        if name in config:
            print(
                "WARNING: An instance already exists with this name. "
                "Continuing will overwrite the existing instance config."
            )
            if not confirm("Are you absolutely certain you want to continue (y/n)? "):
                print("Not continuing")
                sys.exit(0)
        config[name] = data
    JsonIO(config_file)._save_json(config)
示例#3
0
async def create_backup(selected, instance_data):
    if confirm("Would you like to make a backup of the data for this instance? (y/n)"):
        load_basic_configuration(selected)
        if instance_data["STORAGE_TYPE"] == "MongoDB":
            await mongo_to_json(instance_data["DATA_PATH"], instance_data["STORAGE_DETAILS"])
        print("Backing up the instance's data...")
        backup_filename = "redv3-{}-{}.tar.gz".format(
            selected, dt.utcnow().strftime("%Y-%m-%d %H-%M-%S")
        )
        pth = Path(instance_data["DATA_PATH"])
        if pth.exists():
            backup_pth = pth.home()
            backup_file = backup_pth / backup_filename

            to_backup = []
            exclusions = [
                "__pycache__",
                "Lavalink.jar",
                os.path.join("Downloader", "lib"),
                os.path.join("CogManager", "cogs"),
                os.path.join("RepoManager", "repos"),
            ]
            from botbase.cogs.downloader.repo_manager import RepoManager

            repo_mgr = RepoManager()
            repo_output = []
            for _, repo in repo_mgr._repos:
                repo_output.append({"url": repo.url, "name": repo.name, "branch": repo.branch})
            repo_filename = pth / "cogs" / "RepoManager" / "repos.json"
            with open(str(repo_filename), "w") as f:
                f.write(json.dumps(repo_output, indent=4))
            instance_data = {instance_name: basic_config}
            instance_file = pth / "instance.json"
            with open(str(instance_file), "w") as instance_out:
                instance_out.write(json.dumps(instance_data, indent=4))
            for f in pth.glob("**/*"):
                if not any(ex in str(f) for ex in exclusions):
                    to_backup.append(f)
            with tarfile.open(str(backup_file), "w:gz") as tar:
                for f in to_backup:
                    tar.add(str(f), recursive=False)
            print("A backup of {} has been made. It is at {}".format(selected, backup_file))
示例#4
0
def get_data_dir():
    default_data_dir = Path(appdir.user_data_dir)

    print(
        "Hello! Before we begin the full configuration process we need to"
        " gather some initial information about where you'd like us"
        " to store your bot's data. We've attempted to figure out a"
        " sane default data location which is printed below. If you don't"
        " want to change this default please press [ENTER], otherwise"
        " input your desired data location."
    )
    print()
    print("Default: {}".format(default_data_dir))

    new_path = input("> ")

    if new_path != "":
        new_path = Path(new_path)
        default_data_dir = new_path

    if not default_data_dir.exists():
        try:
            default_data_dir.mkdir(parents=True, exist_ok=True)
        except OSError:
            print(
                "We were unable to create your chosen directory."
                " You may need to restart this process with admin"
                " privileges."
            )
            sys.exit(1)

    print("You have chosen {} to be your data directory.".format(default_data_dir))
    if not confirm("Please confirm (y/n):"):
        print("Please start the process over.")
        sys.exit(0)
    return default_data_dir
示例#5
0
async def edit_instance():
    instance_list = load_existing_config()
    if not instance_list:
        print("No instances have been set up!")
        return

    print(
        "You have chosen to edit an instance. The following "
        "is a list of instances that currently exist:\n"
    )
    for instance in instance_list.keys():
        print("{}\n".format(instance))
    print("Please select one of the above by entering its name")
    selected = input("> ")

    if selected not in instance_list.keys():
        print("That isn't a valid instance!")
        return
    instance_data = instance_list[selected]
    default_dirs = deepcopy(basic_config_default)

    current_data_dir = Path(instance_data["DATA_PATH"])
    print("You have selected '{}' as the instance to modify.".format(selected))
    if not confirm("Please confirm (y/n):"):
        print("Ok, we will not continue then.")
        return

    print("Ok, we will continue on.")
    print()
    if confirm("Would you like to change the instance name? (y/n)"):
        name = get_name()
    else:
        name = selected

    if confirm("Would you like to change the data location? (y/n)"):
        default_data_dir = get_data_dir()
        default_dirs["DATA_PATH"] = str(default_data_dir.resolve())
    else:
        default_dirs["DATA_PATH"] = str(current_data_dir.resolve())

    if confirm("Would you like to change the storage type? (y/n):"):
        storage = get_storage_type()

        storage_dict = {1: "JSON", 2: "MongoDB"}
        default_dirs["STORAGE_TYPE"] = storage_dict[storage]
        if storage_dict.get(storage, 1) == "MongoDB":
            from botbase.core.drivers.red_mongo import get_config_details

            storage_details = get_config_details()
            default_dirs["STORAGE_DETAILS"] = storage_details

            if instance_data["STORAGE_TYPE"] == "JSON":
                if confirm("Would you like to import your data? (y/n) "):
                    await json_to_mongo(current_data_dir, storage_details)
        else:
            storage_details = instance_data["STORAGE_DETAILS"]
            default_dirs["STORAGE_DETAILS"] = {}
            if instance_data["STORAGE_TYPE"] == "MongoDB":
                if confirm("Would you like to import your data? (y/n) "):
                    await mongo_to_json(current_data_dir, storage_details)

    if name != selected:
        save_config(selected, {}, remove=True)
    save_config(name, default_dirs)

    print("Your basic configuration has been edited")
示例#6
0
def main():
    description = "Red - 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, sentry_log = init_loggers(cli_flags)
    red = Red(cli_flags=cli_flags, description=description, pm_help=None)
    init_global_checks(red)
    init_events(red, cli_flags)
    red.add_cog(Core(red))
    red.add_cog(CogManagerUI())
    if cli_flags.dev:
        red.add_cog(Dev())
    loop = asyncio.get_event_loop()
    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)
    if tmp_data["enable_sentry"]:
        red.enable_sentry()
    try:
        loop.run_until_complete(red.start(token, bot=not cli_flags.not_bot))
    except discord.LoginFailure:
        log.critical(
            "This token doesn't seem to be valid. If it belongs to "
            "a user account, remember that the --not-bot flag "
            "must be used. For self-bot functionalities instead, "
            "--self-bot"
        )
        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)
        sentry_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:
            red.rpc.server.close()
        except AttributeError:
            pass

        sys.exit(red._shutdown_mode.value)