Merge pull request #275 from zanllp/feature/prompt-from-txt-file

feat: Support loading prompts from separate txt files
pull/277/head
zanllp 2023-06-28 05:24:37 +08:00 committed by GitHub
commit 448b9e6d09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 94 additions and 47 deletions

3
.gitignore vendored
View File

@ -1,4 +1,4 @@
BaiduPCS-Go*
*.log *.log
__pycache__ __pycache__
iib.db iib.db
@ -8,3 +8,4 @@ conf.json
iib.db-journal iib.db-journal
.env .env
standalone.cmd standalone.cmd
.vscode

View File

@ -15,7 +15,7 @@
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Infinite Image Browsing</title> <title>Infinite Image Browsing</title>
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-242b55ec.js"></script> <script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-3ed6c068.js"></script>
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-8035c113.css"> <link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-8035c113.css">
</head> </head>

View File

@ -1,5 +1,6 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
import os import os
import re
import shutil import shutil
import sqlite3 import sqlite3
from scripts.iib.tool import ( from scripts.iib.tool import (
@ -15,7 +16,8 @@ from scripts.iib.tool import (
get_windows_drives, get_windows_drives,
get_sd_webui_conf, get_sd_webui_conf,
get_valid_img_dirs, get_valid_img_dirs,
open_folder open_folder,
get_img_geninfo_txt_path
) )
from fastapi import FastAPI, HTTPException from fastapi import FastAPI, HTTPException
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
@ -171,6 +173,9 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
shutil.rmtree(path) shutil.rmtree(path)
else: else:
os.remove(path) os.remove(path)
txt_path = get_img_geninfo_txt_path(path)
if txt_path:
os.remove(txt_path)
img = DbImg.get(conn, os.path.normpath(path)) img = DbImg.get(conn, os.path.normpath(path))
if img: if img:
logger.info("delete file: %s", path) logger.info("delete file: %s", path)
@ -197,6 +202,9 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
check_path_trust(path) check_path_trust(path)
try: try:
shutil.move(path, req.dest) shutil.move(path, req.dest)
txt_path = get_img_geninfo_txt_path(path)
if txt_path:
shutil.move(txt_path, req.dest)
img = DbImg.get(conn, os.path.normpath(path)) img = DbImg.get(conn, os.path.normpath(path))
if img: if img:
DbImg.safe_batch_remove(conn, [img.id]) DbImg.safe_batch_remove(conn, [img.id])
@ -349,7 +357,7 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
@app.get(pre + "/image_geninfo", dependencies=[Depends(get_token)]) @app.get(pre + "/image_geninfo", dependencies=[Depends(get_token)])
async def image_geninfo(path: str): async def image_geninfo(path: str):
with Image.open(path) as img: with Image.open(path) as img:
return read_info_from_image(img) return read_info_from_image(img, path)
class CheckPathExistsReq(BaseModel): class CheckPathExistsReq(BaseModel):
paths: List[str] paths: List[str]
@ -431,6 +439,8 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
@app.get(db_pre + "/img_selected_custom_tag", dependencies=[Depends(get_token)]) @app.get(db_pre + "/img_selected_custom_tag", dependencies=[Depends(get_token)])
async def get_img_selected_custom_tag(path: str): async def get_img_selected_custom_tag(path: str):
path = os.path.normpath(path) path = os.path.normpath(path)
if not is_valid_image_path(path):
return []
conn = DataBase.get_conn() conn = DataBase.get_conn()
update_extra_paths(conn) update_extra_paths(conn)
if not is_path_under_parents(path): if not is_path_under_parents(path):

View File

@ -19,7 +19,7 @@ def get_exif_data(file_path):
params = None params = None
try: try:
with Image.open(file_path) as img: with Image.open(file_path) as img:
info = read_info_from_image(img) info = read_info_from_image(img, file_path)
params = parse_generation_parameters(info) params = parse_generation_parameters(info)
except Exception as e: except Exception as e:
if is_dev: if is_dev:

View File

@ -29,21 +29,23 @@ is_win = platform.system().lower().find("windows") != -1
try: try:
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv(os.path.join(cwd, ".env"))
except BaseException as e:
print(e)
load_dotenv(os.path.join(cwd, ".env"))
except Exception as e:
print(e)
def get_sd_webui_conf(**kwargs): def get_sd_webui_conf(**kwargs):
try: try:
from modules.shared import opts from modules.shared import opts
return opts.data return opts.data
except: except:
pass pass
try: try:
with open(kwargs.get("sd_webui_config"), "r") as f: with open(kwargs.get("sd_webui_config"), "r") as f:
import json import json
return json.loads(f.read()) return json.loads(f.read())
except: except:
pass pass
@ -121,7 +123,6 @@ def convert_to_bytes(file_size_str):
raise ValueError(f"Invalid file size string '{file_size_str}'") raise ValueError(f"Invalid file size string '{file_size_str}'")
def is_valid_image_path(path): def is_valid_image_path(path):
""" """
判断给定的路径是否是图像文件 判断给定的路径是否是图像文件
@ -136,8 +137,6 @@ def is_valid_image_path(path):
return True return True
def get_temp_path(): def get_temp_path():
"""获取跨平台的临时文件目录路径""" """获取跨平台的临时文件目录路径"""
temp_path = None temp_path = None
@ -168,6 +167,7 @@ def get_temp_path():
temp_path = get_temp_path() temp_path = get_temp_path()
def get_enable_access_control(): def get_enable_access_control():
ctrl = os.getenv("IIB_ACCESS_CONTROL") ctrl = os.getenv("IIB_ACCESS_CONTROL")
if ctrl == "enable": if ctrl == "enable":
@ -176,17 +176,23 @@ def get_enable_access_control():
return False return False
try: try:
from modules.shared import cmd_opts from modules.shared import cmd_opts
return cmd_opts.share or cmd_opts.ngrok or cmd_opts.listen or cmd_opts.server_name
return (
cmd_opts.share or cmd_opts.ngrok or cmd_opts.listen or cmd_opts.server_name
)
except: except:
pass pass
return False return False
enable_access_control = get_enable_access_control() enable_access_control = get_enable_access_control()
def get_locale(): def get_locale():
import locale import locale
env_lang = os.getenv("IIB_SERVER_LANG") env_lang = os.getenv("IIB_SERVER_LANG")
if env_lang in ['zh', 'en']: if env_lang in ["zh", "en"]:
return env_lang return env_lang
lang, _ = locale.getdefaultlocale() lang, _ = locale.getdefaultlocale()
return "zh" if lang and lang.startswith("zh") else "en" return "zh" if lang and lang.startswith("zh") else "en"
@ -198,23 +204,43 @@ locale = get_locale()
def get_formatted_date(timestamp: float) -> str: def get_formatted_date(timestamp: float) -> str:
return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S") return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
def get_modified_date(folder_path: str): def get_modified_date(folder_path: str):
return get_formatted_date(os.path.getmtime(folder_path)) return get_formatted_date(os.path.getmtime(folder_path))
def get_created_date(folder_path: str): def get_created_date(folder_path: str):
return get_formatted_date(os.path.getctime(folder_path)) return get_formatted_date(os.path.getctime(folder_path))
def unique_by(seq, key_func): def unique_by(seq, key_func):
seen = set() seen = set()
return [x for x in seq if not (key := key_func(x)) in seen and not seen.add(key)] return [x for x in seq if not (key := key_func(x)) in seen and not seen.add(key)]
def read_info_from_image(image) -> str: def get_img_geninfo_txt_path(path: str):
txt_path = re.sub(r"\..+$", ".txt", path)
if os.path.exists(txt_path):
return txt_path
def read_info_from_image(image, path="") -> str:
"""
Reads metadata from an image file.
Args:
image (PIL.Image.Image): The image object to read metadata from.
path (str): Optional. The path to the image file. Used to look for a .txt file with additional metadata.
Returns:
str: The metadata as a string.
"""
items = image.info or {} items = image.info or {}
geninfo = items.pop("parameters", None) geninfo = items.pop("parameters", None)
if "exif" in items: if "exif" in items:
exif = piexif.load(items["exif"]) exif = piexif.load(items["exif"])
exif_comment = (exif or {}).get("Exif", {}).get(piexif.ExifIFD.UserComment, b"") exif_comment = (exif or {}).get("Exif", {}).get(piexif.ExifIFD.UserComment, b"")
try: try:
exif_comment = piexif.helper.UserComment.load(exif_comment) exif_comment = piexif.helper.UserComment.load(exif_comment)
except ValueError: except ValueError:
@ -223,6 +249,16 @@ def read_info_from_image(image) -> str:
if exif_comment: if exif_comment:
items["exif comment"] = exif_comment items["exif comment"] = exif_comment
geninfo = exif_comment geninfo = exif_comment
if not geninfo and path:
try:
txt_path = get_img_geninfo_txt_path(path)
if txt_path:
with open(txt_path) as f:
geninfo = f.read()
except Exception as e:
pass
return geninfo return geninfo
@ -336,16 +372,16 @@ def open_folder(folder_path, file_path=None):
folder = os.path.realpath(folder_path) folder = os.path.realpath(folder_path)
if file_path: if file_path:
file = os.path.join(folder, file_path) file = os.path.join(folder, file_path)
if os.name == 'nt': if os.name == "nt":
subprocess.run(['explorer', '/select,', file]) subprocess.run(["explorer", "/select,", file])
elif sys.platform == 'darwin': elif sys.platform == "darwin":
subprocess.run(['open', '-R', file]) subprocess.run(["open", "-R", file])
elif os.name == 'posix': elif os.name == "posix":
subprocess.run(['xdg-open', file]) subprocess.run(["xdg-open", file])
else: else:
if os.name == 'nt': if os.name == "nt":
subprocess.run(['explorer', folder]) subprocess.run(["explorer", folder])
elif sys.platform == 'darwin': elif sys.platform == "darwin":
subprocess.run(['open', folder]) subprocess.run(["open", folder])
elif os.name == 'posix': elif os.name == "posix":
subprocess.run(['xdg-open', folder]) subprocess.run(["xdg-open", folder])

View File

@ -42,10 +42,10 @@ def on_ui_tabs():
path = send_img_path.get("value") path = send_img_path.get("value")
logger.info("img_update_func %s", path) logger.info("img_update_func %s", path)
img = Image.open(path) img = Image.open(path)
info = read_info_from_image(img) info = read_info_from_image(img, path)
return img, info return img, info
except Exception as e: except Exception as e:
logger.error("img_update_func %s",e) logger.error("img_update_func err %s",e)
img_file_info = gr.Textbox(elem_id="iib_hidden_img_file_info") img_file_info = gr.Textbox(elem_id="iib_hidden_img_file_info")
img_update_trigger.click(img_update_func, outputs=[img, img_file_info]) img_update_trigger.click(img_update_func, outputs=[img, img_file_info])

View File

@ -1 +1 @@
import{d as t,o as a,m as r,cr as n}from"./index-242b55ec.js";const p=t({__name:"ImgSliPagePane",props:{paneIdx:{},tabIdx:{},left:{},right:{}},setup(o){return(e,s)=>(a(),r(n,{left:e.left,right:e.right},null,8,["left","right"]))}});export{p as default}; import{d as t,o as a,m as r,cr as n}from"./index-3ed6c068.js";const p=t({__name:"ImgSliPagePane",props:{paneIdx:{},tabIdx:{},left:{},right:{}},setup(o){return(e,s)=>(a(),r(n,{left:e.left,right:e.right},null,8,["left","right"]))}});export{p as default};

View File

@ -1 +1 @@
import{d as R,l as U,o as r,y as _,c as n,n as a,r as e,s as y,p as b,t as L,v as h,x as q,m as M,K as Q,H as u,L as S,O as H,Q as K,W}from"./index-242b55ec.js";import{a as j,f as J,L as X,R as Y,b as Z,S as ee}from"./fullScreenContextMenu-e9059fe5.js";import"./hook-47714a2a.js";import{g as se}from"./db-efa0b620.js";import{u as te}from"./hook-b39ea9fb.js";const ie={class:"hint"},ne={key:1,class:"preview-switch"},le=R({__name:"MatchedImageGrid",props:{tabIdx:{},paneIdx:{},selectedTagIds:{},id:{}},setup(V){const m=V,{queue:p,images:t,onContextMenuClickU:g,stackViewEl:D,previewIdx:l,previewing:v,onPreviewVisibleChange:T,previewImgMove:f,canPreview:I,itemSize:k,gridItems:z,showGenInfo:o,imageGenInfo:w,q:F,multiSelectedIdxs:$,onFileItemClick:B,scroller:C,showMenuIdx:d,onFileDragStart:G,onFileDragEnd:A}=te();return U(()=>m.selectedTagIds,async()=>{var s;const{res:c}=p.pushAction(()=>se(m.selectedTagIds));t.value=await c,(s=C.value)==null||s.scrollToItem(0)},{immediate:!0}),(c,s)=>{const E=H,N=K,O=ee;return r(),_("div",{class:"container",ref_key:"stackViewEl",ref:D},[n(O,{size:"large",spinning:!e(p).isIdle},{default:a(()=>[n(N,{visible:e(o),"onUpdate:visible":s[1]||(s[1]=i=>y(o)?o.value=i:null),width:"70vw","mask-closable":"",onOk:s[2]||(s[2]=i=>o.value=!1)},{cancelText:a(()=>[]),default:a(()=>[n(E,{active:"",loading:!e(F).isIdle},{default:a(()=>[b("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:s[0]||(s[0]=i=>e(L)(e(w)))},[b("div",ie,h(c.$t("doubleClickToCopy")),1),q(" "+h(e(w)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(t)?(r(),M(e(j),{key:0,ref_key:"scroller",ref:C,class:"file-list",items:e(t),"item-size":e(k).first,"key-field":"fullpath","item-secondary-size":e(k).second,gridItems:e(z)},{default:a(({item:i,index:x})=>[n(J,{idx:x,file:i,"show-menu-idx":e(d),"onUpdate:showMenuIdx":s[3]||(s[3]=P=>y(d)?d.value=P:null),onDragstart:e(G),onDragend:e(A),onFileItemClick:e(B),"full-screen-preview-image-url":e(t)[e(l)]?e(Q)(e(t)[e(l)]):"",selected:e($).includes(x),onContextMenuClick:e(g),onPreviewVisibleChange:e(T)},null,8,["idx","file","show-menu-idx","onDragstart","onDragend","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):u("",!0),e(v)?(r(),_("div",ne,[n(e(X),{onClick:s[4]||(s[4]=i=>e(f)("prev")),class:S({disable:!e(I)("prev")})},null,8,["class"]),n(e(Y),{onClick:s[5]||(s[5]=i=>e(f)("next")),class:S({disable:!e(I)("next")})},null,8,["class"])])):u("",!0)]),_:1},8,["spinning"]),e(v)&&e(t)&&e(t)[e(l)]?(r(),M(Z,{key:0,file:e(t)[e(l)],idx:e(l),onContextMenuClick:e(g)},null,8,["file","idx","onContextMenuClick"])):u("",!0)],512)}}});const ue=W(le,[["__scopeId","data-v-2cae0a95"]]);export{ue as default}; import{d as R,l as U,o as r,y as _,c as n,n as a,r as e,s as y,p as b,t as L,v as h,x as q,m as M,K as Q,H as u,L as S,O as H,Q as K,W}from"./index-3ed6c068.js";import{a as j,f as J,L as X,R as Y,b as Z,S as ee}from"./fullScreenContextMenu-994955c4.js";import"./hook-ab96b9b6.js";import{g as se}from"./db-fd44e31c.js";import{u as te}from"./hook-e4d29975.js";const ie={class:"hint"},ne={key:1,class:"preview-switch"},le=R({__name:"MatchedImageGrid",props:{tabIdx:{},paneIdx:{},selectedTagIds:{},id:{}},setup(V){const m=V,{queue:p,images:t,onContextMenuClickU:g,stackViewEl:D,previewIdx:l,previewing:v,onPreviewVisibleChange:T,previewImgMove:f,canPreview:I,itemSize:k,gridItems:z,showGenInfo:o,imageGenInfo:w,q:F,multiSelectedIdxs:$,onFileItemClick:B,scroller:C,showMenuIdx:d,onFileDragStart:G,onFileDragEnd:A}=te();return U(()=>m.selectedTagIds,async()=>{var s;const{res:c}=p.pushAction(()=>se(m.selectedTagIds));t.value=await c,(s=C.value)==null||s.scrollToItem(0)},{immediate:!0}),(c,s)=>{const E=H,N=K,O=ee;return r(),_("div",{class:"container",ref_key:"stackViewEl",ref:D},[n(O,{size:"large",spinning:!e(p).isIdle},{default:a(()=>[n(N,{visible:e(o),"onUpdate:visible":s[1]||(s[1]=i=>y(o)?o.value=i:null),width:"70vw","mask-closable":"",onOk:s[2]||(s[2]=i=>o.value=!1)},{cancelText:a(()=>[]),default:a(()=>[n(E,{active:"",loading:!e(F).isIdle},{default:a(()=>[b("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:s[0]||(s[0]=i=>e(L)(e(w)))},[b("div",ie,h(c.$t("doubleClickToCopy")),1),q(" "+h(e(w)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(t)?(r(),M(e(j),{key:0,ref_key:"scroller",ref:C,class:"file-list",items:e(t),"item-size":e(k).first,"key-field":"fullpath","item-secondary-size":e(k).second,gridItems:e(z)},{default:a(({item:i,index:x})=>[n(J,{idx:x,file:i,"show-menu-idx":e(d),"onUpdate:showMenuIdx":s[3]||(s[3]=P=>y(d)?d.value=P:null),onDragstart:e(G),onDragend:e(A),onFileItemClick:e(B),"full-screen-preview-image-url":e(t)[e(l)]?e(Q)(e(t)[e(l)]):"",selected:e($).includes(x),onContextMenuClick:e(g),onPreviewVisibleChange:e(T)},null,8,["idx","file","show-menu-idx","onDragstart","onDragend","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):u("",!0),e(v)?(r(),_("div",ne,[n(e(X),{onClick:s[4]||(s[4]=i=>e(f)("prev")),class:S({disable:!e(I)("prev")})},null,8,["class"]),n(e(Y),{onClick:s[5]||(s[5]=i=>e(f)("next")),class:S({disable:!e(I)("next")})},null,8,["class"])])):u("",!0)]),_:1},8,["spinning"]),e(v)&&e(t)&&e(t)[e(l)]?(r(),M(Z,{key:0,file:e(t)[e(l)],idx:e(l),onContextMenuClick:e(g)},null,8,["file","idx","onContextMenuClick"])):u("",!0)],512)}}});const ue=W(le,[["__scopeId","data-v-2cae0a95"]]);export{ue as default};

View File

@ -1 +1 @@
import{d as W,Z as $,ay as Z,br as j,bs as J,o,y as k,c as r,r as e,bx as X,m,n as d,x as b,v,H as f,s as B,p as V,t as Y,K as ee,L as A,bv as ne,ag as se,T as te,U as ae,O as ie,Q as le,W as oe}from"./index-242b55ec.js";import{a as re,f as de,L as ue,R as ce,b as pe,S as me}from"./fullScreenContextMenu-e9059fe5.js";/* empty css */import"./hook-47714a2a.js";import{a as U,c as ve,e as fe,u as ge}from"./db-efa0b620.js";import{u as ke}from"./hook-b39ea9fb.js";const be={key:0,class:"search-bar"},ye={class:"hint"},we={key:1,class:"preview-switch"},Ce=W({__name:"SubstrSearch",setup(Ie){const{queue:l,images:a,onContextMenuClickU:y,stackViewEl:F,previewIdx:u,previewing:w,onPreviewVisibleChange:E,previewImgMove:C,canPreview:I,itemSize:_,gridItems:R,showGenInfo:c,imageGenInfo:x,q:T,multiSelectedIdxs:K,onFileItemClick:L,scroller:h,showMenuIdx:g,onFileDragStart:N,onFileDragEnd:O}=ke(),p=$(""),s=$();Z(async()=>{s.value=await U(),s.value.img_count&&s.value.expired&&S()});const S=j(()=>l.pushAction(async()=>(await ge(),s.value=await U(),s.value)).res),M=async()=>{var t;a.value=await l.pushAction(()=>fe(p.value)).res,(t=h.value)==null||t.scrollToItem(0),a.value.length||ne.info(se("fuzzy-search-noResults"))};return J("return-to-iib",async()=>{const t=await l.pushAction(ve).res;s.value.expired=t.expired}),(t,n)=>{const P=te,z=ae,q=ie,G=le,H=me;return o(),k("div",{class:"container",ref_key:"stackViewEl",ref:F},[s.value?(o(),k("div",be,[r(P,{value:p.value,"onUpdate:value":n[0]||(n[0]=i=>p.value=i),placeholder:t.$t("fuzzy-search-placeholder"),disabled:!e(l).isIdle,onKeydown:X(M,["enter"])},null,8,["value","placeholder","disabled","onKeydown"]),s.value.expired||!s.value.img_count?(o(),m(z,{key:0,onClick:e(S),loading:!e(l).isIdle,type:"primary"},{default:d(()=>[b(v(s.value.img_count===0?t.$t("generateIndexHint"):t.$t("UpdateIndex")),1)]),_:1},8,["onClick","loading"])):(o(),m(z,{key:1,type:"primary",onClick:M,loading:!e(l).isIdle,disabled:!p.value},{default:d(()=>[b(v(t.$t("search")),1)]),_:1},8,["loading","disabled"]))])):f("",!0),r(H,{size:"large",spinning:!e(l).isIdle},{default:d(()=>[r(G,{visible:e(c),"onUpdate:visible":n[2]||(n[2]=i=>B(c)?c.value=i:null),width:"70vw","mask-closable":"",onOk:n[3]||(n[3]=i=>c.value=!1)},{cancelText:d(()=>[]),default:d(()=>[r(q,{active:"",loading:!e(T).isIdle},{default:d(()=>[V("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:n[1]||(n[1]=i=>e(Y)(e(x)))},[V("div",ye,v(t.$t("doubleClickToCopy")),1),b(" "+v(e(x)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(a)?(o(),m(e(re),{key:0,ref_key:"scroller",ref:h,class:"file-list",items:e(a),"item-size":e(_).first,"key-field":"fullpath","item-secondary-size":e(_).second,gridItems:e(R)},{default:d(({item:i,index:D})=>[r(de,{idx:D,file:i,"show-menu-idx":e(g),"onUpdate:showMenuIdx":n[4]||(n[4]=Q=>B(g)?g.value=Q:null),onFileItemClick:e(L),"full-screen-preview-image-url":e(a)[e(u)]?e(ee)(e(a)[e(u)]):"",selected:e(K).includes(D),onContextMenuClick:e(y),onDragstart:e(N),onDragend:e(O),onPreviewVisibleChange:e(E)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onDragstart","onDragend","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):f("",!0),e(w)?(o(),k("div",we,[r(e(ue),{onClick:n[5]||(n[5]=i=>e(C)("prev")),class:A({disable:!e(I)("prev")})},null,8,["class"]),r(e(ce),{onClick:n[6]||(n[6]=i=>e(C)("next")),class:A({disable:!e(I)("next")})},null,8,["class"])])):f("",!0)]),_:1},8,["spinning"]),e(w)&&e(a)&&e(a)[e(u)]?(o(),m(pe,{key:1,file:e(a)[e(u)],idx:e(u),onContextMenuClick:e(y)},null,8,["file","idx","onContextMenuClick"])):f("",!0)],512)}}});const De=oe(Ce,[["__scopeId","data-v-bf9bdccd"]]);export{De as default}; import{d as W,Z as $,ay as Z,br as j,bs as J,o,y as k,c as r,r as e,bx as X,m,n as d,x as b,v,H as f,s as B,p as V,t as Y,K as ee,L as A,bv as ne,ag as se,T as te,U as ae,O as ie,Q as le,W as oe}from"./index-3ed6c068.js";import{a as re,f as de,L as ue,R as ce,b as pe,S as me}from"./fullScreenContextMenu-994955c4.js";/* empty css */import"./hook-ab96b9b6.js";import{a as U,c as ve,e as fe,u as ge}from"./db-fd44e31c.js";import{u as ke}from"./hook-e4d29975.js";const be={key:0,class:"search-bar"},ye={class:"hint"},we={key:1,class:"preview-switch"},Ce=W({__name:"SubstrSearch",setup(Ie){const{queue:l,images:a,onContextMenuClickU:y,stackViewEl:F,previewIdx:u,previewing:w,onPreviewVisibleChange:E,previewImgMove:C,canPreview:I,itemSize:_,gridItems:R,showGenInfo:c,imageGenInfo:x,q:T,multiSelectedIdxs:K,onFileItemClick:L,scroller:h,showMenuIdx:g,onFileDragStart:N,onFileDragEnd:O}=ke(),p=$(""),s=$();Z(async()=>{s.value=await U(),s.value.img_count&&s.value.expired&&S()});const S=j(()=>l.pushAction(async()=>(await ge(),s.value=await U(),s.value)).res),M=async()=>{var t;a.value=await l.pushAction(()=>fe(p.value)).res,(t=h.value)==null||t.scrollToItem(0),a.value.length||ne.info(se("fuzzy-search-noResults"))};return J("return-to-iib",async()=>{const t=await l.pushAction(ve).res;s.value.expired=t.expired}),(t,n)=>{const P=te,z=ae,q=ie,G=le,H=me;return o(),k("div",{class:"container",ref_key:"stackViewEl",ref:F},[s.value?(o(),k("div",be,[r(P,{value:p.value,"onUpdate:value":n[0]||(n[0]=i=>p.value=i),placeholder:t.$t("fuzzy-search-placeholder"),disabled:!e(l).isIdle,onKeydown:X(M,["enter"])},null,8,["value","placeholder","disabled","onKeydown"]),s.value.expired||!s.value.img_count?(o(),m(z,{key:0,onClick:e(S),loading:!e(l).isIdle,type:"primary"},{default:d(()=>[b(v(s.value.img_count===0?t.$t("generateIndexHint"):t.$t("UpdateIndex")),1)]),_:1},8,["onClick","loading"])):(o(),m(z,{key:1,type:"primary",onClick:M,loading:!e(l).isIdle,disabled:!p.value},{default:d(()=>[b(v(t.$t("search")),1)]),_:1},8,["loading","disabled"]))])):f("",!0),r(H,{size:"large",spinning:!e(l).isIdle},{default:d(()=>[r(G,{visible:e(c),"onUpdate:visible":n[2]||(n[2]=i=>B(c)?c.value=i:null),width:"70vw","mask-closable":"",onOk:n[3]||(n[3]=i=>c.value=!1)},{cancelText:d(()=>[]),default:d(()=>[r(q,{active:"",loading:!e(T).isIdle},{default:d(()=>[V("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:n[1]||(n[1]=i=>e(Y)(e(x)))},[V("div",ye,v(t.$t("doubleClickToCopy")),1),b(" "+v(e(x)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(a)?(o(),m(e(re),{key:0,ref_key:"scroller",ref:h,class:"file-list",items:e(a),"item-size":e(_).first,"key-field":"fullpath","item-secondary-size":e(_).second,gridItems:e(R)},{default:d(({item:i,index:D})=>[r(de,{idx:D,file:i,"show-menu-idx":e(g),"onUpdate:showMenuIdx":n[4]||(n[4]=Q=>B(g)?g.value=Q:null),onFileItemClick:e(L),"full-screen-preview-image-url":e(a)[e(u)]?e(ee)(e(a)[e(u)]):"",selected:e(K).includes(D),onContextMenuClick:e(y),onDragstart:e(N),onDragend:e(O),onPreviewVisibleChange:e(E)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onDragstart","onDragend","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):f("",!0),e(w)?(o(),k("div",we,[r(e(ue),{onClick:n[5]||(n[5]=i=>e(C)("prev")),class:A({disable:!e(I)("prev")})},null,8,["class"]),r(e(ce),{onClick:n[6]||(n[6]=i=>e(C)("next")),class:A({disable:!e(I)("next")})},null,8,["class"])])):f("",!0)]),_:1},8,["spinning"]),e(w)&&e(a)&&e(a)[e(u)]?(o(),m(pe,{key:1,file:e(a)[e(u)],idx:e(u),onContextMenuClick:e(y)},null,8,["file","idx","onContextMenuClick"])):f("",!0)],512)}}});const De=oe(Ce,[["__scopeId","data-v-bf9bdccd"]]);export{De as default};

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{cn as I,co as _,bX as A,aM as P,b6 as m,cp as y,b8 as b,cq as C,b4 as E,bo as R,c1 as a}from"./index-242b55ec.js";function M(t){return function(n){return n==null?void 0:n[t]}}var O=1,D=2;function T(t,n,e,s){var r=e.length,c=r,d=!s;if(t==null)return!c;for(t=Object(t);r--;){var i=e[r];if(d&&i[2]?i[1]!==t[i[0]]:!(i[0]in t))return!1}for(;++r<c;){i=e[r];var o=i[0],u=t[o],f=i[1];if(d&&i[2]){if(u===void 0&&!(o in t))return!1}else{var g=new I;if(s)var p=s(u,f,o,t,n,g);if(!(p===void 0?_(f,u,O|D,s,g):p))return!1}}return!0}function h(t){return t===t&&!A(t)}function S(t){for(var n=P(t),e=n.length;e--;){var s=n[e],r=t[s];n[e]=[s,r,h(r)]}return n}function l(t,n){return function(e){return e==null?!1:e[t]===n&&(n!==void 0||t in Object(e))}}function L(t){var n=S(t);return n.length==1&&n[0][2]?l(n[0][0],n[0][1]):function(e){return e===t||T(e,t,n)}}function x(t,n,e){var s=t==null?void 0:m(t,n);return s===void 0?e:s}var G=1,v=2;function F(t,n){return y(t)&&h(n)?l(b(t),n):function(e){var s=x(e,t);return s===void 0&&s===n?C(e,t):_(n,s,G|v)}}function B(t){return function(n){return m(n,t)}}function q(t){return y(t)?M(b(t)):B(t)}function N(t){return typeof t=="function"?t:t==null?E:typeof t=="object"?R(t)?F(t[0],t[1]):L(t):q(t)}const U=async()=>(await a.get("/db/basic_info")).data,$=async()=>(await a.get("/db/expired_dirs")).data,X=async()=>{await a.post("/db/update_image_data",{},{timeout:1/0})},H=async t=>(await a.post("/db/match_images_by_tags",t)).data,J=async t=>(await a.post("/db/add_custom_tag",t)).data,Q=async t=>(await a.post("/db/toggle_custom_tag_to_img",t)).data,W=async t=>{await a.post("/db/remove_custom_tag",t)},Y=async t=>(await a.get("/db/img_selected_custom_tag",{params:{path:t}})).data,Z=async t=>(await a.get("/db/search_by_substr",{params:{substr:t}})).data,w="/db/scanned_paths",z=async t=>{await a.post(w,{path:t})},k=async t=>{await a.delete(w,{data:{path:t}})};export{U as a,N as b,$ as c,J as d,Z as e,Y as f,H as g,k as h,z as i,W as r,Q as t,X as u}; import{cn as I,co as _,bX as A,aM as P,b6 as m,cp as y,b8 as b,cq as C,b4 as E,bo as R,c1 as a}from"./index-3ed6c068.js";function M(t){return function(n){return n==null?void 0:n[t]}}var O=1,D=2;function T(t,n,e,s){var r=e.length,c=r,d=!s;if(t==null)return!c;for(t=Object(t);r--;){var i=e[r];if(d&&i[2]?i[1]!==t[i[0]]:!(i[0]in t))return!1}for(;++r<c;){i=e[r];var o=i[0],u=t[o],f=i[1];if(d&&i[2]){if(u===void 0&&!(o in t))return!1}else{var g=new I;if(s)var p=s(u,f,o,t,n,g);if(!(p===void 0?_(f,u,O|D,s,g):p))return!1}}return!0}function h(t){return t===t&&!A(t)}function S(t){for(var n=P(t),e=n.length;e--;){var s=n[e],r=t[s];n[e]=[s,r,h(r)]}return n}function l(t,n){return function(e){return e==null?!1:e[t]===n&&(n!==void 0||t in Object(e))}}function L(t){var n=S(t);return n.length==1&&n[0][2]?l(n[0][0],n[0][1]):function(e){return e===t||T(e,t,n)}}function x(t,n,e){var s=t==null?void 0:m(t,n);return s===void 0?e:s}var G=1,v=2;function F(t,n){return y(t)&&h(n)?l(b(t),n):function(e){var s=x(e,t);return s===void 0&&s===n?C(e,t):_(n,s,G|v)}}function B(t){return function(n){return m(n,t)}}function q(t){return y(t)?M(b(t)):B(t)}function N(t){return typeof t=="function"?t:t==null?E:typeof t=="object"?R(t)?F(t[0],t[1]):L(t):q(t)}const U=async()=>(await a.get("/db/basic_info")).data,$=async()=>(await a.get("/db/expired_dirs")).data,X=async()=>{await a.post("/db/update_image_data",{},{timeout:1/0})},H=async t=>(await a.post("/db/match_images_by_tags",t)).data,J=async t=>(await a.post("/db/add_custom_tag",t)).data,Q=async t=>(await a.post("/db/toggle_custom_tag_to_img",t)).data,W=async t=>{await a.post("/db/remove_custom_tag",t)},Y=async t=>(await a.get("/db/img_selected_custom_tag",{params:{path:t}})).data,Z=async t=>(await a.get("/db/search_by_substr",{params:{substr:t}})).data,w="/db/scanned_paths",z=async t=>{await a.post(w,{path:t})},k=async t=>{await a.delete(w,{data:{path:t}})};export{U as a,N as b,$ as c,J as d,Z as e,Y as f,H as g,k as h,z as i,W as r,Q as t,X as u};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{Z as l,bq as q,b4 as y}from"./index-242b55ec.js";import{u as D,b as E,f as P,c as z,d as G,e as Q,g as R}from"./hook-47714a2a.js";const H=()=>{const e=l(),c=q(),o=l(),t={tabIdx:-1,target:"local",paneIdx:-1,walkMode:!1},{stackViewEl:r,multiSelectedIdxs:u,stack:m}=D({images:e}).toRefs(),{itemSize:f,gridItems:v}=E(t),{showMenuIdx:p}=P(),{onFileDragStart:I,onFileDragEnd:d}=z(),{showGenInfo:g,imageGenInfo:w,q:x,onContextMenuClick:i,onFileItemClick:k}=G(t,{openNext:y}),{previewIdx:F,previewing:M,onPreviewVisibleChange:b,previewImgMove:h,canPreview:C}=Q(t,{scroller:o,files:e}),S=async(n,s,a)=>{m.value=[{curr:"",files:e.value}],await i(n,s,a)};return R("removeFiles",async({paths:n})=>{var s;e.value=(s=e.value)==null?void 0:s.filter(a=>!n.includes(a.fullpath))}),{scroller:o,queue:c,images:e,onContextMenuClickU:S,stackViewEl:r,previewIdx:F,previewing:M,onPreviewVisibleChange:b,previewImgMove:h,canPreview:C,itemSize:f,gridItems:v,showGenInfo:g,imageGenInfo:w,q:x,onContextMenuClick:i,onFileItemClick:k,showMenuIdx:p,multiSelectedIdxs:u,onFileDragStart:I,onFileDragEnd:d}};export{H as u}; import{Z as l,bq as q,b4 as y}from"./index-3ed6c068.js";import{u as D,b as E,f as P,c as z,d as G,e as Q,g as R}from"./hook-ab96b9b6.js";const H=()=>{const e=l(),c=q(),o=l(),t={tabIdx:-1,target:"local",paneIdx:-1,walkMode:!1},{stackViewEl:r,multiSelectedIdxs:u,stack:m}=D({images:e}).toRefs(),{itemSize:f,gridItems:v}=E(t),{showMenuIdx:p}=P(),{onFileDragStart:I,onFileDragEnd:d}=z(),{showGenInfo:g,imageGenInfo:w,q:x,onContextMenuClick:i,onFileItemClick:k}=G(t,{openNext:y}),{previewIdx:F,previewing:M,onPreviewVisibleChange:b,previewImgMove:h,canPreview:C}=Q(t,{scroller:o,files:e}),S=async(n,s,a)=>{m.value=[{curr:"",files:e.value}],await i(n,s,a)};return R("removeFiles",async({paths:n})=>{var s;e.value=(s=e.value)==null?void 0:s.filter(a=>!n.includes(a.fullpath))}),{scroller:o,queue:c,images:e,onContextMenuClickU:S,stackViewEl:r,previewIdx:F,previewing:M,onPreviewVisibleChange:b,previewImgMove:h,canPreview:C,itemSize:f,gridItems:v,showGenInfo:g,imageGenInfo:w,q:x,onContextMenuClick:i,onFileItemClick:k,showMenuIdx:p,multiSelectedIdxs:u,onFileDragStart:I,onFileDragEnd:d}};export{H as u};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
vue/dist/index.html vendored
View File

@ -7,7 +7,7 @@
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Infinite Image Browsing</title> <title>Infinite Image Browsing</title>
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-242b55ec.js"></script> <script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-3ed6c068.js"></script>
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-8035c113.css"> <link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-8035c113.css">
</head> </head>

View File

@ -130,13 +130,13 @@ const zh = {
removeFromSearchScanPathAndQuickMove: '从搜索扫描路径和快速移动中移除', removeFromSearchScanPathAndQuickMove: '从搜索扫描路径和快速移动中移除',
serverKeyRequired: '服务器配置了密匙,你必须提供相同的密匙才能继续使用', serverKeyRequired: '服务器配置了密匙,你必须提供相同的密匙才能继续使用',
shortcutKey: '快捷键(仅允许在全屏预览下使用)', shortcutKey: '快捷键(仅允许在全屏预览下使用)',
shortcutKeyDescription: '点击输入框按下你想使用的案件支持与Shift和Ctrl进行组合', shortcutKeyDescription: '点击输入框按下你想使用的按键支持与Shift和Ctrl进行组合',
fullscreenRestriction: '受技术限制,当前拓展不允许删除打开全屏预览时的首张图片。', fullscreenRestriction: '受技术限制,当前拓展不允许删除打开全屏预览时的首张图片。',
clear: '清除', clear: '清除',
toggleTagSelection: '切换 "{tag}" 标签选中', toggleTagSelection: '切换 "{tag}" 标签选中',
changlog: '更新日志', changlog: '更新日志',
accessControlModeTips: accessControlModeTips:
'为确保数据安全,您当前正以访问控制模式运行,仅能访问授权文件夹。您可以通过编辑本拓展根目录的下.env文件来调整访问权限设置.如果不存在.env文件, 你可以将.env.example文件复制并重命名为.env', '为确保数据安全,您当前正以访问控制模式运行,仅能访问授权文件夹。您可以通过编辑本拓展根目录的下.env文件来调整访问权限设置 (IIB_ACCESS_CONTROL) .如果不存在.env文件, 你可以将.env.example文件复制并重命名为.env',
dontShowAgain: '不再显示', dontShowAgain: '不再显示',
defaultSortingMethod: '默认排序方法', defaultSortingMethod: '默认排序方法',
defaultViewMode: '默认查看模式', defaultViewMode: '默认查看模式',
@ -178,7 +178,7 @@ const en: Record<keyof typeof zh, string> = {
showPreviewImage: 'Show Preview Image', showPreviewImage: 'Show Preview Image',
dontShowAgain: "Don't show again", dontShowAgain: "Don't show again",
accessControlModeTips: accessControlModeTips:
'To ensure data security, you are currently running in access control mode, which only allows access to authorized folders. You can adjust the access permissions settings by editing the .env file in the root directory of this extension. If the .env file does not exist, you can copy the .env.example file and rename it to .env.', 'To ensure data security, you are currently running in access control mode, which only allows access to authorized folders. You can adjust the access permissions settings (IIB_ACCESS_CONTROL) by editing the .env file in the root directory of this extension. If the .env file does not exist, you can copy the .env.example file and rename it to .env.',
changlog: 'Change log', changlog: 'Change log',
clear: 'Clear', clear: 'Clear',
toggleTagSelection: 'Toggle Selection of Tag "{tag}"', toggleTagSelection: 'Toggle Selection of Tag "{tag}"',