Add PTZ nudges, configurable monitoring wall and lunar family dates

This commit is contained in:
Codex
2026-10-03 18:29:18 +08:00
parent de6933c411
commit 52b5a6b389
18 changed files with 434 additions and 20 deletions
+23 -1
View File
@@ -29,6 +29,7 @@ import onvif
import playback
import identity
import genealogy
import ptz
ROOT = Path(__file__).resolve().parent
os.umask(0o077)
@@ -559,13 +560,23 @@ class Handler(BaseHTTPRequestHandler):
self.login(data, path == '/api/setup')
return
self.require_auth()
if path not in ('/api/logout', '/api/family/person', '/api/family/link'):
if path not in ('/api/logout', '/api/family/person', '/api/family/link', '/api/ptz'):
self.require_admin()
if path == '/api/logout':
with LOCK:
DB.execute('DELETE FROM sessions WHERE hash=?', (hashlib.sha256(self.token().encode()).hexdigest(),))
DB.commit()
self.answer({'ok': True}, cookie='vision=; Path=/; Max-Age=0; HttpOnly; SameSite=Strict')
elif path == '/api/ptz':
c = ACCOUNTS.control(self.user, get_object('cameras', data.get('camera')))
try:
result = ptz.CONTROLLER.command(c, data.get('action'))
except ValueError as e:
raise Problem(str(e), 400)
except Exception:
raise Problem('云台通信未成功,请检查设备连接;设备端的一秒超时保护会停止本次转动', 502)
audit('云台 ' + data['action'], c['name'])
self.answer(result)
elif path == '/api/users':
self.answer(ACCOUNTS.save(data, self.user))
elif path in ('/api/family/person', '/api/family/link'):
@@ -715,6 +726,15 @@ class Handler(BaseHTTPRequestHandler):
elif path == '/api/users':
self.require_admin()
self.answer({'users': [ACCOUNTS.public(u) for u in objects('users')]})
elif path == '/api/ptz':
c = ACCOUNTS.control(self.user, get_object('cameras', query.get('camera')))
try:
result = ptz.CONTROLLER.capabilities(c)
except ValueError as e:
raise Problem(str(e), 400)
except Exception:
raise Problem('未能读取云台能力,请确认摄像头的 ONVIF 服务和连接', 502)
self.answer(result)
elif path == '/api/family':
self.answer(FAMILY.snapshot(self.user))
elif path == '/api/audit':
@@ -764,6 +784,8 @@ class Handler(BaseHTTPRequestHandler):
else:
files = {'/': 'index.html', '/app.js': 'app.js', '/live-player.js': 'live-player.js', '/style.css': 'style.css',
'/family.js': 'family.js', '/kinship.js': 'kinship.js',
'/monitor.js': 'monitor.js', '/calendar.js': 'calendar.js', '/date-fields.js': 'date-fields.js',
'/zhao-icon.png': 'zhao-icon.png',
'/vendor/hls.min.js': 'vendor/hls.min.js'}
if path not in files:
raise Problem('页面不存在', 404)