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, Optional, Sequence 

11 

12from icalendar.attr import ( 

13 categories_property, 

14 contacts_property, 

15 description_property, 

16 duration_property, 

17 exdates_property, 

18 location_property, 

19 rdates_property, 

20 rfc_7953_dtend_property, 

21 rfc_7953_dtstart_property, 

22 rfc_7953_duration_property, 

23 rfc_7953_end_property, 

24 rrules_property, 

25 sequence_property, 

26 summary_property, 

27 uid_property, 

28) 

29from icalendar.cal.examples import get_example 

30from icalendar.error import InvalidCalendar 

31 

32from .component import Component 

33 

34if TYPE_CHECKING: 

35 from datetime import date 

36 

37 

38class Available(Component): 

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

40 

41 Description: 

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

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

44 component. "AVAILABLE" subcomponents MAY include recurrence 

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

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

47 of the "RECURRENCE-ID" property). 

48 

49 Examples: 

50 This is a recurring "AVAILABLE" subcomponent: 

51 

52 .. code-block:: text 

53 

54 BEGIN:AVAILABLE 

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

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

57 DTSTART;TZID=America/Denver:20111023T090000 

58 DTEND;TZID=America/Denver:20111023T170000 

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

60 LOCATION:Denver 

61 END:AVAILABLE 

62 

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

64 

65 .. code-block: pycon 

66 

67 >>> from icalendar import Available 

68 >>> a = Available.example() 

69 >>> str(a.summary) 

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

71 

72 """ 

73 

74 name = "VAVAILABLE" 

75 

76 summary = summary_property 

77 description = description_property 

78 sequence = sequence_property 

79 categories = categories_property 

80 uid = uid_property 

81 location = location_property 

82 contacts = contacts_property 

83 exdates = exdates_property 

84 rdates = rdates_property 

85 rrules = rrules_property 

86 

87 start = DTSTART = rfc_7953_dtstart_property 

88 DTEND = rfc_7953_dtend_property 

89 DURATION = duration_property("Available") 

90 duration = rfc_7953_duration_property 

91 end = rfc_7953_end_property 

92 

93 @classmethod 

94 def new( 

95 cls, 

96 /, 

97 categories: Sequence[str] = (), 

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

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

100 created: Optional[date] = None, 

101 description: Optional[str] = None, 

102 end: Optional[datetime] = None, 

103 last_modified: Optional[date] = None, 

104 location: Optional[str] = None, 

105 sequence: Optional[int] = None, 

106 stamp: Optional[date] = None, 

107 start: Optional[datetime] = None, 

108 summary: Optional[str] = None, 

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

110 ): 

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

112 

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

114 

115 Arguments: 

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

117 comments: The :attr:`Component.comments` of the Available component. 

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

119 created: The :attr:`Component.created` of the Available component. 

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

121 last_modified: The :attr:`Component.last_modified` of the 

122 Available component. 

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

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

125 stamp: The :attr:`Component.stamp` of the Available component. 

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

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

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

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

130 

131 Returns: 

132 :class:`Available` 

133 

134 Raises: 

135 InvalidCalendar: If the content is not valid according to :rfc:`7953`. 

136 

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

138 """ 

139 available = super().new( 

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

141 created=created, 

142 last_modified=last_modified, 

143 ) 

144 available.summary = summary 

145 available.description = description 

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

147 available.sequence = sequence 

148 available.categories = categories 

149 available.location = location 

150 available.comments = comments 

151 available.contacts = contacts 

152 if cls._validate_new: 

153 if end is not None and ( 

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

155 ): 

156 raise InvalidCalendar( 

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

158 ) 

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

160 raise InvalidCalendar( 

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

162 ) 

163 available._validate_start_and_end(start, end) # noqa: SLF001 

164 available.start = start 

165 available.end = end 

166 return available 

167 

168 @classmethod 

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

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

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

172 

173 

174__all__ = ["Available"]