"""Professional GEO Report Generator — white-label HTML + PDF.""" import json, os from pathlib import Path from datetime import datetime def _get_branding() -> dict: """Load white-label settings; fall back to Moharek defaults.""" try: settings_path = Path(os.environ.get('OUTPUT_DIR', './output')) / 'settings.json' if settings_path.exists(): s = json.loads(settings_path.read_text()) if s.get('agency_name'): return { 'name': s.get('agency_name', 'Moharek GEO'), 'logo': s.get('agency_logo', '/logo.webp'), 'color': s.get('primary_color', '#10b981'), 'footer': s.get('report_footer', ''), } except Exception: pass return {'name': 'Moharek GEO', 'logo': '/logo.webp', 'color': '#10b981', 'footer': ''} def build_html_report(job_dir: str) -> str: p = Path(job_dir) audit, analysis, recs = {}, {}, {} for fname, target in [('audit.json','audit'),('analysis.json','analysis'),('recommendations.json','recs')]: path = p / fname if path.exists(): try: data = json.loads(path.read_text(encoding='utf-8')) if target == 'audit': audit = data elif target == 'analysis': analysis = data elif target == 'recs': recs = data except Exception: pass brand = _get_branding() pages = audit.get('pages', []) org = audit.get('org_name') or (pages[0].get('title') if pages else 'Website') url = audit.get('url') or (pages[0].get('url') if pages else '') geo = analysis.get('geo_score') or {} score = geo.get('score', 0) status = geo.get('status', 'N/A') breakdown = geo.get('breakdown', {}) actions = recs.get('actions', []) if isinstance(recs, dict) else [] per_page = recs.get('per_page', []) if isinstance(recs, dict) else [] date_str = datetime.utcnow().strftime('%Y-%m-%d') score_color = '#10b981' if score >= 75 else '#f59e0b' if score >= 40 else '#ef4444' accent = brand['color'] def bar(val, max_val=20): pct = min(100, int((val / max_val) * 100)) return f'
{url}
تاريخ التقرير: {date_str} · الحالة: {status}
الصفحات المحللة: {total_pages} · المشاكل المكتشفة: {total_issues}
لا توجد توصيات — شغّل تحليل الذكاء الاصطناعي أولاً.
' if not actions else f'''| # | الأولوية | الإجراء المطلوب |
|---|
لا توجد بيانات صفحات.
' if not per_page else f'''| الصفحة | الحالة | المشاكل |
|---|
{reason}
' results = ai_vis.get('results', []) rows = ''.join(f'''| الاستعلام | النتيجة |
|---|