Installer tweaks (#4070)

## What type of PR is this? (check all applicable)


- [ X] Optimization

## Have you discussed this change with the InvokeAI team?
- [X ] Yes
- [ ] No, because:

      
## Have you updated all relevant documentation?
- [X ] Yes
- [ ] No


## Description

This PR does two things:

1. if the environment variable INVOKEAI_ROOT is defined at install time,
the zipfile installer will default to its value when asking the user
where to install the software
2. If the user has more than 72 models of any type installed, then the
list will be truncated in the TUI and the user given a warning. Anything
larger than this number of models causes the vertical space to overflow.
The only effect of truncation is that the user will not be able to see
and delete the models that were truncated. The message advises the user
to go to the Web Model Manager interface in this event.
This commit is contained in:
Lincoln Stein 2023-07-30 08:25:11 -04:00 committed by GitHub
commit adfcb610b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 6 deletions

View File

@ -149,7 +149,7 @@ class Installer:
return venv_dir return venv_dir
def install( def install(
self, root: str = "~/invokeai-3", version: str = "latest", yes_to_all=False, find_links: Path = None self, root: str = "~/invokeai", version: str = "latest", yes_to_all=False, find_links: Path = None
) -> None: ) -> None:
""" """
Install the InvokeAI application into the given runtime path Install the InvokeAI application into the given runtime path
@ -168,7 +168,8 @@ class Installer:
messages.welcome() messages.welcome()
self.dest = Path(root).expanduser().resolve() if yes_to_all else messages.dest_path(root) default_path = os.environ.get("INVOKEAI_ROOT") or Path(root).expanduser().resolve()
self.dest = default_path if yes_to_all else messages.dest_path(root)
# create the venv for the app # create the venv for the app
self.venv = self.app_venv() self.venv = self.app_venv()

View File

@ -3,6 +3,7 @@ InvokeAI Installer
""" """
import argparse import argparse
import os
from pathlib import Path from pathlib import Path
from installer import Installer from installer import Installer
@ -15,7 +16,7 @@ if __name__ == "__main__":
dest="root", dest="root",
type=str, type=str,
help="Destination path for installation", help="Destination path for installation",
default="~/invokeai", default=os.environ.get("INVOKEAI_ROOT") or "~/invokeai",
) )
parser.add_argument( parser.add_argument(
"-y", "-y",

View File

@ -112,7 +112,7 @@ def main():
extras = get_extras() extras = get_extras()
print(f":crossed_fingers: Upgrading to [yellow]{tag if tag else release}[/yellow]") print(f":crossed_fingers: Upgrading to [yellow]{tag or release or branch}[/yellow]")
if release: if release:
cmd = f'pip install "invokeai{extras} @ {INVOKE_AI_SRC}/{release}.zip" --use-pep517 --upgrade' cmd = f'pip install "invokeai{extras} @ {INVOKE_AI_SRC}/{release}.zip" --use-pep517 --upgrade'
elif tag: elif tag:

View File

@ -58,6 +58,9 @@ logger = InvokeAILogger.getLogger()
# from https://stackoverflow.com/questions/92438/stripping-non-printable-characters-from-a-string-in-python # from https://stackoverflow.com/questions/92438/stripping-non-printable-characters-from-a-string-in-python
NOPRINT_TRANS_TABLE = {i: None for i in range(0, sys.maxunicode + 1) if not chr(i).isprintable()} NOPRINT_TRANS_TABLE = {i: None for i in range(0, sys.maxunicode + 1) if not chr(i).isprintable()}
# maximum number of installed models we can display before overflowing vertically
MAX_OTHER_MODELS = 72
def make_printable(s: str) -> str: def make_printable(s: str) -> str:
"""Replace non-printable characters in a string""" """Replace non-printable characters in a string"""
@ -102,7 +105,7 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
SingleSelectColumns, SingleSelectColumns,
values=[ values=[
"STARTER MODELS", "STARTER MODELS",
"MORE MODELS", "MAIN MODELS",
"CONTROLNETS", "CONTROLNETS",
"LORA/LYCORIS", "LORA/LYCORIS",
"TEXTUAL INVERSION", "TEXTUAL INVERSION",
@ -271,6 +274,11 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
) )
) )
truncation = False
if len(model_labels) > MAX_OTHER_MODELS:
model_labels = model_labels[0:MAX_OTHER_MODELS]
truncation = True
widgets.update( widgets.update(
models_selected=self.add_widget_intelligent( models_selected=self.add_widget_intelligent(
MultiSelectColumns, MultiSelectColumns,
@ -289,6 +297,16 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
models=model_list, models=model_list,
) )
if truncation:
widgets.update(
warning_message=self.add_widget_intelligent(
npyscreen.FixedText,
value=f"Too many models to display (max={MAX_OTHER_MODELS}). Some are not displayed.",
editable=False,
color="CAUTION",
)
)
self.nextrely += 1 self.nextrely += 1
widgets.update( widgets.update(
download_ids=self.add_widget_intelligent( download_ids=self.add_widget_intelligent(
@ -313,7 +331,7 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
widgets = self.add_model_widgets( widgets = self.add_model_widgets(
model_type=model_type, model_type=model_type,
window_width=window_width, window_width=window_width,
install_prompt=f"Additional {model_type.value.title()} models already installed.", install_prompt=f"Installed {model_type.value.title()} models. Unchecked models in the InvokeAI root directory will be deleted. Enter URLs, paths or repo_ids to import.",
**kwargs, **kwargs,
) )