prince1604
Merged short alt detection back into main 'poor quality' report and removed separate 'short_alt' counts as requested
14aaae8 | class ImageAnalyzer: | |
| def analyze_site(self, site_data): | |
| """ | |
| Analyzes the crawled site data for missing ALT text. | |
| :param site_data: Dict { page_url: [image_dicts] } | |
| :return: Dict containing summary and detailed report. | |
| """ | |
| total_images = 0 | |
| total_missing_alt = 0 | |
| total_poor_quality = 0 # Track all poor quality images | |
| total_short_alt_legacy = 0 # Track only strictly short ones | |
| pages_report = [] | |
| # Compile regex for filename patterns | |
| import re | |
| # Pattern 1: Common Camera Prefixes (e.g., DSC_001, IMG_1234, Screenshot-1) | |
| prefix_pattern = re.compile(r'^(dsc|img|pic|screenshot|photo)[\-_]?\d+', re.IGNORECASE) | |
| # Pattern 2: General Slug + Number (e.g., product-12345, item_01) - enforces no spaces | |
| slug_pattern = re.compile(r'^[a-z0-9\-_]+[-_]\d+$', re.IGNORECASE) | |
| for page_url, images in site_data.items(): | |
| missing_images = [] | |
| poor_quality_images = [] | |
| for img in images: | |
| total_images += 1 | |
| alt_text = img.get('alt') | |
| # 1. Strictly Missing | |
| if not alt_text or alt_text.strip() == "": | |
| missing_images.append(img['src']) | |
| total_missing_alt += 1 | |
| continue # Skip further checks if missing | |
| cleaned_alt = alt_text.strip() | |
| lower_alt = cleaned_alt.lower() | |
| word_count = len(cleaned_alt.split()) | |
| is_poor = False | |
| reason = "" | |
| # 2. Advanced Poor Quality Checks | |
| # A) File Name / Extension Check (Highest Priority) | |
| if any(lower_alt.endswith(ext) for ext in ['.jpg', '.png', '.jpeg', '.webp', '.gif', '.svg']): | |
| is_poor = True | |
| reason = "Filename extension detected" | |
| elif prefix_pattern.search(cleaned_alt): | |
| is_poor = True | |
| reason = "Filename pattern detected (prefix)" | |
| elif slug_pattern.match(cleaned_alt): | |
| is_poor = True | |
| reason = "Filename pattern detected (slug)" | |
| # B) Generic / Filler Text (Smart check) | |
| # Flag if alt equals or contains generic terms. | |
| # Exception: "Brand Name Logo" (usually > 2 words or specific) | |
| # If word count is low (< 3) AND contains a generic term, it's likely poor. | |
| # If it is EXACTLY a generic term, it is definitely poor. | |
| generic_terms = {'image', 'photo', 'picture', 'logo', 'banner', 'icon', 'thumbnail', 'placeholder', 'img', 'spacer'} | |
| if not is_poor: | |
| if lower_alt in generic_terms: | |
| # Exact match found (e.g., "logo", "image") -> Bad | |
| is_poor = True | |
| reason = "Generic filler text" | |
| else: | |
| # Check partial match for short phrases (likely "My Logo", "Chart Image") | |
| # If phrase is long (>= 3 words), it might be descriptive enough (e.g., "Eminent Tactiles Logo") | |
| # So we only flag partial generic matches if word count is small (< 3) | |
| has_generic = any(term in lower_alt.split() for term in generic_terms) | |
| if has_generic and word_count < 3: | |
| is_poor = True | |
| reason = "Generic filler text (partial match)" | |
| # C) Too Short / Sparse (Lowest Priority) | |
| if not is_poor: | |
| if len(cleaned_alt) < 5: | |
| is_poor = True | |
| reason = "Too short (< 5 chars)" | |
| elif word_count < 2: | |
| # Single word check | |
| is_poor = True | |
| reason = "Too few words (needs >= 2)" | |
| if is_poor: | |
| # Store with reason | |
| poor_quality_images.append({'src': img['src'], 'alt': alt_text, 'reason': reason}) | |
| total_poor_quality += 1 | |
| # User Intent: "short alt list and that count are add in poor not it show separately" | |
| # Action: Consolidate everything into 'poor_quality' and remove specific 'short_alt' reporting. | |
| pages_report.append({ | |
| "page_url": page_url, | |
| "missing_alt_count": len(missing_images), | |
| "poor_quality_count": len(poor_quality_images), # Contains ALL poor images (Generic, Filename, Short) | |
| "images_without_alt": list(set(missing_images)), | |
| "images_with_poor_alt": poor_quality_images | |
| }) | |
| return { | |
| "summary": { | |
| "total_pages_scanned": len(site_data), | |
| "total_images_found": total_images, | |
| "total_images_missing_alt": total_missing_alt, | |
| "total_images_poor_quality": total_poor_quality | |
| }, | |
| "details": pages_report | |
| } | |