153 lines
5.5 KiB
Python
153 lines
5.5 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, timezone
|
|
import os
|
|
import platform
|
|
|
|
from flask import Blueprint, jsonify, request, session
|
|
|
|
from app.core_settings import get_settings
|
|
from app.services.capabilities import build_capabilities
|
|
from app.services.catalog import get_catalog
|
|
from app.services.kiosk_settings import get_kiosk_settings_service
|
|
from app.services.auth import get_auth_service
|
|
from app.services.influx_http import InfluxHTTPService
|
|
from app.utils.serialization import to_plain
|
|
|
|
|
|
dashboard_blueprint = Blueprint("dashboard", __name__)
|
|
_APP_STARTED_AT = datetime.now(timezone.utc)
|
|
|
|
|
|
def _resolve_kiosk_mode(requested_mode: str, require_write_access: bool = False) -> tuple[str, str]:
|
|
normalized_mode = (requested_mode or "private").strip().lower()
|
|
auth_service = get_auth_service()
|
|
|
|
if normalized_mode == "public":
|
|
if require_write_access and auth_service.enabled and session.get("auth_role") != "admin":
|
|
raise PermissionError("Brak uprawnien do edycji publicznego kiosku")
|
|
return "public", "public"
|
|
|
|
if normalized_mode != "private":
|
|
raise ValueError("Mode musi byc jednym z: public, private")
|
|
|
|
if (not auth_service.enabled) or session.get("auth_role") == "admin":
|
|
return "private", "private"
|
|
|
|
username = session.get("auth_user")
|
|
if not username:
|
|
raise PermissionError("Authentication required")
|
|
return f"user:{username}", "private"
|
|
|
|
|
|
@dashboard_blueprint.get("/dashboard/config")
|
|
def dashboard_config():
|
|
settings = get_settings()
|
|
catalog = get_catalog()
|
|
capabilities = build_capabilities(catalog)
|
|
|
|
payload = {
|
|
"app": {
|
|
"name": settings.app_name,
|
|
"version": settings.version,
|
|
"site_name": settings.site_name,
|
|
"timezone": settings.timezone,
|
|
"installed_power_kwp": settings.installed_power_kwp,
|
|
},
|
|
"defaults": {
|
|
"realtime_range": settings.realtime["history_default_range"],
|
|
"analytics_range": settings.analytics["default_range"],
|
|
"analytics_bucket": settings.analytics["default_bucket"],
|
|
"tab": settings.frontend_defaults["tab"],
|
|
"theme": settings.frontend_defaults["theme"],
|
|
"language": settings.frontend_defaults["language"],
|
|
},
|
|
"auth": {
|
|
"enabled": settings.auth["enabled"],
|
|
},
|
|
"i18n": settings.i18n,
|
|
"capabilities": capabilities,
|
|
"visible_entities": [
|
|
{
|
|
"metric_id": metric.id,
|
|
"label": metric.label,
|
|
"entity_id": metric.entity_id,
|
|
"measurement": metric.measurement,
|
|
"unit": metric.unit,
|
|
"kind": metric.kind,
|
|
}
|
|
for metric in catalog.visible_entities()
|
|
],
|
|
}
|
|
return jsonify(to_plain(payload))
|
|
|
|
|
|
@dashboard_blueprint.get("/dashboard/kiosk-settings")
|
|
def dashboard_kiosk_settings():
|
|
requested_mode = request.args.get("mode") or ("public" if request.args.get("publicKiosk") == "1" else "private")
|
|
try:
|
|
storage_mode, response_mode = _resolve_kiosk_mode(requested_mode)
|
|
payload = get_kiosk_settings_service().get(storage_mode)
|
|
payload["mode"] = response_mode
|
|
return jsonify(to_plain(payload))
|
|
except PermissionError as exc:
|
|
return jsonify({"detail": str(exc)}), 403
|
|
except ValueError as exc:
|
|
return jsonify({"detail": str(exc)}), 400
|
|
|
|
|
|
@dashboard_blueprint.put("/dashboard/kiosk-settings")
|
|
def update_dashboard_kiosk_settings():
|
|
payload = request.get_json(silent=True) or {}
|
|
requested_mode = payload.get("mode", "private")
|
|
try:
|
|
storage_mode, response_mode = _resolve_kiosk_mode(requested_mode, require_write_access=True)
|
|
updated = get_kiosk_settings_service().update_from_session(storage_mode, payload)
|
|
updated["mode"] = response_mode
|
|
return jsonify(to_plain(updated))
|
|
except PermissionError as exc:
|
|
return jsonify({"detail": str(exc)}), 403
|
|
except ValueError as exc:
|
|
return jsonify({"detail": str(exc)}), 400
|
|
|
|
|
|
@dashboard_blueprint.get("/dashboard/diagnostics")
|
|
def dashboard_diagnostics():
|
|
auth_service = get_auth_service()
|
|
try:
|
|
auth_service.require_admin()
|
|
except PermissionError as exc:
|
|
return jsonify({"detail": str(exc)}), 403
|
|
|
|
settings = get_settings()
|
|
influx_diagnostics = InfluxHTTPService(settings).diagnose()
|
|
now = datetime.now(timezone.utc)
|
|
payload = {
|
|
"app": {
|
|
"name": settings.app_name,
|
|
"version": settings.version,
|
|
"debug": settings.debug,
|
|
"timezone": settings.timezone,
|
|
"site_name": settings.site_name,
|
|
"installed_power_kwp": settings.installed_power_kwp,
|
|
"auth_enabled": settings.auth["enabled"],
|
|
"started_at": _APP_STARTED_AT.isoformat(),
|
|
"uptime_seconds": max(int((now - _APP_STARTED_AT).total_seconds()), 0),
|
|
"python_version": platform.python_version(),
|
|
"pid": os.getpid(),
|
|
},
|
|
"api": {
|
|
"status": "ok",
|
|
"prefix": settings.api_prefix,
|
|
"cors_origins_count": len(settings.cors_origins),
|
|
},
|
|
"influx": influx_diagnostics,
|
|
"storage": {
|
|
"sqlite_path": settings.storage["sqlite_path"],
|
|
"historical_import_enabled": settings.history["enabled"],
|
|
"auto_sync_enabled": settings.history["auto_sync_enabled"],
|
|
"default_chunk_days": settings.history["default_chunk_days"],
|
|
},
|
|
}
|
|
return jsonify(to_plain(payload))
|