Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/prop/org.py: 49%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""The ORG property from :rfc:`6350`."""
3from typing import Any, ClassVar
5from icalendar.compatibility import Self
6from icalendar.error import JCalParsingError
7from icalendar.parser import Parameters
8from icalendar.parser_tools import DEFAULT_ENCODING, to_unicode
11class vOrg:
12 r"""vCard ORG (Organization) structured property per :rfc:`6350#section-6.6.4`.
14 The ORG property specifies the organizational name and units
15 associated with the vCard.
17 Its value is a structured type consisting of components separated
18 by semicolons. The components are the organization name, followed
19 by zero or more levels of organizational unit names:
21 .. code-block:: text
23 organization-name; organizational-unit-1; organizational-unit-2; ...
25 Semicolons are field separators and are NOT escaped.
26 Commas and backslashes within field values ARE escaped per :rfc:`6350`.
28 Examples:
29 A property value consisting of an organizational name,
30 organizational unit #1 name, and organizational unit #2 name.
32 .. code-block:: text
34 ORG:ABC\, Inc.;North American Division;Marketing
36 The same example in icalendar.
38 .. code-block:: pycon
40 >>> from icalendar.prop import vOrg
41 >>> org = vOrg(("ABC, Inc.", "North American Division", "Marketing"))
42 >>> org.to_ical()
43 b'ABC\\, Inc.;North American Division;Marketing'
44 >>> vOrg.from_ical(r"ABC\, Inc.;North American Division;Marketing")
45 ('ABC, Inc.', 'North American Division', 'Marketing')
46 """
48 default_value: ClassVar[str] = "TEXT"
49 params: Parameters
50 fields: tuple[str, ...]
52 def __init__(
53 self,
54 fields: tuple[str, ...] | list[str] | str,
55 /,
56 params: dict[str, Any] | None = None,
57 ):
58 """Initialize ORG with variable fields or parse from vCard format string.
60 Parameters:
61 fields: Either a tuple or list of one or more strings, or a
62 vCard format string with semicolon-separated fields
63 params: Optional property parameters
64 """
65 if isinstance(fields, str):
66 fields = self.from_ical(fields)
67 if len(fields) < 1:
68 raise ValueError("ORG must have at least 1 field (organization name)")
69 self.fields = tuple(str(f) for f in fields)
70 self.params = Parameters(params)
72 def to_ical(self) -> bytes:
73 """Generate vCard format with semicolon-separated fields."""
74 from icalendar.prop.text import vText
76 parts = [vText(f).to_ical().decode(DEFAULT_ENCODING) for f in self.fields]
77 return ";".join(parts).encode(DEFAULT_ENCODING)
79 @staticmethod
80 def from_ical(ical: str | bytes) -> tuple[str, ...]:
81 """Parse vCard ORG format into a tuple of fields.
83 Parameters:
84 ical: vCard format string with semicolon-separated fields
86 Returns:
87 Tuple of field values with one or more fields
88 """
89 from icalendar.parser import split_on_unescaped_semicolon
91 ical = to_unicode(ical)
92 fields = split_on_unescaped_semicolon(ical)
93 if len(fields) < 1:
94 raise ValueError(f"ORG must have at least 1 field: {ical}")
95 return tuple(fields)
97 def __eq__(self, other: object) -> bool:
98 """self == other"""
99 return isinstance(other, vOrg) and self.fields == other.fields
101 def __repr__(self) -> str:
102 """String representation."""
103 return f"{self.__class__.__name__}({self.fields}, params={self.params})"
105 @property
106 def name(self) -> str:
107 """The organization name (first field)."""
108 return self.fields[0]
110 @property
111 def units(self) -> tuple[str, ...]:
112 """The organizational unit names (remaining fields after the name)."""
113 return self.fields[1:]
115 @property
116 def ical_value(self) -> tuple[str, ...]:
117 """The organization fields as a tuple."""
118 return self.fields
120 from icalendar.param import VALUE
122 def to_jcal(self, name: str) -> list:
123 """The jCal representation of this property according to :rfc:`7265`."""
124 result = [name, self.params.to_jcal(), self.VALUE.lower()]
125 result.extend(self.fields)
126 return result
128 @classmethod
129 def from_jcal(cls, jcal_property: list) -> Self:
130 """Parse jCal from :rfc:`7265`.
132 Parameters:
133 jcal_property: The jCal property to parse.
135 Raises:
136 ~error.JCalParsingError: If the provided jCal is invalid.
137 """
138 JCalParsingError.validate_property(jcal_property, cls)
139 if len(jcal_property) < 4: # name, params, value_type, at least 1 field
140 raise JCalParsingError(
141 "ORG must have at least 4 elements"
142 " (name, params, value_type, org name),"
143 f" got {len(jcal_property)}"
144 )
145 for i, field in enumerate(jcal_property[3:], start=3):
146 JCalParsingError.validate_value_type(field, str, cls, i)
147 return cls(
148 tuple(jcal_property[3:]),
149 Parameters.from_jcal_property(jcal_property),
150 )
152 @classmethod
153 def examples(cls) -> list[Self]:
154 """Examples of vOrg."""
155 return [cls(("ABC Inc.", "North American Division", "Marketing"))]
158__all__ = ["vOrg"]