Example #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
Example #2
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)
Example #3
0
def get_max_value_by_key(dicts: list, key: str, statistic: Statistic) -> int:
    """Поиск максимума в списке словарей по ключу.

    :param dicts: список словарей;
    :param key: имя ключа;
    :param statistic: объект класса Statistic.

    :return: максимальное найденное значение.
    """
    max_val = 0
    for dict_ in dicts:
        if key not in dict_:
            statistic.append_warn(key, "НЕТ КЛЮЧА")
        if dict_[key] > max_val:
            max_val = dict_[key]
    return max_val
Example #4
0
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("Архив пустой!", "НЕВАЛИД_ЗНАЧ")
Example #5
0
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)
Example #6
0
def run_events_test(ws_client: SoapClient, token: str, cam_info: dict, events: tuple, inaccuracy: int, event_type: int,
                    video_source: str, statistic: Statistic) -> None:
    """Функция запуска проверки наличия событий по детектору.
    Каждое событие появляется через определенное время от начала видео. Функция, учитывая погрешность, вычисляет
    интервал времени, в котором должно быть событие и уходит в sleep на это время. После пробуждения проверяет наличие
    события в этом интервале, используя ws метод ewriter:exec с командой select и нужными фильтрами.

    :param ws_client: объект класса SoapClient;
    :param token: токен авторизации;
    :param cam_info: информация по камере (сервер, имя, профиль);
    :param events: список событий из входных данных вида:
                    [
                        {
                            "time": 15,
                            "info": {...}
                        }
                    ]
    см. подробное описание в тестах по аналитике, которые используют данную функцию;
    :param inaccuracy: погрешность для вычисления грациц интервала, в которых должно быть событие;
    :param event_type: номер события;
    :param video_source: путь к видеоисточнику (нужен для удобства вывода сообщений);
    :param statistic: объект класса Statistic.
    """
    if _video_start_expecting(ws_client, token, cam_info, statistic) is False:
        statistic.append_error("Источник: " + video_source + "!", "НЕТ ВИДЕО")
        return
    # Заранее высчитываются временные интервалы,
    # в которых должны находиться события
    start_server_time: str = ws_common.get_current_server_time(ws_client, token, statistic)
    date_start_server_time = tools.get_date_from_str(start_server_time, statistic)
    for event in events:
        event_time = tools.increment_time(date_start_server_time, event['time'])
        left_interval_time_utc = tools.decrement_time(event_time, inaccuracy)
        right_interval_time_utc = tools.increment_time(event_time, inaccuracy)

        left_interval_time = str(tools.convert_time_from_gtc(left_interval_time_utc))[:-9]
        right_interval_time = str(tools.convert_time_from_gtc(right_interval_time_utc))[:-9]

        left_interval_time_utc = str(left_interval_time_utc)
        right_interval_time_utc = str(right_interval_time_utc)

        event.update({
            "start": left_interval_time_utc,
            "end": right_interval_time_utc
        })
    previous_sleep = 0
    for index, event in enumerate(events):
        time.sleep(event['time'] - previous_sleep + inaccuracy)
        result = _check_event_existing(ws_client, token, event['start'], event['end'], event_type, cam_info, statistic)
        if result[0] == 0:
            statistic.append_success("#" + str(index + 1) + " по источнику " + video_source + " в интервале с " +
                                     left_interval_time + " по " + right_interval_time + "!", "ПОЛУЧЕНО СОБЫТИЕ")
            _check_event_comment(event['info'], result[1][0], statistic)
        elif result[0] == -1:
            statistic.append_error("Событие #" + str(index + 1) + " по источнику " + video_source + " в интервале с " +
                                   left_interval_time + " по " + right_interval_time + "!", "НЕТ СОБЫТИЯ")

            time.sleep(inaccuracy / 2)
            current_server_time: str = ws_common.get_current_server_time(ws_client, token, statistic)
            event.update({
                "start": start_server_time,
                "end": current_server_time
            })
            result = _check_event_existing(ws_client, token, event['start'], event['end'], event_type, cam_info,
                                           statistic)
            if result[0] == 0:
                statistic.append_warn("#" + str(index + 1) + " по источнику " + video_source + " в интервале с " +
                                      start_server_time + " по " + current_server_time + "!", "ПОЛУЧЕНО СОБЫТИЕ")
                _check_event_comment(event['info'], result[1][0], statistic)
            elif result[0] > 1:
                statistic.append_error("Событие #" + str(index + 1) + " по источнику " + video_source +
                                       " в интервале с " + start_server_time + " по " + current_server_time + "!",
                                       "МНОГО СОБЫТИй")
            else:
                statistic.append_error(
                    "Событие #" + str(index + 1) + " по источнику " + video_source + " в интервале с " +
                    start_server_time + " по " + current_server_time + "!", "НЕТ СОБЫТИЯ")
        else:
            statistic.append_error("Событие #" + str(index + 1) + " по источнику " + video_source + " в интервале с " +
                                   left_interval_time + " по " + right_interval_time + "!", "МНОГО СОБЫТИй")
        previous_sleep = event['time']
