Files
pod_trend_agent/graph/nodes/pinterest_custom_load_node.py
3218485270 71a48e4ed5 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 致命终止、线程安全、原子写入等)
2026-08-28 16:24:50 +08:00

82 lines
3.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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}