def faceva_delete_person(client: SoapClient, token: str, name: str, statistic: Statistic) -> bool: """Функция выполнения ws метода FaceVA:DeletePerson :param client: объект класса SoapClient для отправки и приема ws запросов; :param token: токен соединения; :param name: :param statistic: :return: флаг успешности операции """ logger = log.get_logger("scripts/ws/analytics") logger.info( "was called (client: SoapClient, login: str, password: str, name: str, statistic: Statistic)" ) logger.debug("faceva_delete_person(client_obj" + login + ", " + password + ", " + name + ")") data = pattern.faceva_delete_person(login, password, name) response_json = client.call_method2(data[2], data[0], data[1], True) logger.debug("response_json: " + str(response_json)) tools.check_keys_exist(response_json['result'][0], ['cmd', 'name'], "response_json['result'][0]", True, statistic) #tools.check_on_equal_key_values_in_dict(response_json["result"][0], ['cmd', 'name'], ['DeletePerson', name]) logger.info("ws method FaceVA:DeletePerson was executed successfully!") statistic.append_info(method + " выполнен успешно!", "WS МЕТОД") return True
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 init_data(common_input_data: dict, test_name: str, statistic: Statistic) -> dict: """Получение данных для нужного теста из общего json с входными данными для всех тестов. :param common_input_data: словарь со всеми тестами и их входными данными; :param test_name: имя теста, для которого нужно извлечь его входные данные; :param statistic: обхект класса Statistic. :return: словарь с входными данными для указанного теста. """ logger = log.get_logger("scripts/common/initializer") logger.info("was called (common_input_data, test_name)") logger.debug("params (" + str(common_input_data) + ", " + test_name + ")") test_data = {} for test in common_input_data['tests']: tools.check_keys_exist(test, ['name'], 'test', True, statistic) if test['name'] != test_name: continue tools.check_keys_exist(test, ['input_data'], 'test', True, statistic) test_data = test['input_data'] logger.info("put data into 'test_data'") logger.debug("test_data: " + str(test_data)) break if not test_data: statistic.append_error("Отсутствуют для теста " + test_name, "ВХОДНЫЕ_ДАННЫЕ", True) return test_data
def get_cams_id(db_path: str, statistic: Statistic) -> tuple: if not os.path.exists(db_path): statistic.append_error("Файла БД не существует!", "БД", True) cam_jsons = [] try: time.sleep(0.2) conn = sqlite3.connect(db_path) cursor = conn.cursor() sql_cmd = "SELECT setvalue FROM setting WHERE settypeid = ?" cursor.execute(sql_cmd, [1]) cam_jsons: list = cursor.fetchall() conn.commit() conn.close() except sqlite3.OptimizedUnicode: statistic.append_error("Ошибка выполнения команды!", "БД", True) list_id54 = [] for cam_json in cam_jsons: cam_json = json.loads(cam_json[0]) if tools.check_keys_exist(cam_json, ['network_5_4'], 'cam_json', False, statistic) is False: continue tools.check_types(['network_5_4'], [cam_json['network_5_4']], [list], statistic) if not cam_json['network_5_4']: continue if tools.check_keys_exist(cam_json['network_5_4'][0], ['iv54server'], 'cam_json["network_5_4"][0]', False, statistic) is False: continue if tools.check_keys_exist( cam_json['network_5_4'][0]['iv54server'], ['ID_54'], 'cam_json["network_5_4"][0]["iv54server"]', False, statistic) is False: continue if tools.check_keys_exist( cam_json['network_5_4'][0]['iv54server']['ID_54'], ['_value'], 'cam_json["network_5_4"][0]["iv54server"]["ID_54"]', False, statistic) is False: continue to_add = True for id54 in list_id54: if id54 == cam_json['network_5_4'][0]['iv54server']['ID_54'][ "_value"]: to_add = False break if to_add: list_id54.append( cam_json['network_5_4'][0]['iv54server']['ID_54']["_value"]) return tuple(list_id54)
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_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 set_key2(json_cam: dict, key2: str, statistic: Statistic) -> dict: """Установка значения key2 в словаре json камеры при наличии соответсвующего ключа. :param json_cam: словарь с json графа (камеры); :param key2: новое имя камеры (ключ key2); :param statistic: объект класса Statistic. :return: обновленный словарь json графа (камеры). """ tools.check_keys_exist(json_cam, ['common'], "json_cam", True, statistic) tools.check_keys_exist(json_cam['common'], ['key2'], "json_cam['common']", True, statistic) json_cam['common']['key2'] = key2 return json_cam
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 set_random_time_to_json(self) -> None: """ Втавка в указанный json файл рандомизрованного значения по указанному ключу. Значение поля генерируется с учетом ограничения на дату (интервал дат указывается во входный данных теста) :return: """ # fpattern = r'[0-9]{4}.(0[1-9]|1[012]).(0[1-9]|1[0-9]|2[0-9]|3[01])[-]{1}([0-1]\d|2[0-3])(:[0-5]\d){2}' # spattern = r'[0-9]{4}.(0[1-9]|1[012]).(0[1-9]|1[0-9]|2[0-9]|3[01])[ ]{1}([0-1]\d|2[0-3])(:[0-5]\d){2}' formats_array = ["%Y.%m.%d-%H:%M:%S", "%Y.%m.%d %H:%M:%S"] path = self._input_data["json_path"] cams_dict: dict = tools.open_json_file(path, self._statistic) # открываем json по указанному пути и получаем словарь tools.check_keys_exist(cams_dict, ["cams"], "cams_dict", True, self._statistic) for cam in cams_dict["cams"]: tools.check_keys_exist(cam, ["archive"], "archive", False, self._statistic) for format_str in formats_array: try: if time.strptime(self._input_data["start_date"], format_str): output_format: str = format_str except ValueError: continue sdate = time.mktime(time.strptime(self._input_data["start_date"], output_format)) # преобразуем входную дату в struct_time, а затем переводим все в секунды edate = time.mktime(time.strptime(self._input_data["end_date"], output_format)) # преобразуем входную дату в struct_time, а затем переводим все в секунды # if re.match(fpattern, self._input_data["start_date"]) and re.match(fpattern, self._input_data["end_date"]): # separator: str = "-" # if re.match(spattern, self._input_data["start_date"]) and re.match(spattern, self._input_data["end_date"]): # separator: str = " " # format_str: str = '%Y.%m.%d' + separator + '%H:%M:%S' # sdate = time.mktime(time.strptime(self._input_data["start_date"], format_str)) # преобразуем входную дату в struct_time, а затем переводим все в секунды # edate = time.mktime(time.strptime(self._input_data["end_date"], format_str)) # преобразуем входную дату в struct_time, а затем переводим все в секунды delta: float = edate - sdate # разница в секундах между начальной и конечной датой for cam in cams_dict["cams"]: rand: float = random.random() # случайное число [0;1] ndate: float = sdate + delta * rand # генерируем новую дату # new_date: str = time.strftime('%Y.%m.%d-%H:%M:%S', time.localtime(ndate)) # перевод в строковый формат new_date: str = time.strftime(output_format, time.localtime(ndate)) # перевод в строковый формат cam["archive"] = new_date with open(path, 'w', encoding='utf-8') as json_file: json.dump(cams_dict, json_file, ensure_ascii=False, indent="\t")
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_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 check_plugins_versions(self) -> None: """ Проверка версий плагинов Проверка версий плагинов из списка Обращение к WS с запросом версии плагина с помощью метода ws plugin_info:GetInfo Возможно два режима проверки: server и client. Режим server - проверка версии плагинов на сервере Режим client - проверка версии плагинов на клиенте """ # ---------------------------------------- # ПРОВЕРКА ВХОДНЫХ ДАННЫХ tools.check_keys_exist(self._input_data, ["plugins"], 'input_data', True, self._statistic) tools.check_types(["plugins"], [self._input_data["plugins"]], [list], self._statistic) tools.check_values(["len(plugins)"], [len(self._input_data["plugins"])], [0], ["!="], self._statistic) tools.check_keys_exist(self._input_data, ["mode"], 'input_data', True, self._statistic) tools.check_types(["mode"], [self._input_data["mode"]], [str], self._statistic) tools.check_values(["mode"], [self._input_data["mode"]], [""], ["!="], self._statistic) key_names = ['module_name', 'rel_path'] for plugin in self._input_data["plugins"]: tools.check_keys_exist(plugin, key_names, "plugin", True, self._statistic) tools.check_types(key_names, [plugin[key_names[0]], plugin[key_names[1]]], [str, str], self._statistic) tools.check_values(key_names, [plugin[key_names[0]], plugin[key_names[1]]], ["", ""], ["!=", "!="], self._statistic) # ---------------------------------------- if self._input_data["mode"] == "server": ws_client = SoapClient(self._server_ip, self._server_port, self._config, self._statistic) elif self._input_data["mode"] == "client": ws_client = SoapClient(self._client_ip, self._client_port, self._config, self._statistic) else: self._statistic.append_error("Недопустимое значение ключа 'mode'. Доступны: client, server", "ОШИБКА КЛЮЧА JSON", True) token = ws_users.server_login(ws_client, self._login, self._password, self._statistic) for plugin in self._input_data["plugins"]: result: dict = ws_common.get_plugin_info(ws_client, token, plugin['rel_path'], plugin['module_name'], self._statistic) if result['version'] == "not found module version !": self._statistic.append_error(plugin['module_name'], "ОШИБКА ВЕРСИИ МОДУЛЯ") if plugin['rel_path'] == "bad rel_path !": self._statistic.append_warn("Модуль " + plugin['module_name'] + " " + plugin['rel_path'], "НЕКОРРЕКТНЫЙ ПУТЬ") module_info: str = "Version: " + result['version'] + "\n" + "User: "******"\n" + "Build: " + \ result['build'] + "\n" self._statistic.append_success( "Имя модуля: " + plugin['module_name'] + "\n" + "Путь: " + plugin['rel_path'] + "\n" + module_info, "МОДУЛЬ ИНФО")
def listener_pinger_keys_verifier(string: dict, statistic: Statistic) -> None: """Функция проверка правильность ответа ws метода listener_pinger. :param string: значение ключа string из ответа метода :param statistic: объект класса Statistic """ key_names: list = [ 'is_central_server', 'server_name', 'iv54server_port', 'rtmpPort', 'rtspPort', 'wsPort', 'direct_access', 'cams', 'down_servers' ] tools.check_keys_exist(string, key_names, 'string', True, statistic) key_values: list = [ string['is_central_server'], string['server_name'], string['iv54server_port'], string['rtmpPort'], string['rtspPort'], string['wsPort'], string['direct_access'], string['cams'], string['down_servers'] ] key_types: list = [bool, str, int, int, int, int, int, list, list] tools.check_types(key_names, key_values, key_types, statistic) if string["cams"]: for cam in string["cams"]: key_names = ['key2', 'key3', 'ptzStat', 'Status'] key_values = [ cam['key2'], cam['key3'], cam['ptzStat'], cam['Status'] ] key_types = [str, str, bool, bool] tools.check_keys_exist(cam, key_names, 'string["cams"]', True, statistic) tools.check_types(key_names, key_values, key_types, statistic) if string["archive"]: for cam in string["archive"][0]: key_names = [ 'key1', 'key2', 'key3', 'is_video', 'is_audio', 'is_video_linked', 'is_audio_linked' ] tools.check_keys_exist(cam, key_names, 'string["cams"]', True, statistic) key_values = [ cam['key1'], cam['key2'], cam['key3'], cam['is_video'], cam['is_audio'], cam['is_video_linked'], cam['is_audio_linked'] ] key_types = [str, str, str, bool, bool, bool, bool] tools.check_types(key_names, key_values, key_types, statistic) else: statistic.append_warn("Архив пустой!", "НЕВАЛИД_ЗНАЧ")
def get_coordinates(client: SoapClient, login: str, password: str, key2: str, statistic: Statistic) -> dict: """Функция для получения координат (использует ws метод ptzclient:Command). :param client: объект soap клиента; :param login: логин пользователя; :param password: пароль пользователя; :param key2: имя камеры; :param statistic: объект класса Statistic. :return: словарь с координатами (ключи pan и tilt). """ logger = statistic.get_log().get_logger("scripts/tools/ptz") logger.info( "was called (client: SoapClient, login: str, password: str, key2: str)" ) logger.debug("with params (client_obj, " + login + ", " + password + ", " + key2 + ")") logger.info("call ptzclient_command_simple()") statistic.append_info("получение старых координат...", "ИНФО") logger.info("getting old coordinates") query_all_result = ws.ptzclient_command_simple(client, key2, login, password, False, 0, 0, 0, 0, 0, 0, True, 0, 0, -1, -1, False) tools.check_types(["old_coordinates['result'][0]"], [query_all_result["result"][0]], [dict], statistic) is_old_coordinates = tools.check_keys_exist( query_all_result["result"][0], ["pan", "tilt", "timecoords"], 'old_coordinates["result"][0]', False, statistic) old_timecoords = 0 if is_old_coordinates: old_pan = query_all_result["result"][0]["pan"] old_tilt = query_all_result["result"][0]["tilt"] old_timecoords = query_all_result["result"][0]["timecoords"] logger.debug("old_pan: " + str(old_pan) + ", old_tilt: " + str(old_tilt) + ", old_timecoords: " + str(old_timecoords)) count_coordinates_missing = 0 while True: logger.info("call ptzclient_command_simple()") statistic.append_info("получение текуших координат...", "ИНФО") logger.info("getting current coordinates") current_coordinates = ws.ptzclient_command_simple( client, key2, login, password, False, 0, 0, 0, 0, 0, 0, True, 0, 0, -1, -1, False) tools.check_types(["current_coordinates['result'][0]"], [current_coordinates["result"][0]], [dict], statistic) is_current_coordinates = tools.check_keys_exist( current_coordinates["result"][0], ["pan", "tilt"], 'current_coordinates["result"][0]', False, statistic) if is_current_coordinates is False: count_coordinates_missing += 1 if count_coordinates_missing == 3: statistic.append_error( "Получение координат завершилось с ошибкой!", "НЕТ_КООРДИНАТ", False) break continue current_timecoords = current_coordinates["result"][0]["timecoords"] if is_old_coordinates and current_timecoords != old_timecoords or is_old_coordinates is False: current_pan = current_coordinates["result"][0]["pan"] current_tilt = current_coordinates["result"][0]["tilt"] logger.debug("current_pan: " + str(current_pan) + ", current_tilt: " + str(current_tilt)) return {"pan": current_pan, "tilt": current_tilt}
def set_id54(json_cam: dict, new_id54: int, statistic: Statistic) -> dict: """Установка значения id54 в словаре json камеры при наличии соответсвующего ключа (в network_5_4 и sender). :param json_cam: словарь с json графа (камеры); :param new_id54: новый id54 камеры; :param statistic: объект класса Statistic. :return: обновленный словарь json графа (камеры). """ # заменяем id54 в network_5_4 tools.check_keys_exist(json_cam, ['network_5_4'], 'json_cam', True, statistic) tools.check_types(['network_5_4'], [json_cam['network_5_4']], [list], statistic) tools.check_values(['network_5_4'], [len(json_cam['network_5_4'])], [0], [">"], statistic) for index, network_5_4 in enumerate(json_cam['network_5_4']): tools.check_keys_exist(network_5_4, ['iv54server'], 'network_5_4["' + str(index) + '"]', True, statistic) tools.check_keys_exist(network_5_4['iv54server'], ['ID_54'], 'network_5_4["' + str(index) + '"]["iv54server"]', True, statistic) tools.check_keys_exist(network_5_4['iv54server']['ID_54'], ['_value'], 'network_5_4["' + str(index) + '"]["iv54server"]["ID_54"]', True, statistic) json_cam['network_5_4'][index]['iv54server']['ID_54']['_value'] = new_id54 # заменяем id54 в sender tools.check_keys_exist(json_cam, ['sender'], 'json_cam', True, statistic) tools.check_types(['sender'], [json_cam['sender']], [list], statistic) tools.check_values(['sender'], [len(json_cam['sender'])], [0], [">"], statistic) for index, sender in enumerate(json_cam['sender']): tools.check_keys_exist(sender, ['_type'], 'sender["' + str(index) + '"]', True, statistic) tools.check_keys_exist(sender['_type'], ['_value'], 'sender["' + str(index) + '"]["_type"]', True, statistic) type_ = sender['_type']['_value'] tools.check_keys_exist(sender[type_], ['id'], 'sender[' + str(index) + ']["_type"]["_value"]', True, statistic) tools.check_keys_exist(sender[type_]['id'], ['_value'], 'sender["' + str(index) + '"]["_type"]["_value"]["id"]', True, statistic) json_cam['sender'][index][type_]['id']['_value'] = new_id54 return json_cam
def faceva_update_person(client: SoapClient, token: str, id_: int, pacs_id: int, name: str, category: str, comment: str, information: str, department: str, faces: Tuple[dict], delete_faces: Tuple[dict], statistic: Statistic) -> str: """Функция выполнения ws метода FaceVA:UpdatePerson. :param client: объект класса SoapClient для отправки и приема ws запросов; :param token: токен соединения; :param id_: идентификатор персоны в БД; :param pacs_id: идентификатор персоны в БД для СКД; :param name: ФИО персоны; :param category: категория; :param comment: комментарий; :param information: информация; :param department: отдел; :param faces: список фото лиц для добавления; :param delete_faces: список фото для удаления; :param statistic: объект класса Statistic для ведения статистики ошибок и предупреждений. :return: идентификатор персоны в базе. """ logger = statistic.get_log().get_logger("scripts/ws/analytics") logger.info( "was called faceva_update_person(client: SoapClient, login: str, id_: int, pacs_id: int,\ name: str, category: str, comment: str, information: str, department: str, faces: List[dict], \ delete_faces: List[dict])") logger.debug("faceva_update_person(client_obj" + token + ", " + str(id_) + ", " + str(pacs_id) + ", " + name + ", " + category + ", " + comment + ", " + information + ", " + department + ", " + ", " + str(faces) + ", " + str(delete_faces) + ")") params, sysparams, method = pattern.faceva_update_person( token, id_, pacs_id, name, category, comment, information, department, faces, delete_faces) response_json = client.call_method2(method, params, sysparams, [0]) person = response_json['result'][0] key_names = [ "id", "pacs", "name", "category", "comment", "information", "department", "result", "faces" ] tools.check_keys_exist(person, key_names, "['result'][0]", True, statistic) key_names.remove("result") key_names.remove("faces") key_values = [ person["id"], person["pacs"], person["name"], person["category"], person["comment"], person["information"], person["department"] ] key_need_values = [ id_, str(pacs_id), name, category, comment, information, department ] operations = ["==", "==", "==", "==", "==", "==", "=="] if id_ == -1: key_names.pop(0) key_values.pop(0) key_need_values.pop(0) operations.pop(0) tools.check_values(key_names, key_values, key_need_values, operations, statistic) tools.check_types(["faces"], [person["faces"]], [list], statistic) if not person['faces'] and faces: statistic.append_error("Список faces", "НЕТ_ЛИЦ", True) for index, face in enumerate(person["faces"]): tools.check_keys_exist(face, ["result"], "face", True, statistic) if face["result"] == "error": tools.check_keys_exist(face, ["reason"], "face", True, statistic) statistic.append_error("причина: " + face["reason"], "ПЛОХОЕ_ФОТО", False) logger.info("ws method FaceVA:UpdatePerson was executed successfully!") statistic.append_info(method + " выполнен успешно!", "WS МЕТОД") return person["id"]
def faceva_get_faces(client: SoapClient, token: str, from_: int, statistic: Statistic) -> Tuple[dict]: """Функция выполнения ws метода FaceVA:GetFaces. :param client: объект класса SoapClient для отправки и приема ws запросов; :param token: токен соединения; :param from_: начиная с какого id прислать события :param statistic: объект класса Statistic для ведения статистики ошибок и предупреждений :return: список словарей с событиями вида: [ { "event": 154743, "camera": 1955154395, "person": "26617065381036041", // если не пустой, значит это СВОЙ, иначе просто обнаруженное лицо. "score": 0.939386, "time": 1587380094085000, "img": "base64" }, ... ... ] """ logger = statistic.get_log().get_logger("scripts/ws/analytics") logger.info( "was called (client: SoapClient, token: str, from_: int, statistic: Statistic)" ) logger.debug("params (client_obj" + token + ", " + str(from_) + ", stat_obf)") params, sysparams, method = pattern.faceva_get_faces(token, from_) response: dict = client.call_method2(method, params, sysparams, [0]) for index, event in enumerate(response['result']): # пришлось написать это условие, так как может быть ситуация: result: [{}], # это означает, что событий нет. if not event and len(response['result']) == 1: break key_names = ['event', 'camera', 'rect', 'score', 'time', 'img'] tools.check_keys_exist(event, key_names, "result[" + str(index) + "]", True, statistic) key_values = [ event['event'], event['camera'], event['rect'], event['score'], event['time'], event['img'] ] tools.check_types(key_names, key_values, [int, int, dict, float, int, str], statistic) key_names = ['x', 'y', 'w', 'h'] tools.check_keys_exist(event['rect'], key_names, "result[" + str(index) + "]['rect']", True, statistic) key_values = [ event['rect']['x'], event['rect']['y'], event['rect']['w'], event['rect']['h'] ] tools.check_types(key_names, key_values, [int, int, int, int], statistic) statistic.append_info(method + " выполнен успешно!", "WS МЕТОД") return tuple(response['result'])
def call_method2(self, method: str, params: dict, sysparams: dict, expected_user_codes: list) -> dict: """Метод отправки сообщения и приема ответа по протоколу SOAP. :param method: имя ws метода; :param params: параметры метода; :param sysparams: системные параметры; :param expected_user_codes: ожидаемые значения user_code. :return: словарь, полученный из json ответа. """ self._logger.info("was called (method: str, params: dict, sysparams: dict, expected_user_code: int)") self._logger.debug("with params(" + method + ", " + str(params) + ", " + str(sysparams) + ", " + str(expected_user_codes)) try: time.sleep(self._request_ws_pause) self._statistic.append_info("\n Отправка: POST\n" + " URL: " + self._url + "\n" + " WS метод: " + method + "\n" + " Параметры: " + str(params), "WS_ЗАПРОС") sysparams['timeout'] = self._timeout start_time = time.time() response: str = self._client.service.CallMethod2(method, json.dumps(params), json.dumps(sysparams)) response_time = round((time.time() - start_time) * 1000) self._logger.info("response received") self._logger.debug("response: " + str(response)) headers: dict = self._history.last_received['http_headers'] size: str = headers['Content-Length'] self._print_response_info(method, size, response_time) response: dict = json.loads(response) if tools.check_keys_exist(response, ['user_code'], 'response', False, self._statistic) is False: tools.check_keys_exist(response, ['code'], 'response', True, self._statistic) tools.check_keys_exist(response, ['result'], 'response', True, self._statistic) tools.check_types(["response['result']"], [response["result"]], [list], self._statistic) user_code_msg = "" equal_user_codes = False if 'user_code' in response: for expected_user_code in expected_user_codes: if response["user_code"] == expected_user_code: equal_user_codes = True break user_code_msg = "Значение 'user-code': " + str(response["user_code"]) + "! " else: equal_user_codes = True # иногда user_code может быть равен 0 (якобы все хорошо), # но есть ключ code, который может быть НЕ равен 0. code_msg = "" if 'code' in response: for expected_user_code in expected_user_codes: if response['code'] == expected_user_code and equal_user_codes: return response code_msg = "Значение 'code': " + str(response["code"]) + "! " elif equal_user_codes: return response self._logger.error("response: " + str(response)) if 'user_msg' in response: self._statistic.append_error(user_code_msg + code_msg + "Требуется " + str(expected_user_codes) + ". 'user_msg': " + response["user_msg"], "WS_ОТВЕТ: " + method, True) if response['result'] and 'user_msg' in response['result'][0]: self._statistic.append_error(user_code_msg + code_msg + "Требуется " + str(expected_user_codes) + ". 'user_msg': " + response['result'][0]["user_msg"], "WS_ОТВЕТ: " + method, True) self._statistic.append_error(user_code_msg + code_msg + "Требуется " + str(expected_user_codes) + ".", "WS_ОТВЕТ: " + method, True) except ConnectionError: self._statistic.append_error("Сервис не доступен на " + self._url, "WS_ПОДКЛЮЧЕНИЕ") self._logger.error("Unable connect to " + self._url) time.sleep(5) return self.call_method2(method, params, sysparams, expected_user_codes) except TransportError as e: self._statistic.append_error("Код статуса: " + str(e.status_code), "WS_ПОДКЛЮЧЕНИЕ") self._logger.error("Status code is " + str(e.status_code)) time.sleep(5) return self.call_method2(method, params, sysparams, expected_user_codes) except json.JSONDecodeError: self._statistic.append_error("Некорректный формат JSON!", "WS_ОТВЕТ", True)
def listener_pinger_ptz_status(self): """Тестирование ws методов listener_pinger:get_down_servers и listener_pinger:get_local_servers с целью проверки статусов ptz камер. Тест циклично с установленной переодичностью опрашивает методы local_servers и down_servers, проходит по каждым потенциально ptz камерам рутового (верхнего) сервера и проверяет статус ptz. """ # ---------------------------------------- # ПРОВЕРКА ВХОДНЫХ ДАННЫХ key_names = ['template_path', 'period', 'iterations'] tools.check_keys_exist(self._input_data, key_names, 'data', True, self._statistic) key_values = [ self._input_data["template_path"], self._input_data["period"], self._input_data["iterations"] ] tools.check_types(key_names, key_values, [str, int, int], self._statistic) # ---------------------------------------- ws_client = SoapClient(self._ip, self._port, self._config, self._statistic) token = ws_users.server_login(ws_client, self._login, self._password, self._statistic) if self._input_data["template_path"]: template_ptz_list_profiles: dict = tools.open_json_file( self._input_data["template_path"], self._statistic) template_ptz_list_profiles: list = template_ptz_list_profiles[ "result"] self._statistic.append_info("Получен шаблон из файла...", "ИНФО") else: template_ptz_list_profiles: list = ws_ptz.ptzserver_list_profiles( ws_client, token, self._statistic) if not template_ptz_list_profiles: self._statistic.append_error( "Неуспешно... Список PTZ камер пуст!", "ПОЛУЧЕНИЕ ШАБЛОНА", True) self._statistic.append_info( "Получен шаблон из ws ptzserver:list_profiles...", "ИНФО") if not template_ptz_list_profiles: self._statistic.append_error("Пустой список камер в шаблоне!", "ВХ_ДАННЫЕ", True) for iteration in range(self._input_data["iterations"]): local_servers: dict = ws_lp.get_local_servers( ws_client, token, 1, self._statistic) if tools_lp.check_ptz_cams(local_servers["cams"], template_ptz_list_profiles, self._statistic): self._statistic.append_success( "Статусы PTZ в ответе ws listener_pinger:get_local_servers корректны!", "ТЕСТ") else: self._statistic.append_error( "Статусы PTZ в ответе ws listener_pinger:get_local_servers некорректны!", "КРИТ", True) down_servers: dict = ws_lp.get_down_servers( ws_client, token, 1, self._statistic) if tools_lp.check_ptz_cams(down_servers["cams"], template_ptz_list_profiles, self._statistic): self._statistic.append_success( "Статусы PTZ в ответе ws listener_pinger:get_down_servers корректны!", "ТЕСТ") else: self._statistic.append_error( "Статусы PTZ в ответе ws listener_pinger:get_down_servers некорректны!", "КРИТ", True) time.sleep(self._input_data["period"])
def test_faceva_get_event(self): """Тест проверяет ws метод FaceVA:GetEvent. Тест может работать в двух режимах: skd_mode = True - используются только ws методы лиц, то есть точно также, как и вызвает их СКД; skd_mode = False - за эталон берутся события системы и сравниваются с событиями от лиц, таким образом проверяются возможные пропуски. max_counts_event - кол-во событий для проверки, при достижении которых тест должен завершиться. event_getting_timeout - как часто запрашивать события, в случае если они не были найдены. """ ws_client = SoapClient(self._server_ip, self._server_port, self._config, self._statistic) token: str = ws_users.server_login(ws_client, self._login, self._password, self._statistic) current_time = ws_common.get_current_server_time( ws_client, token, self._statistic) events_count = 0 last_event_time = current_time last_event_id = 0 from_event = 0 while True: if self._input_data['skd_mode']: events: Tuple[dict] = ws_analytics.faceva_get_event( ws_client, token, from_event, self._statistic) else: events: Tuple[dict] = ws_ewriter.select( ws_client, token, last_event_time, None, None, [20013], None, None, None, self._statistic) events: list = list(events) events.reverse() if not events or len(events) == 1 and events[0] == {}: time.sleep(self._input_data['event_getting_timeout']) continue events: tuple = tuple(events) self._statistic.append_info("Получены события", "ИНФО") for index, event in enumerate(events): events_count += 1 if self._input_data['skd_mode'] is False: # пропускаем старые (уже проверенные) события if event['evtid'] <= last_event_id: events_count -= 1 continue faceva_events: Tuple[dict] = ws_analytics.faceva_get_event( ws_client, token, 0, self._statistic) index_faceva_event = tools.get_dict_by_keys_values( faceva_events, ('event', ), (event['evtid'], )) if index_faceva_event < 0: self._statistic.append_error( "Нет события: " + str(event['evtid']) + "!", "КРИТ", True) person_id = faceva_events[index_faceva_event]['person'] persons = ws_analytics.faceva_get_data_base( ws_client, token, self._statistic) index_person = tools.get_dict_by_keys_values( persons, ('id', ), (person_id, )) if index_person < 0: self._statistic.append_error( "В базе нет id: " + str(person_id) + "!", "КРИТ", True) person_name = persons[index_person]['name'] if event['evtcomment'].find(person_name) < 0: self._statistic.append_error( "ФИО персоны не совпадают в событии " + str(event['evtid']) + "!", "НЕВАЛИД ЗНАЧ", False) event_id = faceva_events[index_faceva_event]['event'] time_ = faceva_events[index_faceva_event]['time'] camera = faceva_events[index_faceva_event]['camera'] event_time: str = event['evttime'] date_event_time = tools.get_date_from_str(event_time) last_event_time = str( tools.convert_time_to_gtc(date_event_time))[:-3] last_event_id = event_id else: event_id = event['event'] time_ = event['time'] camera = event['camera'] from_event = event_id # Проверка получения кадра по событию. # Выполнение ws метода FaceVA:GetFrame ws_result = ws_analytics.faceva_get_frame( ws_client, token, camera, time_, self._statistic) if tools.check_keys_exist(ws_result, ['img'], 'result[0]', False, self._statistic) is False: self._statistic.append_error( "По событию " + str(event_id) + "!", "ОТСУТСТВУЕТ КАДР", True) elif not ws_result['img']: self._statistic.append_error( "По событию " + str(event_id) + "!", "ОТСУТСТВУЕТ КАДР", True) else: self._statistic.append_success( "По событию '" + str(event_id) + "'!", "ПОЛУЧЕН КАДР") # Проверка получения картинки по событию. # Выполнение ws метода FaceVA:GetEventImage ws_result = ws_analytics.faceva_get_event_image( ws_client, token, event_id, time_, self._statistic) if tools.check_keys_exist(ws_result, ['img'], 'result[0]', False, self._statistic) is False: self._statistic.append_error( "По событию " + str(event_id) + "!", "ОТСУТСТВУЕТ КАРТИНКА", True) elif not ws_result['img']: self._statistic.append_error( "По событию " + str(event_id) + "!", "ОТСУТСТВУЕТ КАРТИНКА", True) else: self._statistic.append_success( "По событию " + str(event_id) + "!", "ПОЛУЧЕНА КАРТИНКА") if events_count >= self._input_data['max_count_events']: break if events_count >= self._input_data['max_count_events']: break