Example #7
0
def compare_local_servers(string: dict, template_string: dict,
                          local_server_ip: str, statistic: Statistic) -> bool:
    """Функция сравнивает значения всех ключей поля string из ws метода listener_pinger_get_local_servers
     с другим таким же словарем.

    Оба словаря должны быть равны значению ключа string из ws метода listener_pinger_get_local_servers или
    listener_pinger_get_down_servers

    :param string: строка ответа;
    :param template_string: эталонная строка;
    :param local_server_ip: ip локального сервера;
    :param statistic: объект класса Statistic.

    :return: флаг корректности.
    """
    is_correct = True

    if string == template_string:
        return is_correct

    checked_keys: list = []
    for template_key in template_string.keys():
        if template_key not in string:
            statistic.append_error(
                template_key + " в 'string' у " + local_server_ip + "!",
                "НЕТ КЛЮЧА")
            continue

        checked_keys.append(template_key)

        if template_key == "cams":
            if template_string["cams"] == string["cams"]:
                continue

            if not template_string["cams"] and string["cams"]:
                statistic.append_warn(
                    "Список камер у сервера " + local_server_ip +
                    " не пустой!", "ЕСТЬ КАМЕРЫ")
                continue

            if not string["cams"] and template_string["cams"]:
                statistic.append_error("Сервер " + local_server_ip + "!",
                                       "НЕТ КАМЕР")
                is_correct = False
                continue

            # ищем камеру, которая отсутствует
            # либо ищем отличие в конкретных ключах у камеры
            # также ищем какие ключи отсутствуют в шаблоне, но есть по факту
            for template_cam in template_string["cams"]:
                # проверка на отсутствие камеры
                string_cam_index = tools.get_dict_by_keys_values(
                    string["cams"], ["key2", "key3"],
                    [template_cam["key2"], template_cam["key3"]])
                if string_cam_index == -1:
                    statistic.append_error(
                        template_cam["key2"] + "(" + template_cam["key3"] +
                        ") на сервере " + local_server_ip + "!", "НЕТ КАМЕРЫ")
                    is_correct = False
                    continue

                if template_cam == string["cams"][string_cam_index]:
                    continue

                # поиск отличий в конкретных ключах у камеры
                for template_cam_key in template_cam:
                    if template_cam_key not in string["cams"][
                            string_cam_index]:
                        statistic.append_error(
                            template_cam_key + " в " + template_cam +
                            " на сервере " + local_server_ip + "'!",
                            "НЕТ КЛЮЧА ПО КАМЕРЕ")
                        is_correct = False
                        continue
                    current_key_value = string["cams"][string_cam_index][
                        template_cam_key]
                    if template_cam[
                            template_cam_key] != current_key_value and template_cam_key != "Status":
                        statistic.append_error(
                            template_cam_key + " в камере " +
                            template_cam["key2"] + "(" + template_cam["key3"] +
                            ") на сервере " + local_server_ip + "!" +
                            " Требуется: " +
                            str(template_cam[template_cam_key]) + "(" +
                            str(current_key_value) + ")!", "НЕВАЛИД ЗНАЧ")
                        is_correct = False
                        continue

                # поиск отсутствующих ключей в шаблоне
                for string_cam_key in string["cams"][string_cam_index]:
                    if string_cam_key not in template_cam:
                        statistic.append_warn(
                            string_cam_key + " в камере " + template_cam +
                            " на сервере" + local_server_ip + " в ШАБЛОНЕ!",
                            "НЕТ КЛЮЧА")
            # ищем камеры, которых нет в шаблоне
            # но есть по факту
            for string_cam in string["cams"]:
                string_cam_is_in_template = False
                for template_cam in template_string["cams"]:
                    if string_cam["key2"] == template_cam["key2"]:
                        string_cam_is_in_template = True
                        break
                if string_cam_is_in_template is False:
                    statistic.append_warn(
                        string_cam["key2"] + " на сервере " + local_server_ip +
                        " в ШАБЛОНЕ!", "НЕТ КАМЕРЫ")

        elif template_key == "archive":
            if template_string[template_key] == string[template_key]:
                continue

            if not template_string[template_key] and string[template_key]:
                statistic.append_warn("Сервер " + local_server_ip,
                                      "ЕСТЬ АРХИВ")
                #is_correct = False
                continue

            if not string[template_key] and template_string[template_key]:
                statistic.append_error("Сервер " + local_server_ip,
                                       "НЕТ АРХИВА")
                is_correct = False

            for archive in template_string[template_key][0]:
                if string[template_key][0].count(archive) > 0:
                    continue
                else:
                    statistic.append_error(
                        str(archive) + " на сервере " + local_server_ip,
                        "НЕТ АРХИВА")
                    is_correct = False

            for archive in string[template_key][0]:
                if template_string[template_key][0].count(archive) > 0:
                    continue
                else:
                    statistic.append_warn(
                        str(archive) + " на сервере " + local_server_ip,
                        "НЕТ АРХИВА")
                    is_correct = False

        else:
            if string[template_key] != template_string[
                    template_key] and template_key != "down_servers":
                statistic.append_error(
                    str(string[template_key]) + " по ключу" + template_key +
                    " на сервере " + local_server_ip + "! Требуется: " +
                    str(template_string[template_key]) + "(" +
                    str(string[template_key]) + ")!", "НЕВАЛИД ЗНАЧ")
                is_correct = False

    return is_correct
