From ee9bac3500be9b8c33661c279453bd7318781601 Mon Sep 17 00:00:00 2001 From: Sergey Krashevich Date: Mon, 26 Jun 2023 10:56:30 +0300 Subject: [PATCH] Add functionality to update YAML config file with PUT request in HTTP endpoint --- frigate/http.py | 19 ++++++++++++++++++- frigate/util.py | 18 ++++++++++++++++++ requirements-wheels.txt | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/frigate/http.py b/frigate/http.py index b4813c1f2..11fc21710 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -29,7 +29,7 @@ from playhouse.shortcuts import model_to_dict from tzlocal import get_localzone_name from frigate.config import FrigateConfig -from frigate.const import CLIPS_DIR, MAX_SEGMENT_DURATION, RECORD_DIR +from frigate.const import CLIPS_DIR, MAX_SEGMENT_DURATION, RECORD_DIR, CONFIG_DIR from frigate.events.external import ExternalEventProcessor from frigate.models import Event, Recordings, Timeline from frigate.object_processing import TrackedObject @@ -44,6 +44,7 @@ from frigate.util import ( get_tz_modifiers, restart_frigate, vainfo_hwaccel, + update_yaml_file, ) from frigate.version import VERSION @@ -1008,6 +1009,22 @@ def config_save(): return "Config successfully saved.", 200 +@bp.route("/config/set", methods=["PUT"]) +def config_set(): + config_file = os.environ.get("CONFIG_FILE", f"{CONFIG_DIR}/config.yml") + + # Check if we can use .yaml instead of .yml + config_file_yaml = config_file.replace(".yml", ".yaml") + + if os.path.isfile(config_file_yaml): + config_file = config_file_yaml + + for key, value in request.args: + logging.debug(f"Update config key {key} to {value}") + keys = key.split(".") + update_yaml_file(config_file, keys, value) + + @bp.route("/config/schema.json") def config_schema(): return current_app.response_class( diff --git a/frigate/util.py b/frigate/util.py index aa19e99fa..e98fe9d4f 100755 --- a/frigate/util.py +++ b/frigate/util.py @@ -14,6 +14,7 @@ from collections import Counter from collections.abc import Mapping from multiprocessing import shared_memory from typing import Any, AnyStr, Optional, Tuple +from ruamel.yaml import YAML import cv2 import numpy as np @@ -1210,3 +1211,20 @@ def get_video_properties(url, get_duration=False): result["height"] = round(height) return result + + +def update_yaml_file(file_path, key_path, new_value): + yaml = YAML() + with open(file_path, "r") as f: + data = yaml.safe_load(f) + + temp = data + for key in key_path[:-1]: + if key not in temp: + temp[key] = {} + temp = temp[key] + + temp[key_path[-1]] = new_value + + with open(file_path, "w") as f: + yaml.dump(data, f) diff --git a/requirements-wheels.txt b/requirements-wheels.txt index f02317e41..3377b9986 100644 --- a/requirements-wheels.txt +++ b/requirements-wheels.txt @@ -14,6 +14,7 @@ pydantic == 1.10.* git+https://github.com/fbcotter/py3nvml#egg=py3nvml PyYAML == 6.0 pytz == 2023.3 +ruamel.yaml == 0.17.* tzlocal == 5.0.* types-PyYAML == 6.0.* requests == 2.31.*