Пример #1
0
def _send_request(zmqclient: ZmqClient, xml_tree_full: Tree, message_id: str, timeout: float,
                  statistic: Statistic) -> Tree:
    """Функция отправки сообщения и с возможностью переотправки.

    :param zmqclient: объект класса ZmqClient;
    :param xml_tree_full: запрос дерево XML;
    :param message_id: id сообщения;
    :param timeout: время ожидания ответа;
    :param statistic: объект класса Statistic.

    :return: ответ в виде дерева XML.
    """
    zmqclient.send_request(xml_tree_full)
    statistic.append_info("Отправка запроса с id: " + str(message_id), "ИНФО")
    send_count = 0

    while True:
        list_xml_responses = _get_response(zmqclient, timeout)
        if list_xml_responses == -1:
            if send_count == 3:
                statistic.append_error("Повторная отправка сообщения '" + str(message_id) + "' завершилась с ошибкой!",
                                       "ZMQ_ОТВЕТ", True)
                break
            zmqclient.send_request(xml_tree_full)
            send_count += 1
            statistic.append_warn("Попытка повторной отправки сообщеия '" + str(message_id), "ZMQ_ОТВЕТ")
            continue
        response_index = search_response_index_by_message_id(list_xml_responses, message_id, statistic)
        if response_index > -1:
            statistic.append_info("Получен ответ на запрос с id '" + str(message_id) + "'", "ИНФО")
            zmqclient.remove_response(message_id)
            return list_xml_responses[response_index]

    return -1
Пример #2
0
def get_setid(path_to_db: str, key1: str, key2: str, key3: str,
              statistic: Statistic) -> int:
    """Получить первичный ключ камеры (поле setid) по ее полному имени.

    :param path_to_db: путь до БД
    :param key1: имя сервера
    :param key2: имя камеры
    :param key3: профиль
    :param statistic: объект класса Statistic
    :return: первичный ключ камеры
    """

    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 setid FROM setting WHERE settypeid = ? AND setname = ?"
        cursor.execute(sql_cmd, [1, db_setname])
        db_setid = cursor.fetchall()[0][0]

        conn.close()
        return db_setid
    except sqlite3.OptimizedUnicode:
        statistic.append_error("Ошибка выполнения команды!", "БД", True)
Пример #3
0
def check_ptz_cams(string_cams: list, ptz_cams: list,
                   statistic: Statistic) -> bool:
    """Функиия проверки статусов ptz у камер.

    :param string_cams: список камер из ответа;
    :param ptz_cams: список реальных ptz камер;
    :param statistic: объект класса Statistic.

    :return: флаг корректности.
    """
    is_correct = True
    for ptz_cam in ptz_cams:
        cam_index_exist = tools.get_dict_by_keys_values(
            string_cams, ["key2"], [ptz_cam["key2"]])
        if cam_index_exist == -1:
            statistic.append_error("'" + ptz_cam["key2"] + "'!", "НЕТ КАМЕРЫ")
            is_correct = False
            continue
        cam_index_ptz = tools.get_dict_by_keys_values(string_cams,
                                                      ["key2", "ptzStat"],
                                                      [ptz_cam["key2"], True])
        if cam_index_ptz == -1:
            statistic.append_error(
                ptz_cam["key2"] + " в ответе ws listener_pinger!", "НЕ PTZ")
            is_correct = False

    return is_correct
Пример #4
0
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
Пример #5
0
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 {}
Пример #6
0
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)
Пример #7
0
def delete_cam(path_to_db: str, key1: str, key2: str, key3: str,
               statistic: Statistic) -> int:
    """Функция удаления камеры из БД.

    :param path_to_db: путь до БД
    :param key1: имя сервера
    :param key2: имя камеры
    :param key3: профиль
    :param statistic: объект класса Statistic
    :return: код ошибки: 0 - все ок.
    """

    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 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 = "DELETE FROM setting WHERE setid = ?"

        cursor.execute(sql_cmd, [str(db_setid)])
        conn.commit()

        conn.close()
        return 0
    except sqlite3.OptimizedUnicode:
        statistic.append_error("Ошибка выполнения команды!", "БД", True)
Пример #8
0
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)
Пример #9
0
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)
Пример #10
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
Пример #11
0
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)
Пример #12
0
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
Пример #13
0
def check_types(names: List[str], values: list, types: list,
                statistic: Statistic) -> None:
    """Проверка типов значений.

    :param names: список имен значений;
    :param values: список значений;
    :param types: список типов;
    :param statistic: объект класса Statistic.
    """
    for index, value in enumerate(values):
        # студия подчеркивает красным, но этом работает...
        if isinstance(value, types[index]) is False:
            statistic.append_error(
                "'" + str(value) + "' ключ '" + names[index] +
                "'... требуется " + str(types[index]), "НЕВАЛИД_ТИП", True)
