mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
cleanup
This commit is contained in:
parent
aa88fadc30
commit
8df02623f2
@ -3,6 +3,7 @@ from pathlib import Path
|
||||
|
||||
from PIL.Image import Image as PILImageType
|
||||
|
||||
|
||||
class ModelImagesBase(ABC):
|
||||
"""Low-level service responsible for storing and retrieving image files."""
|
||||
|
||||
|
@ -9,7 +9,12 @@ from invokeai.app.services.invoker import Invoker
|
||||
from invokeai.app.util.thumbnails import make_thumbnail
|
||||
|
||||
from .model_images_base import ModelImagesBase
|
||||
from .model_images_common import ModelImageFileDeleteException, ModelImageFileNotFoundException, ModelImageFileSaveException
|
||||
from .model_images_common import (
|
||||
ModelImageFileDeleteException,
|
||||
ModelImageFileNotFoundException,
|
||||
ModelImageFileSaveException,
|
||||
)
|
||||
|
||||
|
||||
class ModelImagesService(ModelImagesBase):
|
||||
"""Stores images on disk"""
|
||||
@ -29,7 +34,7 @@ class ModelImagesService(ModelImagesBase):
|
||||
def get(self, model_key: str) -> PILImageType:
|
||||
try:
|
||||
path = self.get_path(model_key)
|
||||
|
||||
|
||||
if not self.validate_path(path):
|
||||
raise ModelImageFileNotFoundException
|
||||
|
||||
@ -57,14 +62,14 @@ class ModelImagesService(ModelImagesBase):
|
||||
path = self.__model_images_folder / (model_key + '.webp')
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def get_url(self, model_key: str) -> str | None:
|
||||
path = self.get_path(model_key)
|
||||
if not self.validate_path(path):
|
||||
return
|
||||
|
||||
|
||||
return self.__invoker.services.urls.get_model_image_url(model_key)
|
||||
|
||||
|
||||
def delete(self, model_key: str) -> None:
|
||||
try:
|
||||
path = self.get_path(model_key)
|
||||
@ -76,7 +81,7 @@ class ModelImagesService(ModelImagesBase):
|
||||
|
||||
except Exception as e:
|
||||
raise ModelImageFileDeleteException from e
|
||||
|
||||
|
||||
def validate_path(self, path: Union[str, Path]) -> bool:
|
||||
"""Validates the path given for an image."""
|
||||
path = path if isinstance(path, Path) else Path(path)
|
||||
|
@ -18,4 +18,4 @@ class LocalUrlService(UrlServiceBase):
|
||||
return f"{self._base_url}/images/i/{image_basename}/full"
|
||||
|
||||
def get_model_image_url(self, model_key: str) -> str:
|
||||
return f"{self._base_url_v2}/models/i/{model_key}/image"
|
||||
return f"{self._base_url_v2}/models/i/{model_key}/image"
|
||||
|
@ -858,7 +858,7 @@
|
||||
"triggerPhrases": "Trigger Phrases",
|
||||
"typePhraseHere": "Type phrase here",
|
||||
"upcastAttention": "Upcast Attention",
|
||||
"uploadImage":"Upload Image",
|
||||
"uploadImage": "Upload Image",
|
||||
"updateModel": "Update Model",
|
||||
"useCustomConfig": "Use Custom Config",
|
||||
"useDefaultSettings": "Use Default Settings",
|
||||
|
@ -1,28 +1,27 @@
|
||||
import { Box, Image } from '@invoke-ai/ui-library';
|
||||
import { typedMemo } from 'common/util/typedMemo';
|
||||
|
||||
import { useGetModelConfigQuery } from 'services/api/endpoints/models';
|
||||
|
||||
type Props = {
|
||||
image_url?: string;
|
||||
};
|
||||
|
||||
const ModelImage = ({ image_url }: Props) => {
|
||||
if (!image_url) {
|
||||
return <Box height="50px" minWidth="50px" />;
|
||||
}
|
||||
|
||||
if (!image_url) return <Box height="50px" minWidth="50px" />;
|
||||
|
||||
return (
|
||||
<Image
|
||||
src={image_url}
|
||||
objectFit="cover"
|
||||
objectPosition="50% 50%"
|
||||
height="50px"
|
||||
width="50px"
|
||||
minHeight="50px"
|
||||
minWidth="50px"
|
||||
borderRadius="base"
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<Image
|
||||
src={image_url}
|
||||
objectFit="cover"
|
||||
objectPosition="50% 50%"
|
||||
height="50px"
|
||||
width="50px"
|
||||
minHeight="50px"
|
||||
minWidth="50px"
|
||||
borderRadius="base"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default typedMemo(ModelImage);
|
||||
|
@ -21,6 +21,7 @@ import { IoWarning } from 'react-icons/io5';
|
||||
import { PiTrashSimpleBold } from 'react-icons/pi';
|
||||
import { useDeleteModelsMutation } from 'services/api/endpoints/models';
|
||||
import type { AnyModelConfig } from 'services/api/types';
|
||||
|
||||
import ModelImage from './ModelImage';
|
||||
|
||||
type ModelListItemProps = {
|
||||
|
@ -1,24 +1,22 @@
|
||||
import { Box, IconButton, Image } from '@invoke-ai/ui-library';
|
||||
import { typedMemo } from 'common/util/typedMemo';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { Box, Button, IconButton, Image } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
|
||||
import { Button } from '@invoke-ai/ui-library';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
import { PiArrowCounterClockwiseBold, PiUploadSimpleBold } from 'react-icons/pi';
|
||||
import { useUpdateModelImageMutation, useDeleteModelImageMutation } from 'services/api/endpoints/models';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { typedMemo } from 'common/util/typedMemo';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiArrowCounterClockwiseBold, PiUploadSimpleBold } from 'react-icons/pi';
|
||||
import { useDeleteModelImageMutation, useUpdateModelImageMutation } from 'services/api/endpoints/models';
|
||||
|
||||
type Props = {
|
||||
model_key: string | null;
|
||||
model_image: string | null;
|
||||
};
|
||||
|
||||
const ModelImageUpload = ({ model_key, model_image }: Props) => {
|
||||
model_key: string | null;
|
||||
model_image?: string | null;
|
||||
};
|
||||
|
||||
const ModelImageUpload = ({ model_key, model_image }: Props) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const [image, setImage] = useState<string | null>(model_image);
|
||||
const [image, setImage] = useState<string | null>(model_image || null);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [updateModelImage] = useUpdateModelImageMutation();
|
||||
@ -28,19 +26,50 @@ type Props = {
|
||||
(files: File[]) => {
|
||||
const file = files[0];
|
||||
|
||||
if (!file) {
|
||||
if (!file || !model_key) {
|
||||
return;
|
||||
}
|
||||
|
||||
setImage(URL.createObjectURL(file));
|
||||
|
||||
updateModelImage({ key: model_key, image: file })
|
||||
.unwrap()
|
||||
.then(() => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageUpdated'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
})
|
||||
.catch((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageUpdateFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
},
|
||||
[dispatch, model_key, t, updateModelImage]
|
||||
);
|
||||
|
||||
const handleResetImage = useCallback(() => {
|
||||
if (!model_key) {
|
||||
return;
|
||||
}
|
||||
setImage(null);
|
||||
deleteModelImage(model_key)
|
||||
.unwrap()
|
||||
.then(() => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageUpdated'),
|
||||
title: t('modelManager.modelImageDeleted'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
@ -50,44 +79,13 @@ type Props = {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageUpdateFailed'),
|
||||
title: t('modelManager.modelImageDeleteFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const handleResetImage = useCallback(() => {
|
||||
if (!model_key) {
|
||||
return;
|
||||
}
|
||||
setImage(null);
|
||||
deleteModelImage(model_key)
|
||||
.unwrap()
|
||||
.then(() => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageDeleted'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
})
|
||||
.catch((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageDeleteFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
}, []);
|
||||
}, [dispatch, model_key, t, deleteModelImage]);
|
||||
|
||||
const { getInputProps, getRootProps } = useDropzone({
|
||||
accept: { 'image/png': ['.png'], 'image/jpeg': ['.jpg', '.jpeg', '.png'] },
|
||||
@ -98,9 +96,7 @@ type Props = {
|
||||
|
||||
if (image) {
|
||||
return (
|
||||
<Box
|
||||
position="relative"
|
||||
>
|
||||
<Box position="relative">
|
||||
<Image
|
||||
src={image}
|
||||
objectFit="cover"
|
||||
|
@ -4,11 +4,11 @@ import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetModelConfigQuery } from 'services/api/endpoints/models';
|
||||
|
||||
import ModelImageUpload from './Fields/ModelImageUpload';
|
||||
import { ModelMetadata } from './Metadata/ModelMetadata';
|
||||
import { ModelAttrView } from './ModelAttrView';
|
||||
import { ModelEdit } from './ModelEdit';
|
||||
import { ModelView } from './ModelView';
|
||||
import ModelImageUpload from './Fields/ModelImageUpload';
|
||||
|
||||
export const Model = () => {
|
||||
const { t } = useTranslation();
|
||||
@ -26,22 +26,22 @@ export const Model = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex alignItems="center" justifyContent="space-between" gap="4" paddingRight="5">
|
||||
<Flex flexDir="column" gap={1} p={2}>
|
||||
<Heading as="h2" fontSize="lg">
|
||||
{data.name}
|
||||
</Heading>
|
||||
<Flex alignItems="center" justifyContent="space-between" gap="4" paddingRight="5">
|
||||
<Flex flexDir="column" gap={1} p={2}>
|
||||
<Heading as="h2" fontSize="lg">
|
||||
{data.name}
|
||||
</Heading>
|
||||
|
||||
{data.source && (
|
||||
<Text variant="subtext">
|
||||
{t('modelManager.source')}: {data?.source}
|
||||
</Text>
|
||||
)}
|
||||
<Box mt="4">
|
||||
<ModelAttrView label="Description" value={data.description} />
|
||||
</Box>
|
||||
</Flex>
|
||||
<ModelImageUpload model_key={selectedModelKey} model_image={data.cover_image} />
|
||||
{data.source && (
|
||||
<Text variant="subtext">
|
||||
{t('modelManager.source')}: {data?.source}
|
||||
</Text>
|
||||
)}
|
||||
<Box mt="4">
|
||||
<ModelAttrView label="Description" value={data.description} />
|
||||
</Box>
|
||||
</Flex>
|
||||
<ModelImageUpload model_key={selectedModelKey} model_image={data.cover_image} />
|
||||
</Flex>
|
||||
|
||||
<Tabs mt="4" h="100%">
|
||||
|
@ -193,7 +193,7 @@ export const modelsApi = api.injectEndpoints({
|
||||
invalidatesTags: ['Model'],
|
||||
}),
|
||||
getModelImage: build.query<string, string>({
|
||||
query: (key) => buildModelsUrl(`i/${key}/image`)
|
||||
query: (key) => buildModelsUrl(`i/${key}/image`),
|
||||
}),
|
||||
convertModel: build.mutation<ConvertMainModelResponse, string>({
|
||||
query: (key) => {
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user