- Use persistent httpx client to maintain session cookies
- Update endpoint path to /web/dataset/call_kw/{model}/{method}
- Handle auth response as dict (uid extraction)
- Remove kanban_state field (doesn't exist in Odoo 19)
- Add close() method for graceful shutdown
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
100 lines
2.7 KiB
Python
100 lines
2.7 KiB
Python
import asyncio
|
|
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
from modules.config_manager import ConfigManager
|
|
from modules.odoo_client import OdooClient
|
|
|
|
CONFIG_DIR = Path(__file__).parent / "config"
|
|
|
|
app_config = ConfigManager(
|
|
settings_path=str(CONFIG_DIR / "settings.yaml"),
|
|
services_path=str(CONFIG_DIR / "services.yaml"),
|
|
)
|
|
|
|
settings = app_config.get_settings()
|
|
odoo_settings = settings.get("odoo", {})
|
|
|
|
odoo_client = OdooClient(
|
|
url=odoo_settings.get("url", "http://localhost:8069"),
|
|
database=odoo_settings.get("database", "odoo"),
|
|
username=odoo_settings.get("username", "admin"),
|
|
password=odoo_settings.get("password", "admin"),
|
|
)
|
|
|
|
|
|
async def refresh_loop():
|
|
from routers.ws import broadcast
|
|
from modules.network_scanner import NetworkScanner
|
|
|
|
refresh = app_config.get_settings().get("refresh", {})
|
|
odoo_interval = refresh.get("odoo_minutes", 5) * 60
|
|
network_interval = refresh.get("network_minutes", 10) * 60
|
|
ping_interval = refresh.get("ping_seconds", 60)
|
|
|
|
last_odoo = 0
|
|
last_network = 0
|
|
last_ping = 0
|
|
|
|
while True:
|
|
now = asyncio.get_event_loop().time()
|
|
|
|
if now - last_ping >= ping_interval:
|
|
try:
|
|
scan_config = app_config.get_network_scan_config()
|
|
scanner = NetworkScanner(scan_config.get("subnet", "192.168.1.0/24"))
|
|
nodes = app_config.get_nodes()
|
|
ips = [n["ip"] for n in nodes]
|
|
statuses = await scanner.ping_all(ips)
|
|
await broadcast("ping_update", statuses)
|
|
except Exception:
|
|
pass
|
|
last_ping = now
|
|
|
|
if now - last_odoo >= odoo_interval:
|
|
try:
|
|
await broadcast("odoo_refresh", {"trigger": "scheduled"})
|
|
except Exception:
|
|
pass
|
|
last_odoo = now
|
|
|
|
await asyncio.sleep(10)
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
try:
|
|
await odoo_client.authenticate()
|
|
except Exception as e:
|
|
print(f"Warning: Could not connect to Odoo: {e}")
|
|
task = asyncio.create_task(refresh_loop())
|
|
yield
|
|
task.cancel()
|
|
await odoo_client.close()
|
|
|
|
|
|
app = FastAPI(title="TV Dashboard API", lifespan=lifespan)
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"],
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
from routers import network, tasks, calendar, services, ws
|
|
|
|
app.include_router(network.router)
|
|
app.include_router(tasks.router)
|
|
app.include_router(calendar.router)
|
|
app.include_router(services.router)
|
|
app.include_router(ws.router)
|
|
|
|
|
|
@app.get("/api/health")
|
|
async def health():
|
|
return {"status": "ok", "odoo_connected": odoo_client.uid is not None}
|