Source code for icalendar.prop.n

"""N property from :rfc:`6350`."""


from typing import Any, ClassVar, NamedTuple

from icalendar.compatibility import Self
from icalendar.error import JCalParsingError
from icalendar.parser import Parameters
from icalendar.parser_tools import DEFAULT_ENCODING, to_unicode


[docs] class NFields(NamedTuple): """Named fields for vCard N (Name) property per :rfc:`6350#section-6.2.2`. Provides named access to the five name components. """ family: str """Family names (also known as surnames).""" given: str """Given names.""" additional: str """Additional names.""" prefix: str """Honorific prefixes.""" suffix: str """Honorific suffixes."""
[docs] class vN: r"""vCard N (Name) structured property per :rfc:`6350#section-6.2.2`. The N property represents a person's name. It consists of a single structured text value. Each component in the structure may have multiple values, separated by commas. The structured property value corresponds, in sequence, to the following fields: - family names (also known as surnames) - given names - additional names - honorific prefixes - honorific suffixes Semicolons are field separators and are NOT escaped. Commas and backslashes within field values ARE escaped per :rfc:`6350`. Examples: .. code-block:: pycon >>> from icalendar.prop import vN >>> n = vN(("Doe", "John", "M.", "Dr.", "Jr.,M.D.,A.C.P.")) >>> n.to_ical() b'Doe;John;M.;Dr.;Jr.\\,M.D.\\,A.C.P.' >>> vN.from_ical(r"Doe;John;M.;Dr.;Jr.\,M.D.\,A.C.P.") NFields(family='Doe', given='John', additional='M.', prefix='Dr.', suffix='Jr.,M.D.,A.C.P.') """ default_value: ClassVar[str] = "TEXT" params: Parameters fields: NFields
[docs] def __init__( self, fields: tuple[str, ...] | list[str] | str | NFields, /, params: dict[str, Any] | None = None, ): """Initialize N with five fields or parse from vCard format string. Parameters: fields: Either an NFields, tuple, or list of five strings, one per field, or a vCard format string with semicolon-separated fields params: Optional property parameters """ if isinstance(fields, str): fields = self.from_ical(fields) if isinstance(fields, NFields): self.fields = fields else: if len(fields) != 5: raise ValueError(f"N must have exactly 5 fields, got {len(fields)}") self.fields = NFields(*(str(f) for f in fields)) self.params = Parameters(params)
[docs] def to_ical(self) -> bytes: """Generate vCard format with semicolon-separated fields.""" from icalendar.prop.text import vText parts = [vText(f).to_ical().decode(DEFAULT_ENCODING) for f in self.fields] return ";".join(parts).encode(DEFAULT_ENCODING)
[docs] @staticmethod def from_ical(ical: str | bytes) -> NFields: """Parse vCard N format into an NFields named tuple. Parameters: ical: vCard format string with semicolon-separated fields Returns: NFields named tuple with five field values. """ from icalendar.parser import split_on_unescaped_semicolon ical = to_unicode(ical) fields = split_on_unescaped_semicolon(ical) if len(fields) != 5: raise ValueError(f"N must have exactly 5 fields, got {len(fields)}: {ical}") return NFields(*fields)
def __eq__(self, other): """self == other""" return isinstance(other, vN) and self.fields == other.fields def __repr__(self): """String representation.""" return f"{self.__class__.__name__}({self.fields}, params={self.params})" @property def ical_value(self) -> NFields: """The name fields as a named tuple.""" return self.fields from icalendar.param import VALUE
[docs] def to_jcal(self, name: str) -> list: """The jCal representation of this property according to :rfc:`7265`.""" result = [name, self.params.to_jcal(), self.VALUE.lower()] result.extend(self.fields) return result
[docs] @classmethod def from_jcal(cls, jcal_property: list) -> Self: """Parse jCal from :rfc:`7265`. Parameters: jcal_property: The jCal property to parse. Raises: ~error.JCalParsingError: If the provided jCal is invalid. """ JCalParsingError.validate_property(jcal_property, cls) if len(jcal_property) != 8: # name, params, value_type, 5 fields raise JCalParsingError( f"N must have 8 elements (name, params, value_type, 5 fields), " f"got {len(jcal_property)}" ) for i, field in enumerate(jcal_property[3:], start=3): JCalParsingError.validate_value_type(field, str, cls, i) return cls( tuple(jcal_property[3:]), Parameters.from_jcal_property(jcal_property), )
[docs] @classmethod def examples(cls) -> list[Self]: """Examples of vN.""" return [cls(("Doe", "John", "M.", "Dr.", "Jr."))]
__all__ = ["NFields", "vN"]