Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/cal/journal.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

77 statements  

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

2 

3from __future__ import annotations 

4 

5import uuid 

6from datetime import date, datetime, timedelta 

7from typing import TYPE_CHECKING, Optional, Sequence 

8 

9from icalendar.attr import ( 

10 CONCEPTS_TYPE_SETTER, 

11 LINKS_TYPE_SETTER, 

12 RELATED_TO_TYPE_SETTER, 

13 attendees_property, 

14 categories_property, 

15 class_property, 

16 color_property, 

17 contacts_property, 

18 create_single_property, 

19 descriptions_property, 

20 exdates_property, 

21 images_property, 

22 organizer_property, 

23 rdates_property, 

24 rrules_property, 

25 sequence_property, 

26 status_property, 

27 summary_property, 

28 uid_property, 

29 url_property, 

30) 

31from icalendar.cal.component import Component 

32from icalendar.error import IncompleteComponent 

33 

34if TYPE_CHECKING: 

35 from icalendar.enums import CLASS, STATUS 

36 from icalendar.prop import vCalAddress 

37 

38 

39class Journal(Component): 

40 """A descriptive text at a certain time or associated with a component. 

41 

42 Description: 

43 A "VJOURNAL" calendar component is a grouping of 

44 component properties that represent one or more descriptive text 

45 notes associated with a particular calendar date. The "DTSTART" 

46 property is used to specify the calendar date with which the 

47 journal entry is associated. Generally, it will have a DATE value 

48 data type, but it can also be used to specify a DATE-TIME value 

49 data type. Examples of a journal entry include a daily record of 

50 a legislative body or a journal entry of individual telephone 

51 contacts for the day or an ordered list of accomplishments for the 

52 day. 

53 

54 Examples: 

55 Create a new Journal: 

56 

57 >>> from icalendar import Journal 

58 >>> journal = Journal.new() 

59 >>> print(journal.to_ical()) 

60 BEGIN:VJOURNAL 

61 DTSTAMP:20250517T080612Z 

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

63 END:VJOURNAL 

64 

65 """ 

66 

67 name = "VJOURNAL" 

68 

69 required = ( 

70 "UID", 

71 "DTSTAMP", 

72 ) 

73 singletons = ( 

74 "CLASS", 

75 "COLOR", 

76 "CREATED", 

77 "DTSTART", 

78 "DTSTAMP", 

79 "LAST-MODIFIED", 

80 "ORGANIZER", 

81 "RECURRENCE-ID", 

82 "SEQUENCE", 

83 "STATUS", 

84 "SUMMARY", 

85 "UID", 

86 "URL", 

87 ) 

88 multiple = ( 

89 "ATTACH", 

90 "ATTENDEE", 

91 "CATEGORIES", 

92 "COMMENT", 

93 "CONTACT", 

94 "EXDATE", 

95 "RELATED", 

96 "RDATE", 

97 "RRULE", 

98 "RSTATUS", 

99 "DESCRIPTION", 

100 ) 

101 

102 DTSTART = create_single_property( 

103 "DTSTART", 

104 "dt", 

105 (datetime, date), 

106 date, 

107 'The "DTSTART" property for a "VJOURNAL" that specifies the exact date at which the journal entry was made.', # noqa: E501 

108 ) 

109 

110 @property 

111 def start(self) -> date: 

112 """The start of the Journal. 

113 

114 The "DTSTART" 

115 property is used to specify the calendar date with which the 

116 journal entry is associated. 

117 """ 

118 start = self.DTSTART 

119 if start is None: 

120 raise IncompleteComponent("No DTSTART given.") 

121 return start 

122 

123 @start.setter 

124 def start(self, value: datetime | date) -> None: 

125 """Set the start of the journal.""" 

126 self.DTSTART = value 

127 

128 end = start 

129 

130 @property 

131 def duration(self) -> timedelta: 

132 """The journal has no duration: timedelta(0).""" 

133 return timedelta(0) 

134 

135 color = color_property 

136 sequence = sequence_property 

137 categories = categories_property 

138 rdates = rdates_property 

139 exdates = exdates_property 

140 rrules = rrules_property 

141 uid = uid_property 

