示例#1
0
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)
示例#2
0
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=bad_request_serializer(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=bad_request_serializer(
                                "Periodic task already exists",
                                error_type="config duplicated periodic_task"))
    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)
    if not success:
        return handle_response(periodic_task_file, success,
                               status.HTTP_201_CREATED)
    return next((ps for ps in get_periodic_tasks()
                 if ps["name"] == periodic_task_file["Name"]), None)
async def create_camera(new_camera: CameraDTO,
                        reboot_processor: Optional[bool] = True):
    """
    Adds a new camera to the processor.
    """
    config_dict = extract_config()
    cameras_name = [x for x in config_dict.keys() if x.startswith("Source_")]
    cameras = [map_camera(x, config_dict) for x in cameras_name]

    if new_camera.id is None:
        ids = [camera["id"] for camera in cameras]
        new_camera.id = str(get_first_unused_id(ids))
    elif new_camera.id in [camera["id"] for camera in cameras]:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=bad_request_serializer(
                                "Camera already exists",
                                error_type="config duplicated camera"))
    camera_dict = map_to_camera_file_format(new_camera)
    config_dict[f"Source_{len(cameras)}"] = camera_dict
    success = update_config(config_dict, reboot_processor)
    if not success:
        return handle_response(camera_dict, success, status.HTTP_201_CREATED)

    camera_screenshot_directory = os.path.join(
        os.environ.get("ScreenshotsDirectory"), new_camera.id)
    Path(camera_screenshot_directory).mkdir(parents=True, exist_ok=True)
    heatmap_directory = os.path.join(os.getenv("SourceLogDirectory"),
                                     new_camera.id, "objects_log")
    Path(heatmap_directory).mkdir(parents=True, exist_ok=True)

    return next(
        (camera
         for camera in get_cameras() if camera["id"] == camera_dict["Id"]),
        None)
示例#4
0
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)
示例#5
0
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=bad_request_serializer(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)
    if not success:
        return handle_response(periodic_task_file, success)
    return next(
        (ps
         for ps in get_periodic_tasks() if ps["name"] == periodic_task_name),
        None)
示例#6
0
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)
示例#7
0
async def delete_area(area_id: str, reboot_processor: Optional[bool] = True):
    """
    Deletes 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 deleted.",
                                error_type="Invalid ID"))
    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]
    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")

    config_dict.pop(f"Area_{index}")
    config_dict = reestructure_areas((config_dict))

    success = update_config(config_dict, reboot_processor)

    area_directory = os.path.join(os.getenv("AreaLogDirectory"), area_id)
    shutil.rmtree(area_directory)

    return handle_response(None, success, status.HTTP_204_NO_CONTENT)
def validate_dates(from_date: date, to_date: date):
    if from_date > to_date:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=bad_request_serializer(
                "Invalid range of dates",
                error_type="from_date doesn't come before to_date",
                loc=["query", "from_date"]))
示例#9
0
async def create_user(auth_info: AuthDTO):
    """
    Creates the API user (if it's not already created) with the given password.
    """
    try:
        create_api_user(auth_info.user, auth_info.password)
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=bad_request_serializer(str(e)))
示例#10
0
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)
def get_heatmap(camera_id: str,
                from_date: date = Query(
                    (date.today() -
                     timedelta(days=date.today().weekday(), weeks=4))),
                to_date: date = Query(date.today()),
                report_type: Optional[str] = "violations"):
    """
    Returns a heatmap image displaying the violations/detections detected by the camera <camera_id>
    """
    validate_camera_existence(camera_id)
    validate_dates(from_date, to_date)
    if report_type in ["violations", "detections"]:
        return generate_heatmap(camera_id, from_date, to_date, report_type)
    else:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=bad_request_serializer(
                                "Invalid report_type",
                                error_type="invalid config"))
示例#12
0
async def create_camera(new_camera: CameraDTO,
                        reboot_processor: Optional[bool] = True):
    """
    Adds a new camera to the processor.
    """
    config_dict = extract_config()
    cameras_name = [x for x in config_dict.keys() if x.startswith("Source_")]
    cameras = [map_camera(x, config_dict) for x in cameras_name]
    if new_camera.id in [camera["id"] for camera in cameras]:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=bad_request_serializer(
                                "Camera already exists",
                                error_type="config duplicated camera"))
    camera_dict = map_to_camera_file_format(new_camera)
    config_dict[f"Source_{len(cameras)}"] = camera_dict
    success = update_config(config_dict, reboot_processor)
    if not success:
        return handle_response(camera_dict, success, status.HTTP_201_CREATED)
    return next((camera for camera in get_cameras(["withImage"])
                 if camera["id"] == camera_dict["Id"]), None)
示例#13
0
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)