Submit GUI commands without page navigation
This commit is contained in:
@@ -1636,6 +1636,22 @@ class CameraControlBridge:
|
||||
payload["redirect_url"] = redirect_url
|
||||
return payload
|
||||
|
||||
def action_payload(self, lang, action, command, result, redirect_url):
|
||||
ok = bool(result.get("ok", True))
|
||||
payload = {
|
||||
"ok": ok,
|
||||
"command": command,
|
||||
"message": text_for(lang, "action.success" if ok else "action.failed_generic"),
|
||||
"redirect_url": redirect_url,
|
||||
"result": result,
|
||||
}
|
||||
if action is not None:
|
||||
payload["action_id"] = action.id
|
||||
payload["action"] = self.api_action(action, lang)
|
||||
if action.kind == "all_off":
|
||||
payload["actions"] = [self.api_action(item, lang) for item in self.actions_snapshot()]
|
||||
return payload
|
||||
|
||||
def frigate_refresh_loop(self):
|
||||
interval = int(self.config.get("defaults", {}).get("frigate_refresh_seconds", 300))
|
||||
if interval <= 0:
|
||||
@@ -1826,17 +1842,36 @@ class CameraControlBridge:
|
||||
if len(parts) == 3 and parts[0] == "action":
|
||||
action_id = urllib.parse.unquote(parts[1])
|
||||
command = urllib.parse.unquote(parts[2]).lower()
|
||||
token_param = urllib.parse.parse_qs(parsed.query).get("token", [None])[0]
|
||||
token_query = f"&token={urllib.parse.quote(token_param)}" if token_param else ""
|
||||
redirect_url = f"/?lang={urllib.parse.quote(lang)}{token_query}"
|
||||
wants_json = "application/json" in self.headers.get("Accept", "").lower()
|
||||
try:
|
||||
result = bridge.execute_action(action_id, command, publish=True)
|
||||
token_param = urllib.parse.parse_qs(parsed.query).get("token", [None])[0]
|
||||
token_query = f"&token={urllib.parse.quote(token_param)}" if token_param else ""
|
||||
self.send_response(303)
|
||||
self.send_header("Location", f"/?lang={urllib.parse.quote(lang)}{token_query}")
|
||||
self.end_headers()
|
||||
action = bridge.action_by_id(action_id)
|
||||
if wants_json:
|
||||
payload = bridge.action_payload(lang, action, command, result, redirect_url)
|
||||
self.send_json(payload, status=200 if payload.get("ok") else 500)
|
||||
else:
|
||||
self.send_response(303)
|
||||
self.send_header("Location", redirect_url)
|
||||
self.end_headers()
|
||||
except Exception as exc:
|
||||
self.send_response(500)
|
||||
self.end_headers()
|
||||
self.wfile.write(str(exc).encode("utf-8"))
|
||||
if wants_json:
|
||||
self.send_json(
|
||||
{
|
||||
"ok": False,
|
||||
"action_id": action_id,
|
||||
"command": command,
|
||||
"message": text_for(lang, "action.failed", error=str(exc)),
|
||||
"redirect_url": redirect_url,
|
||||
},
|
||||
status=500,
|
||||
)
|
||||
else:
|
||||
self.send_response(500)
|
||||
self.end_headers()
|
||||
self.wfile.write(str(exc).encode("utf-8"))
|
||||
return
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
@@ -1874,20 +1909,27 @@ class CameraControlBridge:
|
||||
LOG.info("HTTP fallback GUI listening on %s:%s", bind, port)
|
||||
|
||||
def api_actions(self):
|
||||
return [
|
||||
{
|
||||
"id": action.id,
|
||||
"name": action.display_name(self.default_language),
|
||||
"platform": action.platform,
|
||||
"commands": action.command_list(),
|
||||
"state": action.state,
|
||||
"snapshot": bool(action.cfg.get("snapshot")),
|
||||
"auto_off_seconds": action.auto_off_seconds,
|
||||
"auto_off_at": int(action.auto_off_at) if action.auto_off_at else None,
|
||||
"requires_ack": bool(action.cfg.get("requires_ack")),
|
||||
}
|
||||
for action in self.actions_snapshot()
|
||||
]
|
||||
return [self.api_action(action, self.default_language) for action in self.actions_snapshot()]
|
||||
|
||||
def api_action(self, action, lang=None):
|
||||
lang = lang or self.default_language
|
||||
state_value = (action.state or "unknown").lower()
|
||||
state_label = text_for(lang, f"state.{state_value}")
|
||||
if state_label == f"state.{state_value}":
|
||||
state_label = state_value.upper()
|
||||
return {
|
||||
"id": action.id,
|
||||
"name": action.display_name(lang),
|
||||
"platform": action.platform,
|
||||
"commands": action.command_list(),
|
||||
"state": action.state,
|
||||
"state_label": state_label,
|
||||
"snapshot": bool(action.cfg.get("snapshot")),
|
||||
"snapshot_version": int(action.snapshot_version or 0),
|
||||
"auto_off_seconds": action.auto_off_seconds,
|
||||
"auto_off_at": int(action.auto_off_at) if action.auto_off_at else None,
|
||||
"requires_ack": bool(action.cfg.get("requires_ack")),
|
||||
}
|
||||
|
||||
def html_page(self, lang=None, token_param=None):
|
||||
with self.action_lock:
|
||||
|
||||
Reference in New Issue
Block a user