Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
701 lines
26 KiB
Python
701 lines
26 KiB
Python
"""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",
|
|
]
|