Пример #14
0
def get_cams_names(db_path: str, server: str, statistic: Statistic) -> tuple:
    """Получение списка имен камер с указанного сервера.

    :param db_path: путь к бд;
    :param server: имя сервера;
    :param statistic: объект класса Statistic.

    :return: список имен камер с конкретного сервера.
    """

    if not os.path.exists(db_path):
        statistic.append_error("Файла БД не существует!", "БД", True)

    full_names = []
    try:
        time.sleep(0.2)
        conn = sqlite3.connect(db_path)
        cursor = conn.cursor()

        sql_cmd = "SELECT setname FROM setting WHERE settypeid = ? AND setname LIKE ?"
        cursor.execute(sql_cmd, [1, server + "%"])
        full_names: list = cursor.fetchall()

        conn.commit()
        conn.close()
    except sqlite3.OptimizedUnicode:
        statistic.append_error("Ошибка выполнения команды!", "БД", True)

    if not full_names:
        statistic.append_warn("Сервер: " + server + "!", "НЕТ_КАМЕР")

    cams_names: list = []
    for full_name in full_names:
        first_index_ = full_name[0].find("_")
        last_index_ = full_name[0].rfind("_")
        new_cam_name = full_name[0][first_index_ + 1:last_index_]

        # из-за разных профилей по одной камере могут быть одинаковые имена,
        # а дублирование имен не нужно.
        add = True
        for cam_name in cams_names:
            if new_cam_name == cam_name:
                add = False
                break
        if add:
            cams_names.append(new_cam_name)

    return tuple(cams_names)
Пример #15
0
def compare_dirs(dir1: str, dir2: str, statistic: Statistic) -> None:
    """Сравнение двух директорий
    Рекурсивное сравнение двух директорий.
    Два файла равны, если их имена и содержимое одинаковы.

    :param dir1: Путь к первой директории;
    :param dir2: Путь к второй директории;
    :param statistic: объект класса Statistic.
   """
    slash_index = dir1.rfind("/")
    simple_dir1_name = dir1[slash_index + 1:]
    slash_index = dir2.rfind("/")
    simple_dir2_name = dir2[slash_index + 1:]
    dirs_cmp = filecmp.dircmp(
        dir1,
        dir2)  # сравнение директорий по количеству файлов и поддиректориям
    if len(dirs_cmp.left_only) > 0:
        message = "\nПапки только в " + simple_dir1_name + "\n" + str(
            dirs_cmp.left_only) + "\n"
        statistic.append_error(message, "ОТЛИЧИЕ")
        # print("Папки и файлы, содержащиеся только в пути ", dir1, dirs_cmp.left_only)
    if len(dirs_cmp.right_only) > 0:
        message = "\nПапки только в " + simple_dir2_name + "\n" + str(
            dirs_cmp.right_only) + "\n"
        statistic.append_error(message, "ОТЛИЧИЕ")
    (_, mismatch, errors) = filecmp.cmpfiles(
        dir1, dir2, dirs_cmp.common_files,
        shallow=False)  # непосредственное сравнение файлов
    if len(mismatch) > 0:
        for file in mismatch:
            if os.stat(dir1 + "/" + file).st_mtime > os.stat(dir2 + "/" +
                                                             file).st_mtime:
                first_dir_date = " (новее)"
                second_dir_date = ""
            else:
                first_dir_date = ""
                second_dir_date = " (новее)"

            first_file_info = "\nИмя: /" + simple_dir1_name + "/" + file + "\n" + \
                              "Размер: " + str(os.stat(dir1 + "/" + file).st_size) + " Б" + "\n" + \
                              "Дата изменения: " + time.strftime("%Y-%m-%d %H:%M:%S",
                                                                 time.localtime(os.stat(dir1 + "/" + file).st_mtime)) + first_dir_date
            second_file_info = "Имя: /" + simple_dir2_name + "/" + file + "\n" + \
                               "Размер: " + str(os.stat(dir2 + "/" + file).st_size) + " Б" + "\n" + \
                               "Дата изменения: " + time.strftime("%Y-%m-%d %H:%M:%S",
                                                                  time.localtime(os.stat(dir2 + "/" + file).st_mtime)) + second_dir_date + "\n"
            message = first_file_info + "\n------------------------------------\n" + second_file_info
            message = message.replace("\\", "/")
            statistic.append_error(message, "ОТЛИЧИЕ")
    if len(errors) > 0:
        statistic.append_error("Ошибка доступа к файлам: " + errors, "КРИТ",
                               True)

    # рекурсивный переход по общим поддиректориям
    for common_dir in dirs_cmp.common_dirs:
        new_dir1 = os.path.join(dir1, common_dir)
        new_dir2 = os.path.join(dir2, common_dir)
        compare_dirs(new_dir1, new_dir2, statistic)
