mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[Core] Add redbot --edit cli flag (replacement for [p]set owner&token) (#3060)
* feat(core): add `redbot --edit` cli flag * chore(changelog): add towncrier entries * refactor(core): clean up `redbot --edit`, few fixes * fix(core): prepare for review * chore(changelog): update towncrier entry to use double ticks :p * style(black): ugh, Sinbad's git hook isn't perfect (using worktrees) * fix: Address Flame's first review
This commit is contained in:
parent
078210b54c
commit
1651de1305
1
changelog.d/3060.enhance.rst
Normal file
1
changelog.d/3060.enhance.rst
Normal file
@ -0,0 +1 @@
|
|||||||
|
All ``y/n`` confirmations in cli commands are now unified.
|
||||||
1
changelog.d/3060.feature.rst
Normal file
1
changelog.d/3060.feature.rst
Normal file
@ -0,0 +1 @@
|
|||||||
|
Added ``redbot --edit`` cli flag that can be used to edit instance name, token, owner and datapath.
|
||||||
1
changelog.d/3060.fix.rst
Normal file
1
changelog.d/3060.fix.rst
Normal file
@ -0,0 +1 @@
|
|||||||
|
Arguments ``--co-owner`` and ``--load-cogs`` now properly require at least one argument to be passed.
|
||||||
@ -6,7 +6,10 @@ import asyncio
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
|
from copy import deepcopy
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
@ -23,6 +26,7 @@ from redbot.core.cog_manager import CogManagerUI
|
|||||||
from redbot.core.global_checks import init_global_checks
|
from redbot.core.global_checks import init_global_checks
|
||||||
from redbot.core.events import init_events
|
from redbot.core.events import init_events
|
||||||
from redbot.core.cli import interactive_config, confirm, parse_cli_flags
|
from redbot.core.cli import interactive_config, confirm, parse_cli_flags
|
||||||
|
from redbot.setup import get_data_dir, get_name, save_config
|
||||||
from redbot.core.core_commands import Core
|
from redbot.core.core_commands import Core
|
||||||
from redbot.core.dev_commands import Dev
|
from redbot.core.dev_commands import Dev
|
||||||
from redbot.core import __version__, modlog, bank, data_manager, drivers
|
from redbot.core import __version__, modlog, bank, data_manager, drivers
|
||||||
@ -48,6 +52,12 @@ async def _get_prefix_and_token(red, indict):
|
|||||||
indict["prefix"] = await red._config.prefix()
|
indict["prefix"] = await red._config.prefix()
|
||||||
|
|
||||||
|
|
||||||
|
def _get_instance_names():
|
||||||
|
with data_manager.config_file.open(encoding="utf-8") as fs:
|
||||||
|
data = json.load(fs)
|
||||||
|
return sorted(data.keys())
|
||||||
|
|
||||||
|
|
||||||
def list_instances():
|
def list_instances():
|
||||||
if not data_manager.config_file.exists():
|
if not data_manager.config_file.exists():
|
||||||
print(
|
print(
|
||||||
@ -56,15 +66,157 @@ def list_instances():
|
|||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
with data_manager.config_file.open(encoding="utf-8") as fs:
|
|
||||||
data = json.load(fs)
|
|
||||||
text = "Configured Instances:\n\n"
|
text = "Configured Instances:\n\n"
|
||||||
for instance_name in sorted(data.keys()):
|
for instance_name in _get_instance_names():
|
||||||
text += "{}\n".format(instance_name)
|
text += "{}\n".format(instance_name)
|
||||||
print(text)
|
print(text)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
def edit_instance(red, cli_flags):
|
||||||
|
no_prompt = cli_flags.no_prompt
|
||||||
|
token = cli_flags.token
|
||||||
|
owner = cli_flags.owner
|
||||||
|
old_name = cli_flags.instance_name
|
||||||
|
new_name = cli_flags.edit_instance_name
|
||||||
|
data_path = cli_flags.edit_data_path
|
||||||
|
copy_data = cli_flags.copy_data
|
||||||
|
confirm_overwrite = cli_flags.overwrite_existing_instance
|
||||||
|
|
||||||
|
if data_path is None and copy_data:
|
||||||
|
print("--copy-data can't be used without --edit-data-path argument")
|
||||||
|
sys.exit(1)
|
||||||
|
if new_name is None and confirm_overwrite:
|
||||||
|
print("--overwrite-existing-instance can't be used without --edit-instance-name argument")
|
||||||
|
sys.exit(1)
|
||||||
|
if no_prompt and all(to_change is None for to_change in (token, owner, new_name, data_path)):
|
||||||
|
print(
|
||||||
|
"No arguments to edit were provided. Available arguments (check help for more "
|
||||||
|
"information): --edit-instance-name, --edit-data-path, --copy-data, --owner, --token"
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
_edit_token(red, token, no_prompt)
|
||||||
|
_edit_owner(red, owner, no_prompt)
|
||||||
|
|
||||||
|
data = deepcopy(data_manager.basic_config)
|
||||||
|
name = _edit_instance_name(old_name, new_name, confirm_overwrite, no_prompt)
|
||||||
|
_edit_data_path(data, data_path, copy_data, no_prompt)
|
||||||
|
|
||||||
|
save_config(name, data)
|
||||||
|
if old_name != name:
|
||||||
|
save_config(old_name, {}, remove=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _edit_token(red, token, no_prompt):
|
||||||
|
if token:
|
||||||
|
if not len(token) >= 50:
|
||||||
|
print(
|
||||||
|
"The provided token doesn't look a valid Discord bot token."
|
||||||
|
" Instance's token will remain unchanged.\n"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
red.loop.run_until_complete(red._config.token.set(token))
|
||||||
|
elif not no_prompt and confirm("Would you like to change instance's token?", default=False):
|
||||||
|
interactive_config(red, False, True, print_header=False)
|
||||||
|
print("Token updated.\n")
|
||||||
|
|
||||||
|
|
||||||
|
def _edit_owner(red, owner, no_prompt):
|
||||||
|
if owner:
|
||||||
|
if not (15 <= len(str(owner)) <= 21):
|
||||||
|
print(
|
||||||
|
"The provided owner id doesn't look like a valid Discord user id."
|
||||||
|
" Instance's owner will remain unchanged."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
red.loop.run_until_complete(red._config.owner.set(owner))
|
||||||
|
elif not no_prompt and confirm("Would you like to change instance's owner?", default=False):
|
||||||
|
print(
|
||||||
|
"Remember:\n"
|
||||||
|
"ONLY the person who is hosting Red should be owner."
|
||||||
|
" This has SERIOUS security implications."
|
||||||
|
" The owner can access any data that is present on the host system.\n"
|
||||||
|
)
|
||||||
|
if confirm("Are you sure you want to change instance's owner?", default=False):
|
||||||
|
print("Please enter a Discord user id for new owner:")
|
||||||
|
while True:
|
||||||
|
owner_id = input("> ").strip()
|
||||||
|
if not (15 <= len(owner_id) <= 21 and owner_id.isdecimal()):
|
||||||
|
print("That doesn't look like a valid Discord user id.")
|
||||||
|
continue
|
||||||
|
owner_id = int(owner_id)
|
||||||
|
red.loop.run_until_complete(red._config.owner.set(owner_id))
|
||||||
|
print("Owner updated.")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("Instance's owner will remain unchanged.")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def _edit_instance_name(old_name, new_name, confirm_overwrite, no_prompt):
|
||||||
|
if new_name:
|
||||||
|
name = new_name
|
||||||
|
if name in _get_instance_names() and not confirm_overwrite:
|
||||||
|
name = old_name
|
||||||
|
print(
|
||||||
|
"An instance with this name already exists.\n"
|
||||||
|
"If you want to remove the existing instance and replace it with this one,"
|
||||||
|
" run this command with --overwrite-existing-instance flag."
|
||||||
|
)
|
||||||
|
elif not no_prompt and confirm("Would you like to change the instance name?", default=False):
|
||||||
|
name = get_name()
|
||||||
|
if name in _get_instance_names():
|
||||||
|
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 with this instance name?",
|
||||||
|
default=False,
|
||||||
|
):
|
||||||
|
print("Instance name will remain unchanged.")
|
||||||
|
name = old_name
|
||||||
|
else:
|
||||||
|
print("Instance name updated.")
|
||||||
|
print()
|
||||||
|
else:
|
||||||
|
name = old_name
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def _edit_data_path(data, data_path, copy_data, no_prompt):
|
||||||
|
# This modifies the passed dict.
|
||||||
|
if data_path:
|
||||||
|
data["DATA_PATH"] = data_path
|
||||||
|
if copy_data and not _copy_data(data):
|
||||||
|
print("Can't copy data to non-empty location. Data location will remain unchanged.")
|
||||||
|
data["DATA_PATH"] = data_manager.basic_config["DATA_PATH"]
|
||||||
|
elif not no_prompt and confirm("Would you like to change the data location?", default=False):
|
||||||
|
data["DATA_PATH"] = get_data_dir()
|
||||||
|
if confirm(
|
||||||
|
"Do you want to copy the data from old location?", default=True
|
||||||
|
) and not _copy_data(data):
|
||||||
|
print("Can't copy the data to non-empty location.")
|
||||||
|
if not confirm("Do you still want to use the new data location?"):
|
||||||
|
data["DATA_PATH"] = data_manager.basic_config["DATA_PATH"]
|
||||||
|
print("Data location will remain unchanged.")
|
||||||
|
else:
|
||||||
|
print("Data location updated.")
|
||||||
|
|
||||||
|
|
||||||
|
def _copy_data(data):
|
||||||
|
if Path(data["DATA_PATH"]).exists():
|
||||||
|
if any(os.scandir(data["DATA_PATH"])):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# this is needed because copytree doesn't work when destination folder exists
|
||||||
|
# Python 3.8 has `dirs_exist_ok` option for that
|
||||||
|
os.rmdir(data["DATA_PATH"])
|
||||||
|
shutil.copytree(data_manager.basic_config["DATA_PATH"], data["DATA_PATH"])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def sigterm_handler(red, log):
|
async def sigterm_handler(red, log):
|
||||||
log.info("SIGTERM received. Quitting...")
|
log.info("SIGTERM received. Quitting...")
|
||||||
await red.shutdown(restart=False)
|
await red.shutdown(restart=False)
|
||||||
@ -79,7 +231,7 @@ def main():
|
|||||||
print(description)
|
print(description)
|
||||||
print("Current Version: {}".format(__version__))
|
print("Current Version: {}".format(__version__))
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
elif not cli_flags.instance_name and not cli_flags.no_instance:
|
elif not cli_flags.instance_name and (not cli_flags.no_instance or cli_flags.edit):
|
||||||
print("Error: No instance name was provided!")
|
print("Error: No instance name was provided!")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if cli_flags.no_instance:
|
if cli_flags.no_instance:
|
||||||
@ -108,6 +260,16 @@ def main():
|
|||||||
cli_flags=cli_flags, description=description, dm_help=None, fetch_offline_members=True
|
cli_flags=cli_flags, description=description, dm_help=None, fetch_offline_members=True
|
||||||
)
|
)
|
||||||
loop.run_until_complete(red._maybe_update_config())
|
loop.run_until_complete(red._maybe_update_config())
|
||||||
|
|
||||||
|
if cli_flags.edit:
|
||||||
|
try:
|
||||||
|
edit_instance(red, cli_flags)
|
||||||
|
except (KeyboardInterrupt, EOFError):
|
||||||
|
print("Aborted!")
|
||||||
|
finally:
|
||||||
|
loop.run_until_complete(driver_cls.teardown())
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
init_global_checks(red)
|
init_global_checks(red)
|
||||||
init_events(red, cli_flags)
|
init_events(red, cli_flags)
|
||||||
|
|
||||||
@ -154,8 +316,7 @@ def main():
|
|||||||
log.critical("This token doesn't seem to be valid.")
|
log.critical("This token doesn't seem to be valid.")
|
||||||
db_token = loop.run_until_complete(red._config.token())
|
db_token = loop.run_until_complete(red._config.token())
|
||||||
if db_token and not cli_flags.no_prompt:
|
if db_token and not cli_flags.no_prompt:
|
||||||
print("\nDo you want to reset the token? (y/n)")
|
if confirm("\nDo you want to reset the token?"):
|
||||||
if confirm("> "):
|
|
||||||
loop.run_until_complete(red._config.token.set(""))
|
loop.run_until_complete(red._config.token.set(""))
|
||||||
print("Token has been reset.")
|
print("Token has been reset.")
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|||||||
@ -1,16 +1,41 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
def confirm(m=""):
|
def confirm(text: str, default: Optional[bool] = None) -> bool:
|
||||||
return input(m).lower().strip() in ("y", "yes")
|
if default is None:
|
||||||
|
options = "y/n"
|
||||||
|
elif default is True:
|
||||||
|
options = "Y/n"
|
||||||
|
elif default is False:
|
||||||
|
options = "y/N"
|
||||||
|
else:
|
||||||
|
raise TypeError(f"expected bool, not {type(default)}")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
value = input(f"{text}: [{options}] ").lower().strip()
|
||||||
|
except (KeyboardInterrupt, EOFError):
|
||||||
|
print("\nAborted!")
|
||||||
|
sys.exit(1)
|
||||||
|
if value in ("y", "yes"):
|
||||||
|
return True
|
||||||
|
if value in ("n", "no"):
|
||||||
|
return False
|
||||||
|
if value == "":
|
||||||
|
if default is not None:
|
||||||
|
return default
|
||||||
|
print("Error: invalid input")
|
||||||
|
|
||||||
|
|
||||||
def interactive_config(red, token_set, prefix_set):
|
def interactive_config(red, token_set, prefix_set, *, print_header=True):
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
token = ""
|
token = ""
|
||||||
|
|
||||||
|
if print_header:
|
||||||
print("Red - Discord Bot | Configuration process\n")
|
print("Red - Discord Bot | Configuration process\n")
|
||||||
|
|
||||||
if not token_set:
|
if not token_set:
|
||||||
@ -35,8 +60,7 @@ def interactive_config(red, token_set, prefix_set):
|
|||||||
while not prefix:
|
while not prefix:
|
||||||
prefix = input("Prefix> ")
|
prefix = input("Prefix> ")
|
||||||
if len(prefix) > 10:
|
if len(prefix) > 10:
|
||||||
print("Your prefix seems overly long. Are you sure that it's correct? (y/n)")
|
if not confirm("Your prefix seems overly long. Are you sure that it's correct?"):
|
||||||
if not confirm("> "):
|
|
||||||
prefix = ""
|
prefix = ""
|
||||||
if prefix:
|
if prefix:
|
||||||
loop.run_until_complete(red._config.prefix.set([prefix]))
|
loop.run_until_complete(red._config.prefix.set([prefix]))
|
||||||
@ -54,6 +78,37 @@ def parse_cli_flags(args):
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="List all instance names setup with 'redbot-setup'",
|
help="List all instance names setup with 'redbot-setup'",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--edit",
|
||||||
|
action="store_true",
|
||||||
|
help="Edit the instance. This can be done without console interaction "
|
||||||
|
"by passing --no-prompt and arguments that you want to change (available arguments: "
|
||||||
|
"--edit-instance-name, --edit-data-path, --copy-data, --owner, --token).",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--edit-instance-name",
|
||||||
|
type=str,
|
||||||
|
help="New name for the instance. This argument only works with --edit argument passed.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--overwrite-existing-instance",
|
||||||
|
action="store_true",
|
||||||
|
help="Confirm overwriting of existing instance when changing name."
|
||||||
|
" This argument only works with --edit argument passed.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--edit-data-path",
|
||||||
|
type=str,
|
||||||
|
help=(
|
||||||
|
"New data path for the instance. This argument only works with --edit argument passed."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--copy-data",
|
||||||
|
action="store_true",
|
||||||
|
help="Copy data from old location. This argument only works "
|
||||||
|
"with --edit and --edit-data-path arguments passed.",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--owner",
|
"--owner",
|
||||||
type=int,
|
type=int,
|
||||||
@ -65,7 +120,7 @@ def parse_cli_flags(args):
|
|||||||
"--co-owner",
|
"--co-owner",
|
||||||
type=int,
|
type=int,
|
||||||
default=[],
|
default=[],
|
||||||
nargs="*",
|
nargs="+",
|
||||||
help="ID of a co-owner. Only people who have access "
|
help="ID of a co-owner. Only people who have access "
|
||||||
"to the system that is hosting Red should be "
|
"to the system that is hosting Red should be "
|
||||||
"co-owners, as this gives them complete access "
|
"co-owners, as this gives them complete access "
|
||||||
@ -87,7 +142,7 @@ def parse_cli_flags(args):
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--load-cogs",
|
"--load-cogs",
|
||||||
type=str,
|
type=str,
|
||||||
nargs="*",
|
nargs="+",
|
||||||
help="Force loading specified cogs from the installed packages. "
|
help="Force loading specified cogs from the installed packages. "
|
||||||
"Can be used with the --no-cogs flag to load these cogs exclusively.",
|
"Can be used with the --no-cogs flag to load these cogs exclusively.",
|
||||||
)
|
)
|
||||||
|
|||||||
@ -264,7 +264,7 @@ async def reset_red():
|
|||||||
print("Cancelling...")
|
print("Cancelling...")
|
||||||
return
|
return
|
||||||
|
|
||||||
if confirm("\nDo you want to create a backup for an instance? (y/n) "):
|
if confirm("\nDo you want to create a backup for an instance?"):
|
||||||
for index, instance in instances.items():
|
for index, instance in instances.items():
|
||||||
print("\nRemoving {}...".format(index))
|
print("\nRemoving {}...".format(index))
|
||||||
await create_backup(index)
|
await create_backup(index)
|
||||||
|
|||||||
@ -53,16 +53,6 @@ def save_config(name, data, remove=False):
|
|||||||
if remove and name in _config:
|
if remove and name in _config:
|
||||||
_config.pop(name)
|
_config.pop(name)
|
||||||
else:
|
else:
|
||||||
if name in _config:
|
|
||||||
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)
|
|
||||||
_config[name] = data
|
_config[name] = data
|
||||||
|
|
||||||
with config_file.open("w", encoding="utf-8") as fs:
|
with config_file.open("w", encoding="utf-8") as fs:
|
||||||
@ -73,12 +63,9 @@ def get_data_dir():
|
|||||||
default_data_dir = Path(appdir.user_data_dir)
|
default_data_dir = Path(appdir.user_data_dir)
|
||||||
|
|
||||||
print(
|
print(
|
||||||
"Hello! Before we begin the full configuration process we need to"
|
"We've attempted to figure out a sane default data location which is printed below."
|
||||||
" gather some initial information about where you'd like us"
|
" If you don't want to change this default please press [ENTER],"
|
||||||
" to store your bot's data. We've attempted to figure out a"
|
" otherwise input your desired data location."
|
||||||
" 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()
|
||||||
print("Default: {}".format(default_data_dir))
|
print("Default: {}".format(default_data_dir))
|
||||||
@ -104,7 +91,7 @@ def get_data_dir():
|
|||||||
if not click.confirm("Please confirm", default=True):
|
if not click.confirm("Please confirm", default=True):
|
||||||
print("Please start the process over.")
|
print("Please start the process over.")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
return default_data_dir
|
return str(default_data_dir.resolve())
|
||||||
|
|
||||||
|
|
||||||
def get_storage_type():
|
def get_storage_type():
|
||||||
@ -147,10 +134,15 @@ def basic_setup():
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
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."
|
||||||
|
)
|
||||||
default_data_dir = get_data_dir()
|
default_data_dir = get_data_dir()
|
||||||
|
|
||||||
default_dirs = deepcopy(data_manager.basic_config_default)
|
default_dirs = deepcopy(data_manager.basic_config_default)
|
||||||
default_dirs["DATA_PATH"] = str(default_data_dir.resolve())
|
default_dirs["DATA_PATH"] = default_data_dir
|
||||||
|
|
||||||
storage = get_storage_type()
|
storage = get_storage_type()
|
||||||
|
|
||||||
@ -161,6 +153,14 @@ def basic_setup():
|
|||||||
default_dirs["STORAGE_DETAILS"] = driver_cls.get_config_details()
|
default_dirs["STORAGE_DETAILS"] = driver_cls.get_config_details()
|
||||||
|
|
||||||
name = get_name()
|
name = get_name()
|
||||||
|
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)
|
save_config(name, default_dirs)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
@ -236,53 +236,6 @@ async def mongov1_to_json() -> Dict[str, Any]:
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
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(data_manager.basic_config_default)
|
|
||||||
|
|
||||||
current_data_dir = Path(_instance_data["DATA_PATH"])
|
|
||||||
print("You have selected '{}' as the instance to modify.".format(selected))
|
|
||||||
if not click.confirm("Please confirm", default=True):
|
|
||||||
print("Ok, we will not continue then.")
|
|
||||||
return
|
|
||||||
|
|
||||||
print("Ok, we will continue on.")
|
|
||||||
print()
|
|
||||||
if click.confirm("Would you like to change the instance name?", default=False):
|
|
||||||
name = get_name()
|
|
||||||
else:
|
|
||||||
name = selected
|
|
||||||
|
|
||||||
if click.confirm("Would you like to change the data location?", default=False):
|
|
||||||
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 name != selected:
|
|
||||||
save_config(selected, {}, remove=True)
|
|
||||||
save_config(name, default_dirs)
|
|
||||||
|
|
||||||
print("Your basic configuration has been edited")
|
|
||||||
|
|
||||||
|
|
||||||
async def create_backup(instance: str) -> None:
|
async def create_backup(instance: str) -> None:
|
||||||
data_manager.load_basic_configuration(instance)
|
data_manager.load_basic_configuration(instance)
|
||||||
backend_type = get_current_backend(instance)
|
backend_type = get_current_backend(instance)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user