Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/cal/free_busy.py: 63%

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

38 statements  

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

2 

3from __future__ import annotations 

4 

5import uuid 

6from datetime import date, datetime, timedelta 

7from typing import TYPE_CHECKING, Optional 

8 

9from icalendar.attr import ( 

10 CONCEPTS_TYPE_SETTER, 

11 LINKS_TYPE_SETTER, 

12 RELATED_TO_TYPE_SETTER, 

13 contacts_property, 

14 create_single_property, 

15 organizer_property, 

16 uid_property, 

17 url_property, 

18) 

19from icalendar.cal.component import Component 

20 

21if TYPE_CHECKING: 

22 from icalendar.prop import vCalAddress 

23 

24 

25class FreeBusy(Component): 

26 """ 

27 A "VFREEBUSY" calendar component is a grouping of component 

28 properties that represents either a request for free or busy time 

29 information, a reply to a request for free or busy time 

30 information, or a published set of busy time information. 

31 

32 Examples: 

33 Create a new FreeBusy: 

34 

35 >>> from icalendar import FreeBusy 

36 >>> free_busy = FreeBusy.new() 

37 >>> print(free_busy.to_ical()) 

38 BEGIN:VFREEBUSY 

39 DTSTAMP:20250517T080612Z 

40 UID:d755cef5-2311-46ed-a0e1-6733c9e15c63 

41 END:VFREEBUSY 

42 

43 """ 

44 

45 name = "VFREEBUSY" 

46 

47 required = ( 

48 "UID", 

49 "DTSTAMP", 

50 ) 

51 singletons = ( 

52 "CONTACT", 

53 "DTSTART", 

54 "DTEND", 

55 "DTSTAMP", 

56 "ORGANIZER", 

57 "UID", 

58 "URL", 

59 ) 

60 multiple = ( 

61 "ATTENDEE", 

62 "COMMENT", 

63 "FREEBUSY", 

64 "RSTATUS", 

65 ) 

66 uid = uid_property 

67 url = url_property 

68 organizer = organizer_property 

69 contacts = contacts_property 

70 start = DTSTART = create_single_property( 

71 "DTSTART", 

72 "dt", 

73 (datetime, date), 

74 date, 

75 'The "DTSTART" property for a "VFREEBUSY" specifies the inclusive start of the component.', # noqa: E501 

76 ) 

77 end = DTEND = create_single_property( 

78 "DTEND", 

79 "dt", 

80 (datetime, date), 

81 date, 

82 'The "DTEND" property for a "VFREEBUSY" calendar component specifies the non-inclusive end of the component.', # noqa: E501 

83 ) 

84 

85 @property 

86 def duration(self) -> Optional[timedelta]: 

87 """The duration computed from start and end.""" 

88 if self.DTSTART is None or self.DTEND is None: 

89 return None 

90 return self.DTEND - self.DTSTART 

91 

92 @classmethod 

93 def new( 

94 cls, 

95 /, 

96 comments: list[str] | str | None = None, 

97 concepts: CONCEPTS_TYPE_SETTER = None, 

98 contacts: list[str] | str | None = None, 

99 end: Optional[date | datetime] = None, 

100 links: LINKS_TYPE_SETTER = None, 

101 organizer: Optional[vCalAddress | str] = None, 

102 refids: list[str] | str | None = None, 

103 related_to: RELATED_TO_TYPE_SETTER = None, 

104 stamp: Optional[date] = None, 

105 start: Optional[date | datetime] = None, 

106 uid: Optional[str | uuid.UUID] = None, 

107 url: Optional[str] = None, 

108 ): 

109 """Create a new alarm with all required properties. 

110 

111 This creates a new Alarm in accordance with :rfc:`5545`. 

112 

113 Arguments: 

114 comments: The :attr:`~icalendar.Component.comments` of the component. 

115 concepts: The :attr:`~icalendar.Component.concepts` of the component. 

116 contacts: The :attr:`contacts` of the component. 

117 end: The :attr:`end` of the component. 

118 links: The :attr:`~icalendar.Component.links` of the component. 

119 organizer: The :attr:`organizer` of the component. 

120 refids: :attr:`~icalendar.Component.refids` of the component. 

121 related_to: :attr:`~icalendar.Component.related_to` of the component. 

122 stamp: The :attr:`DTSTAMP` of the component. 

123 If None, this is set to the current time. 

124 start: The :attr:`start` of the component. 

125 uid: The :attr:`uid` of the component. 

126 If None, this is set to a new :func:`uuid.uuid4`. 

127 url: The :attr:`url` of the component. 

128 

129 Returns: 

130 :class:`FreeBusy` 

131 

132 Raises: 

133 InvalidCalendar: If the content is not valid according to :rfc:`5545`. 

134 

135 .. warning:: As time progresses, we will be stricter with the validation. 

136 """ 

137 free_busy: FreeBusy = super().new( 

138 stamp=stamp if stamp is not None else cls._utc_now(), 

139 comments=comments, 

140 links=links, 

141 related_to=related_to, 

142 refids=refids, 

143 concepts=concepts, 

144 ) 

145 free_busy.uid = uid if uid is not None else uuid.uuid4() 

146 free_busy.url = url 

147 free_busy.organizer = organizer 

148 free_busy.contacts = contacts 

149 free_busy.end = end 

150 free_busy.start = start 

151 

152 if cls._validate_new: 

153 cls._validate_start_and_end(start, end) 

154 return free_busy 

155 

156 

157__all__ = ["FreeBusy"]