import asyncio import logging from sqlalchemy import select, text from app.database import AsyncSessionLocal from app.models.marketplace.service import ExpertiseTag logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s') logger = logging.getLogger("Service-Robot-3-Enricher") class ServiceEnricher: """ Service Robot 3: Professional Classifier (Bíró-Kompatibilis Verzió) """ @staticmethod async def match_expertise_and_score(db, scraped_text: str, current_trust_score: int) -> int: """ Keresi a szakmákat és bónusz pontokat ad értük a Staging adatnak. """ if not scraped_text: return current_trust_score tags_query = await db.execute(select(ExpertiseTag).where(ExpertiseTag.is_official == True)) all_tags = tags_query.scalars().all() match_count = 0 for tag in all_tags: for kw in (tag.search_keywords or []): if kw.lower() in scraped_text.lower(): match_count += 1 break # Egy tag elég, ha egyszer megvan # +5 pont minden megtalált szakmáért, max 30 bónusz pont bonus = min(match_count * 5, 30) new_score = min(current_trust_score + bonus, 100) if bonus > 0: logger.info(f"✅ {match_count} szakma azonosítva. Bónusz: +{bonus} pont.") return new_score @classmethod async def run_worker(cls): logger.info("🧠 Service Enricher ONLINE - Adatdúsítás (Nem publikál, csak pontoz!)") while True: try: async with AsyncSessionLocal() as db: query = text(""" UPDATE marketplace.service_staging SET status = 'enriching' WHERE id = ( SELECT id FROM marketplace.service_staging WHERE status = 'enrich_ready' FOR UPDATE SKIP LOCKED LIMIT 1 ) RETURNING id, name, trust_score, raw_data; """) result = await db.execute(query) task = result.fetchone() await db.commit() if task: s_id, name, t_score, raw_data = task web_context = raw_data.get('web_context', '') if isinstance(raw_data, dict) else '' async with AsyncSessionLocal() as process_db: try: # 1. Kiszámoljuk az új pontszámot a webes adatok (kulcsszavak) alapján new_score = await cls.match_expertise_and_score(process_db, web_context, t_score) # 2. Visszaírjuk a Staging táblába, és átadjuk az Auditor-nak (Gamification 2.0: auditor_ready státusz) upd_query = text(""" UPDATE marketplace.service_staging SET status = 'auditor_ready', trust_score = :ns WHERE id = :id """) await process_db.execute(upd_query, {"ns": new_score, "id": s_id}) await process_db.commit() logger.info(f"✅ Dúsítás kész: {name} (Pont: {t_score} -> {new_score}). Átadva az Auditor-nak (auditor_ready).") except Exception as e: await process_db.rollback() logger.error(f"❌ Hiba a dúsítás során ({s_id}): {e}") await process_db.execute(text("UPDATE marketplace.service_staging SET status = 'error' WHERE id = :id"), {"id": s_id}) await process_db.commit() else: await asyncio.sleep(15) except Exception as e: logger.error(f"💀 Kritikus hiba a főciklusban: {e}") await asyncio.sleep(10) if __name__ == "__main__": asyncio.run(ServiceEnricher.run_worker())