átlagos kiegészítséek jó sok

This commit is contained in:
Roo
2026-03-22 11:02:05 +00:00
parent f53e0b53df
commit 5d44339f21
249 changed files with 20922 additions and 2253 deletions

186
backend/app/admin_ui.py Normal file
View File

@@ -0,0 +1,186 @@
#!/usr/bin/env python3
import asyncio
import json
import urllib.parse
import streamlit as st
from sqlalchemy import text
from app.database import AsyncSessionLocal
# Streamlit oldal alapbeállításai
st.set_page_config(
page_title="Service Finder - HITL Adattisztító",
page_icon="🔧",
layout="wide"
)
# --- ADATBÁZIS MŰVELETEK (Hardened Stateless Logic) ---
async def get_review_vehicle():
"""Lekérdez egy javításra váró járművet izolált sessionben."""
async with AsyncSessionLocal() as session:
try:
query = text("""
SELECT id, make, marketing_name, year_from, fuel_type,
raw_api_data, raw_search_context,
trim_level, body_type, power_kw, engine_capacity,
specifications, last_error
FROM vehicle.vehicle_model_definitions
WHERE status = 'manual_review_needed'
ORDER BY priority_score DESC
LIMIT 1
""")
result = await session.execute(query)
row = result.fetchone()
if not row:
return None
vehicle = dict(row._mapping)
# URL bányászat a JSON adatokból
source_url = None
if vehicle.get('raw_api_data'):
api_data = vehicle['raw_api_data']
if isinstance(api_data, str):
try: api_data = json.loads(api_data)
except: api_data = {}
source_url = api_data.get('url') or api_data.get('source_url') or api_data.get('link')
vehicle['extracted_url'] = source_url
return vehicle
except Exception as e:
st.error(f"❌ Lekérdezési hiba: {e}")
return None
finally:
# Garantáljuk a session lezárását
await session.close()
async def update_vehicle_data(vehicle_id, updates, new_status):
"""Elmenti az adatokat és azonnal felszabadítja a hálózati erőforrásokat."""
session = AsyncSessionLocal()
try:
# Dinamikus SQL összeállítása
set_items = [f"{k} = :{k}" for k in updates.keys()]
set_clause = ", ".join(set_items)
sql = text(f"""
UPDATE vehicle.vehicle_model_definitions
SET status = :status, {set_clause}, updated_at = NOW()
WHERE id = :id
""")
params = {"status": new_status, "id": vehicle_id, **updates}
await session.execute(sql, params)
await session.commit()
return True
except Exception as e:
await session.rollback()
st.error(f"❌ Mentési hiba az adatbázisban: {e}")
return False
finally:
# KRITIKUS JAVÍTÁS: Explicit lezárás, hogy ne maradjon nyitott transport
await session.close()
# Itt kényszerítjük a kapcsolat-kezelőt a háttérben futó motor elengedésére
bind = session.bind
if bind:
await bind.dispose()
# --- UI LOGIKA ---
async def main_async():
st.title("🔧 HITL Adattisztító - Autó Adat Javítás")
# Adat betöltése a memóriába (ha üres)
if "current_vehicle" not in st.session_state or st.session_state.current_vehicle is None:
with st.spinner("Adatbázis szinkronizálása..."):
st.session_state.current_vehicle = await get_review_vehicle()
v = st.session_state.current_vehicle
if not v:
st.success("🎉 Minden jármű ellenőrizve!")
if st.button("🔄 Új lekérdezés"):
st.session_state.current_vehicle = None
st.rerun()
return
# Felület felépítése
st.header(f"🚗 {v['year_from'] or '????'} {v['make']} {v['marketing_name']}")
st.caption(f"DB ID: {v['id']} | Üzemanyag: {v['fuel_type'] or 'n/a'}")
# 3 oszlopos nézet
col_raw, col_source, col_edit = st.columns([1, 1, 1.2])
with col_raw:
st.subheader("📄 Robot Naplók")
if v['raw_api_data']:
with st.expander("Nyers JSON (API)", expanded=True):
st.json(v['raw_api_data'])
with st.expander("Keresési Környezet", expanded=False):
st.text_area("Talált szövegek", v['raw_search_context'] or "Nincs adat", height=400)
with col_source:
st.subheader("🔗 Eredeti Források")
if v['extracted_url']:
st.success("📍 Közvetlen adatlap linkje:")
st.markdown(f"### [FORRÁS MEGNYITÁSA ↗️]({v['extracted_url']})")
else:
st.warning("⚠️ Nincs közvetlen link.")
st.markdown("---")
st.write("**Segédeszközök:**")
search_q = urllib.parse.quote(f"{v['make']} {v['marketing_name']} {v['year_from'] or ''} specifications")
st.markdown(f"- [🔍 Google Keresés](https://www.google.com/search?q={search_q})")
us_query = urllib.parse.quote(f"{v['make']} {v['marketing_name']}")
us_url = f"https://www.google.com/search?q=site:ultimatespecs.com+{us_query}"
if v['specifications']:
with st.expander("Már meglévő specifikációk", expanded=True):
st.json(v['specifications'])
with col_edit:
st.subheader("✏️ Adatbevitel")
with st.form("hitl_form_v2", clear_on_submit=False):
trim = st.text_input("Trim / Felszereltség", value=v['trim_level'] or "")
body_opts = ["", "SEDAN", "HATCHBACK", "SUV", "ESTATE", "COUPE", "CONVERTIBLE", "VAN", "PICKUP", "MPV"]
curr_body = v['body_type'] if v['body_type'] in body_opts else ""
body = st.selectbox("Karosszéria", body_opts, index=body_opts.index(curr_body))
pwr = st.number_input("Teljesítmény (kW)", value=int(v['power_kw'] or 0))
cap = st.number_input("Hengerűrtartalom (cm³)", value=int(v['engine_capacity'] or 0))
st.markdown("---")
comment = st.text_area("Megjegyzés (második zsák adatai)", placeholder="További kiegészítő adatok...")
st.write("")
b1, b2, b3 = st.columns(3)
save_btn = b1.form_submit_button("💾 MENTÉS", type="primary")
skip_btn = b2.form_submit_button("⏭️ KIHAGYÁS")
reject_btn = b3.form_submit_button("🗑️ KUKA")
# Mentési logika
if save_btn:
updates = {
"trim_level": trim,
"body_type": body,
"power_kw": pwr,
"engine_capacity": cap,
"last_error": f"Manual fix OK. {comment}".strip()
}
with st.spinner("Véglegesítés..."):
if await update_vehicle_data(v['id'], updates, "published"):
st.session_state.current_vehicle = None
st.rerun()
if skip_btn:
st.session_state.current_vehicle = None
st.rerun()
if reject_btn:
if await update_vehicle_data(v['id'], {"last_error": "Manual rejection"}, "rejected"):
st.session_state.current_vehicle = None
st.rerun()
if __name__ == "__main__":
asyncio.run(main_async())