STABLE: KYC and Auth working, before Asset refactor
This commit is contained in:
84
backend/app/services/harvester_robot.py
Normal file
84
backend/app/services/harvester_robot.py
Normal file
@@ -0,0 +1,84 @@
|
||||
import httpx
|
||||
import asyncio
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from app.models.vehicle import VehicleCatalog # Az imént létrehozott modell
|
||||
|
||||
class VehicleHarvester:
|
||||
def __init__(self):
|
||||
# Az ingyenes CarQueryAPI URL-je (0.3-as verzió)
|
||||
self.base_url = "https://www.carqueryapi.com/api/0.3/"
|
||||
self.headers = {"User-Agent": "ServiceFinder-Harvester-Bot/1.0"}
|
||||
|
||||
async def get_data(self, params: dict):
|
||||
"""Segédfüggvény az API hívásokhoz."""
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
response = await client.get(self.base_url, params=params, headers=self.headers, timeout=10.0)
|
||||
if response.status_code == 200:
|
||||
# Az API néha JSONP-t ad vissza, ezt itt lekezeljük (levágjuk a felesleget)
|
||||
text = response.text
|
||||
if text.startswith("?("): text = text[2:-2]
|
||||
return response.json()
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"Robot hiba: {str(e)}")
|
||||
return None
|
||||
|
||||
async def harvest_all(self, db: AsyncSession):
|
||||
"""A fő folyamat: Minden márka -> Minden modell szinkronizálása."""
|
||||
print("🤖 Robot: Indul a nagy adatgyűjtés...")
|
||||
|
||||
# 1. Márkák lekérése
|
||||
makes_data = await self.get_data({"cmd": "getMakes", "sold_in_us": 0})
|
||||
if not makes_data: return
|
||||
|
||||
makes = makes_data.get("Makes", [])
|
||||
|
||||
for make in makes:
|
||||
make_id = make['make_id']
|
||||
make_display = make['make_display']
|
||||
print(f"--- 🚗 Feldolgozás: {make_display} ---")
|
||||
|
||||
# 2. Modellek lekérése ehhez a márkához
|
||||
models_data = await self.get_data({"cmd": "getModels", "make": make_id})
|
||||
if not models_data: continue
|
||||
|
||||
models = models_data.get("Models", [])
|
||||
|
||||
for model in models:
|
||||
model_name = model['model_name']
|
||||
|
||||
# 3. Megnézzük, benne van-e már a katalógusban
|
||||
stmt = select(VehicleCatalog).where(
|
||||
VehicleCatalog.brand == make_display,
|
||||
VehicleCatalog.model == model_name
|
||||
)
|
||||
res = await db.execute(stmt)
|
||||
if res.scalar_one_or_none():
|
||||
continue # Ha már megvan, ugrunk a következőre
|
||||
|
||||
# 4. Új bejegyzés létrehozása alapadatokkal
|
||||
# Itt a Robot később "mélyebbre" áshat a specifikációkért
|
||||
new_v = VehicleCatalog(
|
||||
brand=make_display,
|
||||
model=model_name,
|
||||
category="car", # Alapértelmezett, később finomítható
|
||||
factory_specs={
|
||||
"api_make_id": make_id,
|
||||
"harvester_source": "carquery"
|
||||
}
|
||||
)
|
||||
db.add(new_v)
|
||||
print(f"✅ Robot rögzítve: {make_display} {model_name}")
|
||||
|
||||
# Márkánként mentünk, hogy ne vesszen el a munka, ha megszakad
|
||||
await db.commit()
|
||||
await asyncio.sleep(1) # Ne terheljük túl az ingyenes API-t (Rate Limit védelem)
|
||||
|
||||
print("🏁 Robot: A munka oroszlánrésze kész!")
|
||||
|
||||
# Ez a rész csak a teszteléshez kell, ha manuálisan indítod a scriptet
|
||||
if __name__ == "__main__":
|
||||
# Itt lehetne egy külön indító logika
|
||||
pass
|
||||
Reference in New Issue
Block a user