chore(snapshot): Auto AI snapshot 2026-07-26 19:44:17

This commit is contained in:
DemonGatanjieu
2026-07-26 19:44:17 +08:00
parent ab86fceb35
commit dee6e6ec79
4 changed files with 25 additions and 10 deletions
-4
View File
@@ -33,10 +33,6 @@ def _extract_safetensors_hash(file_path):
if 'modelspec.hash.blake3' in metadata:
return metadata['modelspec.hash.blake3']
for k, v in metadata.items():
if ('hash' in k.lower() or 'civitai' in k.lower()) and isinstance(v, str):
if len(v) == 64 and all(c in '0123456789abcdefABCDEF' for c in v):
return v
except Exception:
pass
return None
+17
View File
@@ -91,6 +91,7 @@ async def api_scan_folder(request):
skip_rename = data.get("skip_rename", False)
virtual_rename = data.get("virtual_rename", False)
physical_rename = data.get("physical_rename", False)
force_overwrite = data.get("force_overwrite", False)
try:
marker_file = os.path.join(target_dir, '.scan_in_progress')
@@ -106,6 +107,8 @@ async def api_scan_folder(request):
cmd.append("--virtual-rename")
if physical_rename:
cmd.append("--physical-rename")
if force_overwrite:
cmd.append("--force-overwrite")
subprocess.run(
cmd,
@@ -147,6 +150,7 @@ async def api_scan_all(request):
skip_rename = data.get("skip_rename", True)
virtual_rename = data.get("virtual_rename", False)
physical_rename = data.get("physical_rename", False)
force_overwrite = data.get("force_overwrite", False)
try:
with open(marker_file, 'w') as f: f.write('1')
@@ -170,6 +174,8 @@ async def api_scan_all(request):
cmd.append("--virtual-rename")
if physical_rename:
cmd.append("--physical-rename")
if force_overwrite:
cmd.append("--force-overwrite")
if not use_local_metadata:
cmd.append("--skip-local-metadata")
subprocess.run(
@@ -254,6 +260,13 @@ async def api_scan_missing_models(request):
except ImportError:
return web.json_response({"status": "error", "message": "Failed to load scraper module"})
try:
data = await request.json()
except Exception:
data = {}
force_overwrite = data.get("force_overwrite", False)
def run_deep_scan():
GLOBAL_SCAN_STATE["scanning"] = True
GLOBAL_SCAN_STATE["total"] = 0
@@ -282,6 +295,10 @@ async def api_scan_missing_models(request):
# Check if a valid info file exists
has_valid_info = False
actual_info = info_path if os.path.exists(info_path) else (civitai_info_path if os.path.exists(civitai_info_path) else None)
if force_overwrite:
actual_info = None
if actual_info:
try:
with open(actual_info, 'r', encoding='utf-8') as f:
+4 -5
View File
@@ -72,11 +72,6 @@ def extract_safetensors_hash(file_path: str) -> Optional[str]:
if 'modelspec.hash.blake3' in metadata:
return metadata['modelspec.hash.blake3']
# 优先级2: 其他带 hash 的键
for k, v in metadata.items():
if ('hash' in k.lower() or 'civitai' in k.lower()) and isinstance(v, str):
if len(v) == 64 and all(c in '0123456789abcdefABCDEF' for c in v):
return v
except Exception as e:
pass
return None
@@ -200,6 +195,7 @@ def main():
parser.add_argument("--physical-rename", action="store_true", help="物理重命名:真实修改底层的 safetensors 及其附属文件名")
parser.add_argument("--skip-media", action="store_true", help="不下载预览图或视频")
parser.add_argument("--offline-only", action="store_true", help="跳过 Civitai 联网获取,强制使用本地脱机张量推断提取 Base Model")
parser.add_argument("--force-overwrite", action="store_true", help="强制覆盖已存在的信息文件")
args = parser.parse_args()
target_folder = args.folder
@@ -268,6 +264,9 @@ def main():
old_base = os.path.splitext(file_path)[0]
info_exists = os.path.exists(old_base + ".info") or os.path.exists(old_base + ".civitai.info")
if args.force_overwrite:
info_exists = False
preview_exists = args.skip_media
if not preview_exists:
for ext in [".png", ".jpg", ".jpeg", ".webp", ".gif", ".avif", ".mp4", ".webm", ".mov", ".avi", ".preview.png", ".preview.jpg", ".preview.jpeg", ".preview.webp", ".preview.gif", ".preview.avif", ".preview.mp4", ".preview.webm", ".preview.mov", ".preview.avi"]:
+4 -1
View File
@@ -476,6 +476,7 @@ class AnomalousBrowser {
let scanMode = 'civitai';
let enableRename = true;
let enableAutoCheck = true;
let enableForceOverwrite = false;
let updateSections = () => { };
const formGroup = document.createElement('div');
@@ -735,6 +736,7 @@ class AnomalousBrowser {
const s3List = document.createElement('div');
const isInject = localStorage.getItem('anomalous_inject_hash') !== 'false';
s3List.appendChild(createListRow('📦', '模型溯源绑定', 'Model Provenance Binding', '全局生效。每次生成图片或保存工作流时,将模型的精确哈希值隐式写入到图像元数据与工作流 JSON 中,防止未来模型改名或换环境后报错找不到。', 'Global effect. Implicitly embed exact model hashes into generated images and saved workflows, ensuring missing models can always be auto-fixed.', createMaterialSwitch(isInject, (s) => localStorage.setItem('anomalous_inject_hash', s ? 'true' : 'false'))));
s3List.appendChild(createListRow('⚠️', '强制覆盖已有配置', 'Force Overwrite Configs', '扫描时忽略本地已存在的 .info 文件,强制重新计算哈希并覆盖下载。用于修复匹配错乱的模型。', 'Ignore existing .info files and force re-scan/overwrite. Useful for fixing mismatched models.', createMaterialSwitch(enableForceOverwrite, (s) => enableForceOverwrite = s)));
s3List.appendChild(createListRow('🪄', '智能修复当前工作流', 'Smart Fix Current Workflow', '扫描完成后,自动尝试用最新数据修复当前画布中提示缺失的报错模型节点。', 'After scanning, automatically attempt to fix missing model errors on the current canvas.', createMaterialSwitch(enableAutoCheck, (s) => enableAutoCheck = s)));
s3List.lastChild.style.borderBottom = 'none';
@@ -764,7 +766,8 @@ class AnomalousBrowser {
offline_only: scanMode === 'offline',
skip_rename: !enableRename,
virtual_rename: enableRename ? enableVirtualRename : false,
physical_rename: enableRename ? enablePhysicalRename : false
physical_rename: enableRename ? enablePhysicalRename : false,
force_overwrite: enableForceOverwrite
};
let targetUrl = '';