예제 #1
0
    def __setitem__(self, key: 'Union[str, int]', value: 'FieldSetItemValue'):
        if key == '*':
            self.value = self.validate_value(value)

        elif isinstance(key, int):
            if value:
                if isinstance(value, str):
                    self.subfields[key].value = self.validate_value(value)
                elif isinstance(value, Field):
                    self.subfields[key] = value
                elif isinstance(value, (list, tuple)) and len(value) == 2:
                    code, val = value
                    if isinstance(code, str) and isinstance(val, str):
                        self.subfields[key] = SubField(code, val)
                else:
                    raise TypeError
            else:
                self.subfields.pop(key)

        elif isinstance(key, str):
            key = SubField.validate_code(key)
            del self[key]
            if value is not None:
                values = key, value
                self.__bulk_set__(values)
예제 #2
0
    def add(self, code: str, value: 'SubFieldValues' = '')\
            -> 'Field':
        """
        Добавление подполя с указанным кодом (и, возможно, значением)
        к записи.

        :param code: Код подполя (однобуквенный).
        :param value: Значение подполя (опционально).
        :return: Self
        """
        code = SubField.validate_code(code)
        if code == '*':
            if value and isinstance(value, (list, tuple)):
                value = value[0]

            if not self.value:
                self.value = self.validate_value(value)
            else:
                raise ValueError('Значение до первого разделителя уже задано')

        else:
            if value:
                if isinstance(value, str):
                    value = [value]
                for val in value:
                    subfield = SubField(code, val)
                    self.subfields.append(subfield)
        return self
예제 #3
0
    def have_subfield(self, code: str) -> bool:
        """
        Выясняет, есть ли подполе с указанным кодом.

        :param code: Искомый код подполя (должен быть однобуквенным).
        :return: True, если есть хотя бы одно подполе с указанным кодом.
        """
        code = SubField.validate_code(code)
        return code in self.keys()
예제 #4
0
    def all(self, code: str) -> 'FieldGetReturn':
        """
        Список всех подполей с указанным кодом.

        :param code: Код подполя (однобуквенный).
        :return: Список подполей (возможно, пустой).
        """
        code = SubField.validate_code(code)
        return self.get(code)
예제 #5
0
    def __delitem__(self, key: 'Union[str, int]'):
        """
        Метод удаления всех подполей с указанным кодом. Может вызываться
        следующим образом -- del field[key].

        :param key: строковый код
        :return:
        """
        if isinstance(key, int):
            self.subfields.pop(key)
        elif isinstance(key, str):
            key = SubField.validate_code(key)
            self.subfields = [sf for sf in self.subfields if sf.code != key]
예제 #6
0
    def all_values(self, code: str) -> 'List[str]':
        """
        Список значений всех подполей с указанным кодом.
        Пустые значения подполей в список не включаются.

        :param code: Код подполя (однобуквенный).
        :return: Список значений (возможно, пустой).
        """
        code = SubField.validate_code(code)
        if code == '*':
            return [self.get_value_or_first_subfield() or '']
        return [sf.value for sf in self.subfields
                if sf.code == code if sf.value]
예제 #7
0
    def add_non_empty(self, code: str, value: 'Optional[str]') -> 'Field':
        """
        Добавление подполя с указанным кодом при условии,
        что значение поля не пустое.

        :param code: Код подполя (однобуквенный).
        :param value: Значение подполя (опциональное).
        :return: Self
        """
        code = SubField.validate_code(code)
        if value:
            self.add(code, value)
        return self
예제 #8
0
    def insert_at(self, index: int, code: str, value: str) -> 'Field':
        """
        Вставляет подполе в указанную позицию.

        :param index: Позиция для вставки.
        :param code: Код подполя (обязательно).
        :param value: Значение подполя (опционально).
        :return: Self
        """
        assert index >= 0
        code = SubField.validate_code(code)

        subfield = SubField(code, value)
        self.subfields.insert(index, subfield)
        return self
예제 #9
0
    def replace_subfield(self, code: str, old_value: 'Optional[str]',
                         new_value: 'Optional[str]') -> 'Field':
        """
        Заменяет значение подполя с указанным кодом.

        :param code: Код подполя (обязательно).
        :param old_value: Старое значение.
        :param new_value: Новое значение.
        :return: Self.
        """
        code = SubField.validate_code(code)
        for subfield in self.subfields:
            if subfield.code == code and subfield.value == old_value:
                subfield.value = new_value

        return self
예제 #10
0
    def first_value(self, code: str, default: 'Optional[str]' = None)\
            -> 'Optional[str]':
        """
        Находит первое подполе с указанным кодом и выдает его значение.

        :param code: Искомый код.
        :param default: Значение по умолчанию.
        :return: Значение подполя или значение по умолчанию.
        """
        code = SubField.validate_code(code)
        if code == '*':
            return self.get_value_or_first_subfield()
        for subfield in self.subfields:
            if subfield.code == code:
                return subfield.value
        return default
예제 #11
0
    def first(self, code: str, default: 'Optional[SubField]' = None)\
            -> 'Optional[Union[SubField, Value]]':
        """
        Находит первое подполе с указанным кодом.

        :param code: Искомый код.
        :param default: Значение по умолчанию.
        :return: Подполе, значение до разделителя или default.
        """
        code = SubField.validate_code(code)
        result = self.get(code)
        if result:
            if isinstance(result, list):
                return result[0]
            return result
        return default
예제 #12
0
    def __getitem__(self, key: 'Union[str, int]')\
            -> 'FieldGetReturn':
        """
        Получение значения подполя по индексу

        :param key: строковый код или позиция подполя
        :return: список подполей, подполе или строка
        """
        if key == '*':
            if self.value:
                return self.value
        elif isinstance(key, str):
            code = SubField.validate_code(key)
            return [sf for sf in self.subfields if sf.code == code]
        elif isinstance(key, int):
            return self.subfields[key]
        raise KeyError
예제 #13
0
    def set_subfield(self, code: str, value: 'Optional[str]') -> 'Field':
        """
        Устанавливает значение первого повторения подполя с указанным кодом.
        Если value==None, подполе удаляется.

        :param code: Код искомого подполя.
        :param value: Устанавливаемое значение подполя (опционально).
        :return: Self
        """
        code = SubField.validate_code(code)
        if value:
            found = self.first(code)
            if found:
                if isinstance(found, str):
                    self.value = value
                elif isinstance(found, SubField):
                    found.value = value
            else:
                self.add(code, value)
        else:
            return self.remove_subfield(code)
        return self