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
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) + ';'
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
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) + ';'
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')
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)
def __str__(self) -> str: if not self.prefix: return safe_str(self.name) return safe_str(self.name) + ' ' + safe_str(self.prefix)
def __str__(self): return str(self.number) + ' ' + safe_str(self.format)