예제 #1
0
    def parse(ini: IniFile) -> 'List[SearchScenario]':
        """
        Parse the INI file for the search scenarios.

        :param ini: INI file
        :return: List of search scenarios
        """

        section = ini.find('SEARCH')
        if not section:
            return []
        count = safe_int(safe_str(section.get_value('ItemNumb', '0')))
        if not count:
            return []
        result: 'List[SearchScenario]' = []
        for i in range(count):
            name = section.get_value(f'ItemName{i}')
            scenario = SearchScenario(name)
            result.append(scenario)
            scenario.prefix = section.get_value(f'ItemPref{i}') or ''
            scenario.type = safe_int(
                safe_str(section.get_value(f'ItemDictionType{i}', '0')))
            scenario.menu = section.get_value(f'ItemMenu{i}')
            scenario.old = None
            scenario.correction = section.get_value(f'ItemModByDic{i}')
            scenario.truncation = bool(section.get_value(f'ItemTranc{i}', '0'))
            scenario.hint = section.get_value(f'ItemHint{i}')
            scenario.mod_by_dic_auto = section.get_value(
                f'ItemModByDicAuto{i}')
            scenario.logic = safe_int(
                safe_str(section.get_value(f'ItemLogic{i}', '0')))
            scenario.advance = section.get_value(f'ItemAdv{i}')
            scenario.format = section.get_value(f'ItemPft{i}')
        return result
예제 #2
0
    def to_connection_string(self) -> str:
        """
        Выдача строки подключения для текущего соединения.

        :return: Строка подключения
        """

        return 'host=' + safe_str(self.host) + \
               ';port=' + str(self.port) + \
               ';username='******';password='******';database=' + safe_str(self.database) + \
               ';workstation=' + safe_str(self.workstation) + ';'
예제 #3
0
    def write(self) -> 'List[str]':
        """
        Represent the node and its child as lines.

        :return: List of lines
        """
        result = [TreeFile.INDENT * self.level + safe_str(self.value)]
        for child in self.children:
            inner = child.write()
            result.extend(inner)
        return result
예제 #4
0
    def format_pair(prefix: str, value: str, default: str) -> str:
        """
        Format the pair prefix=value.

        :param prefix: Prefix to use
        :param value: Value to use
        :param default: Default value
        :return: Formatted text
        """

        if same_string(value, default):
            return ''

        return prefix + '=' + safe_str(value) + ';'
예제 #5
0
def write_text_record(stream, record: Record) -> None:
    """
    Сохранение записи в файл в текстовом обменном формате ИРБИС.

    :param stream: Текстовый поток, в который разрешена запись.
    :param record: Библиографическая запись.
    :return: None
    """

    assert stream
    assert record

    for field in record.fields:
        parts = ['#' + str(field.tag) + ': ' + safe_str(field.value)]
        for subfield in field.subfields:
            parts.extend(str(subfield))
        line = ''.join(parts) + '\n'
        stream.write(line)
    stream.write(STOP_MARKER + '\n')
예제 #6
0
def write_iso_record(stream, record: Record, encoding: str) -> None:
    """
    Сохранение записи в файл в формате ISO 2709.

    :param stream: Поток
    :param record: Запись
    :param encoding: Кодировка
    :return: None
    """

    record_length = MARKER_LENGTH
    dictionary_length = 1  # С учетом ограничителя справочника
    field_length: 'List[int]' = []

    # Сначала подсчитываем общую длину записи
    for field in record.fields:

        if field.tag <= 0 or field.tag >= 1000:
            # Невозможно закодировать тег поля
            raise Exception

        dictionary_length += 12  # Одна статья справочника
        this_field_length = 0
        if field.tag < 10:
            # В фиксированном поле не бывает подполей и индикаторов
            val = field.value
            if val:
                this_field_length += len(val.encode(encoding))
        else:
            this_field_length += 2  # Индикаторы
            if field.value:
                this_field_length += len(field.value.encode(encoding))
            for subfield in field.subfields:
                code = subfield.code
                if code is None or ord(code) <= 32 or ord(code) >= 255:
                    raise IrbisError('Bad code: ' + safe_str(code))
                this_field_length += 2  # Признак подполя и его код
                val = subfield.value
                if val:
                    this_field_length += len(val.encode(encoding))
        this_field_length += 1  # Разделитель полей

        if this_field_length >= 10_000:
            # Слишком длинное поле
            raise Exception

        field_length.append(this_field_length)
        record_length += this_field_length

    record_length += dictionary_length  # Справочник
    record_length += 1  # Разделитель записей

    if record_length >= 100_000:
        # Слишком длинная запись
        raise Exception

    # Приступаем к кодированию
    dictionary_position = MARKER_LENGTH
    base_address = MARKER_LENGTH + dictionary_length
    current_address = base_address
    buffer = bytearray(record_length)
    for i in range(base_address):
        buffer[i] = 32  # Заполняем пробелами
    encode_int(buffer, 0, 5, record_length)
    encode_int(buffer, 12, 5, base_address)

    buffer[5] = ord('n')  # Record status
    buffer[6] = ord('a')  # Record type
    buffer[7] = ord('m')  # Bibliographical index
    buffer[8] = ord('2')
    buffer[10] = ord('2')
    buffer[11] = ord('2')
    buffer[17] = ord(' ')  # Bibliographical level
    buffer[18] = ord('i')  # Cataloging rules
    buffer[19] = ord(' ')  # Related record
    buffer[20] = ord('4')  # Field length
    buffer[21] = ord('5')  # Field offset
    buffer[22] = ord('0')

    # Кодируем конец справочника
    buffer[base_address - 1] = FIELD_DELIMITER

    # Проходим по полям
    for i, field in enumerate(record.fields):
        # Кодируем справочник
        encode_int(buffer, dictionary_position + 0, 3,
                   field.tag)
        encode_int(buffer, dictionary_position + 3, 4,
                   field_length[i])
        encode_int(buffer, dictionary_position + 7, 5,
                   current_address - base_address)

        # Кодируем поле
        if field.tag < 10:
            # В фиксированном поле не бывает подполей и индикаторов
            encode_str(buffer, current_address, field.value, encoding)
        else:
            # Два индикатора
            buffer[current_address + 0] = 32
            buffer[current_address + 1] = 32
            current_address += 2

            # Значение поля до первого разделителя
            current_address = encode_str(buffer, current_address,
                                         field.value, encoding)

            # Подполя
            for subfield in field.subfields:
                buffer[current_address + 0] = SUBFIELD_DELIMITER
                buffer[current_address + 1] = ord(subfield.code)
                current_address += 2
                current_address = encode_str(buffer, current_address,
                                             subfield.value, encoding)
        buffer[current_address] = FIELD_DELIMITER
        current_address += 1
        dictionary_position += 12

    # Ограничитель записи
    buffer[record_length - 2] = FIELD_DELIMITER
    buffer[record_length - 1] = RECORD_DELIMITER

    # Собственно записываем
    stream.write(buffer)
예제 #7
0
    def __str__(self) -> str:
        if not self.prefix:
            return safe_str(self.name)

        return safe_str(self.name) + ' ' + safe_str(self.prefix)
예제 #8
0
 def __str__(self):
     return str(self.number) + ' ' + safe_str(self.format)