# /opt/docker/dev/service_finder/backend/app/workers/vehicle/robot_report.py import asyncio import psutil import pynvml from datetime import datetime from sqlalchemy import text from sqlalchemy.ext.asyncio import create_async_engine from rich.console import Console from rich.table import Table from rich.panel import Panel from rich.layout import Layout from app.core.config import settings console = Console() async def get_data(): engine = create_async_engine(settings.DATABASE_URL) async with engine.connect() as conn: # Pipeline adatok (R1-R4) pipe = await conn.execute(text(""" SELECT (SELECT count(*) FROM vehicle.catalog_discovery WHERE status = 'pending') as r1, (SELECT count(*) FROM vehicle.vehicle_model_definitions WHERE status = 'unverified') as r2, (SELECT count(*) FROM vehicle.vehicle_model_definitions WHERE status = 'awaiting_ai_synthesis') as r3, (SELECT count(*) FROM vehicle.vehicle_model_definitions WHERE status = 'gold_enriched') as r4 """)) p_res = pipe.fetchone() # AI Termelés ai_hr = await conn.execute(text("SELECT count(*) FROM vehicle.vehicle_model_definitions WHERE status = 'gold_enriched' AND updated_at > NOW() - INTERVAL '1 hour'")) ai_day = await conn.execute(text("SELECT count(*) FROM vehicle.vehicle_model_definitions WHERE status = 'gold_enriched' AND updated_at > NOW() - INTERVAL '24 hours'")) # Market Matrix (1.3) market_res = await conn.execute(text("SELECT vehicle_class, market, count(*) FROM vehicle.catalog_discovery GROUP BY 1, 2")) m_data = market_res.fetchall() # Robot Top listák (2.1 - 2.3) r1_top = await conn.execute(text("SELECT make, count(*) FROM vehicle.catalog_discovery WHERE market = 'RDW' GROUP BY 1 ORDER BY 2 DESC LIMIT 5")) r12_top = await conn.execute(text("SELECT make, count(*) FROM vehicle.catalog_discovery WHERE market = 'USA_IMPORT' GROUP BY 1 ORDER BY 2 DESC LIMIT 5")) r14_top = await conn.execute(text("SELECT make, count(*) FROM vehicle.catalog_discovery WHERE vehicle_class = 'motorcycle' GROUP BY 1 ORDER BY 2 DESC LIMIT 5")) # Általános Top (3.1 - 3.3) pending_top = await conn.execute(text("SELECT make, count(*) FROM vehicle.catalog_discovery WHERE status = 'pending' GROUP BY 1 ORDER BY 2 DESC LIMIT 5")) gold_top = await conn.execute(text("SELECT make, count(*) FROM vehicle.vehicle_model_definitions WHERE status = 'gold_enriched' GROUP BY 1 ORDER BY 2 DESC LIMIT 5")) status_stats = await conn.execute(text("SELECT status, count(*) FROM vehicle.vehicle_model_definitions GROUP BY 1 ORDER BY 2 DESC LIMIT 5")) # Kategória Top (4.1 - 4.3) cat_tops = {} for c in ['car', 'motorcycle', 'truck']: res = await conn.execute(text(f"SELECT make, count(*) FROM vehicle.catalog_discovery WHERE vehicle_class = '{c}' GROUP BY 1 ORDER BY 2 DESC LIMIT 4")) total = await conn.execute(text(f"SELECT count(*) FROM vehicle.catalog_discovery WHERE vehicle_class = '{c}'")) cat_tops[c] = {"list": res.fetchall(), "total": total.scalar() or 0} return { "p": p_res, "ai": (ai_hr.scalar(), ai_day.scalar()), "markets": m_data, "r1": r1_top.fetchall(), "r12": r12_top.fetchall(), "r14": r14_top.fetchall(), "pending": pending_top.fetchall(), "gold": gold_top.fetchall(), "status": status_stats.fetchall(), "cat": cat_tops } def get_hw(): try: pynvml.nvmlInit() h = pynvml.nvmlDeviceGetHandleByIndex(0) info = pynvml.nvmlDeviceGetMemoryInfo(h) return {"cpu": psutil.cpu_percent(), "ram": psutil.virtual_memory().percent, "gpu": pynvml.nvmlDeviceGetUtilizationRates(h).gpu, "vram": f"{int(info.used/1024**2)}/{int(info.total/1024**2)}M", "temp": pynvml.nvmlDeviceGetTemperature(h, 0)} except: return None def mini_table(data, color="white"): t = Table(show_header=False, box=None, expand=True, padding=(0,1)) t.add_column("L", ratio=3); t.add_column("R", justify="right", ratio=2) for r in data: t.add_row(str(r[0])[:12], f"[{color}]{r[1]:,}[/]") return t async def main(): try: d = await get_data(); hw = get_hw() lay = Layout() lay.split_column(Layout(name="head", size=3), Layout(name="body")) lay["body"].split_column(Layout(name="row1"), Layout(name="row2"), Layout(name="row3"), Layout(name="row4")) for r in ["row1", "row2", "row3", "row4"]: lay[r].split_row(Layout(name=f"{r}1"), Layout(name=f"{r}2"), Layout(name=f"{r}3")) # --- FEJLÉC --- h_str = f"💻 CPU: {hw['cpu']}% | 🧠 RAM: {hw['ram']}% | 📟 VRAM: {hw['vram']} | 🔥 GPU: {hw['gpu']}% ({hw['temp']}°C)" if hw else "Hardware adatok nem elérhetőek" lay["head"].update(Panel(h_str, title="[bold orange3]SZÁMÍTÓGÉP ADATOK[/]", style="orange3")) # --- 1. SOR --- r11_t = Table(show_header=False, box=None, expand=True) r11_t.add_row("R1 (Hunter)", f"{d['p'][0]:,}"); r11_t.add_row("R2 (Res)", f"{d['p'][1]:,}") r11_t.add_row("R3 (Wait)", f"{d['p'][2]:,}"); r11_t.add_row("R4 (Gold)", f"[green]{d['p'][3]:,}[/]") r11_t.add_row("AI HR/DAY", f"[cyan]{d['ai'][0]}[/] / [yellow]{d['ai'][1]}[/]") lay["row11"].update(Panel(r11_t, title="1.1 PIPE & AI")) lay["row12"].update(Panel(mini_table(d['gold'], "green"), title="1.2 TOP MÁRKÁK")) r13_t = Table(show_header=True, box=None, expand=True, header_style="bold blue") r13_t.add_column("Típus", ratio=2); r13_t.add_column("EU", justify="right"); r13_t.add_column("USA", justify="right") m_map = {c: {"EU": 0, "USA": 0} for c in ['car', 'motorcycle', 'truck', 'bus']} for c, m, q in d['markets']: key = 'USA' if m == 'USA_IMPORT' else 'EU' if c in m_map: m_map[c][key] += q for c, v in m_map.items(): r13_t.add_row(c[:4].upper(), f"{v['EU']:,}", f"{v['USA']:,}") lay["row13"].update(Panel(r13_t, title="1.3 MARKET MATRIX")) # --- 2. SOR (ROBOTOK) --- lay["row21"].update(Panel(mini_table(d['r1']), title="2.1 ROBOT 1 (RDW)")) lay["row22"].update(Panel(mini_table(d['r12']), title="2.2 ROBOT 1.2 (USA)")) lay["row23"].update(Panel(mini_table(d['r14']), title="2.3 ROBOT 1.4 (BIKE)")) # --- 3. SOR (ÖSSZESÍTŐ) --- lay["row31"].update(Panel(mini_table(d['pending']), title="3.1 PENDING TOP")) lay["row32"].update(Panel(mini_table(d['gold'], "green"), title="3.2 GOLD TOP", border_style="green")) lay["row33"].update(Panel(mini_table(d['status'], "blue"), title="3.3 STATUS", border_style="blue")) # --- 4. SOR (KATEGÓRIÁK) --- for i, (k, l) in enumerate([('car', '4.1 AUTO'), ('motorcycle', '4.2 MOTOR'), ('truck', '4.3 TEHER')], 1): t = mini_table(d['cat'][k]['list'], "yellow") t.add_row("[bold]TOTAL[/]", f"[bold yellow]{d['cat'][k]['total']:,}[/]") lay[f"row4{i}"].update(Panel(t, title=l, border_style="yellow")) console.print(lay) except Exception as e: console.print(f"[bold red]HIBA TÖRTÉNT:[/] {e}") if __name__ == "__main__": asyncio.run(main())