extract-msg 0.48.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. extract_msg/__init__.py +71 -0
  2. extract_msg/__main__.py +115 -0
  3. extract_msg/_rtf/__init__.py +21 -0
  4. extract_msg/_rtf/create_doc.py +29 -0
  5. extract_msg/_rtf/inject_rtf.py +174 -0
  6. extract_msg/_rtf/token.py +35 -0
  7. extract_msg/_rtf/tokenize_rtf.py +253 -0
  8. extract_msg/attachments/__init__.py +144 -0
  9. extract_msg/attachments/attachment.py +188 -0
  10. extract_msg/attachments/attachment_base.py +730 -0
  11. extract_msg/attachments/broken_att.py +42 -0
  12. extract_msg/attachments/custom_att.py +173 -0
  13. extract_msg/attachments/custom_att_handler/__init__.py +80 -0
  14. extract_msg/attachments/custom_att_handler/custom_handler.py +134 -0
  15. extract_msg/attachments/custom_att_handler/lnk_obj_att.py +109 -0
  16. extract_msg/attachments/custom_att_handler/outlook_image_dib.py +141 -0
  17. extract_msg/attachments/emb_msg_att.py +134 -0
  18. extract_msg/attachments/signed_att.py +234 -0
  19. extract_msg/attachments/unsupported_att.py +40 -0
  20. extract_msg/attachments/web_att.py +74 -0
  21. extract_msg/constants/__init__.py +294 -0
  22. extract_msg/constants/ps.py +46 -0
  23. extract_msg/constants/re.py +42 -0
  24. extract_msg/constants/st.py +110 -0
  25. extract_msg/data/logging-config/logging-nt.json +64 -0
  26. extract_msg/data/logging-config/logging-posix.json +64 -0
  27. extract_msg/encoding/__init__.py +277 -0
  28. extract_msg/encoding/_dt/__init__.py +4 -0
  29. extract_msg/encoding/_dt/_mac_ce.py +8 -0
  30. extract_msg/encoding/_dt/_mac_cyrillic.py +8 -0
  31. extract_msg/encoding/_dt/_mac_greek.py +8 -0
  32. extract_msg/encoding/_dt/_mac_iceland.py +8 -0
  33. extract_msg/encoding/_dt/_mac_turkish.py +8 -0
  34. extract_msg/encoding/_dt/_win874_dec.py +8 -0
  35. extract_msg/encoding/_dt/_win950_dec.py +6 -0
  36. extract_msg/encoding/utils.py +329 -0
  37. extract_msg/enums.py +2067 -0
  38. extract_msg/exceptions.py +170 -0
  39. extract_msg/msg_classes/__init__.py +49 -0
  40. extract_msg/msg_classes/appointment.py +195 -0
  41. extract_msg/msg_classes/calendar.py +92 -0
  42. extract_msg/msg_classes/calendar_base.py +496 -0
  43. extract_msg/msg_classes/contact.py +1335 -0
  44. extract_msg/msg_classes/journal.py +131 -0
  45. extract_msg/msg_classes/meeting_cancellation.py +108 -0
  46. extract_msg/msg_classes/meeting_exception.py +55 -0
  47. extract_msg/msg_classes/meeting_forward.py +115 -0
  48. extract_msg/msg_classes/meeting_related.py +65 -0
  49. extract_msg/msg_classes/meeting_request.py +189 -0
  50. extract_msg/msg_classes/meeting_response.py +74 -0
  51. extract_msg/msg_classes/message.py +12 -0
  52. extract_msg/msg_classes/message_base.py +1382 -0
  53. extract_msg/msg_classes/message_signed.py +17 -0
  54. extract_msg/msg_classes/message_signed_base.py +168 -0
  55. extract_msg/msg_classes/msg.py +1172 -0
  56. extract_msg/msg_classes/post.py +53 -0
  57. extract_msg/msg_classes/sticky_note.py +67 -0
  58. extract_msg/msg_classes/task.py +363 -0
  59. extract_msg/msg_classes/task_request.py +86 -0
  60. extract_msg/null_date.py +34 -0
  61. extract_msg/ole_writer.py +1086 -0
  62. extract_msg/open_msg.py +204 -0
  63. extract_msg/properties/__init__.py +23 -0
  64. extract_msg/properties/named.py +481 -0
  65. extract_msg/properties/prop.py +506 -0
  66. extract_msg/properties/properties_store.py +476 -0
  67. extract_msg/py.typed +0 -0
  68. extract_msg/recipient.py +362 -0
  69. extract_msg/structures/__init__.py +34 -0
  70. extract_msg/structures/_helpers.py +345 -0
  71. extract_msg/structures/business_card.py +422 -0
  72. extract_msg/structures/cfoas.py +108 -0
  73. extract_msg/structures/contact_link_entry.py +51 -0
  74. extract_msg/structures/dev_mode_a.py +621 -0
  75. extract_msg/structures/dv_target_device.py +168 -0
  76. extract_msg/structures/entry_id.py +697 -0
  77. extract_msg/structures/misc_id.py +222 -0
  78. extract_msg/structures/mon_stream.py +55 -0
  79. extract_msg/structures/odt.py +74 -0
  80. extract_msg/structures/ole_pres.py +302 -0
  81. extract_msg/structures/ole_stream_struct.py +117 -0
  82. extract_msg/structures/recurrence_pattern.py +199 -0
  83. extract_msg/structures/report_tag.py +127 -0
  84. extract_msg/structures/system_time.py +158 -0
  85. extract_msg/structures/time_zone_definition.py +111 -0
  86. extract_msg/structures/time_zone_struct.py +102 -0
  87. extract_msg/structures/toc_entry.py +137 -0
  88. extract_msg/structures/tz_rule.py +148 -0
  89. extract_msg/utils.py +1270 -0
  90. extract_msg-0.48.2.dist-info/LICENSE.txt +674 -0
  91. extract_msg-0.48.2.dist-info/METADATA +321 -0
  92. extract_msg-0.48.2.dist-info/RECORD +95 -0
  93. extract_msg-0.48.2.dist-info/WHEEL +5 -0
  94. extract_msg-0.48.2.dist-info/entry_points.txt +2 -0
  95. extract_msg-0.48.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,496 @@