Example #8
0
def compare_down_servers(string: dict, template_string: dict,
                         main_server_ip: str, statistic: Statistic) -> bool:
    """Функция проверки эквивалентности "нижних" серверов

    :param string: строка ответа;
    :param template_string: эталонная строка;
    :param main_server_ip: ip главного сервера;
    :param statistic: объект класса Statistic.

    :return: флаг корректности.
    """
    is_correct = True

    if string == template_string:
        return is_correct

    if compare_local_servers(string, template_string, main_server_ip,
                             statistic) is False:
        statistic.append_info(
            "Локальный сервер некорректен в ответе 'get_down' на сервере " +
            main_server_ip, "СРАВНЕНИЕ")
        is_correct = False

    if string["down_servers"] == template_string["down_servers"]:
        return is_correct
    if not string["down_servers"] and template_string["down_servers"]:
        statistic.append_error("Сервер " + main_server_ip + "!",
                               "НЕТ НИЖНИХ СЕРВЕРОВ")
        is_correct = False
    if not template_string["down_servers"] and string["down_servers"]:
        statistic.append_warn("Сервер " + main_server_ip + "!",
                              "ЕСТЬ НИЖНИЕ СЕРВЕРА")
        #is_correct = False

    # проход по шаблону и поиск отличий
    down_servers_names: list = get_down_servers_names(string["down_servers"])
    for template_down_server in template_string["down_servers"]:
        template_down_server_name: str = list(template_down_server.keys())[0]
        statistic.append_info(
            "Сравнение нижнего сервера " + template_down_server_name +
            " с шаблоном...", "ИНФО")
        if template_down_server_name not in down_servers_names:
            statistic.append_error(
                template_down_server_name + " на сервере" + main_server_ip +
                "!", "НЕТ НИЖНЕГО СЕРВЕРА")
            is_correct = False
            continue
        down_server_index = down_servers_names.index(template_down_server_name)
        down_server_string = string["down_servers"][down_server_index][
            template_down_server_name]
        down_server_template_string = template_down_server[
            template_down_server_name]
        if compare_local_servers(
                down_server_string, down_server_template_string,
                template_down_server_name, statistic) is False:
            statistic.append_error(
                "Нижний сервер " + template_down_server_name +
                " не корректен!", "СРАВНЕНИЕ")
            is_correct = False
            continue
    # поиск отсутвующих нижних серверов в шаблоне
    # тобиш, которые есть по факту, но нет в шаблоне
    template_down_servers_names: list = get_down_servers_names(
        template_string["down_servers"])
    for down_server_name in down_servers_names:
        if template_down_servers_names.count(down_server_name) == 0:
            statistic.append_warn(
                down_server_name + " на сервере " + main_server_ip +
                " в ШАБЛОНЕ!", "НЕТ НИЖНЕГО СЕРВЕРА")

    return is_correct