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

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

55 statements  

1"""This implements the sub-component "AVAILABLE" of "VAVAILABILITY". 

2 

3This is specified in :rfc:`7953`. 

4""" 

5 

6from __future__ import annotations 

7 

8import uuid 

9from datetime import datetime 

10from typing import TYPE_CHECKING 

11 

12from icalendar.attr import ( 

13 CONCEPTS_TYPE_SETTER, 

14 LINKS_TYPE_SETTER, 

15 RELATED_TO_TYPE_SETTER, 

16 categories_property, 

17 contacts_property, 

18 description_property, 

19 duration_property, 

20 exdates_property, 

21 location_property, 

22 rdates_property, 

23 rfc_7953_dtend_property, 

24 rfc_7953_dtstart_property, 

25 rfc_7953_duration_property, 

26 rfc_7953_end_property, 

27 rrules_property, 

28 sequence_property, 

29 summary_property, 

30 uid_property, 

31) 

32from icalendar.cal.examples import get_example 

33from icalendar.error import InvalidCalendar 

34 

35from .component import Component 

36 

37if TYPE_CHECKING: 

38 from collections.abc import Sequence 

39 from datetime import date 

40 

41 from icalendar.compatibility import Self 

42 

43 

44class Available(Component): 

45 """Sub-component of "VAVAILABILITY from :rfc:`7953`. 

46 

47 Description: 

48 "AVAILABLE" subcomponents are used to indicate periods of free 

49 time within the time range of the enclosing "VAVAILABILITY" 

50 component. "AVAILABLE" subcomponents MAY include recurrence 

51 properties to specify recurring periods of time, which can be 

52 overridden using normal iCalendar recurrence behavior (i.e., use 

53 of the "RECURRENCE-ID" property). 

54 

55 Examples: 

56 This is a recurring "AVAILABLE" subcomponent: 

57 

58 .. code-block:: ics 

59 

60 BEGIN:AVAILABLE 

61 UID:57DD4AAF-3835-46B5-8A39-B3B253157F01 

62 SUMMARY:Monday to Friday from 9:00 to 17:00 

63 DTSTART;TZID=America/Denver:20111023T090000 

64 DTEND;TZID=America/Denver:20111023T170000 

65 RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR 

66 LOCATION:Denver 

67 END:AVAILABLE 

68 

69 You can get the same example from :meth:`example`: 

70 

71 .. code-block: pycon 

72 

73 >>> from icalendar import Available 

74 >>> a = Available.example() 

75 >>> str(a.summary) 

76 'Monday to Friday from 9:00 to 17:00' 

77 

78 """ 

79 

80 name = "AVAILABLE" 

81 

82 summary = summary_property 

83 description = description_property 

84 sequence = sequence_property 

85 categories = categories_property 

86 uid = uid_property 

87 location = location_property 

88 contacts = contacts_property 

89 exdates = exdates_property 

90 rdates = rdates_property 

91 rrules = rrules_property 

92 from icalendar.attr import RECURRENCE_ID 

93 

94 start = DTSTART = rfc_7953_dtstart_property 

95 DTEND = rfc_7953_dtend_property 

96 DURATION = duration_property("Available") 

97 duration = rfc_7953_duration_property 

98 end = rfc_7953_end_property 

99 

100 @classmethod 

101 def new( 

102 cls, 

103 /, 

104 categories: Sequence[str] = (), 

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

106 concepts: CONCEPTS_TYPE_SETTER = None, 

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

108 created: date | None = None, 

109 description: str | None = None, 

110 end: datetime | None = None, 

111 last_modified: date | None = None, 

112 links: LINKS_TYPE_SETTER = None, 

113 location: str | None = None, 

114 recurrence_id: date | datetime | None = None, 

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

116 related_to: RELATED_TO_TYPE_SETTER = None, 

117 sequence: int | None = None, 

118 stamp: date | None = None, 

119 start: datetime | None = None, 

120 summary: str | None = None, 

121 uid: str | uuid.UUID | None = None, 

122 ) -> Self: 

123 """Create a new Available component with all required properties. 

124 

125 This creates a new Available component in accordance with :rfc:`7953`. 

126 

127 Parameters: 

128 categories: The :attr:`categories` of the Available component. 

129 comments: The :attr:`~icalendar.cal.component.Component.comments` of the Available 

130 component. 

131 concepts: The :attr:`~icalendar.cal.component.Component.concepts` of the Available 

132 component. 

133 contacts: The :attr:`contacts` of the Available component. 

134 created: The :attr:`~icalendar.cal.component.Component.created` of the Available 

135 component. 

136 description: The :attr:`description` of the Available component. 

137 end: The :attr:`end` of the Available component. 

138 last_modified: The :attr:`~icalendar.cal.component.Component.last_modified` of the 

139 Available component. 

140 links: The :attr:`~icalendar.cal.component.Component.links` of the Available component. 

141 location: The :attr:`location` of the Available component. 

142 recurrence_id: The :attr:`RECURRENCE_ID` of the Available component. 

143 refids: :attr:`~icalendar.cal.component.Component.refids` of the Available component. 

144 related_to: :attr:`~icalendar.cal.component.Component.related_to` of the Available 

145 component. 

146 sequence: The :attr:`sequence` of the Available component. 

147 stamp: The :attr:`~icalendar.cal.component.Component.stamp` of the Available component. 

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

149 start: The :attr:`start` of the Available component. 

150 summary: The :attr:`summary` of the Available component. 

151 uid: The :attr:`uid` of the Available component. 

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

153 

154 Returns: 

155 :class:`Available` 

156 

157 Raises: 

158 :exc:`~icalendar.error.InvalidCalendar`: If the content is not valid 

159 according to :rfc:`7953`. 

160 

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

162 """ 

163 available: Self = super().new( 

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

165 created=created, 

166 last_modified=last_modified, 

167 comments=comments, 

168 links=links, 

169 related_to=related_to, 

170 refids=refids, 

171 concepts=concepts, 

172 ) 

173 available.summary = summary 

174 available.description = description 

175 available.uid = uid if uid is not None else uuid.uuid4() 

176 available.sequence = sequence 

177 available.categories = categories 

178 available.location = location 

179 available.contacts = contacts 

180 available.RECURRENCE_ID = recurrence_id 

181 

182 if cls._validate_new: 

183 if end is not None and ( 

184 not isinstance(end, datetime) or end.tzinfo is None 

185 ): 

186 raise InvalidCalendar( 

187 "Available end must be a datetime with a timezone" 

188 ) 

189 if not isinstance(start, datetime) or start.tzinfo is None: 

190 raise InvalidCalendar( 

191 "Available start must be a datetime with a timezone" 

192 ) 

193 available._validate_start_and_end(start, end) 

194 available.start = start 

195 available.end = end 

196 return available 

197 

198 @classmethod 

199 def example(cls, name: str = "rfc_7953_1") -> Available: 

200 """Return the calendar example with the given name.""" 

201 return cls.from_ical(get_example("availabilities", name)).available[0] 

202 

203 

204__all__ = ["Available"]