Source code for icalendar.cal.free_busy

""":rfc:`5545` VFREEBUSY component."""

from __future__ import annotations

import uuid
from datetime import date, datetime, timedelta
from typing import TYPE_CHECKING, Optional

from icalendar.attr import (
    contacts_property,
    create_single_property,
    organizer_property,
    uid_property,
    url_property,
)
from icalendar.cal.component import Component

if TYPE_CHECKING:
    from icalendar.prop import vCalAddress


[docs] class FreeBusy(Component): """ A "VFREEBUSY" calendar component is a grouping of component properties that represents either a request for free or busy time information, a reply to a request for free or busy time information, or a published set of busy time information. Examples: Create a new FreeBusy: >>> from icalendar import FreeBusy >>> free_busy = FreeBusy.new() >>> print(free_busy.to_ical()) BEGIN:VFREEBUSY DTSTAMP:20250517T080612Z UID:d755cef5-2311-46ed-a0e1-6733c9e15c63 END:VFREEBUSY """ name = "VFREEBUSY" required = ( "UID", "DTSTAMP", ) singletons = ( "CONTACT", "DTSTART", "DTEND", "DTSTAMP", "ORGANIZER", "UID", "URL", ) multiple = ( "ATTENDEE", "COMMENT", "FREEBUSY", "RSTATUS", ) uid = uid_property url = url_property organizer = organizer_property contacts = contacts_property start = DTSTART = create_single_property( "DTSTART", "dt", (datetime, date), date, 'The "DTSTART" property for a "VFREEBUSY" specifies the inclusive start of the component.', # noqa: E501 ) end = DTEND = create_single_property( "DTEND", "dt", (datetime, date), date, 'The "DTEND" property for a "VFREEBUSY" calendar component specifies the non-inclusive end of the component.', # noqa: E501 ) @property def duration(self) -> Optional[timedelta]: """The duration computed from start and end.""" if self.DTSTART is None or self.DTEND is None: return None return self.DTEND - self.DTSTART
[docs] @classmethod def new( cls, /, comments: list[str] | str | None = None, contacts: list[str] | str | None = None, end: Optional[date | datetime] = None, organizer: Optional[vCalAddress | str] = None, stamp: Optional[date] = None, start: Optional[date | datetime] = None, uid: Optional[str | uuid.UUID] = None, url: Optional[str] = None, ): """Create a new alarm with all required properties. This creates a new Alarm in accordance with :rfc:`5545`. Arguments: comments: The :attr:`Component.comments` of the component. organizer: The :attr:`organizer` of the component. stamp: The :attr:`DTSTAMP` of the component. If None, this is set to the current time. uid: The :attr:`uid` of the component. If None, this is set to a new :func:`uuid.uuid4`. url: The :attr:`url` of the component. Returns: :class:`FreeBusy` Raises: InvalidCalendar: If the content is not valid according to :rfc:`5545`. .. warning:: As time progresses, we will be stricter with the validation. """ free_busy = super().new( stamp=stamp if stamp is not None else cls._utc_now(), comments=comments ) free_busy.uid = uid if uid is not None else uuid.uuid4() free_busy.url = url free_busy.organizer = organizer free_busy.contacts = contacts free_busy.end = end free_busy.start = start if cls._validate_new: cls._validate_start_and_end(start, end) return free_busy
__all__ = ["FreeBusy"]