v89-v91 模板增强 + 图源映射 + 多模态提示词可配置化
- 图源映射统一:热点采集与 Pinterest 模式均走 config.product.mark_dirs 配置,按任务序号随机抽模特图/平铺图 - 商品产地固定:统一为「中国大陆」+「产地省份=广东省」(不再读站点/字典映射) - 模板 SKU 字段检测:按建议售价同一套路检测 SKU分类/SKU数量/SKU数量单位,必填时填入单品/1/件 - 多模态分析提示词可配置:prompts/pinterest_analyze_system.md + user.md,支持国家覆盖,不丢文件回退内置 - 自定义图片模式:新增 pinterest_custom_load_node,图片数量硬校验,选品清单 ≤ 有效图片数 - 模板导出优化:写入前按货号末 3 位升序排序,不再产生空白 xlsx - 修复 v90 project review 10 项(503 致命终止、线程安全、原子写入等)
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""Pinterest 参考模式自定义节点:加载本地图片文件夹 → 校验数量 → 注册进图池(pinterest_custom_load)。
|
||||
|
||||
仅自定义模式(pinterest.mode=custom)使用,替代 pinterest_search + pinterest_scrape:
|
||||
直接把 pinterest.custom_image_dir 内的有效图片(jpg/jpeg/png/webp)注册进图池,
|
||||
再复用 pinterest_analyze 直接送多模态分析,沿用 Pinterest 后续所有步骤
|
||||
(分析→设计→三合一→OSS→种草图→模板导出)。
|
||||
|
||||
数量校验(硬校验,不满足则不启动分析):
|
||||
1. 文件夹必须有有效图片(>0);
|
||||
2. 选品清单总数(product.spu_tasks 展开后,state.pinterest_target)必须 ≤ 有效图片数 ——
|
||||
「选品清单不得大于有效图片数」。
|
||||
|
||||
每次运行把图池重建为该文件夹的图片集(自定义模式唯一图源),并清空已消费拉黑
|
||||
(used_images),保证用户每次重新上传/选择文件夹的所有有效图片都会被重新多模态分析。
|
||||
"""
|
||||
from typing import Any, Dict
|
||||
|
||||
from graph.pinterest import (
|
||||
image_md5,
|
||||
list_valid_images,
|
||||
save_image_pool,
|
||||
save_used_images,
|
||||
)
|
||||
from graph.validate import with_fallback
|
||||
|
||||
|
||||
@with_fallback("pinterest_custom_load")
|
||||
def pinterest_custom_load_node(state: Dict[str, Any]) -> Dict[str, Any]:
|
||||
config = state["config"]
|
||||
output_dir = state["output_dir"]
|
||||
country = state["country"]
|
||||
|
||||
pcfg = config.get("pinterest") or {}
|
||||
folder = str(pcfg.get("custom_image_dir") or "").strip()
|
||||
|
||||
images = list_valid_images(folder)
|
||||
valid_n = len(images)
|
||||
target = int(state.get("pinterest_target") or 1)
|
||||
|
||||
errors = list(state.get("errors") or [])
|
||||
stats = dict(state.get("stats") or {})
|
||||
|
||||
# —— 硬校验 1:必须有有效图片 ——
|
||||
if valid_n == 0:
|
||||
msg = (f"自定义图片文件夹「{folder or '(未填写)'}」中没有有效图片"
|
||||
f"(请填写 pinterest.custom_image_dir,文件夹内应有 jpg/jpeg/png/webp 图片)")
|
||||
errors.append({"node": "pinterest_custom_load", "type": "ValidationError",
|
||||
"message": msg, "trace": ""})
|
||||
stats["pinterest_custom"] = {"folder": folder, "valid_images": 0, "target": target, "ok": False}
|
||||
print(f"[pinterest_custom_load] ❌ {msg}")
|
||||
return {"errors": errors, "stats": stats}
|
||||
|
||||
# —— 硬校验 2:选品清单总数 ≤ 有效图片数 ——
|
||||
if target > valid_n:
|
||||
msg = (f"选品清单数量({target})大于自定义图片有效数量({valid_n}):"
|
||||
f"选品清单不得大于有效图片数,请补充图片或减少选品")
|
||||
errors.append({"node": "pinterest_custom_load", "type": "ValidationError",
|
||||
"message": msg, "trace": ""})
|
||||
stats["pinterest_custom"] = {"folder": folder, "valid_images": valid_n, "target": target, "ok": False}
|
||||
print(f"[pinterest_custom_load] ❌ {msg}")
|
||||
return {"errors": errors, "stats": stats}
|
||||
|
||||
# —— 每次运行重建图池为该文件夹图片集 + 清空已消费拉黑 → 所有有效图片都被重新分析 ——
|
||||
pool = {"updated_at": "", "images": []}
|
||||
seen_md5: set = set()
|
||||
for f in images:
|
||||
m = str(image_md5(str(f)) or "").strip().lower()
|
||||
if not m or m in seen_md5:
|
||||
continue
|
||||
seen_md5.add(m)
|
||||
pool["images"].append({"path": str(f), "md5": m, "term": "custom"})
|
||||
save_image_pool(output_dir, country, pool)
|
||||
save_used_images(output_dir, country, set())
|
||||
|
||||
stats["pinterest_custom"] = {
|
||||
"folder": folder, "valid_images": valid_n,
|
||||
"target": target, "loaded": len(pool["images"]), "ok": True,
|
||||
}
|
||||
print(f"[pinterest_custom_load] 自定义图源:{folder} → 有效图片 {valid_n} 张(选品清单 {target}),"
|
||||
f"已注册进图池,直接进入多模态分析")
|
||||
return {"custom_mode": True, "pinterest_custom_folder": folder,
|
||||
"custom_load_ok": True, "errors": errors, "stats": stats}
|
||||
Reference in New Issue
Block a user