Пример #16
0
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"]
Пример #17
0
    class TestRunner(threading.Thread):
        """Класс для запуска тесте из тест кейса в отдельном потоке.

        """
        def __init__(self, thread_id: int, module: str, test: str,
                     input_data: dict, config: dict, log: Log):
            threading.Thread.__init__(self)
            self._statistic = Statistic(test, thread_id, config, log)

            self._test_class = test_classes[module](input_data, config,
                                                    self._statistic)
            self._test = test
            self._id = str(thread_id)

        def get_statistic(self):
            """Метод-геттер получения объекта статистики.

            :return:
            """
            return self._statistic

        def run(self):
            """Переопределенный метод запуска потока.

            """
            full_test_name = self._test + "[Поток #" + self._id + "]"
            test_method = getattr(self._test_class, self._test)
            error_msg = ""
            try:
                self._test_class.setup()
                test_method()
            except SystemExit as e:
                error_msg = e.args[0]
            self._test_class.teardown()

            if error_msg:
                self._statistic.append_error(
                    "Тест " + full_test_name +
                    " завершился с критической ошибкой: " + error_msg, "КРИТ")
            else:
                self._statistic.append_success(
                    "Тест " + full_test_name +
                    " завершился без критических ошибок!", "УСПЕХ")
Пример #18
0
def init_run_tests(statistic: Statistic) -> Tuple[Tuple[str]]:
    """Получение списка тестов из тест-кейса

    Временно тест-кейс - это файл run_list.ini

    :return: список тестов вида ИМЯ-КЛАССА.ИМЯ-ТЕСТА
    """
    if not os.path.exists(main.RUN_INI_PATH):
        statistic.append_error("run_list_ini", "ФАЙЛ_НЕ_СУЩ-ЕТ")

    run_list = []
    with open(main.RUN_INI_PATH, encoding="utf-8") as run_list_file:
        for line in run_list_file:
            test_run_info = list(line.partition(" "))
            test_run_info.remove(" ")
            test_run_info[1].replace("\n", "")
            run_list.append(tuple(test_run_info))

    return tuple(run_list)
Пример #19
0
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)
Пример #20
0
def send_hello(zmqclient: ZmqClient, id_: int, timeout: float, statistic: Statistic) -> int:
    """Функция отправки Hello.

    :param zmqclient: объект класса ZmqClient;
    :param id_: идентификатор;
    :param timeout: максимальное ожидание ответа;
    :param statistic: объект класса Statistic.

    :return: индекс успешности ответа: 0 - все ок, 1 - ошибка.
    """
    message_id = str(uuid.uuid1())
    xml_tree_hello = zmq.hello(message_id, id_)
    xml_tree_full = zmq.common_head(xml_tree_hello)

    xml_response = _send_request(zmqclient, xml_tree_full, message_id, timeout, statistic)
    if xml_response == -1:
        statistic.append_error("Запрос 'Hello' прошел неуспешно!", "ZMQ_ОТВЕТ", False)
        return -1

    #log.print_test("Запрос 'Hello' выполнен успешно!")
    return 0
Пример #21
0
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
Пример #22
0
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)
Пример #23
0
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
Пример #24
0
def search_response_index_by_message_id(xml_responses: list, message_id: str, statistic: Statistic) -> int:
    """Поиск в списке xml у которого значение тега messageId совпадает с message_id.

    :param xml_responses: список xml
    :param message_id: значение тега messageId
    :param statistic: объект класса Statistic
    :return: 1) индекс в списке; 2) -1 в случае отсутствия совпадения
    """
    logger = log.get_logger("scripts/xml/zmq")
    logger.info("was called (list_xml_responses, message_id)")
    logger.debug("(" + str(xml_responses) + ", " + str(message_id) + ")")

    for index, response in enumerate(xml_responses):
        tag_nessage_id = response.find(".//messageId")
        if tag_nessage_id is None:
            statistic.append_error("Отсутствует тег 'messageId'", "ZMQ_ОТВЕТ", True)
        logger.debug("response messageId is " + tag_nessage_id.text)
        if message_id == tag_nessage_id.text:
            logger.info("message_Id is equal!")
            return index
        logger.info("message_Id isn't equal!")
    return -1
