fix: 포트 충돌 회피 — note_bridge 8098, intent_service 8099
Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
700
.venv/lib/python3.9/site-packages/icalendar/attr.py
Normal file
700
.venv/lib/python3.9/site-packages/icalendar/attr.py
Normal file
@@ -0,0 +1,700 @@
|
||||
"""Attributes of Components and properties."""
|
||||
from __future__ import annotations
|
||||
|
||||
import itertools
|
||||
from datetime import date, datetime, timedelta
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from icalendar.error import InvalidCalendar
|
||||
from icalendar.prop import vCategory, vDDDTypes, vRecur, vText
|
||||
from icalendar.timezone import tzp
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from icalendar.cal import Component
|
||||
|
||||
|
||||
def _get_rdates(self: Component) -> list[
|
||||
Union[tuple[date, None],
|
||||
tuple[datetime, None],
|
||||
tuple[datetime, datetime]]]:
|
||||
"""The RDATE property defines the list of DATE-TIME values for recurring components.
|
||||
|
||||
RDATE is defined in :rfc:`5545`.
|
||||
The return value is a list of tuples ``(start, end)``.
|
||||
|
||||
``start`` can be a :class:`datetime.date` or a :class:`datetime.datetime`,
|
||||
with and without timezone.
|
||||
|
||||
``end`` is :obj:`None` if the end is not specified and a :class:`datetime.datetime`
|
||||
if the end is specified.
|
||||
|
||||
Value Type:
|
||||
The default value type for this property is DATE-TIME.
|
||||
The value type can be set to DATE or PERIOD.
|
||||
|
||||
Property Parameters:
|
||||
IANA, non-standard, value data type, and time
|
||||
zone identifier property parameters can be specified on this
|
||||
property.
|
||||
|
||||
Conformance:
|
||||
This property can be specified in recurring "VEVENT",
|
||||
"VTODO", and "VJOURNAL" calendar components as well as in the
|
||||
"STANDARD" and "DAYLIGHT" sub-components of the "VTIMEZONE"
|
||||
calendar component.
|
||||
|
||||
Description:
|
||||
This property can appear along with the "RRULE"
|
||||
property to define an aggregate set of repeating occurrences.
|
||||
When they both appear in a recurring component, the recurrence
|
||||
instances are defined by the union of occurrences defined by both
|
||||
the "RDATE" and "RRULE".
|
||||
|
||||
The recurrence dates, if specified, are used in computing the
|
||||
recurrence set. The recurrence set is the complete set of
|
||||
recurrence instances for a calendar component. The recurrence set
|
||||
is generated by considering the initial "DTSTART" property along
|
||||
with the "RRULE", "RDATE", and "EXDATE" properties contained
|
||||
within the recurring component. The "DTSTART" property defines
|
||||
the first instance in the recurrence set. The "DTSTART" property
|
||||
value SHOULD match the pattern of the recurrence rule, if
|
||||
specified. The recurrence set generated with a "DTSTART" property
|
||||
value that doesn't match the pattern of the rule is undefined.
|
||||
The final recurrence set is generated by gathering all of the
|
||||
start DATE-TIME values generated by any of the specified "RRULE"
|
||||
and "RDATE" properties, and then excluding any start DATE-TIME
|
||||
values specified by "EXDATE" properties. This implies that start
|
||||
DATE-TIME values specified by "EXDATE" properties take precedence
|
||||
over those specified by inclusion properties (i.e., "RDATE" and
|
||||
"RRULE"). Where duplicate instances are generated by the "RRULE"
|
||||
and "RDATE" properties, only one recurrence is considered.
|
||||
Duplicate instances are ignored.
|
||||
|
||||
Example:
|
||||
Below, we set one RDATE in a list and get the resulting tuple of start and end.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from icalendar import Event
|
||||
>>> from datetime import datetime
|
||||
>>> event = Event()
|
||||
|
||||
# Add a list of recurrence dates
|
||||
>>> event.add("RDATE", [datetime(2025, 4, 28, 16, 5)])
|
||||
>>> event.rdates
|
||||
[(datetime.datetime(2025, 4, 28, 16, 5), None)]
|
||||
|
||||
.. note::
|
||||
|
||||
You cannot modify the RDATE value by modifying the result.
|
||||
Use :func:`icalendar.cal.Component.add` to add values.
|
||||
|
||||
If you want to compute recurrences, have a look at :ref:`Related projects`.
|
||||
|
||||
"""
|
||||
result = []
|
||||
rdates = self.get("RDATE", [])
|
||||
for rdates in (rdates,) if not isinstance(rdates, list) else rdates:
|
||||
for dts in rdates.dts:
|
||||
rdate = dts.dt
|
||||
if isinstance(rdate, tuple):
|
||||
# we have a period as rdate
|
||||
if isinstance(rdate[1], timedelta):
|
||||
result.append((rdate[0], rdate[0] + rdate[1]))
|
||||
else:
|
||||
result.append(rdate)
|
||||
else:
|
||||
# we have a date/datetime
|
||||
result.append((rdate, None))
|
||||
return result
|
||||
|
||||
|
||||
rdates_property = property(_get_rdates)
|
||||
|
||||
|
||||
def _get_exdates(self: Component) -> list[date|datetime]:
|
||||
"""EXDATE defines the list of DATE-TIME exceptions for recurring components.
|
||||
|
||||
EXDATE is defined in :rfc:`5545`.
|
||||
|
||||
Value Type:
|
||||
The default value type for this property is DATE-TIME.
|
||||
The value type can be set to DATE.
|
||||
|
||||
Property Parameters:
|
||||
IANA, non-standard, value data type, and time
|
||||
zone identifier property parameters can be specified on this
|
||||
property.
|
||||
|
||||
Conformance:
|
||||
This property can be specified in recurring "VEVENT",
|
||||
"VTODO", and "VJOURNAL" calendar components as well as in the
|
||||
"STANDARD" and "DAYLIGHT" sub-components of the "VTIMEZONE"
|
||||
calendar component.
|
||||
|
||||
Description:
|
||||
The exception dates, if specified, are used in
|
||||
computing the recurrence set. The recurrence set is the complete
|
||||
set of recurrence instances for a calendar component. The
|
||||
recurrence set is generated by considering the initial "DTSTART"
|
||||
property along with the "RRULE", "RDATE", and "EXDATE" properties
|
||||
contained within the recurring component. The "DTSTART" property
|
||||
defines the first instance in the recurrence set. The "DTSTART"
|
||||
property value SHOULD match the pattern of the recurrence rule, if
|
||||
specified. The recurrence set generated with a "DTSTART" property
|
||||
value that doesn't match the pattern of the rule is undefined.
|
||||
The final recurrence set is generated by gathering all of the
|
||||
start DATE-TIME values generated by any of the specified "RRULE"
|
||||
and "RDATE" properties, and then excluding any start DATE-TIME
|
||||
values specified by "EXDATE" properties. This implies that start
|
||||
DATE-TIME values specified by "EXDATE" properties take precedence
|
||||
over those specified by inclusion properties (i.e., "RDATE" and
|
||||
"RRULE"). When duplicate instances are generated by the "RRULE"
|
||||
and "RDATE" properties, only one recurrence is considered.
|
||||
Duplicate instances are ignored.
|
||||
|
||||
The "EXDATE" property can be used to exclude the value specified
|
||||
in "DTSTART". However, in such cases, the original "DTSTART" date
|
||||
MUST still be maintained by the calendaring and scheduling system
|
||||
because the original "DTSTART" value has inherent usage
|
||||
dependencies by other properties such as the "RECURRENCE-ID".
|
||||
|
||||
Example:
|
||||
Below, we add an exdate in a list and get the resulting list of exdates.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from icalendar import Event
|
||||
>>> from datetime import datetime
|
||||
>>> event = Event()
|
||||
|
||||
# Add a list of excluded dates
|
||||
>>> event.add("EXDATE", [datetime(2025, 4, 28, 16, 5)])
|
||||
>>> event.exdates
|
||||
[datetime.datetime(2025, 4, 28, 16, 5)]
|
||||
|
||||
.. note::
|
||||
|
||||
You cannot modify the EXDATE value by modifying the result.
|
||||
Use :func:`icalendar.cal.Component.add` to add values.
|
||||
|
||||
If you want to compute recurrences, have a look at :ref:`Related projects`.
|
||||
|
||||
"""
|
||||
result = []
|
||||
exdates = self.get("EXDATE", [])
|
||||
for exdates in (exdates,) if not isinstance(exdates, list) else exdates:
|
||||
for dts in exdates.dts:
|
||||
exdate = dts.dt
|
||||
# we have a date/datetime
|
||||
result.append(exdate)
|
||||
return result
|
||||
|
||||
|
||||
exdates_property = property(_get_exdates)
|
||||
|
||||
|
||||
def _get_rrules(self: Component) -> list[vRecur]:
|
||||
"""RRULE defines a rule or repeating pattern for recurring components.
|
||||
|
||||
RRULE is defined in :rfc:`5545`.
|
||||
:rfc:`7529` adds the ``SKIP`` parameter :class:`icalendar.prop.vSkip`.
|
||||
|
||||
Property Parameters:
|
||||
IANA and non-standard property parameters can
|
||||
be specified on this property.
|
||||
|
||||
Conformance:
|
||||
This property can be specified in recurring "VEVENT",
|
||||
"VTODO", and "VJOURNAL" calendar components as well as in the
|
||||
"STANDARD" and "DAYLIGHT" sub-components of the "VTIMEZONE"
|
||||
calendar component, but it SHOULD NOT be specified more than once.
|
||||
The recurrence set generated with multiple "RRULE" properties is
|
||||
undefined.
|
||||
|
||||
Description:
|
||||
The recurrence rule, if specified, is used in computing
|
||||
the recurrence set. The recurrence set is the complete set of
|
||||
recurrence instances for a calendar component. The recurrence set
|
||||
is generated by considering the initial "DTSTART" property along
|
||||
with the "RRULE", "RDATE", and "EXDATE" properties contained
|
||||
within the recurring component. The "DTSTART" property defines
|
||||
the first instance in the recurrence set. The "DTSTART" property
|
||||
value SHOULD be synchronized with the recurrence rule, if
|
||||
specified. The recurrence set generated with a "DTSTART" property
|
||||
value not synchronized with the recurrence rule is undefined. The
|
||||
final recurrence set is generated by gathering all of the start
|
||||
DATE-TIME values generated by any of the specified "RRULE" and
|
||||
"RDATE" properties, and then excluding any start DATE-TIME values
|
||||
specified by "EXDATE" properties. This implies that start DATE-
|
||||
TIME values specified by "EXDATE" properties take precedence over
|
||||
those specified by inclusion properties (i.e., "RDATE" and
|
||||
"RRULE"). Where duplicate instances are generated by the "RRULE"
|
||||
and "RDATE" properties, only one recurrence is considered.
|
||||
Duplicate instances are ignored.
|
||||
|
||||
The "DTSTART" property specified within the iCalendar object
|
||||
defines the first instance of the recurrence. In most cases, a
|
||||
"DTSTART" property of DATE-TIME value type used with a recurrence
|
||||
rule, should be specified as a date with local time and time zone
|
||||
reference to make sure all the recurrence instances start at the
|
||||
same local time regardless of time zone changes.
|
||||
|
||||
If the duration of the recurring component is specified with the
|
||||
"DTEND" or "DUE" property, then the same exact duration will apply
|
||||
to all the members of the generated recurrence set. Else, if the
|
||||
duration of the recurring component is specified with the
|
||||
"DURATION" property, then the same nominal duration will apply to
|
||||
all the members of the generated recurrence set and the exact
|
||||
duration of each recurrence instance will depend on its specific
|
||||
start time. For example, recurrence instances of a nominal
|
||||
duration of one day will have an exact duration of more or less
|
||||
than 24 hours on a day where a time zone shift occurs. The
|
||||
duration of a specific recurrence may be modified in an exception
|
||||
component or simply by using an "RDATE" property of PERIOD value
|
||||
type.
|
||||
|
||||
Examples:
|
||||
Daily for 10 occurrences:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from icalendar import Event
|
||||
>>> from datetime import datetime
|
||||
>>> from zoneinfo import ZoneInfo
|
||||
>>> event = Event()
|
||||
>>> event.start = datetime(1997, 9, 2, 9, 0, tzinfo=ZoneInfo("America/New_York"))
|
||||
>>> event.add("RRULE", "FREQ=DAILY;COUNT=10")
|
||||
>>> print(event.to_ical())
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID=America/New_York:19970902T090000
|
||||
RRULE:FREQ=DAILY;COUNT=10
|
||||
END:VEVENT
|
||||
>>> event.rrules
|
||||
[vRecur({'FREQ': ['DAILY'], 'COUNT': [10]})]
|
||||
|
||||
Daily until December 24, 1997:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from icalendar import Event, vRecur
|
||||
>>> from datetime import datetime
|
||||
>>> from zoneinfo import ZoneInfo
|
||||
>>> event = Event()
|
||||
>>> event.start = datetime(1997, 9, 2, 9, 0, tzinfo=ZoneInfo("America/New_York"))
|
||||
>>> event.add("RRULE", vRecur({"FREQ": ["DAILY"]}, until=datetime(1997, 12, 24, tzinfo=ZoneInfo("UTC"))))
|
||||
>>> print(event.to_ical())
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID=America/New_York:19970902T090000
|
||||
RRULE:FREQ=DAILY;UNTIL=19971224T000000Z
|
||||
END:VEVENT
|
||||
>>> event.rrules
|
||||
[vRecur({'FREQ': ['DAILY'], 'UNTIL': [datetime.datetime(1997, 12, 24, 0, 0, tzinfo=ZoneInfo(key='UTC'))]})]
|
||||
|
||||
.. note::
|
||||
|
||||
You cannot modify the RRULE value by modifying the result.
|
||||
Use :func:`icalendar.cal.Component.add` to add values.
|
||||
|
||||
If you want to compute recurrences, have a look at :ref:`Related projects`.
|
||||
|
||||
"""
|
||||
rrules = self.get("RRULE", [])
|
||||
if not isinstance(rrules, list):
|
||||
return [rrules]
|
||||
return rrules
|
||||
|
||||
|
||||
rrules_property = property(_get_rrules)
|
||||
|
||||
def multi_language_text_property(main_prop:str, compatibility_prop:str, doc:str) -> property:
|
||||
"""This creates a text property.
|
||||
|
||||
This property can be defined several times with different ``LANGUAGE`` parameters.
|
||||
|
||||
Args:
|
||||
main_prop (str): The property to set and get, such as ``NAME``
|
||||
compatibility_prop (str): An old property used before, such as ``X-WR-CALNAME``
|
||||
doc (str): The documentation string
|
||||
"""
|
||||
def fget(self: Component) -> Optional[str]:
|
||||
"""Get the property"""
|
||||
result = self.get(main_prop, self.get(compatibility_prop))
|
||||
if isinstance(result, list):
|
||||
for item in result:
|
||||
if "LANGUAGE" not in item.params:
|
||||
return item
|
||||
return result
|
||||
|
||||
def fset(self: Component, value:str):
|
||||
"""Set the property."""
|
||||
fdel(self)
|
||||
self.add(main_prop, value)
|
||||
|
||||
def fdel(self: Component):
|
||||
"""Delete the property."""
|
||||
self.pop(main_prop, None)
|
||||
self.pop(compatibility_prop, None)
|
||||
|
||||
return property(fget, fset, fdel, doc)
|
||||
|
||||
|
||||
def single_int_property(prop:str, default:int, doc:str) -> property:
|
||||
"""Create a property for an int value that exists only once.
|
||||
|
||||
Args:
|
||||
prop: The name of the property
|
||||
default: The default value
|
||||
doc: The documentation string
|
||||
"""
|
||||
def fget(self: Component) -> int:
|
||||
"""Get the property"""
|
||||
try:
|
||||
return int(self.get(prop, default))
|
||||
except ValueError as e:
|
||||
raise InvalidCalendar(f"{prop} must be an int") from e
|
||||
|
||||
def fset(self: Component, value:int):
|
||||
"""Set the property."""
|
||||
fdel(self)
|
||||
self.add(prop, value)
|
||||
|
||||
def fdel(self: Component):
|
||||
"""Delete the property."""
|
||||
self.pop(prop, None)
|
||||
|
||||
return property(fget, fset, fdel, doc)
|
||||
|
||||
|
||||
def single_utc_property(name: str, docs: str) -> property:
|
||||
"""Create a property to access a value of datetime in UTC timezone.
|
||||
|
||||
Args:
|
||||
name: name of the property
|
||||
docs: documentation string
|
||||
"""
|
||||
docs = (
|
||||
f"""The {name} property. datetime in UTC
|
||||
|
||||
All values will be converted to a datetime in UTC.
|
||||
"""
|
||||
+ docs
|
||||
)
|
||||
|
||||
def fget(self: Component) -> Optional[datetime]:
|
||||
"""Get the value."""
|
||||
if name not in self:
|
||||
return None
|
||||
dt = self.get(name)
|
||||
if isinstance(dt, vText):
|
||||
# we might be in an attribute that is not typed
|
||||
value = vDDDTypes.from_ical(dt)
|
||||
else:
|
||||
value = getattr(dt, "dt", None)
|
||||
if value is None or not isinstance(value, date):
|
||||
raise InvalidCalendar(f"{name} must be a datetime in UTC, not {value}")
|
||||
return tzp.localize_utc(value)
|
||||
|
||||
def fset(self: Component, value: datetime):
|
||||
"""Set the value"""
|
||||
if not isinstance(value, date):
|
||||
raise TypeError(f"{name} takes a datetime in UTC, not {value}")
|
||||
fdel(self)
|
||||
self.add(name, tzp.localize_utc(value))
|
||||
|
||||
def fdel(self: Component):
|
||||
"""Delete the property."""
|
||||
self.pop(name, None)
|
||||
|
||||
return property(fget, fset, fdel, doc=docs)
|
||||
|
||||
|
||||
def single_string_property(name: str, docs: str, other_name:Optional[str]=None) -> property:
|
||||
"""Create a property to access a single string value."""
|
||||
|
||||
def fget(self: Component) -> str:
|
||||
"""Get the value."""
|
||||
result = self.get(name, None if other_name is None else self.get(other_name, None))
|
||||
if result is None or result == []:
|
||||
return ""
|
||||
if isinstance(result, list):
|
||||
return result[0]
|
||||
return result
|
||||
|
||||
def fset(self: Component, value: str):
|
||||
"""Set the value"""
|
||||
fdel(self)
|
||||
self.add(name, value)
|
||||
|
||||
def fdel(self: Component):
|
||||
"""Delete the property."""
|
||||
self.pop(name, None)
|
||||
if other_name is not None:
|
||||
self.pop(other_name, None)
|
||||
|
||||
return property(fget, fset, fdel, doc=docs)
|
||||
|
||||
color_property = single_string_property(
|
||||
"COLOR",
|
||||
"""This property specifies a color used for displaying the component.
|
||||
|
||||
This implements :rfc:`7986` ``COLOR`` property.
|
||||
|
||||
Property Parameters:
|
||||
IANA and non-standard property parameters can
|
||||
be specified on this property.
|
||||
|
||||
Conformance:
|
||||
This property can be specified once in an iCalendar
|
||||
object or in ``VEVENT``, ``VTODO``, or ``VJOURNAL`` calendar components.
|
||||
|
||||
Description:
|
||||
This property specifies a color that clients MAY use
|
||||
when presenting the relevant data to a user. Typically, this
|
||||
would appear as the "background" color of events or tasks. The
|
||||
value is a case-insensitive color name taken from the CSS3 set of
|
||||
names, defined in Section 4.3 of `W3C.REC-css3-color-20110607 <https://www.w3.org/TR/css-color-3/>`_.
|
||||
|
||||
Example:
|
||||
``"turquoise"``, ``"#ffffff"``
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from icalendar import Todo
|
||||
>>> todo = Todo()
|
||||
>>> todo.color = "green"
|
||||
>>> print(todo.to_ical())
|
||||
BEGIN:VTODO
|
||||
COLOR:green
|
||||
END:VTODO
|
||||
"""
|
||||
)
|
||||
|
||||
sequence_property = single_int_property(
|
||||
"SEQUENCE",
|
||||
0,
|
||||
"""This property defines the revision sequence number of the calendar component within a sequence of revisions.
|
||||
|
||||
Value Type:
|
||||
INTEGER
|
||||
|
||||
Property Parameters:
|
||||
IANA and non-standard property parameters can be specified on this property.
|
||||
|
||||
Conformance:
|
||||
The property can be specified in "VEVENT", "VTODO", or
|
||||
"VJOURNAL" calendar component.
|
||||
|
||||
Description:
|
||||
When a calendar component is created, its sequence
|
||||
number is 0. It is monotonically incremented by the "Organizer's"
|
||||
CUA each time the "Organizer" makes a significant revision to the
|
||||
calendar component.
|
||||
|
||||
The "Organizer" includes this property in an iCalendar object that
|
||||
it sends to an "Attendee" to specify the current version of the
|
||||
calendar component.
|
||||
|
||||
The "Attendee" includes this property in an iCalendar object that
|
||||
it sends to the "Organizer" to specify the version of the calendar
|
||||
component to which the "Attendee" is referring.
|
||||
|
||||
A change to the sequence number is not the mechanism that an
|
||||
"Organizer" uses to request a response from the "Attendees". The
|
||||
"RSVP" parameter on the "ATTENDEE" property is used by the
|
||||
"Organizer" to indicate that a response from the "Attendees" is
|
||||
requested.
|
||||
|
||||
Recurrence instances of a recurring component MAY have different
|
||||
sequence numbers.
|
||||
|
||||
Examples:
|
||||
The following is an example of this property for a calendar
|
||||
component that was just created by the "Organizer":
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from icalendar import Event
|
||||
>>> event = Event()
|
||||
>>> event.sequence
|
||||
0
|
||||
|
||||
The following is an example of this property for a calendar
|
||||
component that has been revised 10 different times by the
|
||||
"Organizer":
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from icalendar import Calendar
|
||||
>>> calendar = Calendar.example("issue_156_RDATE_with_PERIOD_TZID_khal")
|
||||
>>> event = calendar.events[0]
|
||||
>>> event.sequence
|
||||
10
|
||||
"""
|
||||
)
|
||||
|
||||
def _get_categories(component: Component) -> list[str]:
|
||||
"""Get all the categories."""
|
||||
categories : Optional[vCategory|list[vCategory]] = component.get("CATEGORIES")
|
||||
if isinstance(categories, list):
|
||||
_set_categories(component, list(itertools.chain.from_iterable(cat.cats for cat in categories)))
|
||||
return _get_categories(component)
|
||||
if categories is None:
|
||||
categories = vCategory([])
|
||||
component.add("CATEGORIES", categories)
|
||||
return categories.cats
|
||||
|
||||
def _set_categories(component: Component, cats: list[str]) -> None:
|
||||
"""Set the categories."""
|
||||
component["CATEGORIES"] = categories = vCategory(cats)
|
||||
cats.clear()
|
||||
cats.extend(categories.cats)
|
||||
categories.cats = cats
|
||||
|
||||
|
||||
def _del_categories(component: Component) -> None:
|
||||
"""Delete the categories."""
|
||||
component.pop("CATEGORIES", None)
|
||||
|
||||
|
||||
categories_property = property(
|
||||
_get_categories,
|
||||
_set_categories,
|
||||
_del_categories,
|
||||
"""This property defines the categories for a component.
|
||||
|
||||
Property Parameters:
|
||||
IANA, non-standard, and language property parameters can be specified on this
|
||||
property.
|
||||
|
||||
Conformance:
|
||||
The property can be specified within "VEVENT", "VTODO", or "VJOURNAL" calendar
|
||||
components.
|
||||
Since :rfc:`7986` it can also be defined on a "VCALENDAR" component.
|
||||
|
||||
Description:
|
||||
This property is used to specify categories or subtypes
|
||||
of the calendar component. The categories are useful in searching
|
||||
for a calendar component of a particular type and category.
|
||||
Within the "VEVENT", "VTODO", or "VJOURNAL" calendar components,
|
||||
more than one category can be specified as a COMMA-separated list
|
||||
of categories.
|
||||
|
||||
Example:
|
||||
Below, we add the categories to an event:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from icalendar import Event
|
||||
>>> event = Event()
|
||||
>>> event.categories = ["Work", "Meeting"]
|
||||
>>> print(event.to_ical())
|
||||
BEGIN:VEVENT
|
||||
CATEGORIES:Work,Meeting
|
||||
END:VEVENT
|
||||
>>> event.categories.append("Lecture")
|
||||
>>> event.categories == ["Work", "Meeting", "Lecture"]
|
||||
True
|
||||
|
||||
.. note::
|
||||
|
||||
At present, we do not take the LANGUAGE parameter into account.
|
||||
"""
|
||||
)
|
||||
|
||||
uid_property = single_string_property(
|
||||
"UID", """UID specifies the persistent, globally unique identifier for a component.
|
||||
|
||||
We recommend using :func:`uuid.uuid4` to generate new values.
|
||||
|
||||
Returns:
|
||||
The value of the UID property as a string or ``""`` if no value is set.
|
||||
|
||||
Description:
|
||||
The "UID" itself MUST be a globally unique identifier.
|
||||
The generator of the identifier MUST guarantee that the identifier
|
||||
is unique.
|
||||
|
||||
This is the method for correlating scheduling messages with the
|
||||
referenced "VEVENT", "VTODO", or "VJOURNAL" calendar component.
|
||||
The full range of calendar components specified by a recurrence
|
||||
set is referenced by referring to just the "UID" property value
|
||||
corresponding to the calendar component. The "RECURRENCE-ID"
|
||||
property allows the reference to an individual instance within the
|
||||
recurrence set.
|
||||
|
||||
This property is an important method for group-scheduling
|
||||
applications to match requests with later replies, modifications,
|
||||
or deletion requests. Calendaring and scheduling applications
|
||||
MUST generate this property in "VEVENT", "VTODO", and "VJOURNAL"
|
||||
calendar components to assure interoperability with other group-
|
||||
scheduling applications. This identifier is created by the
|
||||
calendar system that generates an iCalendar object.
|
||||
|
||||
Implementations MUST be able to receive and persist values of at
|
||||
least 255 octets for this property, but they MUST NOT truncate
|
||||
values in the middle of a UTF-8 multi-octet sequence.
|
||||
|
||||
:rfc:`7986` states that UID can be used, for
|
||||
example, to identify duplicate calendar streams that a client may
|
||||
have been given access to. It can be used in conjunction with the
|
||||
"LAST-MODIFIED" property also specified on the "VCALENDAR" object
|
||||
to identify the most recent version of a calendar.
|
||||
|
||||
Conformance:
|
||||
:rfc:`5545` states that the "UID" property can be specified on "VEVENT", "VTODO",
|
||||
and "VJOURNAL" calendar components.
|
||||
:rfc:`7986` modifies the definition of the "UID" property to
|
||||
allow it to be defined in an iCalendar object.
|
||||
:rfc:`9074` adds a "UID" property to "VALARM" components to allow a unique
|
||||
identifier to be specified. The value of this property can then be used
|
||||
to refer uniquely to the "VALARM" component.
|
||||
|
||||
This property can be specified once only.
|
||||
|
||||
Security:
|
||||
:rfc:`7986` states that UID values MUST NOT include any data that
|
||||
might identify a user, host, domain, or any other security- or
|
||||
privacy-sensitive information. It is RECOMMENDED that calendar user
|
||||
agents now generate "UID" values that are hex-encoded random
|
||||
Universally Unique Identifier (UUID) values as defined in
|
||||
Sections 4.4 and 4.5 of :rfc:`4122`.
|
||||
You can use the :mod:`uuid` module to generate new UUIDs.
|
||||
|
||||
Compatibility:
|
||||
For Alarms, ``X-ALARMUID`` is also considered.
|
||||
|
||||
Examples:
|
||||
The following is an example of such a property value:
|
||||
``5FC53010-1267-4F8E-BC28-1D7AE55A7C99``.
|
||||
|
||||
Set the UID of a calendar:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from icalendar import Calendar
|
||||
>>> from uuid import uuid4
|
||||
>>> calendar = Calendar()
|
||||
>>> calendar.uid = uuid4()
|
||||
>>> print(calendar.to_ical())
|
||||
BEGIN:VCALENDAR
|
||||
UID:d755cef5-2311-46ed-a0e1-6733c9e15c63
|
||||
END:VCALENDAR
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
|
||||
__all__ = [
|
||||
"categories_property",
|
||||
"color_property",
|
||||
"exdates_property",
|
||||
"multi_language_text_property",
|
||||
"rdates_property",
|
||||
"rrules_property",
|
||||
"sequence_property",
|
||||
"single_int_property",
|
||||
"single_utc_property",
|
||||
"uid_property",
|
||||
]
|
||||
Reference in New Issue
Block a user