142 

143 summary = summary_property 

144 descriptions = descriptions_property 

145 classification = class_property 

146 url = url_property 

147 organizer = organizer_property 

148 contacts = contacts_property 

149 status = status_property 

150 attendees = attendees_property 

151 

152 @property 

153 def description(self) -> str: 

154 """The concatenated descriptions of the journal. 

155 

156 A Journal can have several descriptions. 

157 This is a compatibility method. 

158 """ 

159 descriptions = self.descriptions 

160 if not descriptions: 

161 return None 

162 return "\r\n\r\n".join(descriptions) 

163 

164 @description.setter 

165 def description(self, description: Optional[str]): 

166 """Set the description""" 

167 self.descriptions = description 

168 

169 @description.deleter 

170 def description(self): 

171 """Delete all descriptions.""" 

172 del self.descriptions 

173 

174 images = images_property 

175 

176 @classmethod 

177 def new( 

178 cls, 

179 /, 

180 attendees: Optional[list[vCalAddress]] = None, 

181 categories: Sequence[str] = (), 

182 classification: Optional[CLASS] = None, 

183 color: Optional[str] = None, 

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

185 concepts: CONCEPTS_TYPE_SETTER = None, 

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

187 created: Optional[date] = None, 

188 description: Optional[str | Sequence[str]] = None, 

189 last_modified: Optional[date] = None, 

190 links: LINKS_TYPE_SETTER = None, 

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

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

193 related_to: RELATED_TO_TYPE_SETTER = None, 

194 sequence: Optional[int] = None, 

195 stamp: Optional[date] = None, 

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

197 status: Optional[STATUS] = None, 

198 summary: Optional[str] = None, 

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

200 url: Optional[str] = None, 

201 ): 

202 """Create a new journal entry with all required properties. 

203 

204 This creates a new Journal in accordance with :rfc:`5545`. 

205 

206 Arguments: 

207 attendees: The :attr:`attendees` of the journal. 

208 categories: The :attr:`categories` of the journal. 

209 classification: The :attr:`classification` of the journal. 

210 color: The :attr:`color` of the journal. 

211 comments: The :attr:`~icalendar.Component.comments` of the journal. 

212 concepts: The :attr:`~icalendar.Component.concepts` of the journal. 

213 contacts: The :attr:`contacts` of the journal. 

214 created: The :attr:`~icalendar.Component.created` of the journal. 

215 description: The :attr:`description` of the journal. 

216 end: The :attr:`end` of the journal. 

217 last_modified: The :attr:`~icalendar.Component.last_modified` of 

218 the journal. 

219 links: The :attr:`~icalendar.Component.links` of the journal. 

220 organizer: The :attr:`organizer` of the journal. 

221 refids: :attr:`~icalendar.Component.refids` of the journal. 

222 related_to: :attr:`~icalendar.Component.related_to` of the journal. 

223 sequence: The :attr:`sequence` of the journal. 

224 stamp: The :attr:`~icalendar.Component.stamp` of the journal. 

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

226 start: The :attr:`start` of the journal. 

227 status: The :attr:`status` of the journal. 

228 summary: The :attr:`summary` of the journal. 

229 uid: The :attr:`uid` of the journal. 

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

231 url: The :attr:`url` of the journal. 

232 

233 Returns: 

234 :class:`Journal` 

235 

236 Raises: 

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

238 

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

240 """ 

241 journal: Journal = super().new( 

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

243 created=created, 

244 last_modified=last_modified, 

245 comments=comments, 

246 links=links, 

247 related_to=related_to, 

248 refids=refids, 

249 concepts=concepts, 

250 ) 

251 journal.summary = summary 

252 journal.descriptions = description 

253 journal.uid = uid if uid is not None else uuid.uuid4() 

254 journal.start = start 

255 journal.color = color 

256 journal.categories = categories 

257 journal.sequence = sequence 

258 journal.classification = classification 

259 journal.url = url 

260 journal.organizer = organizer 

261 journal.contacts = contacts 

262 journal.start = start 

263 journal.status = status 

264 journal.attendees = attendees 

265 

266 return journal 

267 

268 

269__all__ = ["Journal"]