(installer) use prompt-toolkit for directory picking instead of tkinter

This commit is contained in:
Eugene Brodsky 2023-01-10 16:55:57 -05:00
parent c279314cf5
commit 802b95b9d9
4 changed files with 55 additions and 12 deletions

View File

@ -24,6 +24,7 @@ opencv-python
picklescan
pillow
pip>=22
prompt-toolkit
pudb
pyreadline3
pytorch-lightning==1.7.7

View File

@ -11,7 +11,7 @@ from pathlib import Path
from tempfile import TemporaryDirectory, TemporaryFile
SUPPORTED_PYTHON = ">=3.9.0,<3.11"
INSTALLER_REQS = ["rich", "semver", "requests", "plumbum"]
INSTALLER_REQS = ["rich", "semver", "requests", "plumbum", "prompt-toolkit"]
OS = platform.uname().system
ARCH = platform.uname().machine
@ -128,6 +128,8 @@ class Installer:
Obtain the InvokeAI installation payload
"""
pass
def install(self, path: str = "~/invokeai", version: str = "latest") -> None:
"""
Install the InvokeAI application into the given runtime path

View File

@ -2,12 +2,20 @@
InvokeAI Installer
"""
import argparse
from installer import Installer
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--destination", type=str, help="Destination path for installation", default="~/invokeai")
args = parser.parse_args()
inst = Installer()
try:
inst.install()
inst.install(path=args.destination)
except KeyboardInterrupt as exc:
print("\n")
print("Ctrl-C pressed. Aborting.")

View File

@ -4,8 +4,10 @@ Installer user interaction
import platform
from pathlib import Path
from tkinter.filedialog import askdirectory
from prompt_toolkit import prompt
from prompt_toolkit.completion import PathCompleter
from prompt_toolkit.shortcuts import CompleteStyle
from rich import box, print
from rich.console import Console
from rich.panel import Panel
@ -49,26 +51,56 @@ def dest_path(init_path=None) -> Path:
:rtype: Path
"""
# TODO: feels like this could be refactored for clarity (@ebr)
dest = init_path
if dest is not None:
dest = Path(dest).expanduser().resolve()
dest_confirmed = False
while not dest_confirmed:
console.line()
if dest is not None:
dest = Path(dest).expanduser().resolve()
print(f"InvokeAI will be installed at {dest}")
dest_confirmed = Confirm.ask(f"Continue?")
print(f"InvokeAI will be installed at {dest}")
dest_confirmed = Confirm.ask(f"Is this correct?", default="y")
if not dest_confirmed:
print(f"Please select the destination directory for the installation")
resp = askdirectory(initialdir=dest)
if resp == ():
continue
dest = Path(resp).expanduser().resolve()
# needs more thought into how to handle this nicely
# so that the first selected destination continues to shows up as
# default until the user is done selecting (potentially multiple times)
old_dest = dest
path_completer = PathCompleter(
only_directories=True,
expanduser=True,
get_paths=lambda: [Path(dest).parent],
file_filter=lambda n: not n.startswith("."),
)
print(f"Please select the destination directory for the installation \[{dest}]: ")
selected = prompt(
"[Tab] to complete ⮞ ",
complete_in_thread=True,
completer=path_completer,
complete_style=CompleteStyle.READLINE_LIKE,
)
print(selected)
if Path(selected).is_absolute():
# use the absolute path directly
dest = Path(selected)
else:
# the user entered a relative path - offer to create it as a sibling to the original destination
dest = dest.parent / Path(selected)
dest = dest.expanduser().resolve()
if dest.exists():
print(f":exclamation: Directory {dest} already exists.")
dest_confirmed = Confirm.ask(
":question: Are you sure you want to (re)install in this location?", default="y"
)
if not dest_confirmed:
dest = old_dest
try:
dest.mkdir(exist_ok=True, parents=True)