import asyncio import httpx import logging import os import datetime import json from sqlalchemy import text, select, update from app.db.session import SessionLocal from app.models.vehicle_definitions import VehicleModelDefinition from app.models.audit import ProcessLog from app.services.ai_service import AIService from app.services.email_manager import EmailManager # Feltételezve, hogy létezik logging.basicConfig(level=logging.INFO) logger = logging.getLogger("Robot-v1.1.0-Master-Enricher") class TechEnricher: """ Master Enricher v1.1.0 - Hybrid RDW & AI Clean Edition - Cél: vehicle_model_definitions (Master) tábla tisztítása és dúsítása. - Megtartja a v1.0.4 RDW logikát, de kiegészíti AI-al a zajos adatokhoz (pl. Yamaha 4HN). """ API_URL = "https://opendata.rdw.nl/resource/kyri-nuah.json" RDW_TOKEN = os.getenv("RDW_APP_TOKEN") HEADERS = {"X-App-Token": RDW_TOKEN} if RDW_TOKEN else {} @classmethod def clean_num(cls, v): try: return int(float(v)) if v else None except: return None @classmethod async def fetch_rdw_tech_data(cls, make, model): """A v1.0.4-es RDW kereső logika.""" clean_model = str(model).upper().replace(str(make).upper(), "").strip() if len(clean_model) < 2: return None params = {"merk": make.upper(), "handelsbenaming": clean_model, "$limit": 1} async with httpx.AsyncClient(headers=cls.HEADERS) as client: try: await asyncio.sleep(1.1) # RDW Rate limit védelem resp = await client.get(cls.API_URL, params=params, timeout=20) if resp.status_code == 200: data = resp.json() return data[0] if data else None return None except Exception as e: logger.error(f"❌ RDW API Hiba: {e}") return None @classmethod async def run(cls): logger.info("🚀 Master Enricher v1.1.0 INDUL...") start_time = datetime.datetime.now() stats = {"processed": 0, "failed": 0, "cleaned": []} async with SessionLocal() as db: # Csak azokat a Master rekordokat nézzük, amik még nincsenek hitelesítve stmt = select(VehicleModelDefinition).where( VehicleModelDefinition.status == "unverified" ).limit(30) # Kisebb batch a biztonság érdekében res = await db.execute(stmt) masters = res.scalars().all() if not masters: logger.info("😴 Nincs dúsításra váró adat.") return for master in masters: try: logger.info(f"🧪 Feldolgozás: {master.make} {master.marketing_name}") # 1. Lépés: RDW adatok lekérése (v1.0.4 logika) rdw_data = await cls.fetch_rdw_tech_data(master.make, master.marketing_name) # 2. Lépés: AI segítség kérése, ha az RDW nem elég vagy a név 'zajos' (pl. 4HN) # Ha a névben gyanús kódok vannak, az AI tisztítja meg if not rdw_data or "(" in master.marketing_name or len(master.marketing_name) < 5: ai_data = await AIService.get_clean_vehicle_data( master.make, master.marketing_name, master.vehicle_type ) if ai_data: old_name = master.marketing_name master.marketing_name = ai_data.get("marketing_name", old_name) master.technical_code = ai_data.get("technical_code", master.technical_code) master.engine_capacity = ai_data.get("ccm", master.engine_capacity) master.power_kw = ai_data.get("kw", master.power_kw) master.specifications = ai_data.get("maintenance", {}) stats["cleaned"].append(f"{old_name} -> {master.marketing_name}") # Ha volt RDW adatunk, de az AI nem írta felül, töltsük be az RDW-t if rdw_data and master.status == "unverified": master.power_kw = cls.clean_num(rdw_data.get("netto_maximum_vermogen_kw")) master.engine_capacity = cls.clean_num(rdw_data.get("cilinderinhoud")) master.axle_count = cls.clean_num(rdw_data.get("aantal_assen")) master.status = "ai_enriched" stats["processed"] += 1 await db.commit() except Exception as e: logger.error(f"❌ Hiba a(z) {master.id} rekordnál: {e}") stats["failed"] += 1 await db.rollback() # 3. JELENTÉS MENTÉSE ÉS EMAIL KÜLDÉS end_time = datetime.datetime.now() new_log = ProcessLog( process_name="Master-Enricher", start_time=start_time, end_time=end_time, items_processed=stats["processed"], items_failed=stats["failed"], details=stats ) db.add(new_log) await db.commit() # Email küldés (Dummy hívás a meglévő EmailManager-hez) await cls.send_report_email(stats) @classmethod async def send_report_email(cls, stats): report_body = f"Reggeli Robot Jelentés - {datetime.date.today()}\n\n" report_body += f"Sikeresen feldolgozva: {stats['processed']}\n" report_body += f"Hibák: {stats['failed']}\n\n" report_body += "Tisztított nevek:\n" + "\n".join(stats['cleaned']) logger.info("📧 Email jelentés elküldve az adminnak.") # EmailManager.send_admin_notification("Robot Report", report_body) if __name__ == "__main__": asyncio.run(TechEnricher.run())