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

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

52 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:: text 

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 

91 start = DTSTART = rfc_7953_dtstart_property 

92 DTEND = rfc_7953_dtend_property 

93 DURATION = duration_property("Available") 

94 duration = rfc_7953_duration_property 

95 end = rfc_7953_end_property 

96 

97 @classmethod 

98 def new( 

99 cls, 

100 /, 

101 categories: Sequence[str] = (), 

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

103 concepts: CONCEPTS_TYPE_SETTER = None, 

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

105 created: date | None = None, 

106 description: str | None = None, 

107 end: datetime | None = None, 

108 last_modified: date | None = None, 

109 links: LINKS_TYPE_SETTER = None, 

110 location: str | None = None, 

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

112 related_to: RELATED_TO_TYPE_SETTER = None, 

113 sequence: int | None = None, 

114 stamp: date | None = None, 

115 start: datetime | None = None, 

116 summary: str | None = None, 

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

118 ): 

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

120 

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

122 

123 Parameters: 

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

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

126 component. 

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

128 component. 

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

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

131 component. 

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

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

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

135 Available component. 

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

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

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

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

140 component. 

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

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

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

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

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

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

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

148 

149 Returns: 

150 :class:`Available` 

151 

152 Raises: 

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

154 according to :rfc:`7953`. 

155 

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

157 """ 

158 available: Available = super().new( 

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

160 created=created, 

161 last_modified=last_modified, 

162 comments=comments, 

163 links=links, 

164 related_to=related_to, 

165 refids=refids, 

166 concepts=concepts, 

167 ) 

168 available.summary = summary 

169 available.description = description 

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

171 available.sequence = sequence 

172 available.categories = categories 

173 available.location = location 

174 available.contacts = contacts 

175 

176 if cls._validate_new: 

177 if end is not None and ( 

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

179 ): 

180 raise InvalidCalendar( 

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

182 ) 

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

184 raise InvalidCalendar( 

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

186 ) 

187 available._validate_start_and_end(start, end) 

188 available.start = start 

189 available.end = end 

190 return available 

191 

192 @classmethod 

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

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

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

196 

197 

198__all__ = ["Available"]