def replace_region_on_cam_json(json_detector: dict, new_region: dict, only_points: bool, statistic: Statistic) -> dict: """Полное замены зоны на детекторе без проверки внутренних ключей. :param json_detector: json с секцией детектора; :param new_region: словарь с новым регионом; :param only_points: заменить только список points; :param statistic: объект класса Statistic. :return: новые словарь json детектора. """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (json_detector: dict, new_region: dict, only_points: bool, statistic: Statistic)") logger.debug("replace_region_on_cam_json(" + str(json_detector) + ", " + str(new_region) + ", " + str(only_points) + ")") region_name = get_region_name(new_region, statistic) detector_name = get_plugin_type(json_detector, statistic) data = get_region_from_detector_json(json_detector, region_name, statistic) index_region = data[0] original_region = data[1] if index_region == -1: statistic.append_error("в " + region_name, "НЕТ_ЗОНЫ", False) return {} if only_points: if '_points' not in original_region: statistic.append_error("'_points' в '" + region_name + "'!", "НЕТ_КЛЮЧА", False) elif '_points' not in new_region: statistic.append_error("'_points' в новой зоне!", "НЕТ_КЛЮЧА", False) json_detector[detector_name]['detection_regions']['square']['_value'][index_region]['_points'] = \ new_region['_points'] else: json_detector[detector_name]['detection_regions']['square']['_value'][index_region] = new_region return json_detector
def check_detection_regions_keys(json_detector: dict, statistic: Statistic) -> bool: """Проверка существования основных ключей для зоны детектора. :param json_detector: json с секцией детектора; :param statistic: объект класса Statistic. :return: флаг корректности. """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (dict_json_detector)") logger.debug("with params (" + str(json_detector) + ")") detector_name = get_plugin_type(json_detector, statistic) if tools.check_keys_exist(json_detector[detector_name], ['detection_regions'], detector_name, False, statistic) is False: return False if tools.check_keys_exist(json_detector[detector_name]['detection_regions'], ['square'], detector_name, False, statistic) is False: return False if tools.check_keys_exist(json_detector[detector_name]['detection_regions']['square'], ['_value'], detector_name, False, statistic) is False: return False return True
def get_statistic_by_cam(client: SoapClient, key1: str, key2: str, statistic: Statistic) -> dict: """Получение статистики по указанной камере. Использует ws метод list_statistic_for_profiles. :param client: объект клиента класса SoapClient; :param key1: key1 IV7 (имя сервреа); :param key2: key2 IV7 (имя камеры); :param statistic: объект класса Statistic. :return: ответ ws метода - статистика по указанной камере. """ logger = statistic.get_log().get_logger("scripts/common/tools") logger.info("was called (client: SoapClient, key1: str, key2: str)") logger.debug("with params (client_obj, " + key1 + ", " + key2 + ")") logger.info( "call func ipcameras.list_statistic_for_profiles(client, token)") logger.debug("ipcameras.list_statistic_for_profiles(client_obj, '')") all_stat = ipcameras.list_statistic_for_profiles(client, "") if not all_stat: return {} for stat in all_stat: check_keys_exist(stat, ['key1', 'key2'], 'statistic_for_profiles', True, statistic) if stat['key2'] == key2 and stat['key1'] == key1: return stat return {}
def get_servers(db_path: str, statistic: Statistic) -> Tuple[str]: """Получение списка всех серверов из БД. :param db_path: путь к бд; :param statistic: объект класса Statistic. :return: список серверов. """ logger = statistic.get_log().get_logger("scripts/common/db") logger.info("was called (path_to_db: str, statistic: Statistic)") logger.debug("with params (" + db_path + ")") if not os.path.exists(db_path): statistic.append_error("Файла БД не существует!", "БД", True) try: time.sleep(0.2) conn = sqlite3.connect(db_path) cursor = conn.cursor() sql_cmd = "SELECT vsrname FROM videoserver" cursor.execute(sql_cmd) query_result = cursor.fetchall() conn.commit() conn.close() servers = [] for result in query_result: servers.append(result[0]) if not servers: statistic.append_error("Не обнаружено ни одного сервера!", "БД") return tuple(servers) except sqlite3.OptimizedUnicode: statistic.append_error("Ошибка выполнения команды!", "БД", True)
def ptzserver_command_simple(client: SoapClient, key2: str, token: str, statistic: Statistic, stop: bool = False, left: int = 0, right: int = 0, up: int = 0, down: int = 0, zoom_in: int = 0, zoom_out: int = 0, query_all: bool = False, go_to_preset: int = 0, set_preset: int = 0, pan_to: int = -1, tilt_to: int = -1, home: bool = False) -> dict: """ :param client: :param key2: :param token: :param stop: :param left: :param right: :param up: :param down: :param zoom_in: :param zoom_out: :param query_all: :param go_to_preset: :param set_preset: :param pan_to: :param tilt_to: :param home: :return: """ logger = statistic.get_log().get_logger("scripts/ws/ptz") logger.info( "was called (client: SoapClient, key2: str, token: str, statistic: Statistic, stop: bool,\ left: int, right: int, up: int, down: int, zoom_in: int, zoom_out: int, query_all: bool,\ go_to_preset: int, set_preset: int, pan_to: int, tilt_to: int, home: bool)" ) logger.debug("params (client_obj, " + key2 + ", " + token + ", statistic_obj" + str(stop) + ", " + str(left) + ", " + str(right) + ", " + str(up) + ", " + str(down) + ", " + str(zoom_in) + ", " + str(zoom_out) + ", " + str(query_all) + ", " + str(go_to_preset) + ", " + str(set_preset) + ", " + str(pan_to) + ", " + str(tilt_to) + ", " + str(home) + ")") params, sysparams, method = pattern.ptzserver_command_simple( key2, token, stop, left, right, up, down, zoom_in, zoom_out, query_all, go_to_preset, set_preset, pan_to, tilt_to, home) response = client.call_method2(method, params, sysparams, [0]) logger.info("ws method ptzserver:Command was executed successfully!") statistic.append_info("ptzserver:Command выполнен успешно", "WS_МЕТОД") return response
def faceva_get_event_image(client: SoapClient, token: str, event: int, time: int, statistic: Statistic) -> dict: """Функция выполнения ws метода FaceVA:GetEventImage. :param client: объект класса SoapClient для отправки и приема ws запросов; :param token: токен соединения; :param event: номер события; :param time: время события (в unix формате); :param statistic: объект класса Statistic для ведения статистики ошибок и предупреждений :return: в случае успеха словарь ответа вида: { "img": "base64 code" } в случае ошибки словарь вида: { "result": "error" } """ logger = statistic.get_log().get_logger("scripts/ws/analytics") logger.info( "was called (client: SoapClient, token: str, event: int, time: int, statistic: Statistic)" ) logger.debug("params (client_obj" + token + ", " + str(event) + ", " + str(time) + ", stat_obf)") params, sysparams, method = pattern.faceva_get_event_image( token, event, time) response = client.call_method2(method, params, sysparams, [0]) statistic.append_info(method + " выполнен успешно!", "WS МЕТОД") return response['result'][0]
def send_add_model_to_hot_list(zmqclient: ZmqClient, model_id: str, descriptor: str, res_num: int, reaction_code: int, archive: int, timeout: float, statistic: Statistic) -> str: """Функция отправки запроса AddModelToHotList. :param zmqclient: объект класса ZmqClient; :param model_id: id построенной модели; :param descriptor: дескриптор фото; :param res_num: :param reaction_code: :param archive: :param timeout: время ожидания ответа; :param statistic: объект класса Statistic. :return: id сообщения в виде строки. """ logger = statistic.get_log().get_logger("scripts/xml/zmq") logger.info("was called (zmqclient, model_id, descriptor, res_num, reaction_code, archive)") message_id = str(uuid.uuid1()) xml_tree_add_to_hot = zmq.add_model_to_hot_list(message_id, model_id, descriptor, res_num, reaction_code, archive) xml_tree_full = zmq.common_head(xml_tree_add_to_hot) xml_response = _common_check_response(_send_request(zmqclient, xml_tree_full, message_id, timeout, statistic), "AddToHotlist", statistic) return str(message_id)
def open_json_file(path: str, statistic: Statistic) -> dict: """Открытие файла с содержимым в формате json. Функция считывает json из файла и преобразует в словарь. Если файл не существует - генерируется критическая ошибка. :param path: путь к файлу; :param statistic: объект класса Statistic. :return: сожержимое json файла в виде словаря. """ logger = statistic.get_log().get_logger("scripts/common/tools") logger.info("was called (path: str, statistic: Statistic)") logger.debug("with params (" + path + ", statistic_obj)") if not os.path.exists(path): statistic.append_error(path, "НЕ СУЩЕСТВУЕТ", True) with open(path, encoding='utf-8') as json_file: try: logger.info("open json file '" + path + "' was executed successfully") result = json.load(json_file) statistic.append_info( "Открытие файла '" + path + "' выполнено успешно...", "JSON_ФАЙЛ") return result except json.JSONDecodeError: logger.error("В файле '" + path + "' отсутствует корректная строка JSON!") statistic.append_error( "В файле '" + path + "' отсутствует корректная строка JSON!", "JSON_ФАЙЛ", True)
def check_keys_exist(dict_on_check: dict, keys: list, dict_name: str, is_critical: bool, statistic: Statistic) -> bool: """проверка на наличия ключей в словаре. :param dict_on_check: словарь к проверке; :param keys: список ключей, на существование которых идет проверка; :param dict_name: имя проверяемого словаря для понимания пользователем; :param is_critical: флаг - выбрасывать исключение при отсутствии ключа или нет и отпечатать только сообщение; :param statistic: экземляр класса Statistic для добавления ошибок и предупреждений. :return: флак успешности проверки. """ logger = statistic.get_log().get_logger("scripts/common/tools") logger.info("was called") logger.debug("with params (" + str(dict_on_check) + ", " + str(keys) + ", " + dict_name + ", " + str(is_critical) + ")") if isinstance(dict_on_check, dict) is False: statistic.append_error("'" + dict_name + "'", "НЕТ_СЛОВАРЯ", True) success = True for key in keys: if key not in dict_on_check: success = False if is_critical: statistic.append_error("'" + key + "' в '" + dict_name + "'!", "НЕТ_КЛЮЧА", True) else: logger.error("'" + key + "' в '" + dict_name + "'!") statistic.append_error("'" + key + "' в '" + dict_name + "'!", "НЕТ_КЛЮЧА") return success
def get_date_from_str(current_date: str, statistic: Statistic) -> datetime: """Функция возвращает datetime из строки. Аргумент current_date может быть вида: 1) %Y.%m.%d %H:%M:%S 2) %Y-%m-%dT%H:%M-%S 3) %Y-%m-%d %H:%M:%S 4) %Y-%m-%d %H:%M:%S.%f :param current_date: строка текущей даты; :param statistic: объект класса Statistic. :return: datetime. """ logger = statistic.get_log().get_logger("scripts/common/tools") logger.info("was called (current_date: str)") logger.debug("params (client_obj, " + current_date + ")") formats = [ '%Y.%m.%d %H:%M:%S', '%Y-%m-%dT%H:%M-%S', '%Y-%m-%d %H:%M:%S', "%Y-%m-%d %H:%M:%S.%f" ] for format_ in formats: try: return datetime.strptime(current_date, format_) except ValueError: continue statistic.append_error( "Не поддерживаемый формат даты " + current_date + "!", "НЕВАЛИД ФОРМАТ", True)
def get_points_from_region(json_detector: dict, region_name: str, statistic: Statistic) -> dict: """Получение словаря со списком _points из указанной зоны детектора. :param json_detector: json с секцией детектора; :param region_name: имя зоны; :param statistic: объект класса Statistic. :return: словарь со списком _points. """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (json_detector: dict, region_name: str, statistic: Statistic") logger.debug("get_points_from_region(" + str(json_detector) + ", " + region_name + ")") data = get_region_from_detector_json(json_detector, region_name, statistic) index_region = data[0] region = data[1] if index_region == -1: statistic.append_error("в " + region_name, "НЕТ_ЗОНЫ", False) return {} for first_lvl_key in region: if first_lvl_key == '_points': return { first_lvl_key: region[first_lvl_key] } return {}
def faceva_get_frame(client: SoapClient, token: str, camera: int, time: int, statistic: Statistic) -> dict: """Функция выполнения ws метода FaceVA:GetFrame. :param client: объект класса SoapClient для отправки и приема ws запросов; :param token: токен соединения; :param camera: номер камеры; :param time: время события (в unix формате); :param statistic: объект класса Statistic для ведения статистики ошибок и предупреждений. :return: словарь ответа вида: { "img": "base64 code" } """ logger = statistic.get_log().get_logger("scripts/ws/analytics") logger.info( "was called (client: SoapClient, token: str, event: int, time: int, statistic: Statistic)" ) logger.debug("params (client_obj" + token + ", " + str(camera) + ", " + str(time) + ", stat_obf)") params, sysparams, method = pattern.faceva_get_frame(token, camera, time) response = client.call_method2(method, params, sysparams, [0]) return response['result'][0]
def replace_region_values_on_cam_json(json_detector: dict, region_name: str, new_region: dict, force: bool, statistic: Statistic) -> dict: """Замена зоны по ключам (только существующие ключи). :param json_detector: json с секцией детектора; :param region_name: имя зоны; :param new_region: словарь с новым регионом; :param force: вставить принудительно настройку, если ее нет в json; :param statistic: объект класса Statistic. :return: json с измененной секцией детектора в зоне """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (json_detector: dict, region_name: str, new_region: dict, statistic: Statistic") logger.debug("with params (" + str(json_detector) + ", " + region_name + ", " + str(new_region) + ")") detector_name = get_plugin_type(json_detector, statistic) data = get_region_from_detector_json(json_detector, region_name, statistic) index_region = data[0] region = data[1] if index_region == -1: statistic.append_error(region_name, "НЕТ ЗОНЫ") return {} region_json = json_detector[detector_name]['detection_regions']['square']['_value'][index_region] for first_lvl_key in new_region.keys(): if tools.check_keys_exist(region, [first_lvl_key], region_name, False, statistic) is False: if force: region_json[first_lvl_key] = new_region[first_lvl_key] txt_msg = first_lvl_key + " в зоне '" + region_name + " выполнена успешно!" logger.info(txt_msg) statistic.append_success(txt_msg, "ПРИНУДИТЕЛЬНАЯ ВСТАВКА КЛЮЧА В ЗОНЕ") continue # если данный ключ является отрисовкой зоны _points, то содержимое меняем # немного по другому if first_lvl_key == '_points': region_json['_points'] = new_region['_points'] txt_msg = "_ points в зоне " + region_name + " выполнена успешно!" logger.info(txt_msg) statistic.append_info(txt_msg, "ЗАМЕНА КЛЮЧЕЙ В ЗОНЕ") continue # для остальных ключей делаем замену в _value if tools.check_keys_exist(region[first_lvl_key], ['_value'], region_name + "[" + str(index_region) + "]", False, statistic) is False: continue if tools.check_keys_exist(new_region[first_lvl_key], ['_value'], first_lvl_key + " в новом регионе!", False, statistic) is False: continue region_json[first_lvl_key]['_value'] = new_region[first_lvl_key]['_value'] txt_msg = first_lvl_key + "[_value] в зоне '" + region_name + " выполнена успешно!" logger.info(txt_msg) statistic.append_success(txt_msg, "ЗАМЕНА КЛЮЧА В ЗОНЕ") return json_detector
def get_cam_json(path_to_db: str, key1: str, key2: str, key3: str, statistic: Statistic) -> dict: """Получение json графа (камеры) из БД. Делает SELECT запрос к БД на получение json-ов всех камер и профилей, а затем осуществляется поиск нужной камеры. :param path_to_db: путь к файлу БД; :param key1: имя сервера; :param key2: имя камеры; :param key3: профиль камеры; :param statistic: объект класса Statistic. :return: json в виде словаря. """ logger = statistic.get_log().get_logger("scripts/common/db") logger.info( "was called path_to_db: str, key1: str, key2: str, key3: str, statistic: Statistic)" ) logger.debug("with params (" + path_to_db + ", " + key1 + ", " + key2 + ", " + key3 + ")") if not os.path.exists(path_to_db): statistic.append_error("Файла БД не существует!", "БД", True) try: time.sleep(0.2) conn = sqlite3.connect(path_to_db) cursor = conn.cursor() db_setname = key1 + "_" + key2 + "_" + key3 sql_cmd = 'SELECT setvalue FROM setting WHERE settypeid = ? AND setname = ?' cursor.execute(sql_cmd, [1, db_setname]) json_cam = cursor.fetchall() conn.commit() conn.close() if not json_cam: statistic.append_error("Камера '" + db_setname + "' отсутствует!", "БД") return {} logger.info("db select json by '" + db_setname + "' cam was executed successfully!") statistic.append_info( "Получение json из БД камеры '" + db_setname + "' выполнено успешно!", "БД") # в некоторых плагинах есть сочетания слешей вида: \/, которое нельзя никак заменять. # При десериализации по умолчанию символ \ пропадает, как служебный. # Поэтому перед десериализацией необходимо добавить два слеша, чтобы было так (\\/). # Однако почему то в таком случае после десериализации оно так и останется (\\/), а не (\/). # То есть потом при сериализации этот момент нужно учесть и заменить на \/. replaced_json_cam = json_cam[0][0].replace("\\/", "\\\\/") return json.loads(replaced_json_cam, parse_float=json_float_parser) except sqlite3.OptimizedUnicode: statistic.append_error("Ошибка выполнения команды!", "БД", True)
def insert_graphs_to_db(ws_client: SoapClient, token: str, path_to_db: str, json_: dict, key1: str, key3: str, count: int, statistic: Statistic) -> tuple: """Добавление в БД указанного количества графов c указанным json. Соблюдается уникальность key2 и id54 в БД. :param ws_client: объект клиента класса SoapClient; :param token: логин пользователя для ws метода; :param path_to_db: путь к БД; :param json_: json графа (камеры); :param key1: имя сервера; :param key3: профиль key3; :param count: количество графов для добавления в БД; :param statistic: объект класса Statistic. :return: кортеж key2 добавленных камер. """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (client: SoapClient, login: str, password: str, path_to_db: str, json_: dict, key1: str," + "key3: str, count: int, statistic: Statistic)") logger.info("call func db.get_lists_id54_and_key2(path_to_db)") logger.debug("params (" + path_to_db + ")") list_key2 = list(db.get_cams_names(path_to_db, key1, statistic)) list_id54 = list(db.get_cams_id(path_to_db, statistic)) logger.debug("list_key2: " + str(list_key2)) logger.debug("list_id54: " + str(list_id54)) list_new_key2: list = [] for graph in range(count): free_id54 = get_free_id54(tuple(list_id54)) free_key2 = get_free_key2(tuple(list_key2), free_id54) logger.debug("free_id54: " + str(free_id54)) logger.debug("free_key2: " + str(free_key2)) list_id54.append(free_id54) list_key2.append(free_key2) list_new_key2.append(free_key2) set_key2(json_, free_key2, statistic) set_id54(json_, free_id54, statistic) setid = db.insert_new_cam(path_to_db, key1, free_key2, key3, json_, statistic) logger.info("Вставка камеры '" + free_key2 + "' в БД выполена успешно!") statistic.append_info("Вставка камеры '" + free_key2 + "' в БД выполена успешно!", "ИНФО") ws_video_server.reload_graph(ws_client, token, setid, statistic) logger.info("Перезагрузка графа в процессе по камере " + free_key2 + " выполнена успешно!") statistic.append_info("Перезагрузка графа в процессе по камере " + free_key2 + " выполнена успешно!", "ИНФО") return tuple(list_new_key2)
def update_setname_by_cam(path_to_db: str, key1: str, key2: str, key3: str, new_key1: str, new_key2: str, new_key3: str, statistic: Statistic) -> int: """Функция изменения имени камеры в БД. :param path_to_db: :param key1: имя сервера :param key2: имя камеры :param key3: профиль камеры :param new_key1: новое имя сервера :param new_key2: новое имя камеры :param new_key3: новый профиль :param statistic: объект класса Statistic :return: код ошибки: 0 - все ок. """ logger = statistic.get_log().get_logger("scripts/common/db") logger.info( "was called (path_to_db: str, key1: str, key2: str, key3: str, new_key1: str, new_key2: str," + "new_key3: str, statistic: Statistic)") logger.debug("with params (" + path_to_db + ", " + key1 + ", " + key2 + ", " + key3 + ", " + new_key1 + ", " + new_key2 + ", " + new_key3 + ")") if not os.path.exists(path_to_db): statistic.append_error("Файла БД не существует!", "БД", True) try: time.sleep(0.2) conn = sqlite3.connect(path_to_db) cursor = conn.cursor() db_setname = key1 + "_" + key2 + "_" + key3 db_new_setname = new_key1 + "_" + new_key2 + "_" + new_key3 sql_cmd = "SELECT setid FROM setting WHERE settypeid = ? AND setname = ?" cursor.execute(sql_cmd, [1, db_setname]) db_setid = cursor.fetchall()[0][0] time.sleep(0.2) sql_cmd = "UPDATE setting SET setname = ? WHERE setid = ?" cursor.execute(sql_cmd, [db_new_setname, str(db_setid)]) conn.commit() conn.close() logger.info("db update setname for '" + key2 + "' cam was executed successfully") log.print_all("Обновление имени камеры c '" + db_setname + "' на '" + db_new_setname + "' выполнено успешно!") return 0 except sqlite3.OptimizedUnicode: statistic.append_error("Ошибка выполнения команды!", "БД", True)
def get_down_servers(client: SoapClient, token: str, direct_access: int, statistic: Statistic) -> dict: """WS метод listener_pinger_get_down_servers с проверками существования ключей и типов их значений. :param client: объект клиента; :param token: токен авторизации; :param direct_access: параметр ws метода; :param statistic: объект класса Statistic. :return: response["result"][0]["data"]["string"] """ logger = statistic.get_log().get_logger("scripts/ws/listener_pinger") logger.info( "was called (client: SoapClient, token: str, direct_access: int, statistic: Statistic)" ) logger.debug("with params (client_obj, " + token + ", " + str(direct_access) + ", stat_obj)") params, sysparams, method = pattern.listener_pinger_get_down_servers( token, direct_access) response = client.call_method2(method, params, sysparams, [0]) tools.check_types(["response['result'][0]"], [response["result"][0]], [dict], statistic) tools.check_keys_exist(response["result"][0], ['data', 'hash'], 'response["result"][0]', False, statistic) tools.check_types( ['data', 'hash'], [response["result"][0]["data"], response["result"][0]["hash"]], [dict, str], statistic) tools.check_keys_exist(response["result"][0]["data"], ['string'], 'response["result"][0]["data"]', False, statistic) tools.check_types(["response['result'][0]['data']['string']"], [response["result"][0]["data"]["string"]], [dict], statistic) string = response["result"][0]["data"]["string"] tools_lp.listener_pinger_keys_verifier(string, statistic) for down_server in string["down_servers"]: for key in down_server: tools_lp.listener_pinger_keys_verifier(down_server[key], statistic) logger.info("ws '" + method + "' выполнен успешно!") statistic.append_info(method + "' выполнен успешно!", "WS_МЕТОД") return response["result"][0]["data"]["string"]
def _common_check_response(xml_response: Tree, method_name: str, statistic: Statistic) -> Tree: logger = statistic.get_log().get_logger("scripts/xml/zmq") logger.info("was called (xml_response)") logger.debug("(" + Tree.tostring(xml_response).decode() + ")") if xml_response == -1: statistic.append_error(method_name + " завершился с ошибкой!", "ZMQ_ОТВЕТ") return -1 status = int(xml_response.find(".//status").text) if status != 0: status_descr = xml_response.find(".//statusDescr").text statistic.append_error("Статус ответа: " + str(status_descr), "ZMQ_ОТВЕТ") return -1 return xml_response
def get_plugin_type(section: dict, statistic: Statistic) -> str: """Функция получение типа плгина из секции блока json камеры. :param section: секция json; :param statistic: объект класса Statistic. :return: тип плагина. """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called func get_plugin_type(section: dict, statistic: Statistic)") logger.debug("with params (" + str(section) + ")") tools.check_keys_exist(section, ["_type"], "section", True, statistic) tools.check_keys_exist(section['_type'], ["_value"], "section['_type']", True, statistic) return section['_type']['_value']
def write_to_file(path: str, content: str, statistic: Statistic) -> None: """Функция записи в файл. :param path: путь к файлу; :param content: содержимое для записи; :param statistic: объект класса Statistic. """ logger = statistic.get_log().get_logger("scripts/common/tools") logger.info("was called (path: str, content: str)") logger.debug("with params (" + path + ", " + content + ")") with open(path, 'w') as txt_file: txt_file.write(content) logger.info("write content to file '" + path + "' was executed successfully!") statistic.append_info( "Запись в файл '" + path + "' выполнена успешно!", "ИНФО")
def create_json_from_profiles(key1: str, extra_blocks: dict, video_path: str, decode: bool, statistic: Statistic) -> dict: """Получение профилей common, media, muxer, iv54server, sender и доп. блоков. :param key1: имя видеосервера; :param extra_blocks: словарь с доп. json блоками (например аналитика и декодек); :param video_path: путь до источника видео; :param decode: флаг - нужно ли добавлять блок декодека в граф; :param statistic: объект класса Statistic. :return: словарь json камеры (граф для вставки в БД). Параметр extra_blocks должен иметь вид, например: { "analytics": [....], "decode": [....] } Могут быть любые блоки, но суть в том, что блоком считается ключ верхнего уровня и его значения словаря extra_blocks. """ logger = statistic.get_log().get_logger("scripts/common/graph") common: dict = profiles.get_common_dict(key1, "1") # Для дампа необходимо использовать устройство IP камеры, # а для всего остального (авишки/видео) устройство мультимедиа. file_type = tools.get_file_type(video_path) if file_type == "raw": data_dump: tuple = tools.get_dump_name_and_step(video_path) device: dict = profiles.get_ipcameras_dict("ipcameras:RVI:Unknown", "1", "admin", "admin", data_dump[0], data_dump[1]) else: device: dict = profiles.get_device_media_dict(video_path) muxer: dict = profiles.get_muxer_dict("trackSource") network_5_4: dict = profiles.get_network_5_4_dict(1) sender: dict = profiles.get_sender_dict(1) dicts = [common, device, muxer, network_5_4, sender] if decode: dicts.append(profiles.get_decode_dict()) for block in extra_blocks: dicts.append( { block: extra_blocks[block] } ) logger.info("call func tools.get_full_dict(list)") logger.debug("params (" + str(dicts) + ")") return tools.get_full_dict(dicts)
def get_region_from_detector_json(json_detector: dict, region_name: str, statistic: Statistic) -> tuple: """Получение индекса и json зоны из детектора по ее имени. :param json_detector: json с секцией детектора; :param region_name: имя зоны; :param statistic: объект класса Statistic. :return: кортеж: 0 - индекс региона в списке зон, 1 - json зоны. """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (json_detector: dict, region_name: str, statistic: Statistic)") logger.debug("with params(" + str(json_detector) + ", " + region_name + ")") zones = get_detection_regions_from_detector_json(json_detector, statistic) for index, region in enumerate(zones): if get_region_name(region, statistic) == region_name: return index, dict(region) return -1, {}
def ptzserver_list_profiles(client: SoapClient, token: str, statistic: Statistic) -> list: logger = statistic.get_log().get_logger("scripts/ws/ptz") logger.info( "was called (client: SoapClient, token: str, statistic: Statistic)") logger.debug("with params (client_obj, " + token + ", stat_obj)") params, sysparams, method = pattern.ptzserver_list_profiles(token) response = client.call_method2(method, params, sysparams, [0]) logger.info("ws method " + method + " was executed successfully!") statistic.append_info(method + " выполнен успешно!", "WS_МЕТОД") if not response["result"] or response["result"] == [{}]: statistic.append_error("Список PTZ камер пуст!", "НЕТ PTZ КАМЕР") return [] return response["result"]
def faceva_get_data_base(client: SoapClient, token: str, statistic: Statistic) -> tuple: """Функция выполнеия ws метода FaceVA:GetDataBase :param client: объект класса SoapClient для отправки и приема ws запросов; :param token: токен соединения; :param statistic: объект класса Statistic для ведения статистики ошибок и предупреждений. :return: список персон, который приходит в ответе в ключе persons вида: [ { "id": 26617065162932227, "name": Иванов Иван Иванович, ["pacs": 1], ["category": "category"], ["department": "department"], ["comment": "comment"], ["information": "information"] } ] """ logger = statistic.get_log().get_logger("scripts/ws/analytics") logger.info("was called(client, login, password)") logger.debug("with params (client_obj, " + token + ", stat_obj)") params, sysparams, method = pattern.faceva_get_data_base(token) response_json = client.call_method2(method, params, sysparams, [0]) result = response_json["result"][0] tools.check_keys_exist(result, ['persons'], "result", True, statistic) persons = result["persons"] tools.check_types(["persons"], [persons], [list], statistic) if not persons: statistic.append_warn("data base persons", "EMPTY") for person in persons: tools.check_keys_exist(person, ["id", "name"], 'person', True, statistic) logger.info("ws method FaceVA:GetDataBase was executed successfully!") statistic.append_info(method + " выполнен успешно!", "WS МЕТОД") return tuple(persons)
def get_plugin_index(block: dict, plugin_type: str, statistic: Statistic) -> int: """Проверка существования секции с указанном типом в блоке. :param block: блок json; :param plugin_type: тип секции (плагина); :param statistic: объект класса Statistic. :return: индекс плагина в блоке. """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (block: dict, plugin_type: str, statistic: Statistic)") logger.debug("with params (" + str(block) + ", " + plugin_type + ")") section_index = -1 for index, section_from_file in enumerate(block): if plugin_type == get_plugin_type(section_from_file, statistic): section_index = index break return section_index
def _check_event_comment(event_info: dict, event: dict, statistic: Statistic) -> None: """Функция проверки вхождений значений ключей из event_info в event['evtcomment']. То есть есть ли указанные значения в комментарии события. :param event_info: ключи со значениями, которые надо искать в комментарии; :param event: событие (ответ ws); :param statistic: объект класса Statistic. """ logger = statistic.get_log().get_logger("scripts/tools/analytics") logger.info("was called (event_info: dict, event: dict, statistic: Statistic)") logger.debug("params (client_obj, " + str(event_info) + ", " + str(event) + ", stat_obj)") for key, value in event_info.items(): index = event['evtcomment'].find(value) if index == -1: statistic.append_error("Ожидалось: " + value + ". Получено: " + event['evtcomment'] + "!", "НЕВАЛИД " + key, False) else: statistic.append_success("Получено: '" + event['evtcomment'] + "'", "ВАЛИД " + key)
def get_region_name(region: dict, statistic: Statistic) -> str: """Получение имени зоны из указанного json зоны. :param region: json зоны; :param statistic: объект класса Statistic. :return: имя зоны (региона). """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (region: dict, statistic: Statistic)") logger.debug("with params (" + str(region) + ")") if tools.check_keys_exist(region, ['name'], 'region', False, statistic) is False: return "" if tools.check_keys_exist(region['name'], ['_value'], 'region["name"]', False, statistic) is False: return "" return region['name']['_value']
def send_enroll_models(zmqclient: ZmqClient, photo_path: str, timeout: float, statistic: Statistic) -> tuple: """Функция отправки EnrollModels. :param zmqclient: объект класса ZmqClient; :param photo_path: путь к фото; :param timeout: время ожидания ответа; :param statistic: объект класса Statistic. :return: дескриптор фото и ее id. """ logger = statistic.get_log().get_logger("scripts/xml/zmq") logger.info("was called (zmqclient, list_photo_paths, timeout)") message_id = str(uuid.uuid1()) photo_type = tools.get_file_type(photo_path) photo_id = str(uuid.uuid1()) photo_base64 = tools.get_photos_base64([photo_path])[0] xml_tree_enroll_models = zmq.enroll_models(message_id, False, photo_base64, photo_type, photo_id) xml_tree_full = zmq.common_head(xml_tree_enroll_models) xml_response = _common_check_response(_send_request(zmqclient, xml_tree_full, message_id, timeout, statistic), "EnrollModels", statistic) list_faces = xml_response.findall(".//face") if not list_faces: statistic.append_error("В ответе нет лиц!", "ZMQ_ОТВЕТ", True) if len(list_faces) > 1: statistic.append_error("Кол-во лиц > 1", "ZMQ_ОТВЕТ", True) descriptor = "" image_id = xml_response.find(".//image") if image_id is None: statistic.append_error("Отсутствует тек 'image'!", "ZMQ_ОТВЕТ", False) image_id = xml_response.find(".//image").text if image_id != photo_id: statistic.append_error("ID каритнки не совпадают!", "ZMQ_ОТВЕТ", False) for face in list_faces: descriptor = face.find(".//model").text break return descriptor, photo_id
def get_detection_regions_from_detector_json(json_detector: dict, statistic: Statistic) -> tuple: """Получение списках всех зон детектора. :param json_detector: json с секцией детектора; :param statistic: объект класса Statistic. :return: список имен зон. """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (json_detector: dict, statistic: Statistic)") logger.debug("with params (" + str(json_detector) + ")") if check_detection_regions_keys(json_detector, statistic) is False: return () detector_name = get_plugin_type(json_detector, statistic) zones: list = json_detector[detector_name]['detection_regions']['square']['_value'] tools.check_types(["zones"], [zones], [list], statistic) return tuple(zones)
def __init__(self, ip: str, port: int, config: dict, statistic: Statistic): self._statistic = statistic self._logger = statistic.get_log().get_logger("client/soapClient") self._ip = ip self._port = port self._history = HistoryPlugin() self._url = 'http://' + self._ip + ':' + str(self._port) + '/axis2/services/Iv7Server/?wsdl' while True: try: self._client = Client(self._url, plugins=[self._history]) break except ConnectionError: self._statistic.append_error("Сервис не доступен на " + self._url, "WS_ПОДКЛЮЧЕНИЕ") self._logger.error("Unable connect to " + self._url) time.sleep(5) self._request_ws_pause: float = config['ws']['pause'] self._timeout: int = config['ws']['timeout'] self._expected_response_time: float = config['ws']['expected_response_time']