← back to Dw Yolo Loop
thibaut-mfr-fix/title_scrub.py
73 lines
#!/usr/bin/env python3
"""Thibaut title de-SKU transformer. Buckets: AUTOFIX / BACKLOG.
Preview-only unless --emit (writes /tmp/thibaut_title_proposals.tsv). No Shopify writes."""
import re, sys
rows = []
with open('/tmp/thibaut_title_cases.tsv') as f:
for line in f:
line = line.rstrip('\n')
if not line: continue
pid, mfr, pat, title = line.split('\t')
rows.append((pid, mfr, pat.strip(), title))
def strip_suffix(t):
m = re.search(r'\s*\|\s*Thibaut\s*$', t)
return (t[:m.start()], ' | Thibaut') if m else (t, '')
def cs(t):
return re.sub(r'\s{2,}', ' ', t).strip(' -–|,')
def clean_pattern(mfr, pat, body):
"""Derive a clean pattern name from a possibly-corrupted pattern_name/title body."""
src = pat if pat else body
src = re.split(r'\s+thibaut\s+', src, flags=re.I)[0] # cut at " Thibaut <repeat>"
src = re.sub(r'\(.*$', '', src) # cut at first paren
src = re.sub(r'\b'+re.escape(mfr)+r'\b', '', src, flags=re.I)
src = re.sub(r'\bproduct\b', '', src, flags=re.I)
return cs(src)
def rebuild(mfr, clean_pat, title):
body, suf = strip_suffix(title)
had_wc = bool(re.search(r'\bwallcovering\b', body, re.I))
r = body
for pat_repr in (re.escape(clean_pat), re.escape(mfr)):
r = re.sub(r'\b'+pat_repr+r'\b', ' ', r, flags=re.I)
r = re.sub(r'\(\s*\)', ' ', r)
r = re.sub(r'\bthibaut\b|\bproduct\b|\bwallcovering\b', ' ', r, flags=re.I)
color = cs(re.sub(r'[-–()]', ' ', r))
new = clean_pat + (' - ' + color if color else '')
if had_wc:
new += ' Wallcovering'
return cs(new) + suf
AUTOFIX=[]; BACKLOG=[]
for pid, mfr, pat, title in rows:
body0,_ = strip_suffix(title)
cp = clean_pattern(mfr, pat, body0)
sku_led = bool(re.match(r'^\s*'+re.escape(mfr)+r'\b', body0, re.I)) # title starts with SKU -> no real name
# unusable pattern: empty, too short, still holds the SKU, sku-led, or pattern_name itself = "<SKU> <color>"
bad_cp = (sku_led or not cp or len(cp) < 3 or re.search(r'\b'+re.escape(mfr)+r'\b', cp, re.I))
if bad_cp:
BACKLOG.append((pid, mfr, pat, title)); continue
new = rebuild(mfr, cp, title)
nb,_ = strip_suffix(new)
if not nb or len(nb) < 3 or re.search(r'\b'+re.escape(mfr)+r'\b', new, re.I) \
or re.search(r'\bthibaut\b', nb, re.I):
BACKLOG.append((pid, mfr, pat, title))
else:
AUTOFIX.append((pid, mfr, cp, title, new))
if '--emit' in sys.argv:
with open('/tmp/thibaut_title_proposals.tsv','w') as out:
for pid, mfr, cp, old, new in AUTOFIX:
out.write(f"{pid}\t{mfr}\t{old}\t{new}\n")
print(f"AUTOFIX={len(AUTOFIX)} BACKLOG={len(BACKLOG)}\n")
print("===== AUTOFIX =====")
for pid, mfr, cp, old, new in AUTOFIX:
print(f"{pid} {mfr}\n OLD: {old}\n NEW: {new}")
print("\n===== BACKLOG (needs real pattern name; title left as-is, tag still ensured) =====")
for pid, mfr, pat, title in BACKLOG:
print(f"{pid} {mfr} pat='{pat}' :: {title}")