diff --git a/installer/lib/installer.py b/installer/lib/installer.py index 8ab512eee8..42079cd90c 100644 --- a/installer/lib/installer.py +++ b/installer/lib/installer.py @@ -456,7 +456,7 @@ def get_torch_source() -> (Union[str, None],str): optional_modules = None if OS == "Linux": if device == "rocm": - url = "https://download.pytorch.org/whl/rocm5.2" + url = "https://download.pytorch.org/whl/rocm5.4.2" elif device == "cpu": url = "https://download.pytorch.org/whl/cpu" diff --git a/invokeai/app/api/routers/images.py b/invokeai/app/api/routers/images.py index 55f1a2f036..453c114a28 100644 --- a/invokeai/app/api/routers/images.py +++ b/invokeai/app/api/routers/images.py @@ -23,6 +23,16 @@ async def get_image( filename = ApiDependencies.invoker.services.images.get_path(image_type, image_name) return FileResponse(filename) +@images_router.get("/{image_type}/thumbnails/{image_name}", operation_id="get_thumbnail") +async def get_thumbnail( + image_type: ImageType = Path(description="The type of image to get"), + image_name: str = Path(description="The name of the image to get"), +): + """Gets a thumbnail""" + # TODO: This is not really secure at all. At least make sure only output results are served + filename = ApiDependencies.invoker.services.images.get_path(image_type, 'thumbnails/' + image_name) + return FileResponse(filename) + @images_router.post( "/uploads/", diff --git a/invokeai/app/api/routers/sessions.py b/invokeai/app/api/routers/sessions.py index dc8fa03fc4..0316398088 100644 --- a/invokeai/app/api/routers/sessions.py +++ b/invokeai/app/api/routers/sessions.py @@ -51,7 +51,7 @@ async def list_sessions( query: str = Query(default="", description="The query string to search for"), ) -> PaginatedResults[GraphExecutionState]: """Gets a list of sessions, optionally searching""" - if filter == "": + if query == "": result = ApiDependencies.invoker.services.graph_execution_manager.list( page, per_page ) diff --git a/invokeai/app/services/image_storage.py b/invokeai/app/services/image_storage.py index ad0ff23f14..c80a4bfb31 100644 --- a/invokeai/app/services/image_storage.py +++ b/invokeai/app/services/image_storage.py @@ -9,6 +9,7 @@ from queue import Queue from typing import Dict from PIL.Image import Image +from invokeai.app.util.save_thumbnail import save_thumbnail from invokeai.backend.image_util import PngWriter @@ -66,6 +67,9 @@ class DiskImageStorage(ImageStorageBase): Path(os.path.join(output_folder, image_type)).mkdir( parents=True, exist_ok=True ) + Path(os.path.join(output_folder, image_type, "thumbnails")).mkdir( + parents=True, exist_ok=True + ) def get(self, image_type: ImageType, image_name: str) -> Image: image_path = self.get_path(image_type, image_name) @@ -87,7 +91,11 @@ class DiskImageStorage(ImageStorageBase): self.__pngWriter.save_image_and_prompt_to_png( image, "", image_subpath, None ) # TODO: just pass full path to png writer - + save_thumbnail( + image=image, + filename=image_name, + path=os.path.join(self.__output_folder, image_type, "thumbnails"), + ) image_path = self.get_path(image_type, image_name) self.__set_cache(image_path, image) diff --git a/invokeai/app/services/sqlite.py b/invokeai/app/services/sqlite.py index e5bba4ad31..fd089014bb 100644 --- a/invokeai/app/services/sqlite.py +++ b/invokeai/app/services/sqlite.py @@ -59,6 +59,7 @@ class SqliteItemStorage(ItemStorageABC, Generic[T]): f"""INSERT OR REPLACE INTO {self._table_name} (item) VALUES (?);""", (item.json(),), ) + self._conn.commit() finally: self._lock.release() self._on_changed(item) @@ -84,6 +85,7 @@ class SqliteItemStorage(ItemStorageABC, Generic[T]): self._cursor.execute( f"""DELETE FROM {self._table_name} WHERE id = ?;""", (str(id),) ) + self._conn.commit() finally: self._lock.release() self._on_deleted(id) diff --git a/invokeai/app/util/save_thumbnail.py b/invokeai/app/util/save_thumbnail.py new file mode 100644 index 0000000000..86fdbe7ef6 --- /dev/null +++ b/invokeai/app/util/save_thumbnail.py @@ -0,0 +1,25 @@ +import os +from PIL import Image + + +def save_thumbnail( + image: Image.Image, + filename: str, + path: str, + size: int = 256, +) -> str: + """ + Saves a thumbnail of an image, returning its path. + """ + base_filename = os.path.splitext(filename)[0] + thumbnail_path = os.path.join(path, base_filename + ".webp") + + if os.path.exists(thumbnail_path): + return thumbnail_path + + image_copy = image.copy() + image_copy.thumbnail(size=(size, size)) + + image_copy.save(thumbnail_path, "WEBP") + + return thumbnail_path diff --git a/pyproject.toml b/pyproject.toml index 3e05263724..224f16c42e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ dependencies = [ "albumentations", "click", "clip_anytorch", # replacing "clip @ https://github.com/openai/CLIP/archive/eaa22acb90a5876642d0507623e859909230a52d.zip", - "compel==1.0.4", + "compel==1.0.5", "datasets", "diffusers[torch]~=0.14", "dnspython==2.2.1",