91 lines
4.2 KiB
Python
Executable File
91 lines
4.2 KiB
Python
Executable File
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()) |