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

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

54 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 

42class Available(Component): 

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

44 

45 Description: 

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

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

48 component. "AVAILABLE" subcomponents MAY include recurrence 

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

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

51 of the "RECURRENCE-ID" property). 

52 

53 Examples: 

54 This is a recurring "AVAILABLE" subcomponent: 

55 

56 .. code-block:: ics 

57 

58 BEGIN:AVAILABLE 

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

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

61 DTSTART;TZID=America/Denver:20111023T090000 

62 DTEND;TZID=America/Denver:20111023T170000 

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

64 LOCATION:Denver 

65 END:AVAILABLE 

66 

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

68 

69 .. code-block: pycon 

70 

71 >>> from icalendar import Available 

72 >>> a = Available.example() 

73 >>> str(a.summary) 

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

75 

76 """ 

77 

78 name = "AVAILABLE" 

79 

80 summary = summary_property 

81 description = description_property 

82 sequence = sequence_property 

83 categories = categories_property 

84 uid = uid_property 

85 location = location_property 

86 contacts = contacts_property 

87 exdates = exdates_property 

88 rdates = rdates_property 

89 rrules = rrules_property 

90 from icalendar.attr import RECURRENCE_ID 

91 

92 start = DTSTART = rfc_7953_dtstart_property 

93 DTEND = rfc_7953_dtend_property 

94 DURATION = duration_property("Available") 

95 duration = rfc_7953_duration_property 

96 end = rfc_7953_end_property 

97 

98 @classmethod 

99 def new( 

100 cls, 

101 /, 

102 categories: Sequence[str] = (), 

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

104 concepts: CONCEPTS_TYPE_SETTER = None, 

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

106 created: date | None = None, 

107 description: str | None = None, 

108 end: datetime | None = None, 

109 last_modified: date | None = None, 

110 links: LINKS_TYPE_SETTER = None, 

111 location: str | None = None, 

112 recurrence_id: date | datetime | None = None, 

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

114 related_to: RELATED_TO_TYPE_SETTER = None, 

115 sequence: int | None = None, 

116 stamp: date | None = None, 

117 start: datetime | None = None, 

118 summary: str | None = None, 

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

120 ): 

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

122 

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

124 

125 Parameters: 

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

127 comments: The :attr:`~icalendar.Component.comments` of the Available 

128 component. 

129 concepts: The :attr:`~icalendar.Component.concepts` of the Available 

130 component. 

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

132 created: The :attr:`~icalendar.Component.created` of the Available 

133 component. 

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

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

136 last_modified: The :attr:`~icalendar.Component.last_modified` of the 

137 Available component. 

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

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

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

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

142 related_to: :attr:`~icalendar.Component.related_to` of the Available 

143 component. 

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

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

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

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

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

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

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

151 

152 Returns: 

153 :class:`Available` 

154 

155 Raises: 

156 ~error.InvalidCalendar: If the content is not valid 

157 according to :rfc:`7953`. 

158 

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

160 """ 

161 available: Available = super().new( 

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

163 created=created, 

164 last_modified=last_modified, 

165 comments=comments, 

166 links=links, 

167 related_to=related_to, 

168 refids=refids, 

169 concepts=concepts, 

170 ) 

171 available.summary = summary 

172 available.description = description 

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

174 available.sequence = sequence 

175 available.categories = categories 

176 available.location = location 

177 available.contacts = contacts 

178 available.RECURRENCE_ID = recurrence_id 

179 

180 if cls._validate_new: 

181 if end is not None and ( 

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

183 ): 

184 raise InvalidCalendar( 

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

186 ) 

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

188 raise InvalidCalendar( 

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

190 ) 

191 available._validate_start_and_end(start, end) 

192 available.start = start 

193 available.end = end 

194 return available 

195 

196 @classmethod 

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

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

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

200 

201 

202__all__ = ["Available"]