CoolFace
Apppublic

ghstedpixel/app.py

sourceHugging Faceupdated 4mo agoView on Hugging Face
0likes
schema.py185 linesDownload Raw Back to root
1import re2from urllib.parse import urlparse, parse_qs, unquote3 4def parse_size_type_and_variants(size_str: str):5    """Identifies the explicit size category domain and outputs clean structural signatures for cross-matching"""6    if not size_str: return None, []7    s = size_str.upper().strip()8    storage_match = re.search(r'(\d+)\s*(GB|TB)', s)9    if storage_match:10        val = int(storage_match.group(1))11        unit = storage_match.group(2)12        sig = f"{val}GB" if unit == "GB" else f"{val*1024}GB"13        return "storage", [sig]14            15    liquid_match = re.search(r'(\d+(?:\.\d+)?)\s*(?:FL\.?\s*)?(OZ|ML)', s)16    if liquid_match:17        num = float(liquid_match.group(1))18        unit = liquid_match.group(2)19        if unit in ["OZ", "FL"]:20            if abs(num - 3.4) < 0.2: return "liquid", ["3.4OZ", "100ML"]21            if abs(num - 1.7) < 0.2: return "liquid", ["1.7OZ", "50ML"]22            if abs(num - 2.5) < 0.2: return "liquid", ["2.5OZ", "75ML"]23            if abs(num - 4.2) < 0.2: return "liquid", ["4.2OZ", "125ML"]24            if abs(num - 1.0) < 0.2: return "liquid", ["3.0OZ", "30ML"]25            if abs(num - 6.7) < 0.3: return "liquid", ["6.7OZ", "200ML"]26            return "liquid", [f"{num}OZ"]27        else:28            if abs(num - 100) < 6: return "liquid", ["3.4OZ", "100ML"]29            if abs(num - 50) < 4: return "liquid", ["1.7OZ", "50ML"]30            if abs(num - 75) < 5: return "liquid", ["2.5OZ", "75ML"]31            if abs(num - 125) < 6: return "liquid", ["4.2OZ", "125ML"]32            if abs(num - 30) < 3: return "liquid", ["1.0OZ", "30ML"]33            if abs(num - 200) < 11: return "liquid", ["6.7OZ", "200ML"]34            return "liquid", [f"{num}ML"]35                36    clothing_map = {37        "XS": "XS", "EXTRA SMALL": "XS", "EXTRASMALL": "XS",38        "S": "S", "SMALL": "S", "M": "M", "MEDIUM": "M", "L": "L", "LARGE": "L",39        "XL": "XL", "X-LARGE": "XL", "EXTRALARGE": "XL",40        "XXL": "2XL", "2XL": "2XL", "2X-LARGE": "2XL",41        "3XL": "3XL", "3X-LARGE": "3XL", "XXXL": "3XL"42    }43    for k, v in clothing_map.items():44        if f" {k} " in f" {s} " or s == k or s.replace("-", "") == k.replace(" ", ""): return "clothing", [v]45                46    shoe_match = re.search(r'\b(?:SIZE|SZ|US|UK|EU)?\s*(\d+(?:\.5)?)\b', s)47    if shoe_match: return "numeric", [shoe_match.group(1)]48    return "generic", [s.replace(" ", "")]49 50def is_size_mismatched(target_size: str, parsed_text: str) -> bool:51    """Scans and rejects store pages listing alternate competing product configurations automatically"""52    if not target_size or not parsed_text: return False53    category, target_variants = parse_size_type_and_variants(target_size)54    if not category or not target_variants: return False55            56    text_upper = " " + parsed_text.upper() + " "57    for var in target_variants:58        if category == "clothing":59            if re.search(r'\b' + re.escape(var) + r'\b', text_upper): return False60        elif category in ["storage", "liquid"]:61            if var in text_upper.replace(" ", ""): return False62        elif category == "numeric":63            if re.search(r'\b(?:SIZE|SZ|US|UK|EU)?\s*' + re.escape(var) + r'\b', text_upper): return False64 65    if category == "storage":66        found_storage = re.findall(r'(\d+)\s*(GB|TB)', text_upper)67        for val, unit in found_storage:68            sig = f"{val}GB" if unit == "GB" else f"{val*1024}GB"69            if sig not in target_variants: return True70    elif category == "liquid":71        found_liquids = re.findall(r'(\d+(?:\.\d+)?)\s*(?:FL\.?\s*)?(OZ|ML)', text_upper)72        for num, unit in found_liquids:73            _, found_variants = parse_size_type_and_variants(f"{num} {unit}")74            if found_variants and not any(fv in target_variants for fv in found_variants): return True75    elif category == "clothing":76        clothing_words = ["XS", "SMALL", "MEDIUM", "LARGE", "XL", "XXL", "2XL", "3XL"]77        for word in clothing_words:78            _, f_vars = parse_size_type_and_variants(word)79            if f_vars and f_vars[0] != target_variants[0]:80                if re.search(r'\b' + re.escape(word) + r'\b', text_upper) or re.search(r'\b' + re.escape(f_vars[0]) + r'\b', text_upper): return True81    elif category == "numeric":82        found_numbers = re.findall(r'\b(?:SIZE|SZ|US|UK|EU)?\s*(\d+(?:\.5)?)\b', text_upper)83        for num in found_numbers:84            if num not in target_variants: return True85                    86    return False87 88def extract_universal_sizing(text: str) -> str:89    """Uses a normalized regex matrix to extract clean formatting standards for product layout rendering"""90    if not text or len(text) > 100: return ""91    text_cleaned = re.sub(r"['’]S\b", "", text.upper())92    text_norm = " " + text_cleaned.strip() + " "93        94    storage_match = re.search(r'(\d+)\s*(GB|TB)\b', text_norm)95    if storage_match: return f"{storage_match.group(1)} {storage_match.group(2)}"96            97    dim_match = re.search(r'(\d+(?:\.\d+)?)\s*(?:FL\.?\s*)?(OZ|ML)\b', text_norm)98    if dim_match: return f"{dim_match.group(1)} {dim_match.group(2)}"99            100    if "EXTRA LARGE" in text_norm or "X-LARGE" in text_norm: return "XL"101    if "LARGE" in text_norm: return "L"102    if "MEDIUM" in text_norm: return "M"103    if "SMALL" in text_norm: return "S"104    clothing_match = re.search(r'\b(XS|S|M|L|XL|2XL|XXL|3XL|4XL)\b', text_norm)105    if clothing_match: return clothing_match.group(1)106            107    shoe_match = re.search(r'\b(?:SIZE|SZ|US|UK|EU)?\s*(\d+(?:\.5)?)\b', text_norm)108    if shoe_match: return shoe_match.group(1)109    110    return ""111 112def clean_google_link(url: str) -> str:113    """114    Aggressively strips tracking redirects from both google.com and googleadservices.com,115    instantly routing users to the direct outbound merchant hosting the product.116    """117    if not url:118        return ""119        120    # Catch both organic shopping gates and paid ad service redirects121    if "google.com" not in url and "googleadservices.com" not in url:122        return url123        124    try:125        # Step 1: Recursively unquote to clear multi-layered encoding tricks (%2F, %3A, etc.)126        decoded_link = unquote(url)127        while "%" in decoded_link:128            prev_link = decoded_link129            decoded_link = unquote(decoded_link)130            if prev_link == decoded_link:131                break132        133        # Step 2: Query parameter interception gate134        parsed_url = urlparse(decoded_link)135        qs = parse_qs(parsed_url.query)136        137        # 'adurl' handles googleadservices/aclk ads; 'url'/'q' handle organic redirects138        for redirect_param in ['adurl', 'url', 'q', 'link', 'shopping_redirect', 'destination']:139            if redirect_param in qs:140                target_url = qs[redirect_param][0].strip()141                if target_url.startswith(("http://", "https://")):142                    return target_url143 144        # Step 3: Global Heuristic Regex Fallback145        # Extract any raw embedded HTTP/HTTPS url that skips Google's tracking ecosystem entirely146        found_urls = re.findall(r'(https?://[^\s&"\'<>]+)', decoded_link)147        for sub_url in found_urls:148            if "google.com" not in sub_url and "googleadservices.com" not in sub_url:149                if "?" in sub_url:150                    base_part, query_part = sub_url.split("?", 1)151                    # Strip downstream marketing bloat tags clean152                    query_part = re.sub(r'&?(gclid|gclsrc|utm_[^&=]+|affp|affiliate)[^&]*', '', query_part, flags=re.IGNORECASE)153                    sub_url = f"{base_part}?{query_part}".rstrip('?').rstrip('&')154                return sub_url155 156    except Exception as e:157        print(f"⚠️ [Link Extractor Error] Could not unwrap target metadata: {e}")158        159    return url160 161def parse_price_locally(dense_text, product_name):162    """Programmatic textual parsing engine to extract valid retail pricing while isolating shipping costs and spoof values"""163    print("⚙️ [Local Solver] Running regex matrix heuristic extraction on text payload...")164    prices = []165    tokens = dense_text.split(" | ")166    keywords = [k.lower() for k in product_name.split() if len(k) > 2]167    invalid_context_markers = ["shipping", "save", "off", "reduced", "per month", "/mo", "discount", "coupon"]168        169    for token in tokens:170        token_clean = token.lower()171        if any(k in token_clean for k in keywords):172            if any(marker in token_clean for marker in invalid_context_markers): continue173            matches = re.findall(r'\$\s*([\d,]+(?:\.\d{2})?)', token)174            for m in matches:175                try:176                    clean_m = m.replace(',', '')177                    price_val = float(clean_m)178                    if 1.0 < price_val < 9000.0 and price_val not in [1.7, 3.3, 5.0, 6.8, 16.5, 18.0]: prices.append(price_val)179                except: continue180                    181    if prices:182        lowest_extracted = min(prices)183        print(f"🎯 [Local Solver Success] Located valid competitive target minimum: ${lowest_extracted}")184        return {"price": lowest_extracted, "found": True}185    return {"price": None, "found": False}