def map_to_file_format(config_dto: ConfigDTO): config_dict = dict() config_dict["App"] = map_to_config_file_format(config_dto.app) config_dict["CORE"] = map_to_config_file_format(config_dto.core) for count, area in enumerate(config_dto.areas): config_dict["Area_" + str(count)] = map_to_config_file_format(area) for count, camera in enumerate(config_dto.cameras): config_dict["Source_" + str(count)] = map_to_camera_file_format(camera) config_dict["Detector"] = map_to_config_file_format(config_dto.detector) if config_dto.classifier: config_dict["Classifier"] = map_to_camera_file_format( config_dto.classifier) config_dict["Tracker"] = map_to_config_file_format(config_dto.tracker) for count, source_post_processor in enumerate( config_dto.sourcePostProcessors): config_dict["SourcePostProcessor_" + str(count)] = map_to_config_file_format( source_post_processor, True) for count, source_logger in enumerate(config_dto.sourceLoggers): config_dict["SourceLogger_" + str(count)] = map_to_config_file_format( source_logger, True) for count, area_logger in enumerate(config_dto.areaLoggers): config_dict["AreaLogger_" + str(count)] = map_to_config_file_format( area_logger, True) for count, periodic_task in enumerate(config_dto.periodicTasks): config_dict["PeriodicTask_" + str(count)] = map_to_config_file_format( periodic_task, True) return config_dict
async def create_area(new_area: AreaConfigDTO, reboot_processor: Optional[bool] = True): """ Adds a new area to the processor. """ config_dict = extract_config() areas_name = [x for x in config_dict.keys() if x.startswith("Area_")] areas = [map_section_from_config(x, config_dict) for x in areas_name] if new_area.id in [area["id"] for area in areas]: raise HTTPException(status_code=400, detail="Area already exists") cameras = [x for x in config_dict.keys() if x.startswith("Source_")] cameras = [map_camera(x, config_dict, []) for x in cameras] camera_ids = [camera["id"] for camera in cameras] if not all(x in camera_ids for x in new_area.cameras.split(",")): non_existent_cameras = set( new_area.cameras.split(",")) - set(camera_ids) raise HTTPException( status_code=404, detail=f"The cameras: {non_existent_cameras} do not exist") area_dict = map_to_config_file_format(new_area) config_dict[f"Area_{len(areas)}"] = area_dict success = update_config(config_dict, reboot_processor) return handle_response(area_dict, success, status.HTTP_201_CREATED)
async def edit_periodic_task(periodic_task_name: str, edited_periodic_task: PeriodicTaskDTO, reboot_processor: Optional[bool] = True): """ Edits the configuration related to the periodic task <periodic_task_name>. """ edited_periodic_task.name = periodic_task_name config_dict = extract_config() edited_periodic_task_section = next( (key for key, value in config_dict.items() if key.startswith("PeriodicTask_") and value["Name"] == periodic_task_name), None) if not edited_periodic_task_section: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"The periodic_task: {periodic_task_name} does not exist") try: validate_periodic_task(edited_periodic_task) except ValidationError as e: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) periodic_task_file = map_to_config_file_format(edited_periodic_task, True) config_dict[edited_periodic_task_section] = periodic_task_file success = update_config(config_dict, reboot_processor) return handle_response(periodic_task_file, success)
async def create_periodic_task(new_periodic_task: PeriodicTaskDTO, reboot_processor: Optional[bool] = True): """ Adds a periodic task. """ config_dict = extract_config() periodic_tasks_index = [ int(x[-1]) for x in config_dict.keys() if x.startswith("PeriodicTask_") ] periodic_tasks = get_periodic_tasks() try: validate_periodic_task(new_periodic_task) except ValidationError as e: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) if new_periodic_task.name in [ps["name"] for ps in periodic_tasks]: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Periodict task already exists") periodic_task_file = map_to_config_file_format(new_periodic_task, True) index = 0 if periodic_tasks_index: index = max(periodic_tasks_index) + 1 config_dict[f"PeriodicTask_{index}"] = periodic_task_file success = update_config(config_dict, reboot_processor) return handle_response(periodic_task_file, success, status.HTTP_201_CREATED)
async def edit_logger(logger_name: str, edited_logger: SourceLoggerDTO, reboot_processor: Optional[bool] = True): """ Edits the configuration related to the logger <logger_name> """ edited_logger.name = logger_name config_dict = extract_config() edited_logger_section = next(( key for key, value in config_dict.items() if key.startswith("SourceLogger_") and value["Name"] == logger_name ), None) if not edited_logger_section: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"The logger: {logger_name} does not exist") try: validate_logger(edited_logger) except ValidationError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=bad_request_serializer(str(e)) ) logger_file = map_to_config_file_format(edited_logger, True) config_dict[edited_logger_section] = logger_file success = update_config(config_dict, reboot_processor) if not success: return handle_response(logger_file, success) return next((ps for ps in get_source_loggers() if ps["name"] == logger_name), None)
async def create_area(new_area: AreaConfigDTO, reboot_processor: Optional[bool] = True): """ Adds a new area to the processor. """ config_dict = extract_config() areas_name = [x for x in config_dict.keys() if x.startswith("Area_")] areas = [map_section_from_config(x, config_dict) for x in areas_name] if new_area.id in [area["id"] for area in areas]: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=bad_request_serializer( "Area already exists", error_type="config duplicated area")) cameras = [x for x in config_dict.keys() if x.startswith("Source_")] cameras = [map_camera(x, config_dict, []) for x in cameras] camera_ids = [camera["id"] for camera in cameras] if not all(x in camera_ids for x in new_area.cameras.split(",")): non_existent_cameras = set( new_area.cameras.split(",")) - set(camera_ids) raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"The cameras: {non_existent_cameras} do not exist") area_dict = map_to_config_file_format(new_area) config_dict[f"Area_{len(areas)}"] = area_dict success = update_config(config_dict, reboot_processor) if not success: return handle_response(area_dict, success, status.HTTP_201_CREATED) return next( (area for area in get_areas() if area["id"] == area_dict["Id"]), None)
async def create_logger(new_logger: SourceLoggerDTO, reboot_processor: Optional[bool] = True): """ Adds a logger. """ config_dict = extract_config() loggers_index = [int(x[-1]) for x in config_dict.keys() if x.startswith("SourceLogger_")] loggers = get_source_loggers() try: validate_logger(new_logger) except ValidationError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=bad_request_serializer(str(e)) ) if new_logger.name in [ps["name"] for ps in loggers]: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=bad_request_serializer("Logger already exists", error_type="config duplicated logger") ) logger_file = map_to_config_file_format(new_logger, True) index = 0 if loggers_index: index = max(loggers_index) + 1 config_dict[f"SourceLogger_{index}"] = logger_file success = update_config(config_dict, reboot_processor) if not success: return handle_response(logger_file, success, status.HTTP_201_CREATED) return next((ps for ps in get_source_loggers() if ps["name"] == logger_file["Name"]), None)
async def edit_area(area_id: str, edited_area: AreaConfigDTO, reboot_processor: Optional[bool] = True): """ Edits the configuration related to the area <area_id> """ edited_area.id = area_id config_dict = extract_config() area_names = [x for x in config_dict.keys() if x.startswith("Area_")] areas = [map_section_from_config(x, config_dict) for x in area_names] areas_ids = [area["id"] for area in areas] try: index = areas_ids.index(area_id) except ValueError: raise HTTPException(status_code=404, detail=f"The area: {area_id} does not exist") cameras = [x for x in config_dict.keys() if x.startswith("Source_")] cameras = [map_camera(x, config_dict, []) for x in cameras] camera_ids = [camera["id"] for camera in cameras] if not all(x in camera_ids for x in edited_area.cameras.split(",")): non_existent_cameras = set( edited_area.cameras.split(",")) - set(camera_ids) raise HTTPException( status_code=404, detail=f"The cameras: {non_existent_cameras} do not exist") area_dict = map_to_config_file_format(edited_area) config_dict[f"Area_{index}"] = area_dict success = update_config(config_dict, reboot_processor) return handle_response(area_dict, success)
def update_core_config(core: CoreDTO, reboot_processor: Optional[bool] = True): """ Updates the core configuration of the processor """ config_dict = extract_config() core_dict = map_to_config_file_format(core) config_dict["CORE"] = core_dict success = update_config(config_dict, reboot_processor) return handle_response(core_dict, success)
def update_classifier_config(classifier: ClassifierDTO, reboot_processor: Optional[bool] = True): """ Updates the classifier configuration of the processor """ config_dict = extract_config() classifier_dict = map_to_config_file_format(classifier) config_dict["Classifier"] = classifier_dict success = update_config(config_dict, reboot_processor) return handle_response(classifier_dict, success)
def update_app_config(app: AppDTO, reboot_processor: Optional[bool] = True): """ Updates the app configuration of the processor """ config_dict = extract_config() app_dict = map_to_config_file_format(app) config_dict["App"] = app_dict success = update_config(config_dict, reboot_processor) return handle_response(app_dict, success)
def update_detector_config(detector: DetectorDTO, reboot_processor: Optional[bool] = True): """ Updates the detector configuration of the processor """ config_dict = extract_config() detector_dict = map_to_config_file_format(detector) config_dict["Detector"] = detector_dict success = update_config(config_dict, reboot_processor) return handle_response(detector_dict, success)
def update_tracker_config(tracker: TrackerDTO, reboot_processor: Optional[bool] = True): """ Updates the tracker configuration of the processor """ config_dict = extract_config() tracker_dict = map_to_config_file_format(tracker) config_dict["Tracker"] = tracker_dict success = update_config(config_dict, reboot_processor) return handle_response(tracker_dict, success)
async def edit_area(area_id: str, edited_area: AreaConfigDTO, reboot_processor: Optional[bool] = True): """ Edits the configuration related to the area <area_id> """ if area_id.upper() == ALL_AREAS: area = modify_area_all(edited_area) if edited_area.occupancy_rules: set_occupancy_rules(ALL_AREAS, edited_area.occupancy_rules) else: delete_area_occupancy_rules(ALL_AREAS) area["occupancy_rules"] = get_area_occupancy_rules(ALL_AREAS) return area edited_area.id = area_id config_dict = extract_config() area_names = [x for x in config_dict.keys() if x.startswith("Area_")] areas = [map_section_from_config(x, config_dict) for x in area_names] areas_ids = [area["id"] for area in areas] try: index = areas_ids.index(area_id) except ValueError: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"The area: {area_id} does not exist") cameras = [x for x in config_dict.keys() if x.startswith("Source_")] cameras = [map_camera(x, config_dict, []) for x in cameras] camera_ids = [camera["id"] for camera in cameras] if not all(x in camera_ids for x in edited_area.cameras.split(",")): non_existent_cameras = set(edited_area.cameras.split(",")) - set(camera_ids) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"The cameras: {non_existent_cameras}" f"do not exist") occupancy_rules = edited_area.occupancy_rules del edited_area.occupancy_rules area_dict = map_to_config_file_format(edited_area) config_dict[f"Area_{index}"] = area_dict success = update_config(config_dict, reboot_processor) if occupancy_rules: set_occupancy_rules(edited_area.id, occupancy_rules) else: delete_area_occupancy_rules(area_id) if not success: return handle_response(area_dict, success) area = next((area for area in get_areas() if area["id"] == area_id), None) area["occupancy_rules"] = get_area_occupancy_rules(area["id"]) return area
async def create_area(new_area: AreaConfigDTO, reboot_processor: Optional[bool] = True): """ Adds a new area to the processor. """ # TODO: We have to autogenerate the ID. config = get_config() areas = config.get_areas() if new_area.id in [area.id for area in areas]: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=bad_request_serializer("Area already exists", error_type="config duplicated area") ) elif new_area.id.upper() == ALL_AREAS: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=bad_request_serializer("Area with ID: 'ALL' is not valid.", error_type="Invalid ID") ) cameras = config.get_video_sources() camera_ids = [camera.id for camera in cameras] if not all(x in camera_ids for x in new_area.cameras.split(",")): non_existent_cameras = set(new_area.cameras.split(",")) - set(camera_ids) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"The cameras: {non_existent_cameras} do not exist") occupancy_rules = new_area.occupancy_rules del new_area.occupancy_rules area_dict = map_to_config_file_format(new_area) config_dict = extract_config() config_dict[f"Area_{len(areas)-1}"] = area_dict success = update_config(config_dict, reboot_processor) if occupancy_rules: set_occupancy_rules(new_area.id, occupancy_rules) if not success: return handle_response(area_dict, success, status.HTTP_201_CREATED) area_directory = os.path.join(os.getenv("AreaLogDirectory"), new_area.id, "occupancy_log") Path(area_directory).mkdir(parents=True, exist_ok=True) area_config_directory = os.path.join(os.getenv("AreaConfigDirectory"), new_area.id) Path(area_config_directory).mkdir(parents=True, exist_ok=True) # known issue: Occupancy rules not returned return next((area for area in get_areas() if area["id"] == area_dict["Id"]), None)
async def create_post_processor(new_post_processor: SourcePostProcessorDTO, reboot_processor: Optional[bool] = True): """ Adds a post processor. """ config_dict = extract_config() post_processors_index = [int(x[-1]) for x in config_dict.keys() if x.startswith("SourcePostProcessor_")] post_processors = get_source_post_processors() try: validate_post_processor(new_post_processor) except ValidationError as e: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) if new_post_processor.name in [ps["name"] for ps in post_processors]: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Post Processor already exists") post_processor_file = map_to_config_file_format(new_post_processor, True) index = 0 if post_processors_index: index = max(post_processors_index) + 1 config_dict[f"SourcePostProcessor_{index}"] = post_processor_file success = update_config(config_dict, reboot_processor) return handle_response(post_processor_file, success, status.HTTP_201_CREATED)
async def edit_area(area_id: str, edited_area: AreaConfigDTO, reboot_processor: Optional[bool] = True): """ Edits the configuration related to the area <area_id> """ if area_id.upper() == ALL_AREAS: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=bad_request_serializer( "Area with ID: 'ALL' cannot be edited.", error_type="Invalid ID")) edited_area.id = area_id config_dict = extract_config() area_names = [x for x in config_dict.keys() if x.startswith("Area_")] areas = [map_section_from_config(x, config_dict) for x in area_names] areas_ids = [area["id"] for area in areas] try: index = areas_ids.index(area_id) except ValueError: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"The area: {area_id} does not exist") cameras = [x for x in config_dict.keys() if x.startswith("Source_")] cameras = [map_camera(x, config_dict, []) for x in cameras] camera_ids = [camera["id"] for camera in cameras] if not all(x in camera_ids for x in edited_area.cameras.split(",")): non_existent_cameras = set( edited_area.cameras.split(",")) - set(camera_ids) raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"The cameras: {non_existent_cameras} do not exist") area_dict = map_to_config_file_format(edited_area) config_dict[f"Area_{index}"] = area_dict success = update_config(config_dict, reboot_processor) if not success: return handle_response(area_dict, success) return next((area for area in get_areas() if area["id"] == area_id), None)
def map_to_camera_file_format(camera: CameraDTO): camera_file = map_to_config_file_format(camera) camera_file.pop("Image", None) return camera_file