Пример #25
0
def insert_new_cam(path_to_db: str, key1: str, key2: str, key3: str,
                   json_graph: dict, statistic: Statistic) -> int:
    """Вставка нового графа (камеры) в таблицу

    :param path_to_db: путь до БД
    :param key1: имя сервера
    :param key2: имя камеры
    :param key3: профиль
    :param json_graph: граф в формате json
    :param statistic: объект класса Statistic
    :return: первичный ключ
    """

    if not os.path.exists(path_to_db):
        statistic.append_error("Файла БД не существует!", "БД", True)

    try:
        time.sleep(0.5)
        conn = sqlite3.connect(path_to_db)
        cursor = conn.cursor()
        db_setname = key1 + "_" + key2 + "_" + key3
        db_setvalue = json.dumps(json_graph).replace("\\\\/$", "\\/$")

        obj_md5_hash = hashlib.md5(db_setvalue.encode('utf-8'))
        db_sethash = obj_md5_hash.hexdigest()

        sql_cmd = "INSERT INTO setting (setid, settypeid, setname, setvalue, setcomment, setinfo, sethash) " \
                  "VALUES (?, ?, ?, ?, ?, ?, ?)"
        cursor.execute(sql_cmd,
                       [None, 1, db_setname, db_setvalue, "", "", db_sethash])
        conn.commit()
        time.sleep(0.5)
        db_setid = get_setid(path_to_db, key1, key2, key3, statistic)

        conn.close()
        return db_setid
    except sqlite3.OptimizedUnicode:
        statistic.append_error("Ошибка выполнения команды!", "БД", True)
Пример #26
0
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)
Пример #27
0
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
Пример #28
0
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"]
Пример #29
0
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}
Пример #30
0
def go_to_coordinate(client: SoapClient,
                     login: str,
                     password: str,
                     key2: str,
                     ws_method: str,
                     cmd: str,
                     coordinate: int,
                     statistic: Statistic,
                     inaccuracy: int = 0) -> bool:
    """Функция перевода камеры в указанные координаты.

    :param client: объект soap клиентя
    :param login: логин пользователя
    :param password: пароль пользователя
    :param key2: имя камеры
    :param ws_method: через какой метод выполнять команду (ptzserver или ptzclient)
    :param cmd: команда
    :param coordinate: координаты
    :param statistic: объект класса Statistic
    :param inaccuracy точность
    :return: флаг успешности перехода
    """
    logger = statistic.get_log().get_logger("scripts/tools/ptz")
    logger.info(
        "was called (client: SoapClient, login: str, password: str, key2: str, \
                cmd: str, coordinate: int, inaccuracy: int = 0)")
    logger.debug("with params (client_obj, " + login + ", " + password + ", " +
                 key2 + ", " + cmd + ", " + str(coordinate) + ", " +
                 str(inaccuracy) + ")")

    pan_to = -1
    tilt_to = -1
    if cmd == "PanTo":
        pan_to = coordinate
    elif cmd == "TiltTo":
        tilt_to = coordinate
    else:
        statistic.append_error(cmd, "НЕВАЛИД_КОМАНДА_PTZ", True)

    if ws_method == "ptzclient":
        ws.ptzclient_command_simple(client, key2, login, password, False, 0, 0,
                                    0, 0, 0, 0, False, 0, 0, pan_to, tilt_to,
                                    False)
        message = "ws 'ptzclient:Command[" + cmd + "=" + str(
            coordinate) + "]' отправлен..."
    elif ws_method == "ptzserver":
        ws.ptzserver_command_simple(client, key2, login, password, False, 0, 0,
                                    0, 0, 0, 0, False, 0, 0, pan_to, tilt_to,
                                    False)
        message = "ws 'ptzserver:Command[" + cmd + "=" + str(
            coordinate) + "]' отправлен..."
    else:
        statistic.append_error(ws_method, "НЕВАЛИД_МЕТОД_PTZ", True)

    statistic.append_info(message, "ПЕРЕХОД В КООРДИНАТЫ")
    logger.info(message)
    time.sleep(1)

    coordinates = get_coordinates(client, login, password, key2, statistic)
    if cmd == "TiltTo":
        current_coordinate = coordinates["tilt"]
    else:
        current_coordinate = coordinates["pan"]

    if compare_coordinates(coordinate, current_coordinate, inaccuracy):
        statistic.append_info(
            cmd + " " + str(coordinate) + " выполнена успешно!", "УСПЕХ")
        logger.info(cmd + " " + str(coordinate) +
                    " was executed successfully!")
        return True
    else:
        return False