diff --git a/VERSION b/VERSION index 17e51c3..d917d3e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 +0.1.2 diff --git a/app.py b/app.py index 132925f..09ae24d 100644 --- a/app.py +++ b/app.py @@ -302,6 +302,30 @@ def media_json(path, playback=False): raise Problem('视频服务暂不可用,或该时段尚无可回放录像', 503) +def media_config_watch(): + # Reconcile API configuration after atomic file replacements. Multiple rapid + # writes can be coalesced by a filesystem watcher; the file remains authority. + applied = None + while True: + try: + raw = CONFIG.read_bytes() + digest = hashlib.sha256(raw).digest() + if digest != applied: + desired = json.loads(raw)['paths'] + existing = {p['name'] for p in media_json('/v3/config/paths/list?itemsPerPage=200').get('items', [])} + for name, body in desired.items(): + action, method = ('patch', 'PATCH') if name in existing else ('add', 'POST') + req = urllib.request.Request('http://127.0.0.1:' + str(API_PORT) + '/v3/config/paths/' + action + '/' + name, + data=json.dumps(body).encode(), method=method, + headers={'Authorization': MEDIA_AUTH, 'Content-Type': 'application/json'}) + with urllib.request.urlopen(req, timeout=5) as response: + response.read() + applied = digest + except Exception: + pass # Retry on the next pass, including after a media process restart. + time.sleep(5) + + def status(): try: data = media_json('/v3/paths/list?itemsPerPage=200') @@ -682,6 +706,7 @@ def initialize(): if __name__ == '__main__': initialize() threading.Thread(target=storage_watch, daemon=True).start() + threading.Thread(target=media_config_watch, daemon=True).start() bindings = [h.strip() for h in os.environ.get('VISION_BIND', '127.0.0.1').split(',') if h.strip()] port = int(os.environ.get('VISION_PORT', '8790')) servers = []