Files
cms-SiteForge/app/relations.py
T

51 lines
2.7 KiB
Python
Raw Normal View History

"""Content assembly: stable, site-scoped brand/category relationships.
Only materializes associations supported by source data. Generated brand shells
are clearly marked and contain no fabricated copy.
"""
from collections import defaultdict
from . import db
from .core import save_entry
from .theme_pro import fields,slug
KINDS=('product','vehicle')
def preview(site_id):
records=db.rows("SELECT * FROM entries WHERE site_id=? AND type IN ('product','vehicle','brand')",(site_id,))
brand_pages={r['title'].casefold():r for r in records if r['type']=='brand'}
routes={r['route'] for r in db.rows('SELECT route FROM entries WHERE site_id=?',(site_id,))}
brands=defaultdict(list);cats=defaultdict(list);issues=[]
for row in records:
if row['type'] not in KINDS:continue
attrs=fields(row)
brand=str(attrs.get('brand') or '').strip();category=str(attrs.get('category') or '').strip()
if brand: brands[brand].append(row['route'])
else:issues.append({'route':row['route'],'severity':'review','message':'未填写品牌'})
if category:cats[category].append(row['route'])
else:issues.append({'route':row['route'],'severity':'review','message':'未填写分类'})
if not row['cover']:issues.append({'route':row['route'],'severity':'review','message':'缺少产品封面图'})
candidates=[]
for name,products in brands.items():
if name.casefold() in brand_pages:continue
url=f'/brands/{slug(name)}/'
if url in routes:
issues.append({'route':url,'severity':'block','message':'品牌自动生成路径与已有页面冲突'});continue
candidates.append({'brand':name,'route':url,'products':len(products)})
return {'brands':[{ 'name':k,'items':len(v)} for k,v in brands.items()],
'categories':[{'name':k,'items':len(v)} for k,v in cats.items()],
'brand_pages_missing':candidates,'issues':issues,
'products':sum(len(x) for x in brands.values()),
'note':'仅根据已有产品字段建立关系;缺少真实品牌介绍/图片时不会自动编造。'}
def commit(site_id):
result=preview(site_id)
if any(issue['severity']=='block' for issue in result['issues']):
raise ValueError('存在路径冲突,请先处理后再装配')
created=[]
for brand in result['brand_pages_missing']:
save_entry(site_id,{'type':'brand','title':brand['brand'],'route':brand['route'],
'summary':'','body':'','status':'published','meta':{'fields':{'source':'auto-assembled'},'source_auto_assembled':True}},
source='relations-assembly')
created.append(brand['route'])
return {'created_brand_pages':created,'count':len(created),'preview':result}