117 lines
5.1 KiB
Python
117 lines
5.1 KiB
Python
import asyncio
|
|
import logging
|
|
import warnings
|
|
import os
|
|
from sqlalchemy import select, update, and_, func, or_, case # Explicit case import
|
|
from app.db.session import SessionLocal
|
|
from app.models.vehicle_definitions import VehicleModelDefinition
|
|
import httpx
|
|
|
|
# 1. KRITIKUS JAVÍTÁS: A figyelmeztetések globális elnyomása az import előtt
|
|
warnings.filterwarnings("ignore", category=RuntimeWarning, module='duckduckgo_search')
|
|
from duckduckgo_search import DDGS
|
|
|
|
# Logolás beállítása, hogy lássuk a haladást
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s')
|
|
logger = logging.getLogger("Robot-Researcher-v2.1")
|
|
|
|
class ResearcherBot:
|
|
def __init__(self):
|
|
self.batch_size = 15
|
|
self.max_parallel_queries = 5
|
|
|
|
async def fetch_source(self, label, query):
|
|
"""Egyedi forrás lekérése a DuckDuckGo-tól."""
|
|
try:
|
|
def search():
|
|
# Az újabb verziókban a DDGS() hívás így a legstabilabb
|
|
with DDGS() as ddgs:
|
|
results = ddgs.text(query, max_results=3)
|
|
return [r['body'] for r in results] if results else []
|
|
|
|
results = await asyncio.to_thread(search)
|
|
|
|
if not results:
|
|
return f"=== SOURCE: {label} | NO DATA FOUND ===\n\n"
|
|
|
|
content = f"=== SOURCE: {label} | QUERY: {query} ===\n"
|
|
content += "\n---\n".join(results)
|
|
content += "\n=== END SOURCE ===\n\n"
|
|
return content
|
|
except Exception as e:
|
|
logger.error(f"❌ Keresési hiba ({label}): {e}")
|
|
return f"=== SOURCE: {label} ERROR: {str(e)} ===\n\n"
|
|
|
|
async def research_vehicle(self, vehicle_id):
|
|
async with SessionLocal() as db:
|
|
res = await db.execute(select(VehicleModelDefinition).where(VehicleModelDefinition.id == vehicle_id))
|
|
v = res.scalar_one_or_none()
|
|
if not v: return
|
|
|
|
make, model = v.make, v.marketing_name
|
|
# Jelöljük be, hogy a kutatás folyamatban van
|
|
await db.execute(update(VehicleModelDefinition).where(VehicleModelDefinition.id == vehicle_id).values(status='research_in_progress'))
|
|
await db.commit()
|
|
|
|
logger.info(f"🔎 Kutatás indul: {make} {model}")
|
|
|
|
queries = [
|
|
("TECH_SPECS", f"{make} {model} technical specifications engine power"),
|
|
("MAINTENANCE", f"{make} {model} service manual oil capacity spark plug"),
|
|
("TIRES_BRAKES", f"{make} {model} tire size brake pad type"),
|
|
("FLUIDS", f"{make} {model} coolant quantity transmission oil")
|
|
]
|
|
|
|
tasks = [self.fetch_source(label, q) for label, q in queries]
|
|
search_results = await asyncio.gather(*tasks)
|
|
|
|
full_context = "".join(search_results)
|
|
|
|
async with SessionLocal() as db:
|
|
await db.execute(
|
|
update(VehicleModelDefinition)
|
|
.where(VehicleModelDefinition.id == vehicle_id)
|
|
.values(
|
|
raw_search_context=full_context,
|
|
status='awaiting_ai_synthesis', # Itt adjuk át a Robot 2.2-nek (Alchemist)
|
|
updated_at=func.now()
|
|
)
|
|
)
|
|
await db.commit()
|
|
logger.info(f"✅ Kutatás kész, adat a tartályban: {make} {model}")
|
|
|
|
async def run(self):
|
|
logger.info("🚀 Robot 2.1 (Researcher) ONLINE")
|
|
while True:
|
|
async with SessionLocal() as db:
|
|
# 2. KRITIKUS JAVÍTÁS: func.case helyett az explicit case() használata
|
|
# Ez javítja a "TypeError: got an unexpected keyword argument 'else_'" hibát
|
|
priorities = case(
|
|
(and_(VehicleModelDefinition.vehicle_type == 'car',
|
|
VehicleModelDefinition.make.in_(['SUZUKI', 'TOYOTA', 'SKODA', 'VOLKSWAGEN', 'OPEL'])), 1),
|
|
(VehicleModelDefinition.vehicle_type == 'car', 2),
|
|
(and_(VehicleModelDefinition.vehicle_type == 'motorcycle',
|
|
VehicleModelDefinition.make.in_(['HONDA', 'YAMAHA', 'SUZUKI', 'KAWASAKI'])), 3),
|
|
else_=4
|
|
)
|
|
|
|
stmt = select(VehicleModelDefinition.id).where(
|
|
or_(VehicleModelDefinition.status == 'unverified', VehicleModelDefinition.status == 'awaiting_research')
|
|
).order_by(priorities).limit(self.batch_size)
|
|
|
|
res = await db.execute(stmt)
|
|
ids = [r[0] for r in res.fetchall()]
|
|
|
|
if not ids:
|
|
logger.info("💤 Nincs több feldolgozandó feladat, pihenés...")
|
|
await asyncio.sleep(60)
|
|
continue
|
|
|
|
# Batch feldolgozás indítása párhuzamosan
|
|
await asyncio.gather(*[self.research_vehicle(rid) for rid in ids])
|
|
|
|
# Rövid szünet a keresőmotorok kímélése érdekében
|
|
await asyncio.sleep(2)
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(ResearcherBot().run()) |