def test_clone_1(self): original = MarcRecord().add(100, 'Some value') original.database = 'IBIS' clone = original.clone() self.assertEqual(original.database, clone.database) self.assertEqual(original.mfn, clone.mfn) self.assertEqual(original.status, clone.status) self.assertEqual(original.version, clone.version) self.assertEqual(len(original.fields), len(clone.fields))
def test_is_deleted_1(self): record = MarcRecord() self.assertFalse(record.is_deleted()) record.status = LOGICALLY_DELETED self.assertTrue(record.is_deleted()) record.status = PHYSICALLY_DELETED self.assertTrue(record.is_deleted()) record.status = LAST self.assertFalse(record.is_deleted())
def test_write_record_01(self): sf = SubField with random_binary_file() as stream: record = MarcRecord() record.add(700, sf('a', 'Миронов'), sf('b', 'А. В.'), sf('g', 'Алексей Владимирович')) record.add(200, sf('a', f'Работа с ИРБИС64: версия 0.0'), sf('e', 'руководство пользователя')) record.add(210, sf('a', 'Иркутск'), SubField('c', 'ИРНИТУ'), sf('d', '2018')) record.add(920, 'PAZK') iso.write_record(stream, record, UTF) self.assertTrue(stream.name)
def test_write_text_record(self): sf = SubField with random_text_file() as stream: for i in range(10): record = MarcRecord() record.add(700, sf('a', 'Миронов'), sf('b', 'А. В.'), sf('g', 'Алексей Владимирович')) record.add(200, sf('a', f'Работа с ИРБИС64: версия {i}.0'), sf('e', 'руководство пользователя')) record.add(210, sf('a', 'Иркутск'), SubField('c', 'ИРНИТУ'), sf('d', '2018')) record.add(920, 'PAZK') write_text_record(stream, record)
def test_14_write_record(self): record = MarcRecord() record.add(200, SubField('a', 'Сгенерированная запись')) record.add(300, 'Комментарий') record.add(700, SubField('a', 'Пайтон'), SubField('b', 'М.'), SubField('g', 'Монти')) record.add(910, SubField('a', '0'), SubField('b', '1'), SubField('c', '?'), SubField('d', 'ФКХ')) print('Write record') max_mfn = self.connection.write_record(record) print('New max MFN=', max_mfn, sep='') print(record) print()
def test_fma_1(self): record = MarcRecord().add(100, 'Field 100/1').add(100, 'Field 100/2') record.add(200, SubField('a', 'SubA/1'), SubField('b', 'SubB/1')) record.add(200, SubField('a', 'SubA/2'), SubField('b', 'SubB/2')) self.assertEqual(record.fma(100), ['Field 100/1', 'Field 100/2']) self.assertEqual(record.fma(200, 'a'), ['SubA/1', 'SubA/2']) self.assertEqual(record.fma(200, 'b'), ['SubB/1', 'SubB/2']) self.assertEqual(record.fma(200, 'c'), []) self.assertEqual(record.fma(300), []) self.assertEqual(record.fma(300, 'a'), [])
def test_33_format_record(self): sf = SubField record = MarcRecord() record.add(700, sf('a', 'Миронов'), sf('b', 'А. В.'), sf('g', 'Алексей Владимирович')) record.add(200, sf('a', f'Работа с ИРБИС64: версия 1.0'), sf('e', 'руководство пользователя')) record.add(210, sf('a', 'Иркутск'), SubField('c', 'ИРНИТУ'), sf('d', '2018')) record.add(920, 'PAZK') text = self.connection.format_record('@brief', record) self.assertEqual( text, 'Миронов, Алексей Владимирович. Работа с ИРБИС64: ' 'версия 1.0 [Текст] : руководство пользователя, 2018')
def test_encode_1(self): record = MarcRecord() record.mfn = 123 record.version = 321 record.status = LAST record.add(100, 'Field100').add(200, SubField('a', 'SubA'), SubField('b', 'SubB')) self.assertEqual(record.encode(), ['123#32', '0#321', '100#Field100', '200#^aSubA^bSubB'])
def test_init_2(self): f100 = RecordField(100, 'Field 100') f200 = RecordField(200, 'Field 200') record = MarcRecord(f100, f200) self.assertEqual(len(record.fields), 2) self.assertEqual(record.fields[0].tag, 100) self.assertEqual(record.fields[1].tag, 200)
def test_init_1(self): record = MarcRecord() self.assertIsNone(record.database) self.assertEqual(record.mfn, 0) self.assertEqual(record.version, 0) self.assertEqual(record.status, 0) self.assertEqual(len(record.fields), 0)
def read_text_record(stream: TextIO) -> Optional[MarcRecord]: """ Чтение записи из файла в текстовом обменном формате ИРБИС. :param stream: Файл :return: Запись или None """ result = MarcRecord() while True: line: str = stream.readline() if not line: break line = line.strip() if line.startswith(STOP_MARKER): break if not line.startswith('#'): break parts = line[1:].split(':', 1) if len(parts) != 2: break tag = int(parts[0]) text = parts[1][1:] field = RecordField(tag) field.parse(text) result.fields.append(field) if not result.fields: # Если в записи нет полей, возвращаем None return None return result
def test_iter_1(self): record = MarcRecord().add(100, 'Field 100') \ .add(200, SubField('a', 'SubA'), SubField('b', 'SubB')) s = list(record) self.assertEqual(len(s), 2) self.assertEqual(s[0].tag, 100) self.assertEqual(s[1].tag, 200)
def test_iadd_1(self): record = MarcRecord() self.assertEqual(len(record.fields), 0) record += RecordField(100, 'Field 100') self.assertEqual(len(record.fields), 1) record += RecordField(200, SubField('a', 'SubA')) self.assertEqual(len(record.fields), 2)
def test_setitem_1(self): f100 = RecordField(100, 'Field 100') f200 = RecordField(200, SubField('a', 'SubA'), SubField('b', 'SubB')) record = MarcRecord() record.fields.append(f100) record.fields.append(f200) new_value = 'New value' record[100] = new_value self.assertEqual(f100.value, new_value) record[200] = '^aNewA^bNewB' self.assertEqual(f200.subfields[0].value, 'NewA') self.assertEqual(f200.subfields[1].value, 'NewB') record[300] = new_value self.assertEqual(len(record.fields), 3) self.assertEqual(record.fields[2].tag, 300) self.assertEqual(record.fields[2].value, new_value) record[400] = RecordField().add('a', 'NewA').add('b', 'NewB') self.assertEqual(len(record.fields), 4) self.assertEqual(record.fields[3].tag, 400) self.assertEqual(record.fields[3].subfields[0].value, 'NewA') self.assertEqual(record.fields[3].subfields[1].value, 'NewB') record[300] = SubField('a', 'OtherA') self.assertEqual(len(record.fields), 4) self.assertEqual(record.fields[2].tag, 300) self.assertIsNone(record.fields[2].value) self.assertEqual(record.fields[2].subfields[0].value, 'OtherA')
def test_isub_1(self): f100 = RecordField(100, 'Field 100') f200 = RecordField(200, SubField('a', 'SubA')) record = MarcRecord(f100, f200) record -= (f100, f200) self.assertEqual(len(record.fields), 0) record -= (f100, f200) self.assertEqual(len(record.fields), 0)
def test_record_parse_1(self): record = MarcRecord() text = ['123#32', '0#321', '100#Field 100', '200#^aSubA^bSubB'] record.parse(text) self.assertEqual(len(record.fields), 2) self.assertEqual(record.mfn, 123) self.assertEqual(record.status, LAST) self.assertEqual(record.version, 321) self.assertEqual(record.fields[0].tag, 100) self.assertEqual(record.fields[0].value, 'Field 100') self.assertEqual(len(record.fields[0].subfields), 0) self.assertEqual(record.fields[1].tag, 200) self.assertIsNone(record.fields[1].value) self.assertEqual(len(record.fields[1].subfields), 2) self.assertEqual(record.fields[1].subfields[0].code, 'a') self.assertEqual(record.fields[1].subfields[0].value, 'SubA') self.assertEqual(record.fields[1].subfields[1].code, 'b') self.assertEqual(record.fields[1].subfields[1].value, 'SubB')
def test_fm_2(self): record = MarcRecord().add(100, '', SubField('a', '100A'), SubField('b', '100B')) record.add(200, '', SubField('b', '200B'), SubField('c', '200C')) self.assertEqual('100A', record.fm(100, 'a')) self.assertEqual('100B', record.fm(100, 'b')) self.assertIsNone(record.fm(100, 'c')) self.assertIsNone(record.fm(200, 'a')) self.assertEqual('200B', record.fm(200, 'b')) self.assertEqual('200C', record.fm(200, 'c'))
def test_setitem_2(self): f100 = RecordField(100, 'Field 100') f200 = RecordField(200, SubField('a', 'SubA'), SubField('b', 'SubB')) record = MarcRecord() record.fields.append(f100) record.fields.append(f200) self.assertEqual(len(record.fields), 2) record[100] = None self.assertEqual(len(record.fields), 1) record[200] = None self.assertEqual(len(record.fields), 0)
def test_len_1(self): record = MarcRecord() self.assertEqual(len(record), 0) record.add(100, 'Field 100') self.assertEqual(len(record), 1) record.add(200, 'Field 200') self.assertEqual(len(record), 2)
def test_iter_2(self): record = MarcRecord().add(100, 'Field 100') \ .add(200, SubField('a', 'SubA'), SubField('b', 'SubB')) i = iter(record) f = next(i) self.assertEqual(f.tag, 100) f = next(i) self.assertEqual(f.tag, 200) ok = False try: next(i) except StopIteration: ok = True self.assertTrue(ok)
def test_all_1(self): record = MarcRecord() record.add(100, 'Field100').add(200, 'Field200') \ .add(300, 'Field300/1').add(300, 'Field300/2') self.assertEqual(len(record.fields), 4) self.assertEqual(len(record.all(100)), 1) self.assertEqual(len(record.all(200)), 1) self.assertEqual(len(record.all(300)), 2) self.assertEqual(len(record.all(400)), 0)
def test_write_record_2(self): sf = SubField with random_binary_file() as stream: for i in range(10): record = MarcRecord() record.add(700, sf('a', 'Миронов'), sf('b', 'А. В.'), sf('g', 'Алексей Владимирович')) record.add(200, sf('a', f'Работа с ИРБИС64: версия {i}.0'), sf('e', 'руководство пользователя')) record.add(210, sf('a', 'Иркутск'), SubField('c', 'ИРНИТУ'), sf('d', '2018')) record.add(920, 'PAZK') iso.write_record(stream, record, UTF) filename = stream.name with open(filename, 'rb') as fh: count = 0 while True: record = iso.read_record(fh, UTF) if record is None: break self.assertEqual(len(record.fields), 4) count += 1 self.assertEqual(count, 10)
def read_record(stream: BinaryIO, charset=ANSI) -> Optional[MarcRecord]: """ Чтение записи из файла в формате ISO 2709. :param stream: Файл или файлоподобный объект :param charset: Кодировка :return: Декодированная запись либо None """ # Считываем длину записи marker = stream.read(5) if len(marker) != 5: return None # а затем и ее остаток record_length = parse_int(marker) need = record_length - 5 tail = stream.read(need) if len(tail) != need: return None # Простая проверка, что мы имеем дело с нормальной ISO-записью record = marker + tail if record[record_length - 1] != RECORD_DELIMITER: return None # Превращаем запись в Unicode indicator_length = parse_int(record[10:11]) base_address = parse_int(record[12:17]) # Начинаем собственно конверсию result = MarcRecord() # Пошли по полям при помощи справочника directory = MARKER_LENGTH while record[directory] != FIELD_DELIMITER: # если нарвались на разделитель, значит, справочник закончился tag = parse_int(record[directory:directory + 3]) field_length = parse_int(record[directory + 3:directory + 7]) field_offset = parse_int( record[directory + 7:directory + 12]) + base_address field = RecordField(tag) result.fields.append(field) if tag < 10: # фиксированное поле # не может содержать подполей и индикаторов field.value = record[field_offset:field_offset + field_length - 1].decode(charset) else: # поле переменной длины # содержит два однобайтных индикатора # может содержать подполя start = field_offset + indicator_length stop = field_offset + field_length - indicator_length + 1 position = start # ищем значение поля до первого разделителя while position < stop: if record[start] == SUBFIELD_DELIMITER: break position += 1 # если есть текст до первого раздлителя, запоминаем его if position != start: field.value = record[start:position].decode(charset) # просматриваем подполя start = position while start < stop: position = start + 1 while position < stop: if record[position] == SUBFIELD_DELIMITER: break position += 1 subfield = SubField(chr(record[start + 1]), record[start + 2:position].decode(charset)) field.subfields.append(subfield) start = position # переходим к следующему полю в справочнике directory += 12 return result
def test_clear_1(self): record = MarcRecord().add(100, 'Some value') record.clear() self.assertEqual(len(record.fields), 0)
def test_write_record_001(self): with random_binary_file() as stream: record = MarcRecord() iso.write_record(stream, record, UTF) self.assertTrue(stream.name)
def test_bool_1(self): record = MarcRecord() self.assertFalse(bool(record)) record.add(100, 'Field 100') self.assertTrue(bool(record))
def test_str_1(self): record = MarcRecord().add(100, 'Field 100') \ .add(200, 'Field 200', SubField('a', 'Subfield A')) self.assertEqual('100#Field 100\n200#Field 200^aSubfield A', str(record))
def test_getitem_1(self): record = MarcRecord().add(100, 'Field 100') \ .add(200, SubField('a', 'SubA'), SubField('b', 'SubB')) self.assertEqual(record[100], 'Field 100') self.assertIsNone(record[200]) self.assertIsNone(record[300])
def test_fm_1(self): record = MarcRecord().add(100, 'Field 100').add(200, 'Field 200') self.assertEqual('Field 100', record.fm(100)) self.assertEqual('Field 200', record.fm(200)) self.assertIsNone(record.fm(300))
def test_iadd_2(self): record = MarcRecord() record += (RecordField(100, 'Field 100'), RecordField(200, 'Field 200')) self.assertEqual(len(record.fields), 2)