mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
(installer) use prompt-toolkit for directory picking instead of tkinter
This commit is contained in:
parent
c279314cf5
commit
802b95b9d9
@ -24,6 +24,7 @@ opencv-python
|
|||||||
picklescan
|
picklescan
|
||||||
pillow
|
pillow
|
||||||
pip>=22
|
pip>=22
|
||||||
|
prompt-toolkit
|
||||||
pudb
|
pudb
|
||||||
pyreadline3
|
pyreadline3
|
||||||
pytorch-lightning==1.7.7
|
pytorch-lightning==1.7.7
|
||||||
|
@ -11,7 +11,7 @@ from pathlib import Path
|
|||||||
from tempfile import TemporaryDirectory, TemporaryFile
|
from tempfile import TemporaryDirectory, TemporaryFile
|
||||||
|
|
||||||
SUPPORTED_PYTHON = ">=3.9.0,<3.11"
|
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
|
OS = platform.uname().system
|
||||||
ARCH = platform.uname().machine
|
ARCH = platform.uname().machine
|
||||||
@ -128,6 +128,8 @@ class Installer:
|
|||||||
Obtain the InvokeAI installation payload
|
Obtain the InvokeAI installation payload
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
def install(self, path: str = "~/invokeai", version: str = "latest") -> None:
|
def install(self, path: str = "~/invokeai", version: str = "latest") -> None:
|
||||||
"""
|
"""
|
||||||
Install the InvokeAI application into the given runtime path
|
Install the InvokeAI application into the given runtime path
|
||||||
|
@ -2,12 +2,20 @@
|
|||||||
InvokeAI Installer
|
InvokeAI Installer
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
from installer import Installer
|
from installer import Installer
|
||||||
|
|
||||||
if __name__ == "__main__":
|
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()
|
inst = Installer()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
inst.install()
|
inst.install(path=args.destination)
|
||||||
except KeyboardInterrupt as exc:
|
except KeyboardInterrupt as exc:
|
||||||
print("\n")
|
print("\n")
|
||||||
print("Ctrl-C pressed. Aborting.")
|
print("Ctrl-C pressed. Aborting.")
|
||||||
|
@ -4,8 +4,10 @@ Installer user interaction
|
|||||||
|
|
||||||
import platform
|
import platform
|
||||||
from pathlib import Path
|
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 import box, print
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
@ -49,26 +51,56 @@ def dest_path(init_path=None) -> Path:
|
|||||||
:rtype: Path
|
:rtype: Path
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# TODO: feels like this could be refactored for clarity (@ebr)
|
||||||
|
|
||||||
dest = init_path
|
dest = init_path
|
||||||
|
if dest is not None:
|
||||||
|
dest = Path(dest).expanduser().resolve()
|
||||||
|
|
||||||
dest_confirmed = False
|
dest_confirmed = False
|
||||||
|
|
||||||
while not dest_confirmed:
|
while not dest_confirmed:
|
||||||
console.line()
|
console.line()
|
||||||
if dest is not None:
|
|
||||||
dest = Path(dest).expanduser().resolve()
|
|
||||||
print(f"InvokeAI will be installed at {dest}")
|
print(f"InvokeAI will be installed at {dest}")
|
||||||
dest_confirmed = Confirm.ask(f"Continue?")
|
dest_confirmed = Confirm.ask(f"Is this correct?", default="y")
|
||||||
|
|
||||||
if not dest_confirmed:
|
if not dest_confirmed:
|
||||||
print(f"Please select the destination directory for the installation")
|
|
||||||
resp = askdirectory(initialdir=dest)
|
# needs more thought into how to handle this nicely
|
||||||
if resp == ():
|
# so that the first selected destination continues to shows up as
|
||||||
continue
|
# default until the user is done selecting (potentially multiple times)
|
||||||
dest = Path(resp).expanduser().resolve()
|
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():
|
if dest.exists():
|
||||||
print(f":exclamation: Directory {dest} already exists.")
|
print(f":exclamation: Directory {dest} already exists.")
|
||||||
dest_confirmed = Confirm.ask(
|
dest_confirmed = Confirm.ask(
|
||||||
":question: Are you sure you want to (re)install in this location?", default="y"
|
":question: Are you sure you want to (re)install in this location?", default="y"
|
||||||
)
|
)
|
||||||
|
if not dest_confirmed:
|
||||||
|
dest = old_dest
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dest.mkdir(exist_ok=True, parents=True)
|
dest.mkdir(exist_ok=True, parents=True)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user