feat: add scoped device catalog and unlimited custom area hierarchy
This commit is contained in:
@@ -32,6 +32,7 @@ import playback
|
||||
import identity
|
||||
import genealogy
|
||||
import households
|
||||
import inventory
|
||||
import ptz
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
@@ -75,6 +76,7 @@ class Problem(Exception):
|
||||
ACCOUNTS = identity.Accounts(sys.modules[__name__])
|
||||
FAMILY = genealogy.Family(sys.modules[__name__])
|
||||
HOUSEHOLDS = households.Households(sys.modules[__name__])
|
||||
INVENTORY = inventory.Inventory(sys.modules[__name__])
|
||||
|
||||
|
||||
def setting(key, default=None):
|
||||
@@ -165,13 +167,21 @@ def object_key(table, body):
|
||||
|
||||
@serialized_save
|
||||
def save_site(body, actor=None):
|
||||
family = HOUSEHOLDS.prepare(actor, 'sites', body)
|
||||
family = HOUSEHOLDS.prepare(actor, 'sites', body, (('sites', 'parentId'),))
|
||||
key = object_key('sites', body)
|
||||
parent = clean_text(body.get('parentId', ''), 32)
|
||||
ancestor, seen = parent, {key}
|
||||
while ancestor:
|
||||
if ancestor in seen:
|
||||
raise Problem('区域不能放到自己或自己的下级区域中')
|
||||
seen.add(ancestor)
|
||||
ancestor = (get_object('sites', ancestor) or {}).get('parentId', '')
|
||||
item = {k: clean_text(body.get(k, ''), 240 if k in ('address', 'note') else 100,
|
||||
required=k == 'name') for k in SITE_FIELDS}
|
||||
item.update(id=key, kind=body.get('kind', 'home'), familyId=family)
|
||||
if item['kind'] not in ('home', 'company', 'other'):
|
||||
raise Problem('请选择家庭、公司或其他用途')
|
||||
item.update(id=key, kind=body.get('kind', 'home'), familyId=family, parentId=parent,
|
||||
category=clean_text(body.get('category', ''), 40))
|
||||
if item['kind'] not in ('home', 'company', 'office', 'factory', 'other'):
|
||||
raise Problem('请选择有效区域用途')
|
||||
save_object('sites', item)
|
||||
audit('保存空间', item['name'])
|
||||
return item
|
||||
@@ -238,6 +248,7 @@ def save_asset(body, actor=None):
|
||||
item = {k: clean_text(body.get(k, ''), 120, required=k == 'name')
|
||||
for k in ('name', 'brand', 'model', 'serial', 'point', 'note')}
|
||||
item.update(id=key, siteId=site, lensCount=integer(body.get('lensCount', 2), 1, 16), familyId=family)
|
||||
item.update(INVENTORY.metadata(body, get_object('assets', key)))
|
||||
attached = [c for c in objects('cameras') if c.get('assetId') == key]
|
||||
if len(attached) > item['lensCount']:
|
||||
raise Problem('镜头数不能小于已经建立的通道数')
|
||||
@@ -269,6 +280,7 @@ def save_recorder(body, actor=None):
|
||||
if not isinstance(password, str) or len(password) > 256 or any(ord(c) < 32 for c in password):
|
||||
raise Problem('密码格式不正确')
|
||||
item['password'] = password or old.get('password', '')
|
||||
item.update(INVENTORY.metadata(body, old))
|
||||
save_object('recorders', item)
|
||||
write_media_config()
|
||||
audit('保存录像机', item['name'])
|
||||
@@ -411,7 +423,7 @@ def status():
|
||||
storage = dict(STORAGE)
|
||||
scan = dict(SCAN)
|
||||
return {'cameras': cameras, 'assets': objects('assets'), 'recorders': [public_camera(r) for r in objects('recorders')],
|
||||
'sites': objects('sites'), 'mediaOnline': media,
|
||||
'sites': objects('sites'), 'devices': objects('devices'), 'mediaOnline': media,
|
||||
'storage': {**setting('storage'), **storage}, 'scan': scan,
|
||||
'version': (ROOT / 'VERSION').read_text().strip(), 'uptime': round(time.time() - STARTED)}
|
||||
|
||||
@@ -660,6 +672,10 @@ class Handler(BaseHTTPRequestHandler):
|
||||
self.answer(HOUSEHOLDS.save(data, self.user))
|
||||
elif path == '/api/households/leadership':
|
||||
self.answer(HOUSEHOLDS.leadership(data, self.user))
|
||||
elif path == '/api/device-view':
|
||||
self.answer(HOUSEHOLDS.save_view(data, self.user))
|
||||
elif path == '/api/devices':
|
||||
self.answer(INVENTORY.save(data, self.user))
|
||||
elif path in ('/api/family/person', '/api/family/link', '/api/family/event'):
|
||||
self.answer(FAMILY.save(path.rsplit('/', 1)[-1], data, self.user))
|
||||
elif path == '/api/sites':
|
||||
@@ -900,6 +916,7 @@ 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', '/households.js': 'households.js',
|
||||
'/device-model.js': 'device-model.js', '/devices.js': 'devices.js',
|
||||
'/family-graph.js': 'family-graph.js', '/family-map.js': 'family-map.js',
|
||||
'/family-map.css': 'family-map.css', '/chinese-theme.css': 'chinese-theme.css',
|
||||
'/family-events.js': 'family-events.js',
|
||||
|
||||
Reference in New Issue
Block a user