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

89 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 

8 

9from icalendar.attr import ( 

10 ATTACHMENTS_TYPE_SETTER, 

11 ATTENDEE_TYPE_SETTER, 

12 CONCEPTS_TYPE_SETTER, 

13 LINKS_TYPE_SETTER, 

14 RELATED_TO_TYPE_SETTER, 

15 REQUEST_STATUS_property, 

16 attachments_property, 

17 attendees_property, 

18 categories_property, 

19 class_property, 

20 color_property, 

21 contacts_property, 

22 create_single_property, 

23 descriptions_property, 

24 exdates_property, 

25 images_property, 

26 organizer_property, 

27 rdates_property, 

28 rrules_property, 

29 sequence_property, 

30 status_property, 

31 summary_property, 

32 uid_property, 

33 url_property, 

34) 

35from icalendar.cal.component import Component 

36from icalendar.cal.examples import get_example 

37from icalendar.error import IncompleteComponent 

38 

39if TYPE_CHECKING: 

40 from collections.abc import Sequence 

41 

42 from icalendar.compatibility import Self 

43 from icalendar.enums import CLASS, STATUS 

44 from icalendar.prop import vCalAddress 

45 

46 

47class Journal(Component): 

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

49 

50 Description: 

51 A "VJOURNAL" calendar component is a grouping of 

52 component properties that represent one or more descriptive text 

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

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

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

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

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

58 a legislative body or a journal entry of individual telephone 

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

60 day. 

61 

62 Examples: 

63 Create a new Journal: 

64 

65 >>> from icalendar import Journal 

66 >>> journal = Journal.new() 

67 >>> print(journal.to_ical()) 

68 BEGIN:VJOURNAL 

69 DTSTAMP:20250517T080612Z 

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

71 END:VJOURNAL 

72 

73 Get the example Journal. 

74 

75 .. code-block:: pycon 

76 

77 >>> from icalendar import Journal 

78 >>> journal = Journal.example() 

79 >>> print(journal.to_ical().decode()) 

80 BEGIN:VJOURNAL 

81 DESCRIPTION:Aurora project plans were reviewed. 

82 DTSTAMP:19970901T130000Z 

83 DTSTART;VALUE=DATE:19970317 

84 SUMMARY:Staff meeting minutes 

85 UID:19970901T130000Z-123405@example.com 

86 END:VJOURNAL 

87 

88 """ 

89 

90 name = "VJOURNAL" 

91 

92 required = ( 

93 "UID", 

94 "DTSTAMP", 

95 ) 

96 singletons = ( 

97 "CLASS", 

98 "COLOR", 

99 "CREATED", 

100 "DTSTART", 

101 "DTSTAMP", 

102 "LAST-MODIFIED", 

103 "ORGANIZER", 

104 "RECURRENCE-ID", 

105 "SEQUENCE", 

106 "STATUS", 

107 "SUMMARY", 

108 "UID", 

109 "URL", 

110 ) 

111 multiple = ( 

112 "ATTACH", 

113 "ATTENDEE", 

114 "CATEGORIES", 

115 "COMMENT", 

116 "CONTACT", 

117 "EXDATE", 

118 "RELATED", 

119 "RDATE", 

120 "RRULE", 

121 "REQUEST-STATUS", 

122 "DESCRIPTION", 

123 ) 

124 

125 DTSTART = create_single_property( 

126 "DTSTART", 

127 "dt", 

128 (datetime, date), 

129 date, 

130 'The "DTSTART" property for a "VJOURNAL" that specifies the exact date at which the journal entry was made.', 

131 ) 

132 

133 @property 

134 def start(self) -> date: 

135 """The start of the Journal. 

136 

137 The "DTSTART" 

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

139 journal entry is associated. 

