support subpath
parent
4455ca9148
commit
e543c58ffb
8
app.py
8
app.py
|
|
@ -44,7 +44,7 @@ def paths_check(paths):
|
|||
if os.path.isabs(path):
|
||||
abs_path = path
|
||||
else:
|
||||
abs_path = os.path.join(os.getcwd(), path)
|
||||
abs_path = os.path.normpath(os.path.join(os.getcwd(), path))
|
||||
if not os.path.exists(abs_path):
|
||||
print(f"{tag} The path '{abs_path}' will be ignored (value: {path}).")
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ class AppUtils:
|
|||
allow_cors=False,
|
||||
enable_shutdown=False,
|
||||
sd_webui_dir: Optional[str] = None,
|
||||
base="",
|
||||
base: Optional[str]=None,
|
||||
export_fe_fn=False,
|
||||
):
|
||||
"""
|
||||
|
|
@ -88,6 +88,8 @@ class AppUtils:
|
|||
self.allow_cors = allow_cors
|
||||
self.enable_shutdown = enable_shutdown
|
||||
self.sd_webui_dir = sd_webui_dir
|
||||
if base and not base.startswith('/'):
|
||||
base = '/' + base
|
||||
self.base = base
|
||||
self.export_fe_fn = export_fe_fn
|
||||
if sd_webui_dir:
|
||||
|
|
@ -151,7 +153,7 @@ class AppUtils:
|
|||
# 用于在首页显示
|
||||
@app.get("/")
|
||||
def index():
|
||||
if self.base and self.base != DEFAULT_BASE:
|
||||
if isinstance(self.base, str):
|
||||
with open(index_html_path, "r", encoding="utf-8") as file:
|
||||
content = file.read().replace(DEFAULT_BASE, self.base)
|
||||
return Response(content=content, media_type="text/html")
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ Promise.resolve().then(async () => {
|
|||
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
`.replace(/\/infinite_image_browsing/g, (window.location.pathname + '/infinite_image_browsing').replace(/\/\//g, '/'))
|
||||
let containerSelector = '#infinite_image_browsing_container_wrapper'
|
||||
let shouldMaximize = true
|
||||
|
||||
|
|
|
|||
|
|
@ -96,8 +96,9 @@ async def verify_secret(request: Request):
|
|||
|
||||
DEFAULT_BASE = "/infinite_image_browsing"
|
||||
def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
||||
pre = "/infinite_image_browsing"
|
||||
|
||||
api_base = kwargs.get("base") if isinstance(kwargs.get("base"), str) else DEFAULT_BASE
|
||||
fe_public_path = kwargs.get("fe_public_path") if isinstance(kwargs.get("fe_public_path"), str) else api_base
|
||||
# print(f"IIB api_base:{api_base} fe_public_path:{fe_public_path}")
|
||||
if IIB_DEBUG:
|
||||
@app.exception_handler(Exception)
|
||||
async def exception_handler(request: Request, exc: Exception):
|
||||
|
|
@ -133,7 +134,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
f"An exception occurred while processing {request.method} {request.url}: {exc}"
|
||||
)
|
||||
|
||||
pre = kwargs.get("base") or DEFAULT_BASE
|
||||
|
||||
if kwargs.get("allow_cors"):
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
|
|
@ -237,22 +238,13 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
def filter_allowed_files(files: List[FileInfoDict]):
|
||||
return [x for x in files if is_path_trusted(x["fullpath"])]
|
||||
|
||||
static_dir = f"{cwd}/vue/dist"
|
||||
@app.get(pre + "/fe-static/{file_path:path}")
|
||||
async def serve_static_file(file_path: str):
|
||||
file_full_path = f"{static_dir}/{file_path}"
|
||||
if file_path.endswith(".js"):
|
||||
with open(file_full_path, "r", encoding="utf-8") as file:
|
||||
content = file.read().replace(DEFAULT_BASE, pre)
|
||||
return Response(content=content, media_type="text/javascript")
|
||||
else:
|
||||
return FileResponse(file_full_path)
|
||||
|
||||
@app.get(f"{pre}/hello")
|
||||
|
||||
@app.get(f"{api_base}/hello")
|
||||
async def greeting():
|
||||
return "hello"
|
||||
|
||||
@app.get(f"{pre}/global_setting", dependencies=[Depends(verify_secret)])
|
||||
@app.get(f"{api_base}/global_setting", dependencies=[Depends(verify_secret)])
|
||||
async def global_setting():
|
||||
all_custom_tags = []
|
||||
|
||||
|
|
@ -284,7 +276,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
file_paths: List[str]
|
||||
|
||||
@app.post(
|
||||
pre + "/delete_files",
|
||||
api_base + "/delete_files",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def delete_files(req: DeleteFilesReq):
|
||||
|
|
@ -325,7 +317,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
dest_folder: str
|
||||
|
||||
@app.post(
|
||||
pre + "/mkdirs",
|
||||
api_base + "/mkdirs",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def create_folders(req: CreateFoldersReq):
|
||||
|
|
@ -340,7 +332,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
create_dest_folder: Optional[bool] = False
|
||||
|
||||
@app.post(
|
||||
pre + "/copy_files",
|
||||
api_base + "/copy_files",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def copy_files(req: MoveFilesReq):
|
||||
|
|
@ -360,7 +352,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
raise HTTPException(400, detail=error_msg)
|
||||
|
||||
@app.post(
|
||||
pre + "/move_files",
|
||||
api_base + "/move_files",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def move_files(req: MoveFilesReq):
|
||||
|
|
@ -394,7 +386,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
)
|
||||
raise HTTPException(400, detail=error_msg)
|
||||
|
||||
@app.get(pre + "/files", dependencies=[Depends(verify_secret)])
|
||||
@app.get(api_base + "/files", dependencies=[Depends(verify_secret)])
|
||||
async def get_target_folder_files(folder_path: str):
|
||||
files: List[FileInfoDict] = []
|
||||
try:
|
||||
|
|
@ -450,7 +442,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
|
||||
return {"files": filter_allowed_files(files)}
|
||||
|
||||
@app.get(pre + "/image-thumbnail", dependencies=[Depends(verify_secret)])
|
||||
@app.get(api_base + "/image-thumbnail", dependencies=[Depends(verify_secret)])
|
||||
async def thumbnail(path: str, t: str, size: str = "256x256"):
|
||||
check_path_trust(path)
|
||||
if not temp_path:
|
||||
|
|
@ -483,7 +475,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
headers={"Cache-Control": "max-age=31536000", "ETag": hash},
|
||||
)
|
||||
|
||||
@app.get(pre + "/file", dependencies=[Depends(verify_secret)])
|
||||
@app.get(api_base + "/file", dependencies=[Depends(verify_secret)])
|
||||
async def get_file(path: str, t: str, disposition: Optional[str] = None):
|
||||
filename = path
|
||||
import mimetypes
|
||||
|
|
@ -516,12 +508,12 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
headers=headers,
|
||||
)
|
||||
|
||||
@app.post(pre + "/send_img_path", dependencies=[Depends(verify_secret)])
|
||||
@app.post(api_base + "/send_img_path", dependencies=[Depends(verify_secret)])
|
||||
async def api_set_send_img_path(path: str):
|
||||
send_img_path["value"] = path
|
||||
|
||||
# 等待图片信息生成完成
|
||||
@app.get(pre + "/gen_info_completed", dependencies=[Depends(verify_secret)])
|
||||
@app.get(api_base + "/gen_info_completed", dependencies=[Depends(verify_secret)])
|
||||
async def api_set_send_img_path():
|
||||
for _ in range(30): # timeout 3s
|
||||
if send_img_path["value"] == "": # 等待setup里面生成完成
|
||||
|
|
@ -531,7 +523,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
await asyncio.sleep(0.1)
|
||||
return send_img_path["value"] == ""
|
||||
|
||||
@app.get(pre + "/image_geninfo", dependencies=[Depends(verify_secret)])
|
||||
@app.get(api_base + "/image_geninfo", dependencies=[Depends(verify_secret)])
|
||||
async def image_geninfo(path: str):
|
||||
with Image.open(path) as img:
|
||||
if is_img_created_by_comfyui(img):
|
||||
|
|
@ -551,7 +543,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
class GeninfoBatchReq(BaseModel):
|
||||
paths: List[str]
|
||||
|
||||
@app.post(pre + "/image_geninfo_batch", dependencies=[Depends(verify_secret)])
|
||||
@app.post(api_base + "/image_geninfo_batch", dependencies=[Depends(verify_secret)])
|
||||
async def image_geninfo_batch(req: GeninfoBatchReq):
|
||||
res = {}
|
||||
for path in req.paths:
|
||||
|
|
@ -562,7 +554,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
class CheckPathExistsReq(BaseModel):
|
||||
paths: List[str]
|
||||
|
||||
@app.post(pre + "/check_path_exists", dependencies=[Depends(verify_secret)])
|
||||
@app.post(api_base + "/check_path_exists", dependencies=[Depends(verify_secret)])
|
||||
async def check_path_exists(req: CheckPathExistsReq):
|
||||
update_all_scanned_paths()
|
||||
res = {}
|
||||
|
|
@ -570,14 +562,25 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
res[path] = os.path.exists(path) and is_path_trusted(path)
|
||||
return res
|
||||
|
||||
@app.get(pre)
|
||||
@app.get(api_base)
|
||||
def index_bd():
|
||||
if pre != DEFAULT_BASE:
|
||||
if fe_public_path:
|
||||
with open(index_html_path, "r", encoding="utf-8") as file:
|
||||
content = file.read().replace(DEFAULT_BASE, pre)
|
||||
content = file.read().replace(DEFAULT_BASE, fe_public_path)
|
||||
return Response(content=content, media_type="text/html")
|
||||
return FileResponse(index_html_path)
|
||||
|
||||
static_dir = f"{cwd}/vue/dist"
|
||||
@app.get(api_base + "/fe-static/{file_path:path}")
|
||||
async def serve_static_file(file_path: str):
|
||||
file_full_path = f"{static_dir}/{file_path}"
|
||||
if file_path.endswith(".js"):
|
||||
with open(file_full_path, "r", encoding="utf-8") as file:
|
||||
content = file.read().replace(DEFAULT_BASE, fe_public_path)
|
||||
return Response(content=content, media_type="text/javascript")
|
||||
else:
|
||||
return FileResponse(file_full_path)
|
||||
|
||||
class PathsReq(BaseModel):
|
||||
paths: List[str]
|
||||
|
||||
|
|
@ -585,7 +588,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
path: str
|
||||
|
||||
@app.post(
|
||||
pre + "/open_folder",
|
||||
api_base + "/open_folder",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
def open_folder_using_explore(req: OpenFolderReq):
|
||||
|
|
@ -593,7 +596,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
raise HTTPException(status_code=403)
|
||||
open_folder(*os.path.split(req.path))
|
||||
|
||||
@app.post(pre + "/shutdown")
|
||||
@app.post(api_base + "/shutdown")
|
||||
async def shutdown_app():
|
||||
# This API endpoint is mainly used as a sidecar in Tauri applications to shut down the application
|
||||
if not kwargs.get("enable_shutdown"):
|
||||
|
|
@ -602,7 +605,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
return {"message": "Application is shutting down."}
|
||||
|
||||
@app.post(
|
||||
pre + "/zip",
|
||||
api_base + "/zip",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
def zip_files(req: PathsReq):
|
||||
|
|
@ -614,9 +617,9 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
create_zip_file(req.paths, file_path)
|
||||
return FileResponse(file_path, media_type="application/zip")
|
||||
|
||||
db_pre = pre + "/db"
|
||||
db_api_base = api_base + "/db"
|
||||
|
||||
@app.get(db_pre + "/basic_info", dependencies=[Depends(verify_secret)])
|
||||
@app.get(db_api_base + "/basic_info", dependencies=[Depends(verify_secret)])
|
||||
async def get_db_basic_info():
|
||||
conn = DataBase.get_conn()
|
||||
img_count = DbImg.count(conn)
|
||||
|
|
@ -629,7 +632,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
"expired_dirs": expired_dirs,
|
||||
}
|
||||
|
||||
@app.get(db_pre + "/expired_dirs", dependencies=[Depends(verify_secret)])
|
||||
@app.get(db_api_base + "/expired_dirs", dependencies=[Depends(verify_secret)])
|
||||
async def get_db_expired():
|
||||
conn = DataBase.get_conn()
|
||||
expired_dirs = Folder.get_expired_dirs(conn)
|
||||
|
|
@ -639,7 +642,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
}
|
||||
|
||||
@app.post(
|
||||
db_pre + "/update_image_data",
|
||||
db_api_base + "/update_image_data",
|
||||
dependencies=[Depends(verify_secret)],
|
||||
)
|
||||
async def update_image_db_data():
|
||||
|
|
@ -665,7 +668,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
folder_paths: List[str] = None
|
||||
size: Optional[int] = 200
|
||||
|
||||
@app.post(db_pre + "/search_by_substr", dependencies=[Depends(verify_secret)])
|
||||
@app.post(db_api_base + "/search_by_substr", dependencies=[Depends(verify_secret)])
|
||||
async def search_by_substr(req: SearchBySubstrReq):
|
||||
if IIB_DEBUG:
|
||||
logger.info(req)
|
||||
|
|
@ -694,7 +697,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
folder_paths: List[str] = None
|
||||
size: Optional[int] = 200
|
||||
|
||||
@app.post(db_pre + "/match_images_by_tags", dependencies=[Depends(verify_secret)])
|
||||
@app.post(db_api_base + "/match_images_by_tags", dependencies=[Depends(verify_secret)])
|
||||
async def match_image_by_tags(req: MatchImagesByTagsReq):
|
||||
if IIB_DEBUG:
|
||||
logger.info(req)
|
||||
|
|
@ -714,7 +717,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
"cursor": next_cursor
|
||||
}
|
||||
|
||||
@app.get(db_pre + "/img_selected_custom_tag", dependencies=[Depends(verify_secret)])
|
||||
@app.get(db_api_base + "/img_selected_custom_tag", dependencies=[Depends(verify_secret)])
|
||||
async def get_img_selected_custom_tag(path: str):
|
||||
path = os.path.normpath(path)
|
||||
if not is_valid_image_path(path):
|
||||
|
|
@ -733,7 +736,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
# tags = Tag.get_all_custom_tag()
|
||||
return ImageTag.get_tags_for_image(conn, img.id, type="custom")
|
||||
|
||||
@app.post(db_pre + "/get_image_tags", dependencies=[Depends(verify_secret)])
|
||||
@app.post(db_api_base + "/get_image_tags", dependencies=[Depends(verify_secret)])
|
||||
async def get_img_tags(req: PathsReq):
|
||||
conn = DataBase.get_conn()
|
||||
return ImageTag.batch_get_tags_by_path(conn, req.paths)
|
||||
|
|
@ -743,7 +746,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
tag_id: int
|
||||
|
||||
@app.post(
|
||||
db_pre + "/toggle_custom_tag_to_img",
|
||||
db_api_base + "/toggle_custom_tag_to_img",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def toggle_custom_tag_to_img(req: ToggleCustomTagToImgReq):
|
||||
|
|
@ -786,7 +789,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
tag_id: int
|
||||
|
||||
@app.post(
|
||||
db_pre + "/batch_update_image_tag",
|
||||
db_api_base + "/batch_update_image_tag",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def batch_update_image_tag(req: BatchUpdateImageReq):
|
||||
|
|
@ -828,7 +831,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
tag_name: str
|
||||
|
||||
@app.post(
|
||||
db_pre + "/add_custom_tag",
|
||||
db_api_base + "/add_custom_tag",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def add_custom_tag(req: AddCustomTagReq):
|
||||
|
|
@ -841,7 +844,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
tag_id: str
|
||||
|
||||
@app.post(
|
||||
db_pre + "/remove_custom_tag",
|
||||
db_api_base + "/remove_custom_tag",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def remove_custom_tag(req: RemoveCustomTagReq):
|
||||
|
|
@ -854,7 +857,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
tag_id: str
|
||||
|
||||
@app.post(
|
||||
db_pre + "/remove_custom_tag_from_img",
|
||||
db_api_base + "/remove_custom_tag_from_img",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def remove_custom_tag_from_img(req: RemoveCustomTagFromReq):
|
||||
|
|
@ -869,7 +872,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
type: Optional[ExtraPathType]
|
||||
|
||||
@app.post(
|
||||
f"{db_pre}/extra_paths",
|
||||
f"{db_api_base}/extra_paths",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def create_extra_path(extra_path: ExtraPathModel):
|
||||
|
|
@ -884,7 +887,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
conn.commit()
|
||||
|
||||
@app.get(
|
||||
f"{db_pre}/extra_paths",
|
||||
f"{db_api_base}/extra_paths",
|
||||
dependencies=[Depends(verify_secret)],
|
||||
)
|
||||
async def read_extra_paths():
|
||||
|
|
@ -892,7 +895,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
return ExtraPath.get_extra_paths(conn)
|
||||
|
||||
@app.delete(
|
||||
f"{db_pre}/extra_paths",
|
||||
f"{db_api_base}/extra_paths",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def delete_extra_path(extra_path: ExtraPathModel):
|
||||
|
|
@ -902,7 +905,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
|
||||
|
||||
@app.post(
|
||||
f"{db_pre}/rebuild_index",
|
||||
f"{db_api_base}/rebuild_index",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def rebuild_index():
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from scripts.iib.logger import logger
|
|||
|
||||
from fastapi import FastAPI
|
||||
import gradio as gr
|
||||
from modules.shared import cmd_opts
|
||||
|
||||
"""
|
||||
api函数声明和启动分离方便另外一边被外部调用
|
||||
|
|
@ -71,7 +72,14 @@ def on_ui_tabs():
|
|||
|
||||
def on_app_started(_: gr.Blocks, app: FastAPI) -> None:
|
||||
# 第一个参数是SD-WebUI传进来的gr.Blocks,但是不需要使用
|
||||
infinite_image_browsing_api(app)
|
||||
DEFAULT_BASE = "/infinite_image_browsing"
|
||||
fe_public_path = None
|
||||
subpath = vars(cmd_opts).get("subpath")
|
||||
|
||||
if subpath:
|
||||
base = "/" + subpath + "/" + DEFAULT_BASE
|
||||
fe_public_path = base.replace('//', '/')
|
||||
infinite_image_browsing_api(app, fe_public_path = fe_public_path)
|
||||
|
||||
|
||||
script_callbacks.on_ui_tabs(on_ui_tabs)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ Promise.resolve().then(async () => {
|
|||
* This is a file generated using `yarn build`.
|
||||
* If you want to make changes, please modify `index.tpl.js` and run the command to generate it again.
|
||||
*/
|
||||
const html = `__built_html__`
|
||||
const html = `__built_html__`.replace(/\/infinite_image_browsing/g, (window.location.pathname + '/infinite_image_browsing').replace(/\/\//g, '/'))
|
||||
let containerSelector = '#infinite_image_browsing_container_wrapper'
|
||||
let shouldMaximize = true
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue