#!/usr/bin/env python3 """Patch feed-sync-v4.py to fix category exclusion bug.""" import re with open('/var/www/sneakerpicks/scripts/feed-sync-v4.py', 'r') as f: code = f.read() # Fix is_sneaker: check footwear category IDs and inclusions BEFORE category exclusions old_func = '''def is_sneaker(title, brand, product_type, google_category): title_lower = (title or '').lower() brand_lower = (brand or '').lower() ptype_lower = (product_type or '').lower() gcat_lower = (google_category or '').lower() for pat in EXCLUDE_TITLE_PATTERNS: if re.search(pat, title_lower): return False, f'title_exclude:{pat}' for pat in NON_SNEAKER_CATEGORY_PATTERNS: if pat in ptype_lower or pat in gcat_lower: return False, f'category_exclude:{pat}' for cat_id in FOOTWEAR_CATEGORY_IDS: if gcat_lower.startswith(cat_id) or f'> {cat_id}' in gcat_lower: return True, f'gcat_id:{cat_id}' for pat in SNEAKER_CATEGORY_PATTERNS: if pat in ptype_lower or pat in gcat_lower: return True, f'category_match:{pat}' if brand_lower in SNEAKER_BRANDS: return True, f'brand_match:{brand_lower}' for pat in SNEAKER_MODEL_PATTERNS: if re.search(pat, title_lower): return True, f'model_match:{pat}' return False, 'no_match\'''' new_func = '''def is_sneaker(title, brand, product_type, google_category): title_lower = (title or '').lower() brand_lower = (brand or '').lower() ptype_lower = (product_type or '').lower() gcat_lower = (google_category or '').lower() # Step 1: Title exclusions (clothing, accessories, etc.) for pat in EXCLUDE_TITLE_PATTERNS: if re.search(pat, title_lower): return False, f'title_exclude:{pat}' # Step 2: Google category ID check (187=Shoes, 1604=Athletic Shoes) — highest priority for cat_id in FOOTWEAR_CATEGORY_IDS: if gcat_lower.startswith(cat_id) or f'> {cat_id}' in gcat_lower: return True, f'gcat_id:{cat_id}' # Step 3: Category inclusions (sneaker/footwear/shoes in product_type or category) for pat in SNEAKER_CATEGORY_PATTERNS: if pat in ptype_lower or pat in gcat_lower: return True, f'category_match:{pat}' # Step 4: Category exclusions — only checked AFTER inclusions # This prevents "Apparel & Accessories > Shoes" from being excluded by 'accessori' for pat in NON_SNEAKER_CATEGORY_PATTERNS: if pat in ptype_lower or pat in gcat_lower: return False, f'category_exclude:{pat}' # Step 5: Known sneaker brand if brand_lower in SNEAKER_BRANDS: return True, f'brand_match:{brand_lower}' # Step 6: Known model patterns for pat in SNEAKER_MODEL_PATTERNS: if re.search(pat, title_lower): return True, f'model_match:{pat}' return False, 'no_match\'''' if old_func in code: code = code.replace(old_func, new_func) with open('/var/www/sneakerpicks/scripts/feed-sync-v4.py', 'w') as f: f.write(code) print("PATCHED successfully") else: print("ERROR: old function not found, trying to find it...") # Show surrounding context idx = code.find('def is_sneaker') if idx >= 0: print(code[idx:idx+800]) else: print("is_sneaker not found at all!")