140 """ 

141 start = self.DTSTART 

142 if start is None: 

143 raise IncompleteComponent("No DTSTART given.") 

144 return start 

145 

146 @start.setter 

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

148 """Set the start of the journal.""" 

149 self.DTSTART = value 

150 

151 end = start 

152 

153 @property 

154 def duration(self) -> timedelta: 

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

156 return timedelta(0) 

157 

158 color = color_property 

159 sequence = sequence_property 

160 categories = categories_property 

161 rdates = rdates_property 

162 exdates = exdates_property 

163 rrules = rrules_property 

164 REQUEST_STATUS = REQUEST_STATUS_property 

165 uid = uid_property 

166 

167 summary = summary_property 

168 descriptions = descriptions_property 

169 classification = class_property 

170 url = url_property 

171 organizer = organizer_property 

172 contacts = contacts_property 

173 status = status_property 

174 attendees = attendees_property 

175 attachments = attachments_property 

176 from icalendar.attr import RECURRENCE_ID 

177 

178 @property 

179 def description(self) -> str: 

180 """The concatenated descriptions of the journal. 

181 

182 A Journal can have several descriptions. 

183 This is a compatibility method. 

184 """ 

185 descriptions = self.descriptions 

186 if not descriptions: 

187 return None 

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

189 

190 @description.setter 

191 def description(self, description: str | None): 

192 """Set the description""" 

193 self.descriptions = description 

194 

195 @description.deleter 

196 def description(self): 

197 """Delete all descriptions.""" 

198 del self.descriptions 

199 

200 images = images_property 

201 

202 @classmethod 

203 def new( 

204 cls, 

205 /, 

206 attachments: ATTACHMENTS_TYPE_SETTER = None, 

207 attendees: ATTENDEE_TYPE_SETTER = None, 

208 categories: Sequence[str] = (), 

209 classification: CLASS | None = None, 

210 color: str | None = None, 

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

212 concepts: CONCEPTS_TYPE_SETTER = None, 

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

214 created: date | None = None, 

215 description: str | Sequence[str] | None = None, 

216 last_modified: date | None = None, 

217 links: LINKS_TYPE_SETTER = None, 

218 organizer: vCalAddress | str | None = None, 

219 recurrence_id: date | datetime | None = None, 

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

221 related_to: RELATED_TO_TYPE_SETTER = None, 

222 request_status: list[str] | str | None = None, 

223 sequence: int | None = None, 

224 stamp: date | None = None, 

225 start: date | datetime | None = None, 

226 status: STATUS | None = None, 

227 summary: str | None = None, 

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

229 url: str | None = None, 

230 ) -> Self: 

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

232 

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

234 

235 Parameters: 

236 attachments: The :attr:`attachments` of the journal. 

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

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

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

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

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

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

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

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

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

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

247 the journal. 

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

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

250 recurrence_id: The :attr:`RECURRENCE_ID` of the journal. 

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

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

253 request_status: The :attr:`REQUEST_STATUS` of the journal. 

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

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

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

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

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

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

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

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

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

263 

264 Returns: 

265 :class:`Journal` 

266 

267 Raises: 

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

269 according to :rfc:`5545`. 

270 

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

272 """ 

273 journal: Self = super().new( 

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

275 created=created, 

276 last_modified=last_modified, 

277 comments=comments, 

278 links=links, 

279 related_to=related_to, 

280 refids=refids, 

281 concepts=concepts, 

282 ) 

283 journal.summary = summary 

284 journal.descriptions = description 

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

286 journal.start = start 

287 journal.color = color 

288 journal.categories = categories 

289 journal.sequence = sequence 

290 journal.classification = classification 

291 journal.url = url 

292 journal.organizer = organizer 

293 journal.attachments = attachments 

294 journal.contacts = contacts 

295 journal.start = start 

296 journal.status = status 

297 journal.REQUEST_STATUS = request_status 

298 journal.attendees = attendees 

299 journal.RECURRENCE_ID = recurrence_id 

300 

301 return journal 

302 

303 @classmethod 

304 def example(cls, name: str = "example") -> Journal: 

305 """Return the journal example with the given name.""" 

306 return cls.from_ical(get_example("journals", name)) 

307 

308 

309__all__ = ["Journal"]