1
+ __all__ = [
2
+ 'CalendarBase',
3
+ ]
4
+
5
+
6
+ import datetime
7
+ import enum
8
+ import functools
9
+ import logging
10
+
11
+ from typing import List, Optional, Type, Union
12
+
13
+ from ..constants import ps
14
+ from ..enums import AppointmentAuxilaryFlag, AppointmentColor, AppointmentStateFlag, BusyStatus, IconIndex, MeetingRecipientType, ResponseStatus
15
+ from .message_base import MessageBase
16
+ from ..structures.entry_id import EntryID
17
+ from ..structures.misc_id import GlobalObjectID
18
+ from ..structures.recurrence_pattern import RecurrencePattern
19
+ from ..structures.time_zone_definition import TimeZoneDefinition
20
+ from ..structures.time_zone_struct import TimeZoneStruct
21
+
22
+
23
+ logger = logging.getLogger(__name__)
24
+ logger.addHandler(logging.NullHandler())
25
+
26
+
27
+ class CalendarBase(MessageBase):
28
+ """
29
+ Common base for all Appointment and Meeting objects.
30
+ """
31
+
32
+ @functools.cached_property
33
+ def allAttendeesString(self) -> Optional[str]:
34
+ """
35
+ A list of all attendees, excluding the organizer.
36
+ """
37
+ return self.getNamedProp('8238', ps.PSETID_APPOINTMENT)
38
+
39
+ @functools.cached_property
40
+ def appointmentAuxilaryFlags(self) -> Optional[AppointmentAuxilaryFlag]:
41
+ """
42
+ The auxiliary state of the object.
43
+ """
44
+ return self.getNamedAs('8207', ps.PSETID_APPOINTMENT, AppointmentAuxilaryFlag)
45
+
46
+ @functools.cached_property
47
+ def appointmentColor(self) -> Optional[AppointmentColor]:
48
+ """
49
+ The color to be used when displaying a Calendar object.
50
+ """
51
+ return self.getNamedAs('8214', ps.PSETID_APPOINTMENT, AppointmentColor)
52
+
53
+ @functools.cached_property
54
+ def appointmentDuration(self) -> Optional[int]:
55
+ """
56
+ The length of the event, in minutes.
57
+ """
58
+ return self.getNamedProp('8213', ps.PSETID_APPOINTMENT)
59
+
60
+ @functools.cached_property
61
+ def appointmentEndWhole(self) -> Optional[datetime.datetime]:
62
+ """
63
+ The end date and time of the event in UTC.
64
+ """
65
+ return self.getNamedProp('820E', ps.PSETID_APPOINTMENT)
66
+
67
+ @functools.cached_property
68
+ def appointmentNotAllowPropose(self) -> bool:
69
+ """
70
+ Indicates that attendees are not allowed to propose a new date and/or
71
+ time for the meeting if True.
72
+ """
73
+ return bool(self.getNamedProp('8259', ps.PSETID_APPOINTMENT))
74
+
75
+ @functools.cached_property
76
+ def appointmentRecur(self) -> Optional[RecurrencePattern]:
77
+ """
78
+ Specifies the dates and times when a recurring series occurs by using
79
+ one of the recurrence patterns and ranges specified in this section.
80
+ """
81
+ return self.getNamedAs('8216', ps.PSETID_APPOINTMENT, RecurrencePattern)
82
+
83
+ @functools.cached_property
84
+ def appointmentSequence(self) -> Optional[int]:
85
+ """
86
+ Specified the sequence number of a Meeting object.
87
+
88
+ A meeting object begins with the sequence number set to 0 and is
89
+ incremented each time the organizer sends out a Meeting Update object.
90
+ """
91
+ return self.getNamedProp('8201', ps.PSETID_APPOINTMENT)
92
+
93
+ @functools.cached_property
94
+ def appointmentStartWhole(self) -> Optional[datetime.datetime]:
95
+ """
96
+ The start date and time of the event in UTC.
97
+ """
98
+ return self.getNamedProp('820D', ps.PSETID_APPOINTMENT)
99
+
100
+ @functools.cached_property
101
+ def appointmentStateFlags(self) -> Optional[AppointmentStateFlag]:
102
+ """
103
+ The appointment state of the object.
104
+ """
105
+ return self.getNamedAs('8217', ps.PSETID_APPOINTMENT, AppointmentStateFlag)
106
+
107
+ @functools.cached_property
108
+ def appointmentSubType(self) -> bool:
109
+ """
110
+ Whether the event is an all-day event or not.
111
+ """
112
+ return bool(self.getNamedProp('8215', ps.PSETID_APPOINTMENT))
113
+
114
+ @functools.cached_property
115
+ def appointmentTimeZoneDefinitionEndDisplay(self) -> Optional[TimeZoneDefinition]:
116
+ """
117
+ Specifies the time zone information for the appointmentEndWhole property
118
+ Used to convert the end date and time to and from UTC.
119
+ """
120
+ return self.getNamedAs('825F', ps.PSETID_APPOINTMENT, TimeZoneDefinition)
121
+
122
+ @functools.cached_property
123
+ def appointmentTimeZoneDefinitionRecur(self) -> Optional[TimeZoneDefinition]:
124
+ """
125
+ Specified the time zone information that specifies how to convert the
126
+ meeting date and time on a recurring series to and from UTC.
127
+ """
128
+ return self.getNamedAs('8260', ps.PSETID_APPOINTMENT, TimeZoneDefinition)
129
+
130
+ @functools.cached_property
131
+ def appointmentTimeZoneDefinitionStartDisplay(self) -> Optional[TimeZoneDefinition]:
132
+ """
133
+ Specifies the time zone information for the appointmentStartWhole
134
+ property.
135
+
136
+ Used to convert the start date and time to and from UTC.
137
+ """
138
+ return self.getNamedAs('825E', ps.PSETID_APPOINTMENT, TimeZoneDefinition)
139
+
140
+ @functools.cached_property
141
+ def appointmentUnsendableRecipients(self) -> Optional[bytes]:
142
+ """
143
+ A list of unsendable attendees.
144
+
145
+ Currently the raw bytes for the structure, but will return a usable
146
+ class in the future.
147
+ """
148
+ return self.getNamedProp('825D', ps.PSETID_APPOINTMENT)
149
+
150
+ @functools.cached_property
151
+ def bcc(self) -> Optional[str]:
152
+ """
153
+ Returns the bcc field, if it exists.
154
+ """
155
+ return self._genRecipient('bcc', MeetingRecipientType.SENDABLE_RESOURCE_OBJECT)
156
+
157
+ @functools.cached_property
158
+ def birthdayContactAttributionDisplayName(self) -> Optional[str]:
159
+ """
160
+ Indicated the name of the contact associated with the birthday event.
161
+ """
162
+ return self.getNamedProp('BirthdayContactAttributionDisplayName', ps.PSETID_ADDRESS)
163
+
164
+ @functools.cached_property
165
+ def birthdayContactEntryID(self) -> Optional[EntryID]:
166
+ """
167
+ Indicates the EntryID of the contact associated with the birthday event.
168
+ """
169
+ return self.getNamedAs('BirthdayContactEntryId', ps.PSETID_ADDRESS, EntryID.autoCreate)
170
+
171
+ @functools.cached_property
172
+ def birthdayContactPersonGuid(self) -> Optional[bytes]:
173
+ """
174
+ Indicates the person ID's GUID of the contact associated with the
175
+ birthday event.
176
+ """
177
+ return self.getNamedProp('BirthdayContactPersonGuid', ps.PSETID_ADDRESS)
178
+
179
+ @functools.cached_property
180
+ def busyStatus(self) -> Optional[BusyStatus]:
181
+ """
182
+ Specified the availability of a user for the event described by the
183
+ object.
184
+ """
185
+ return self.getNamedAs('8205', ps.PSETID_APPOINTMENT, BusyStatus)
186
+
187
+ @functools.cached_property
188
+ def cc(self) -> Optional[str]:
189
+ """
190
+ Returns the cc field, if it exists.
191
+ """
192
+ return self._genRecipient('cc', MeetingRecipientType.SENDABLE_OPTIONAL_ATTENDEE)
193
+
194
+ @functools.cached_property
195
+ def ccAttendeesString(self) -> Optional[str]:
196
+ """
197
+ A list of all the sendable attendees, who are also optional attendees.
198
+ """
199
+ return self.getNamedProp('823C', ps.PSETID_APPOINTMENT)
200
+
201
+ @functools.cached_property
202
+ def cleanGlobalObjectID(self) -> Optional[GlobalObjectID]:
203
+ """
204
+ The value of the globalObjectID property for an object that represents
205
+ an Exception object to a recurring series, where the year, month, and
206
+ day fields are all 0.
207
+ """
208
+ return self.getNamedAs('0023', ps.PSETID_MEETING, GlobalObjectID)
209
+
210
+ @functools.cached_property
211
+ def clipEnd(self) -> Optional[datetime.datetime]:
212
+ """
213
+ For single-instance Calendar objects, the end date and time of the
214
+ event in UTC.
215
+
216
+ For a recurring series, midnight in the user's machine time zone, on
217
+ the date of the last instance, then is persisted in UTC, unless the
218
+ recurring series has no end, in which case the value MUST be
219
+ "31 August 4500 11:49 PM".
220
+
221
+ Honestly, not sure what this is. [MS-OXOCAL]: PidLidClipEnd.
222
+ """
223
+ return self.getNamedProp('8236', ps.PSETID_APPOINTMENT)
224
+
225
+ @functools.cached_property
226
+ def clipStart(self) -> Optional[datetime.datetime]:
227
+ """
228
+ For single-instance Calendar objects, the start date and time of the
229
+ event in UTC.
230
+
231
+ For a recurring series, midnight in the user's machine time zone, on
232
+ the date of the first instance, then is persisted in UTC.
233
+
234
+ Honestly, not sure what this is. [MS-OXOCAL]: PidLidClipStart.
235
+ """
236
+ return self.getNamedProp('8235', ps.PSETID_APPOINTMENT)
237
+
238
+ @functools.cached_property
239
+ def commonEnd(self) -> Optional[datetime.datetime]:
240
+ """
241
+ The end date and time of an event.
242
+
243
+ MUST be equal to appointmentEndWhole.
244
+ """
245
+ return self.getNamedProp('8517', ps.PSETID_COMMON)
246
+
247
+ @functools.cached_property
248
+ def commonStart(self) -> Optional[datetime.datetime]:
249
+ """
250
+ The start date and time of an event.
251
+
252
+ MUST be equal to appointmentStartWhole.
253
+ """
254
+ return self.getNamedProp('8516', ps.PSETID_COMMON)
255
+
256
+ @functools.cached_property
257
+ def endDate(self) -> Optional[datetime.datetime]:
258
+ """
259
+ The end date of the appointment.
260
+ """
261
+ return self.getPropertyVal('00610040')
262
+
263
+ @functools.cached_property
264
+ def globalObjectID(self) -> Optional[GlobalObjectID]:
265
+ """
266
+ The unique identifier or the Calendar object.
267
+ """
268
+ return self.getNamedAs('0003', ps.PSETID_MEETING, GlobalObjectID)
269
+
270
+ @functools.cached_property
271
+ def iconIndex(self) -> Optional[Union[IconIndex, int]]:
272
+ """
273
+ The icon to use for the object.
274
+ """
275
+ return self.getPropertyAs('10800003', IconIndex.tryMake)
276
+
277
+ @functools.cached_property
278
+ def isBirthdayContactWritable(self) -> bool:
279
+ """
280
+ Indicates whether the contact associated with the birthday event is
281
+ writable.
282
+ """
283
+ return bool(self.getNamedProp('IsBirthdayContactWritable', ps.PSETID_ADDRESS))
284
+ @functools.cached_property
285
+ def isException(self) -> bool:
286
+ """
287
+ Whether the object represents an exception.
288
+
289
+ ``False`` indicates that the object represents a recurring series or a
290
+ single-instance object.
291
+ """
292
+ return bool(self.getNamedProp('000A', ps.PSETID_MEETING))
293
+
294
+ @functools.cached_property
295
+ def isRecurring(self) -> bool:
296
+ """
297
+ Whether the object is associated with a recurring series.
298
+ """
299
+ return bool(self.getNamedProp('0005', ps.PSETID_MEETING))
300
+
301
+ @functools.cached_property
302
+ def keywords(self) -> Optional[List[str]]:
303
+ """
304
+ The color to be used when displaying a Calendar object.
305
+ """
306
+ return self.getNamedProp('Keywords', ps.PS_PUBLIC_STRINGS)
307
+
308
+ @functools.cached_property
309
+ def linkedTaskItems(self) -> Optional[List[EntryID]]:
310
+ """
311
+ A list of PidTagEntryId properties of Task objects related to the
312
+ Calendar object that are set by a client.
313
+ """
314
+ return self.getNamedAs('820C', ps.PSETID_APPOINTMENT, lambda x: list(EntryID.autoCreate(y) for y in x))
315
+
316
+ @functools.cached_property
317
+ def location(self) -> Optional[str]:
318
+ """
319
+ Returns the location of the meeting.
320
+ """
321
+ return self.getNamedProp('8208', ps.PSETID_APPOINTMENT)
322
+
323
+ @functools.cached_property
324
+ def meetingDoNotForward(self) -> bool:
325
+ """
326
+ Whether to allow the meeting to be forwarded.
327
+
328
+ True disallows forwarding.
329
+ """
330
+ return bool(self.getNamedProp('DoNotForward', ps.PS_PUBLIC_STRINGS))
331
+
332
+ @functools.cached_property
333
+ def meetingWorkspaceUrl(self) -> Optional[str]:
334
+ """
335
+ The URL of the Meeting Workspace, as specified in [MS-MEETS], that is
336
+ associated with a Calendar object.
337
+ """
338
+ return self.getNamedProp('8209', ps.PSETID_APPOINTMENT)
339
+
340
+ @functools.cached_property
341
+ def nonSendableBcc(self) -> Optional[str]:
342
+ """
343
+ A list of all unsendable attendees who are also resource objects.
344
+ """
345
+ return self.getNamedProp('8538', ps.PSETID_COMMON)
346
+
347
+ @functools.cached_property
348
+ def nonSendableCc(self) -> Optional[str]:
349
+ """
350
+ A list of all unsendable attendees who are also optional attendees.
351
+ """
352
+ return self.getNamedProp('8537', ps.PSETID_COMMON)
353
+
354
+ @functools.cached_property
355
+ def nonSendableTo(self) -> Optional[str]:
356
+ """
357
+ A list of all unsendable attendees who are also required attendees.
358
+ """
359
+ return self.getNamedProp('8536', ps.PSETID_COMMON)
360
+
361
+ @functools.cached_property
362
+ def nonSendBccTrackStatus(self) -> Optional[List[ResponseStatus]]:
363
+ """
364
+ A ResponseStatus for each of the attendees in nonSendableBcc.
365
+ """
366
+ return self.getNamedAs('8545', ps.PSETID_COMMON, ResponseStatus.fromIter)
367
+
368
+ @functools.cached_property
369
+ def nonSendCcTrackStatus(self) -> Optional[List[ResponseStatus]]:
370
+ """
371
+ A ResponseStatus for each of the attendees in nonSendableCc.
372
+ """
373
+ return self.getNamedAs('8544', ps.PSETID_COMMON, ResponseStatus.fromIter)
374
+
375
+ @functools.cached_property
376
+ def nonSendToTrackStatus(self) -> Optional[List[ResponseStatus]]:
377
+ """
378
+ A ResponseStatus for each of the attendees in nonSendableTo.
379
+ """
380
+ return self.getNamedAs('8543', ps.PSETID_COMMON, ResponseStatus.fromIter)
381
+
382
+ @functools.cached_property
383
+ def optionalAttendees(self) -> Optional[str]:
384
+ """
385
+ Returns the optional attendees of the meeting.
386
+ """
387
+ return self.getNamedProp('0007', ps.PSETID_MEETING)
388
+
389
+ @property
390
+ def organizer(self) -> Optional[str]:
391
+ """
392
+ The meeting organizer.
393
+ """
394
+ return self.getStringStream('__substg1.0_0042')
395
+
396
+ @functools.cached_property
397
+ def ownerAppointmentID(self) -> Optional[int]:
398
+ """
399
+ A quasi-unique value among all Calendar objects in a user's mailbox.
400
+ Assists a client or server in finding a Calendar object but is not
401
+ guaranteed to be unique among all objects.
402
+ """
403
+ return self.getPropertyVal('00620003')
404
+
405
+ @functools.cached_property
406
+ def ownerCriticalChange(self) -> Optional[datetime.datetime]:
407
+ """
408
+ The date and time at which a Meeting Request object was sent by the
409
+ organizer, in UTC.
410
+ """
411
+ return self.getNamedProp('001A', ps.PSETID_MEETING)
412
+
413
+ @property
414
+ def recipientTypeClass(self) -> Type[enum.IntEnum]:
415
+ return MeetingRecipientType
416
+
417
+ @functools.cached_property
418
+ def recurrencePattern(self) -> Optional[str]:
419
+ """
420
+ A description of the recurrence specified by the appointmentRecur
421
+ property.
422
+ """
423
+ return self.getNamedProp('8232', ps.PSETID_APPOINTMENT)
424
+
425
+ @functools.cached_property
426
+ def recurring(self) -> bool:
427
+ """
428
+ Specifies whether the object represents a recurring series.
429
+ """
430
+ return bool(self.getNamedProp('8223', ps.PSETID_APPOINTMENT))
431
+
432
+ @functools.cached_property
433
+ def replyRequested(self) -> bool:
434
+ """
435
+ Whether the organizer requests a reply from attendees.
436
+ """
437
+ return bool(self.getPropertyVal('0C17000B'))
438
+
439
+ @functools.cached_property
440
+ def requiredAttendees(self) -> Optional[str]:
441
+ """
442
+ Returns the required attendees of the meeting.
443
+ """
444
+ return self.getNamedProp('0006', ps.PSETID_MEETING)
445
+
446
+ @functools.cached_property
447
+ def resourceAttendees(self) -> Optional[str]:
448
+ """
449
+ Returns the resource attendees of the meeting.
450
+ """
451
+ return self.getNamedProp('0008', ps.PSETID_MEETING)
452
+
453
+ @functools.cached_property
454
+ def responseStatus(self) -> ResponseStatus:
455
+ """
456
+ The response status of an attendee.
457
+ """
458
+ return ResponseStatus(self.getNamedProp('8218', ps.PSETID_APPOINTMENT, 0))
459
+
460
+ @functools.cached_property
461
+ def startDate(self) -> Optional[datetime.datetime]:
462
+ """
463
+ The start date of the appointment.
464
+ """
465
+ return self.getPropertyVal('00600040')
466
+
467
+ @functools.cached_property
468
+ def timeZoneDescription(self) -> Optional[str]:
469
+ """
470
+ A human-readable description of the time zone that is represented by the
471
+ data in the timeZoneStruct property.
472
+ """
473
+ return self.getNamedProp('8234', ps.PSETID_APPOINTMENT)
474
+
475
+ @functools.cached_property
476
+ def timeZoneStruct(self) -> Optional[TimeZoneStruct]:
477
+ """
478
+ Set on a recurring series to specify time zone information.
479
+
480
+ Specifies how to convert time fields between local time and UTC.
481
+ """
482
+ return self.getNamedAs('8233', ps.PSETID_APPOINTMENT, TimeZoneStruct)
483
+
484
+ @functools.cached_property
485
+ def to(self) -> Optional[str]:
486
+ """
487
+ Returns the to field, if it exists.
488
+ """
489
+ return self._genRecipient('to', MeetingRecipientType.SENDABLE_REQUIRED_ATTENDEE)
490
+
491
+ @functools.cached_property
492
+ def toAttendeesString(self) -> Optional[str]:
493
+ """
494
+ A list of all the sendable attendees, who are also required attendees.
495
+ """
496
+ return self.getNamedProp('823B', ps.PSETID_APPOINTMENT)