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.
- extract_msg/__init__.py +71 -0
- extract_msg/__main__.py +115 -0
- extract_msg/_rtf/__init__.py +21 -0
- extract_msg/_rtf/create_doc.py +29 -0
- extract_msg/_rtf/inject_rtf.py +174 -0
- extract_msg/_rtf/token.py +35 -0
- extract_msg/_rtf/tokenize_rtf.py +253 -0
- extract_msg/attachments/__init__.py +144 -0
- extract_msg/attachments/attachment.py +188 -0
- extract_msg/attachments/attachment_base.py +730 -0
- extract_msg/attachments/broken_att.py +42 -0
- extract_msg/attachments/custom_att.py +173 -0
- extract_msg/attachments/custom_att_handler/__init__.py +80 -0
- extract_msg/attachments/custom_att_handler/custom_handler.py +134 -0
- extract_msg/attachments/custom_att_handler/lnk_obj_att.py +109 -0
- extract_msg/attachments/custom_att_handler/outlook_image_dib.py +141 -0
- extract_msg/attachments/emb_msg_att.py +134 -0
- extract_msg/attachments/signed_att.py +234 -0
- extract_msg/attachments/unsupported_att.py +40 -0
- extract_msg/attachments/web_att.py +74 -0
- extract_msg/constants/__init__.py +294 -0
- extract_msg/constants/ps.py +46 -0
- extract_msg/constants/re.py +42 -0
- extract_msg/constants/st.py +110 -0
- extract_msg/data/logging-config/logging-nt.json +64 -0
- extract_msg/data/logging-config/logging-posix.json +64 -0
- extract_msg/encoding/__init__.py +277 -0
- extract_msg/encoding/_dt/__init__.py +4 -0
- extract_msg/encoding/_dt/_mac_ce.py +8 -0
- extract_msg/encoding/_dt/_mac_cyrillic.py +8 -0
- extract_msg/encoding/_dt/_mac_greek.py +8 -0
- extract_msg/encoding/_dt/_mac_iceland.py +8 -0
- extract_msg/encoding/_dt/_mac_turkish.py +8 -0
- extract_msg/encoding/_dt/_win874_dec.py +8 -0
- extract_msg/encoding/_dt/_win950_dec.py +6 -0
- extract_msg/encoding/utils.py +329 -0
- extract_msg/enums.py +2067 -0
- extract_msg/exceptions.py +170 -0
- extract_msg/msg_classes/__init__.py +49 -0
- extract_msg/msg_classes/appointment.py +195 -0
- extract_msg/msg_classes/calendar.py +92 -0
- extract_msg/msg_classes/calendar_base.py +496 -0
- extract_msg/msg_classes/contact.py +1335 -0
- extract_msg/msg_classes/journal.py +131 -0
- extract_msg/msg_classes/meeting_cancellation.py +108 -0
- extract_msg/msg_classes/meeting_exception.py +55 -0
- extract_msg/msg_classes/meeting_forward.py +115 -0
- extract_msg/msg_classes/meeting_related.py +65 -0
- extract_msg/msg_classes/meeting_request.py +189 -0
- extract_msg/msg_classes/meeting_response.py +74 -0
- extract_msg/msg_classes/message.py +12 -0
- extract_msg/msg_classes/message_base.py +1382 -0
- extract_msg/msg_classes/message_signed.py +17 -0
- extract_msg/msg_classes/message_signed_base.py +168 -0
- extract_msg/msg_classes/msg.py +1172 -0
- extract_msg/msg_classes/post.py +53 -0
- extract_msg/msg_classes/sticky_note.py +67 -0
- extract_msg/msg_classes/task.py +363 -0
- extract_msg/msg_classes/task_request.py +86 -0
- extract_msg/null_date.py +34 -0
- extract_msg/ole_writer.py +1086 -0
- extract_msg/open_msg.py +204 -0
- extract_msg/properties/__init__.py +23 -0
- extract_msg/properties/named.py +481 -0
- extract_msg/properties/prop.py +506 -0
- extract_msg/properties/properties_store.py +476 -0
- extract_msg/py.typed +0 -0
- extract_msg/recipient.py +362 -0
- extract_msg/structures/__init__.py +34 -0
- extract_msg/structures/_helpers.py +345 -0
- extract_msg/structures/business_card.py +422 -0
- extract_msg/structures/cfoas.py +108 -0
- extract_msg/structures/contact_link_entry.py +51 -0
- extract_msg/structures/dev_mode_a.py +621 -0
- extract_msg/structures/dv_target_device.py +168 -0
- extract_msg/structures/entry_id.py +697 -0
- extract_msg/structures/misc_id.py +222 -0
- extract_msg/structures/mon_stream.py +55 -0
- extract_msg/structures/odt.py +74 -0
- extract_msg/structures/ole_pres.py +302 -0
- extract_msg/structures/ole_stream_struct.py +117 -0
- extract_msg/structures/recurrence_pattern.py +199 -0
- extract_msg/structures/report_tag.py +127 -0
- extract_msg/structures/system_time.py +158 -0
- extract_msg/structures/time_zone_definition.py +111 -0
- extract_msg/structures/time_zone_struct.py +102 -0
- extract_msg/structures/toc_entry.py +137 -0
- extract_msg/structures/tz_rule.py +148 -0
- extract_msg/utils.py +1270 -0
- extract_msg-0.48.2.dist-info/LICENSE.txt +674 -0
- extract_msg-0.48.2.dist-info/METADATA +321 -0
- extract_msg-0.48.2.dist-info/RECORD +95 -0
- extract_msg-0.48.2.dist-info/WHEEL +5 -0
- extract_msg-0.48.2.dist-info/entry_points.txt +2 -0
- extract_msg-0.48.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1335 @@
|
|
|
1
|
+
__all__ = [
|
|
2
|
+
'Contact',
|
|
3
|
+
]
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import datetime
|
|
7
|
+
import functools
|
|
8
|
+
import io
|
|
9
|
+
import json
|
|
10
|
+
|
|
11
|
+
from typing import Dict, List, Optional, Set, Tuple, Union
|
|
12
|
+
|
|
13
|
+
from ..constants import HEADER_FORMAT_TYPE, ps
|
|
14
|
+
from ..enums import (
|
|
15
|
+
ContactLinkState, ElectronicAddressProperties, Gender,
|
|
16
|
+
InsecureFeatures, PostalAddressID
|
|
17
|
+
)
|
|
18
|
+
from ..exceptions import SecurityError
|
|
19
|
+
from .message_base import MessageBase
|
|
20
|
+
from ..structures.business_card import BusinessCardDisplayDefinition
|
|
21
|
+
from ..structures.entry_id import EntryID
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# I would use TypeAlias, but my type checker *really* hates that.
|
|
25
|
+
_EMAIL_DICT = Dict[str, Optional[Union[str, EntryID]]]
|
|
26
|
+
_FAX_DICT = _EMAIL_DICT
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Contact(MessageBase):
|
|
30
|
+
"""
|
|
31
|
+
Class used for parsing contacts.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def getJson(self) -> str:
|
|
35
|
+
# To save a lot of trouble and repetiion, just return a JSON version of
|
|
36
|
+
# the header format properties.
|
|
37
|
+
return json.dumps(self.headerFormatProperties)
|
|
38
|
+
|
|
39
|
+
@functools.cached_property
|
|
40
|
+
def account(self) -> Optional[str]:
|
|
41
|
+
"""
|
|
42
|
+
The account name of the contact.
|
|
43
|
+
"""
|
|
44
|
+
return self.getStringStream('__substg1.0_3A00')
|
|
45
|
+
|
|
46
|
+
@functools.cached_property
|
|
47
|
+
def addressBookProviderArrayType(self) -> Optional[ElectronicAddressProperties]:
|
|
48
|
+
"""
|
|
49
|
+
A union of which Electronic Address properties are set on the contact.
|
|
50
|
+
|
|
51
|
+
Property is stored in the MSG file as a sinlge int. The result should be
|
|
52
|
+
a union of the flags specified by addressBookProviderEmailList.
|
|
53
|
+
"""
|
|
54
|
+
return self.getNamedAs('8029', ps.PSETID_ADDRESS, ElectronicAddressProperties)
|
|
55
|
+
|
|
56
|
+
@functools.cached_property
|
|
57
|
+
def addressBookProviderEmailList(self) -> Optional[Set[ElectronicAddressProperties]]:
|
|
58
|
+
"""
|
|
59
|
+
A set of which Electronic Address properties are set on the contact.
|
|
60
|
+
"""
|
|
61
|
+
return self.getNamedAs('8028', ps.PSETID_ADDRESS, ElectronicAddressProperties.fromIter)
|
|
62
|
+
|
|
63
|
+
@functools.cached_property
|
|
64
|
+
def assistant(self) -> Optional[str]:
|
|
65
|
+
"""
|
|
66
|
+
The name of the contact's assistant.
|
|
67
|
+
"""
|
|
68
|
+
return self.getStringStream('__substg1.0_3A30')
|
|
69
|
+
|
|
70
|
+
@functools.cached_property
|
|
71
|
+
def assistantTelephoneNumber(self) -> Optional[str]:
|
|
72
|
+
"""
|
|
73
|
+
Contains the telephone number of the contact's administrative assistant.
|
|
74
|
+
"""
|
|
75
|
+
return self.getStringStream('__substg1.0_3A2E')
|
|
76
|
+
|
|
77
|
+
@functools.cached_property
|
|
78
|
+
def autoLog(self) -> bool:
|
|
79
|
+
"""
|
|
80
|
+
Whether the client should create a Journal object for each action
|
|
81
|
+
associated with the Contact object.
|
|
82
|
+
"""
|
|
83
|
+
return bool(self.getNamedProp('8025', ps.PSETID_ADDRESS))
|
|
84
|
+
|
|
85
|
+
@functools.cached_property
|
|
86
|
+
def billing(self) -> Optional[str]:
|
|
87
|
+
"""
|
|
88
|
+
Billing information for the contact.
|
|
89
|
+
"""
|
|
90
|
+
return self.getNamedProp('8535', ps.PSETID_COMMON)
|
|
91
|
+
|
|
92
|
+
@functools.cached_property
|
|
93
|
+
def birthday(self) -> Optional[datetime.datetime]:
|
|
94
|
+
"""
|
|
95
|
+
The birthday of the contact at 11:59 UTC.
|
|
96
|
+
"""
|
|
97
|
+
return self.getPropertyVal('3A420040')
|
|
98
|
+
|
|
99
|
+
@functools.cached_property
|
|
100
|
+
def birthdayEventEntryID(self) -> Optional[EntryID]:
|
|
101
|
+
"""
|
|
102
|
+
The EntryID of an optional Appointement object that represents the
|
|
103
|
+
contact's birtday.
|
|
104
|
+
"""
|
|
105
|
+
return self.getNamedAs('804D', ps.PSETID_ADDRESS, EntryID.autoCreate)
|
|
106
|
+
|
|
107
|
+
@functools.cached_property
|
|
108
|
+
def birthdayLocal(self) -> Optional[datetime.datetime]:
|
|
109
|
+
"""
|
|
110
|
+
The birthday of the contact at 0:00 in the client's local time zone.
|
|
111
|
+
"""
|
|
112
|
+
return self.getNamedProp('80DE', ps.PSETID_ADDRESS)
|
|
113
|
+
|
|
114
|
+
@functools.cached_property
|
|
115
|
+
def businessCard(self) -> bytes:
|
|
116
|
+
if InsecureFeatures.PIL_IMAGE_PARSING not in self.insecureFeatures:
|
|
117
|
+
return SecurityError('PIL_IMAGE_PARSING must be enabled to create a business card image.')
|
|
118
|
+
# First import PIL here so it's an optional dependency.
|
|
119
|
+
try:
|
|
120
|
+
import PIL.Image
|
|
121
|
+
import PIL.ImageDraw
|
|
122
|
+
except ImportError:
|
|
123
|
+
raise ImportError('PIL or Pillow is required for generating the business card.') from None
|
|
124
|
+
|
|
125
|
+
raise NotImplementedError('This function is not complete and as such is not yet functional. Please wait until later in the work cycle for this version.')
|
|
126
|
+
|
|
127
|
+
# See "contact business card details.txt" for details.
|
|
128
|
+
cardDef = self.businessCardDisplayDefinition
|
|
129
|
+
# First things first, let's make the image we will be placing everything
|
|
130
|
+
# onto.
|
|
131
|
+
im = PIL.Image.new('RGB', (250, 150), cardDef.backgroundColor)
|
|
132
|
+
# Create the ImageDraw instance so we can draw on it easily.
|
|
133
|
+
imDraw = PIL.ImageDraw.ImageDraw(im)
|
|
134
|
+
|
|
135
|
+
# Create the border of the image:
|
|
136
|
+
imDraw.rectangle(((0, 0), (249, 149)), outline = (109, 109, 109))
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# Finally, return the image.
|
|
140
|
+
out = io.BytesIO()
|
|
141
|
+
im.save(out, 'png')
|
|
142
|
+
return out
|
|
143
|
+
|
|
144
|
+
@functools.cached_property
|
|
145
|
+
def businessCardCardPicture(self) -> Optional[bytes]:
|
|
146
|
+
"""
|
|
147
|
+
The image to be used on a business card.
|
|
148
|
+
|
|
149
|
+
Must be either a PNG file or a JPEG file.
|
|
150
|
+
"""
|
|
151
|
+
return self.getNamedProp('8041', ps.PSETID_ADDRESS)
|
|
152
|
+
|
|
153
|
+
@functools.cached_property
|
|
154
|
+
def businessCardDisplayDefinition(self) -> Optional[BusinessCardDisplayDefinition]:
|
|
155
|
+
"""
|
|
156
|
+
Specifies the customization details for displaying a contact as a
|
|
157
|
+
business card.
|
|
158
|
+
"""
|
|
159
|
+
return self.getNamedAs('8040', ps.PSETID_ADDRESS, BusinessCardDisplayDefinition)
|
|
160
|
+
|
|
161
|
+
@functools.cached_property
|
|
162
|
+
def businessFax(self) -> Optional[_FAX_DICT]:
|
|
163
|
+
"""
|
|
164
|
+
Returns a ``dict`` of the data for the business fax.
|
|
165
|
+
|
|
166
|
+
Returns ``None`` if no fields are set.
|
|
167
|
+
|
|
168
|
+
Keys are "address_type", "email_address", "number",
|
|
169
|
+
"original_display_name", and "original_entry_id".
|
|
170
|
+
"""
|
|
171
|
+
data = {
|
|
172
|
+
'address_type': self.businessFaxAddressType,
|
|
173
|
+
'email_address': self.businessFaxEmailAddress,
|
|
174
|
+
'number': self.businessFaxNumber,
|
|
175
|
+
'original_display_name': self.businessFaxOriginalDisplayName,
|
|
176
|
+
'original_entry_id': self.businessFaxOriginalEntryId,
|
|
177
|
+
}
|
|
178
|
+
return data if any(data[x] for x in data) else None
|
|
179
|
+
|
|
180
|
+
@functools.cached_property
|
|
181
|
+
def businessFaxAddressType(self) -> Optional[str]:
|
|
182
|
+
"""
|
|
183
|
+
The type of address for the fax.
|
|
184
|
+
|
|
185
|
+
MUST be set to "FAX" if present.
|
|
186
|
+
"""
|
|
187
|
+
return self.getNamedProp('80C2', ps.PSETID_ADDRESS)
|
|
188
|
+
|
|
189
|
+
@functools.cached_property
|
|
190
|
+
def businessFaxEmailAddress(self) -> Optional[str]:
|
|
191
|
+
"""
|
|
192
|
+
Contains a user-readable display name, followed by the "@" character,
|
|
193
|
+
followed by a fax number.
|
|
194
|
+
"""
|
|
195
|
+
return self.getNamedProp('80C3', ps.PSETID_ADDRESS)
|
|
196
|
+
|
|
197
|
+
@functools.cached_property
|
|
198
|
+
def businessFaxNumber(self) -> Optional[str]:
|
|
199
|
+
"""
|
|
200
|
+
Contains the number of the contact's business fax.
|
|
201
|
+
"""
|
|
202
|
+
return self.getStringStream('__substg1.0_3A24')
|
|
203
|
+
|
|
204
|
+
@functools.cached_property
|
|
205
|
+
def businessFaxOriginalDisplayName(self) -> Optional[str]:
|
|
206
|
+
"""
|
|
207
|
+
The normalized subject for the contact.
|
|
208
|
+
"""
|
|
209
|
+
return self.getNamedProp('80C4', ps.PSETID_ADDRESS)
|
|
210
|
+
|
|
211
|
+
@functools.cached_property
|
|
212
|
+
def businessFaxOriginalEntryId(self) -> Optional[EntryID]:
|
|
213
|
+
"""
|
|
214
|
+
The one-off EntryID corresponding to this fax address.
|
|
215
|
+
"""
|
|
216
|
+
return self.getNamedAs('80C5', ps.PSETID_ADDRESS, EntryID.autoCreate)
|
|
217
|
+
|
|
218
|
+
@functools.cached_property
|
|
219
|
+
def businessTelephoneNumber(self) -> Optional[str]:
|
|
220
|
+
"""
|
|
221
|
+
Contains the number of the contact's business telephone.
|
|
222
|
+
"""
|
|
223
|
+
return self.getStringStream('__substg1.0_3A08')
|
|
224
|
+
|
|
225
|
+
@functools.cached_property
|
|
226
|
+
def businessTelephone2Number(self) -> Optional[Union[str, List[str]]]:
|
|
227
|
+
"""
|
|
228
|
+
Contains the second number or numbers of the contact's business.
|
|
229
|
+
"""
|
|
230
|
+
return self.getSingleOrMultipleString('__substg1.0_3A1B')
|
|
231
|
+
|
|
232
|
+
@functools.cached_property
|
|
233
|
+
def businessHomePage(self) -> Optional[str]:
|
|
234
|
+
"""
|
|
235
|
+
Contains the url of the homepage of the contact's business.
|
|
236
|
+
"""
|
|
237
|
+
return self.getStringStream('__substg1.0_3A51')
|
|
238
|
+
|
|
239
|
+
@functools.cached_property
|
|
240
|
+
def callbackTelephoneNumber(self) -> Optional[str]:
|
|
241
|
+
"""
|
|
242
|
+
Contains the contact's callback telephone number.
|
|
243
|
+
"""
|
|
244
|
+
return self.getStringStream('__substg1.0_3A02')
|
|
245
|
+
|
|
246
|
+
@functools.cached_property
|
|
247
|
+
def carTelephoneNumber(self) -> Optional[str]:
|
|
248
|
+
"""
|
|
249
|
+
Contains the number of the contact's car telephone.
|
|
250
|
+
"""
|
|
251
|
+
return self.getStringStream('__substg1.0_3A1E')
|
|
252
|
+
|
|
253
|
+
@functools.cached_property
|
|
254
|
+
def childrensNames(self) -> Optional[List[str]]:
|
|
255
|
+
"""
|
|
256
|
+
A list of the named of the contact's children.
|
|
257
|
+
"""
|
|
258
|
+
return self.getMultipleString('__substg1.0_3A58')
|
|
259
|
+
|
|
260
|
+
@functools.cached_property
|
|
261
|
+
def companyMainTelephoneNumber(self) -> Optional[str]:
|
|
262
|
+
"""
|
|
263
|
+
Contains the number of the main telephone of the contact's company.
|
|
264
|
+
"""
|
|
265
|
+
return self.getStringStream('__substg1.0_3A57')
|
|
266
|
+
|
|
267
|
+
@functools.cached_property
|
|
268
|
+
def companyName(self) -> Optional[str]:
|
|
269
|
+
"""
|
|
270
|
+
The name of the company the contact works at.
|
|
271
|
+
"""
|
|
272
|
+
return self.getStringStream('__substg1.0_3A16')
|
|
273
|
+
|
|
274
|
+
@functools.cached_property
|
|
275
|
+
def computerNetworkName(self) -> Optional[str]:
|
|
276
|
+
"""
|
|
277
|
+
The name of the network to wwhich the contact's computer is connected.
|
|
278
|
+
"""
|
|
279
|
+
return self.getStringStream('__substg1.0_3A49')
|
|
280
|
+
|
|
281
|
+
@functools.cached_property
|
|
282
|
+
def contactCharacterSet(self) -> Optional[int]:
|
|
283
|
+
"""
|
|
284
|
+
The character set that is used for this Contact object.
|
|
285
|
+
"""
|
|
286
|
+
return self.getNamedProp('8023', ps.PSETID_ADDRESS)
|
|
287
|
+
|
|
288
|
+
@functools.cached_property
|
|
289
|
+
def contactItemData(self) -> Optional[List[int]]:
|
|
290
|
+
"""
|
|
291
|
+
Used to help display the contact information.
|
|
292
|
+
"""
|
|
293
|
+
return self.getNamedProp('8007', ps.PSETID_ADDRESS)
|
|
294
|
+
|
|
295
|
+
@functools.cached_property
|
|
296
|
+
def contactLinkedGlobalAddressListEntryID(self) -> Optional[EntryID]:
|
|
297
|
+
"""
|
|
298
|
+
The EntryID of the GAL object to which the duplicate contact is linked.
|
|
299
|
+
"""
|
|
300
|
+
return self.getNamedAs('80E2', ps.PSETID_ADDRESS, EntryID.autoCreate)
|
|
301
|
+
|
|
302
|
+
@functools.cached_property
|
|
303
|
+
def contactLinkGlobalAddressListLinkID(self) -> Optional[str]:
|
|
304
|
+
"""
|
|
305
|
+
The GUID of the GAL contact to which the duplicate contact is linked.
|
|
306
|
+
"""
|
|
307
|
+
return self.getNamedProp('80E8', ps.PSETID_ADDRESS)
|
|
308
|
+
|
|
309
|
+
@functools.cached_property
|
|
310
|
+
def contactLinkGlobalAddressListLinkState(self) -> Optional[ContactLinkState]:
|
|
311
|
+
"""
|
|
312
|
+
The state of linking between the GAL contact and the duplicate contact.
|
|
313
|
+
"""
|
|
314
|
+
return self.getNamedAs('80E6', ps.PSETID_ADDRESS, ContactLinkState)
|
|
315
|
+
|
|
316
|
+
@functools.cached_property
|
|
317
|
+
def contactLinkLinkRejectHistory(self) -> Optional[List[bytes]]:
|
|
318
|
+
"""
|
|
319
|
+
A list of any contacts that were previously rejected for linking with
|
|
320
|
+
the duplicate contact.
|
|
321
|
+
"""
|
|
322
|
+
return self.getNamedProp('80E5', ps.PSETID_ADDRESS)
|
|
323
|
+
|
|
324
|
+
@functools.cached_property
|
|
325
|
+
def contactLinkSMTPAddressCache(self) -> Optional[List[str]]:
|
|
326
|
+
"""
|
|
327
|
+
A list of the SMTP addresses that are used by the GAL contact that are
|
|
328
|
+
linked to the duplicate contact.
|
|
329
|
+
"""
|
|
330
|
+
return self.getNamedProp('80E3', ps.PSETID_ADDRESS)
|
|
331
|
+
|
|
332
|
+
@functools.cached_property
|
|
333
|
+
def contactPhoto(self) -> Optional[bytes]:
|
|
334
|
+
"""
|
|
335
|
+
The contact photo, if it exists.
|
|
336
|
+
"""
|
|
337
|
+
if self.hasPicture:
|
|
338
|
+
if len(self.attachments) > 0:
|
|
339
|
+
contactPhotoAtt = next((att for att in self.attachments if att.isAttachmentContactPhoto), None)
|
|
340
|
+
if contactPhotoAtt:
|
|
341
|
+
return contactPhotoAtt.data
|
|
342
|
+
return None
|
|
343
|
+
|
|
344
|
+
@functools.cached_property
|
|
345
|
+
def contactUserField1(self) -> Optional[str]:
|
|
346
|
+
"""
|
|
347
|
+
Used to store custom text for a business card.
|
|
348
|
+
"""
|
|
349
|
+
return self.getNamedProp('804F', ps.PSETID_ADDRESS)
|
|
350
|
+
|
|
351
|
+
@functools.cached_property
|
|
352
|
+
def contactUserField2(self) -> Optional[str]:
|
|
353
|
+
"""
|
|
354
|
+
Used to store custom text for a business card.
|
|
355
|
+
"""
|
|
356
|
+
return self.getNamedProp('8050', ps.PSETID_ADDRESS)
|
|
357
|
+
|
|
358
|
+
@functools.cached_property
|
|
359
|
+
def contactUserField3(self) -> Optional[str]:
|
|
360
|
+
"""
|
|
361
|
+
Used to store custom text for a business card.
|
|
362
|
+
"""
|
|
363
|
+
return self.getNamedProp('8051', ps.PSETID_ADDRESS)
|
|
364
|
+
|
|
365
|
+
@functools.cached_property
|
|
366
|
+
def contactUserField4(self) -> Optional[str]:
|
|
367
|
+
"""
|
|
368
|
+
Used to store custom text for a business card.
|
|
369
|
+
"""
|
|
370
|
+
return self.getNamedProp('8052', ps.PSETID_ADDRESS)
|
|
371
|
+
|
|
372
|
+
@functools.cached_property
|
|
373
|
+
def customerID(self) -> Optional[str]:
|
|
374
|
+
"""
|
|
375
|
+
The contact's customer ID number.
|
|
376
|
+
"""
|
|
377
|
+
return self.getStringStream('__substg1.0_3A4A')
|
|
378
|
+
|
|
379
|
+
@functools.cached_property
|
|
380
|
+
def departmentName(self) -> Optional[str]:
|
|
381
|
+
"""
|
|
382
|
+
The name of the department the contact works in.
|
|
383
|
+
"""
|
|
384
|
+
return self.getStringStream('__substg1.0_3A18')
|
|
385
|
+
|
|
386
|
+
@functools.cached_property
|
|
387
|
+
def displayName(self) -> Optional[str]:
|
|
388
|
+
"""
|
|
389
|
+
The full name of the contact.
|
|
390
|
+
"""
|
|
391
|
+
return self.getStringStream('__substg1.0_3001')
|
|
392
|
+
|
|
393
|
+
@functools.cached_property
|
|
394
|
+
def displayNamePrefix(self) -> Optional[str]:
|
|
395
|
+
"""
|
|
396
|
+
The contact's honorific title.
|
|
397
|
+
"""
|
|
398
|
+
return self.getStringStream('__substg1.0_3A45')
|
|
399
|
+
|
|
400
|
+
@functools.cached_property
|
|
401
|
+
def email1(self) -> Optional[_EMAIL_DICT]:
|
|
402
|
+
"""
|
|
403
|
+
Returns a ``dict`` of the data for email 1.
|
|
404
|
+
|
|
405
|
+
Returns ``None`` if no fields are set.
|
|
406
|
+
|
|
407
|
+
Keys are "address_type", "display_name", "email_address",
|
|
408
|
+
"original_display_name", and "original_entry_id".
|
|
409
|
+
"""
|
|
410
|
+
data = {
|
|
411
|
+
'address_type': self.email1AddressType,
|
|
412
|
+
'display_name': self.email1DisplayName,
|
|
413
|
+
'email_address': self.email1EmailAddress,
|
|
414
|
+
'original_display_name': self.email1OriginalDisplayName,
|
|
415
|
+
'original_entry_id': self.email1OriginalEntryId,
|
|
416
|
+
}
|
|
417
|
+
return data if any(data[x] for x in data) else None
|
|
418
|
+
|
|
419
|
+
@functools.cached_property
|
|
420
|
+
def email1AddressType(self) -> Optional[str]:
|
|
421
|
+
"""
|
|
422
|
+
The address type of the first email address.
|
|
423
|
+
"""
|
|
424
|
+
return self.getNamedProp('8082', ps.PSETID_ADDRESS)
|
|
425
|
+
|
|
426
|
+
@functools.cached_property
|
|
427
|
+
def email1DisplayName(self) -> Optional[str]:
|
|
428
|
+
"""
|
|
429
|
+
The user-readable display name of the first email address.
|
|
430
|
+
"""
|
|
431
|
+
return self.getNamedProp('8080', ps.PSETID_ADDRESS)
|
|
432
|
+
|
|
433
|
+
@functools.cached_property
|
|
434
|
+
def email1EmailAddress(self) -> Optional[str]:
|
|
435
|
+
"""
|
|
436
|
+
The first email address.
|
|
437
|
+
"""
|
|
438
|
+
return self.getNamedProp('8083', ps.PSETID_ADDRESS)
|
|
439
|
+
|
|
440
|
+
@functools.cached_property
|
|
441
|
+
def email1OriginalDisplayName(self) -> Optional[str]:
|
|
442
|
+
"""
|
|
443
|
+
The first SMTP email address that corresponds to the first email address
|
|
444
|
+
for the contact.
|
|
445
|
+
"""
|
|
446
|
+
return self.getNamedProp('8084', ps.PSETID_ADDRESS)
|
|
447
|
+
|
|
448
|
+
@functools.cached_property
|
|
449
|
+
def email1OriginalEntryId(self) -> Optional[EntryID]:
|
|
450
|
+
"""
|
|
451
|
+
The EntryID of the object correspinding to this electronic address.
|
|
452
|
+
"""
|
|
453
|
+
return self.getNamedAs('8085', ps.PSETID_ADDRESS, EntryID.autoCreate)
|
|
454
|
+
|
|
455
|
+
@functools.cached_property
|
|
456
|
+
def email2(self) -> Optional[_EMAIL_DICT]:
|
|
457
|
+
"""
|
|
458
|
+
Returns a ``dict`` of the data for email 2.
|
|
459
|
+
|
|
460
|
+
Returns ``None`` if no fields are set.
|
|
461
|
+
"""
|
|
462
|
+
data = {
|
|
463
|
+
'address_type': self.email2AddressType,
|
|
464
|
+
'display_name': self.email2DisplayName,
|
|
465
|
+
'email_address': self.email2EmailAddress,
|
|
466
|
+
'original_display_name': self.email2OriginalDisplayName,
|
|
467
|
+
'original_entry_id': self.email2OriginalEntryId,
|
|
468
|
+
}
|
|
469
|
+
return data if any(data[x] for x in data) else None
|
|
470
|
+
|
|
471
|
+
@functools.cached_property
|
|
472
|
+
def email2AddressType(self) -> Optional[str]:
|
|
473
|
+
"""
|
|
474
|
+
The address type of the second email address.
|
|
475
|
+
"""
|
|
476
|
+
return self.getNamedProp('8092', ps.PSETID_ADDRESS)
|
|
477
|
+
|
|
478
|
+
@functools.cached_property
|
|
479
|
+
def email2DisplayName(self) -> Optional[str]:
|
|
480
|
+
"""
|
|
481
|
+
The user-readable display name of the second email address.
|
|
482
|
+
"""
|
|
483
|
+
return self.getNamedProp('8090', ps.PSETID_ADDRESS)
|
|
484
|
+
|
|
485
|
+
@functools.cached_property
|
|
486
|
+
def email2EmailAddress(self) -> Optional[str]:
|
|
487
|
+
"""
|
|
488
|
+
The second email address.
|
|
489
|
+
"""
|
|
490
|
+
return self.getNamedProp('8093', ps.PSETID_ADDRESS)
|
|
491
|
+
|
|
492
|
+
@functools.cached_property
|
|
493
|
+
def email2OriginalDisplayName(self) -> Optional[str]:
|
|
494
|
+
"""
|
|
495
|
+
The second SMTP email address that corresponds to the second email
|
|
496
|
+
address for the contact.
|
|
497
|
+
"""
|
|
498
|
+
return self.getNamedProp('8094', ps.PSETID_ADDRESS)
|
|
499
|
+
|
|
500
|
+
@functools.cached_property
|
|
501
|
+
def email2OriginalEntryId(self) -> Optional[EntryID]:
|
|
502
|
+
"""
|
|
503
|
+
The EntryID of the object correspinding to this electronic address.
|
|
504
|
+
"""
|
|
505
|
+
return self.getNamedAs('8095', ps.PSETID_ADDRESS, EntryID.autoCreate)
|
|
506
|
+
|
|
507
|
+
@functools.cached_property
|
|
508
|
+
def email3(self) -> Optional[_EMAIL_DICT]:
|
|
509
|
+
"""
|
|
510
|
+
Returns a ``dict`` of the data for email 3.
|
|
511
|
+
|
|
512
|
+
Returns ``None`` if no fields are set.
|
|
513
|
+
"""
|
|
514
|
+
data = {
|
|
515
|
+
'address_type': self.email3AddressType,
|
|
516
|
+
'display_name': self.email3DisplayName,
|
|
517
|
+
'email_address': self.email3EmailAddress,
|
|
518
|
+
'original_display_name': self.email3OriginalDisplayName,
|
|
519
|
+
'original_entry_id': self.email3OriginalEntryId,
|
|
520
|
+
}
|
|
521
|
+
return data if any(data[x] for x in data) else None
|
|
522
|
+
|
|
523
|
+
@functools.cached_property
|
|
524
|
+
def email3AddressType(self) -> Optional[str]:
|
|
525
|
+
"""
|
|
526
|
+
The address type of the third email address.
|
|
527
|
+
"""
|
|
528
|
+
return self.getNamedProp('80A2', ps.PSETID_ADDRESS)
|
|
529
|
+
|
|
530
|
+
@functools.cached_property
|
|
531
|
+
def email3DisplayName(self) -> Optional[str]:
|
|
532
|
+
"""
|
|
533
|
+
The user-readable display name of the third email address.
|
|
534
|
+
"""
|
|
535
|
+
return self.getNamedProp('80A0', ps.PSETID_ADDRESS)
|
|
536
|
+
|
|
537
|
+
@functools.cached_property
|
|
538
|
+
def email3EmailAddress(self) -> Optional[str]:
|
|
539
|
+
"""
|
|
540
|
+
The third email address.
|
|
541
|
+
"""
|
|
542
|
+
return self.getNamedProp('80A3', ps.PSETID_ADDRESS)
|
|
543
|
+
|
|
544
|
+
@functools.cached_property
|
|
545
|
+
def email3OriginalDisplayName(self) -> Optional[str]:
|
|
546
|
+
"""
|
|
547
|
+
The third SMTP email address that corresponds to the third email address
|
|
548
|
+
for the contact.
|
|
549
|
+
"""
|
|
550
|
+
return self.getNamedProp('80A4', ps.PSETID_ADDRESS)
|
|
551
|
+
|
|
552
|
+
@functools.cached_property
|
|
553
|
+
def email3OriginalEntryId(self) -> Optional[EntryID]:
|
|
554
|
+
"""
|
|
555
|
+
The EntryID of the object correspinding to this electronic address.
|
|
556
|
+
"""
|
|
557
|
+
return self.getNamedAs('80A5', ps.PSETID_ADDRESS, EntryID.autoCreate)
|
|
558
|
+
|
|
559
|
+
@functools.cached_property
|
|
560
|
+
def emails(self) -> Tuple[Union[_EMAIL_DICT, None], Union[_EMAIL_DICT, None], Union[_EMAIL_DICT, None]]:
|
|
561
|
+
"""
|
|
562
|
+
Returns a tuple of all the email ``dict``\\s.
|
|
563
|
+
|
|
564
|
+
Value for an email will be ``None`` if no fields were set.
|
|
565
|
+
"""
|
|
566
|
+
return (self.email1, self.email2, self.email3)
|
|
567
|
+
|
|
568
|
+
@functools.cached_property
|
|
569
|
+
def faxNumbers(self) -> Dict[str, Optional[_FAX_DICT]]:
|
|
570
|
+
"""
|
|
571
|
+
Returns a ``dict`` of the fax numbers.
|
|
572
|
+
|
|
573
|
+
Entry will be ``None`` if no fields were set.
|
|
574
|
+
|
|
575
|
+
Keys are "business", "home", and "primary".
|
|
576
|
+
"""
|
|
577
|
+
return {
|
|
578
|
+
'business': self.businessFax,
|
|
579
|
+
'home': self.homeFax,
|
|
580
|
+
'primary': self.primaryFax,
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
@functools.cached_property
|
|
584
|
+
def fileUnder(self) -> Optional[str]:
|
|
585
|
+
"""
|
|
586
|
+
The name under which to file a contact when displaying a list of
|
|
587
|
+
contacts.
|
|
588
|
+
"""
|
|
589
|
+
return self.getNamedProp('8005', ps.PSETID_ADDRESS)
|
|
590
|
+
|
|
591
|
+
@functools.cached_property
|
|
592
|
+
def fileUnderID(self) -> Optional[int]:
|
|
593
|
+
"""
|
|
594
|
+
The format to use for fileUnder. See PidLidFileUnderId in [MS-OXOCNTC]
|
|
595
|
+
for details.
|
|
596
|
+
"""
|
|
597
|
+
return self.getNamedProp('8006', ps.PSETID_ADDRESS)
|
|
598
|
+
|
|
599
|
+
@functools.cached_property
|
|
600
|
+
def freeBusyLocation(self) -> Optional[str]:
|
|
601
|
+
"""
|
|
602
|
+
A URL path from which a client can retrieve free/busy status information
|
|
603
|
+
for the contact as an iCalendat file.
|
|
604
|
+
"""
|
|
605
|
+
return self.getNamedProp('80D8', ps.PSETID_ADDRESS)
|
|
606
|
+
|
|
607
|
+
@functools.cached_property
|
|
608
|
+
def ftpSite(self) -> Optional[str]:
|
|
609
|
+
"""
|
|
610
|
+
The contact's File Transfer Protocol url.
|
|
611
|
+
"""
|
|
612
|
+
return self.getStringStream('__substg1.0_3A4C')
|
|
613
|
+
|
|
614
|
+
@functools.cached_property
|
|
615
|
+
def gender(self) -> Gender:
|
|
616
|
+
"""
|
|
617
|
+
The gender of the contact.
|
|
618
|
+
"""
|
|
619
|
+
return Gender(self.getPropertyVal('3A4D0002', 0))
|
|
620
|
+
|
|
621
|
+
@functools.cached_property
|
|
622
|
+
def generation(self) -> Optional[str]:
|
|
623
|
+
"""
|
|
624
|
+
A generational abbreviation that follows the full name of the contact.
|
|
625
|
+
"""
|
|
626
|
+
return self.getStringStream('__substg1.0_3A05')
|
|
627
|
+
|
|
628
|
+
@functools.cached_property
|
|
629
|
+
def givenName(self) -> Optional[str]:
|
|
630
|
+
"""
|
|
631
|
+
The first name of the contact.
|
|
632
|
+
"""
|
|
633
|
+
return self.getStringStream('__substg1.0_3A06')
|
|
634
|
+
|
|
635
|
+
@functools.cached_property
|
|
636
|
+
def governmentIDNumber(self) -> Optional[str]:
|
|
637
|
+
"""
|
|
638
|
+
The contact's government ID number.
|
|
639
|
+
"""
|
|
640
|
+
return self.getStringStream('__substg1.0_3A07')
|
|
641
|
+
|
|
642
|
+
@functools.cached_property
|
|
643
|
+
def hasPicture(self) -> bool:
|
|
644
|
+
"""
|
|
645
|
+
Whether the contact has a contact photo.
|
|
646
|
+
"""
|
|
647
|
+
return bool(self.getNamedProp('8015', ps.PSETID_ADDRESS))
|
|
648
|
+
|
|
649
|
+
@property
|
|
650
|
+
def headerFormatProperties(self) -> HEADER_FORMAT_TYPE:
|
|
651
|
+
def strListToStr(inp: Optional[Union[str, List[str]]]):
|
|
652
|
+
"""
|
|
653
|
+
Small internal function for things that may return a string or list.
|
|
654
|
+
"""
|
|
655
|
+
if inp is None or isinstance(inp, str):
|
|
656
|
+
return inp
|
|
657
|
+
else:
|
|
658
|
+
return ', '.join(inp)
|
|
659
|
+
|
|
660
|
+
# Checking outlook printing, default behavior is to completely omit
|
|
661
|
+
# *any* field that is not present. So while for extensability the
|
|
662
|
+
# option exists to have it be present even if no data is found, we are
|
|
663
|
+
# specifically not doing that.
|
|
664
|
+
return {
|
|
665
|
+
'-personal details-': {
|
|
666
|
+
'Full Name': self.displayName,
|
|
667
|
+
'Last Name': self.surname,
|
|
668
|
+
'First Name': self.givenName,
|
|
669
|
+
'Job Title': self.jobTitle,
|
|
670
|
+
'Department': self.departmentName,
|
|
671
|
+
'Company': self.companyName,
|
|
672
|
+
},
|
|
673
|
+
'-addresses-': {
|
|
674
|
+
'Business Address': self.workAddress,
|
|
675
|
+
'Home Address': self.homeAddress,
|
|
676
|
+
'Other Address': self.otherAddress,
|
|
677
|
+
'IM Address': self.instantMessagingAddress,
|
|
678
|
+
},
|
|
679
|
+
'-phone numbers-': {
|
|
680
|
+
'Business': self.businessTelephoneNumber,
|
|
681
|
+
'Business 2': strListToStr(self.businessTelephone2Number),
|
|
682
|
+
'Assistant': self.assistantTelephoneNumber,
|
|
683
|
+
'Company Main Phone': self.companyMainTelephoneNumber,
|
|
684
|
+
'Home': self.homeTelephoneNumber,
|
|
685
|
+
'Home 2': strListToStr(self.homeTelephone2Number),
|
|
686
|
+
'Mobile': self.mobileTelephoneNumber,
|
|
687
|
+
'Car': self.carTelephoneNumber,
|
|
688
|
+
'Radio': self.radioTelephoneNumber,
|
|
689
|
+
'Pager': self.pagerTelephoneNumber,
|
|
690
|
+
'Callback': self.callbackTelephoneNumber,
|
|
691
|
+
'Other': self.otherTelephoneNumber,
|
|
692
|
+
'Primary Phone': self.primaryTelephoneNumber,
|
|
693
|
+
'Telex': self.telexNumber,
|
|
694
|
+
'TTY/TDD Phone': self.tddTelephoneNumber,
|
|
695
|
+
'ISDN': self.isdnNumber,
|
|
696
|
+
'Business Fax': self.businessFaxNumber,
|
|
697
|
+
'Home Fax': self.homeFaxNumber,
|
|
698
|
+
},
|
|
699
|
+
'-emails-': {
|
|
700
|
+
'Email': self.email1EmailAddress or self.email1OriginalDisplayName,
|
|
701
|
+
'Email Display As': self.email1DisplayName,
|
|
702
|
+
'Email 2': self.email2EmailAddress or self.email2OriginalDisplayName,
|
|
703
|
+
'Email2 Display As': self.email2DisplayName,
|
|
704
|
+
'Email 3': self.email3EmailAddress or self.email3OriginalDisplayName,
|
|
705
|
+
'Email3 Display As': self.email3DisplayName,
|
|
706
|
+
},
|
|
707
|
+
'-other-': {
|
|
708
|
+
'Birthday': self.birthday.__format__(self.dateFormat) if self.birthdayLocal else None,
|
|
709
|
+
'Anniversary': self.weddingAnniversary.__format__(self.dateFormat) if self.weddingAnniversaryLocal else None,
|
|
710
|
+
'Spouse/Partner': self.spouseName,
|
|
711
|
+
'Profession': self.profession,
|
|
712
|
+
'Children': strListToStr(self.childrensNames),
|
|
713
|
+
'Hobbies': self.hobbies,
|
|
714
|
+
'Assistant': self.assistant,
|
|
715
|
+
'Web Page': self.webpageUrl,
|
|
716
|
+
},
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
@functools.cached_property
|
|
720
|
+
def hobbies(self) -> Optional[str]:
|
|
721
|
+
"""
|
|
722
|
+
The hobies of the contact.
|
|
723
|
+
"""
|
|
724
|
+
return self.getStringStream('__substg1.0_3A43')
|
|
725
|
+
|
|
726
|
+
@functools.cached_property
|
|
727
|
+
def homeAddress(self) -> Optional[str]:
|
|
728
|
+
"""
|
|
729
|
+
The complete home address of the contact.
|
|
730
|
+
"""
|
|
731
|
+
return self.getNamedProp('801A', ps.PSETID_ADDRESS)
|
|
732
|
+
|
|
733
|
+
@functools.cached_property
|
|
734
|
+
def homeAddressCountry(self) -> Optional[str]:
|
|
735
|
+
"""
|
|
736
|
+
The country portion of the contact's home address.
|
|
737
|
+
"""
|
|
738
|
+
return self.getStringStream('__substg1.0_3A5A')
|
|
739
|
+
|
|
740
|
+
@functools.cached_property
|
|
741
|
+
def homeAddressCountryCode(self) -> Optional[str]:
|
|
742
|
+
"""
|
|
743
|
+
The country code portion of the contact's home address.
|
|
744
|
+
"""
|
|
745
|
+
return self.getNamedProp('80DA', ps.PSETID_ADDRESS)
|
|
746
|
+
|
|
747
|
+
@functools.cached_property
|
|
748
|
+
def homeAddressLocality(self) -> Optional[str]:
|
|
749
|
+
"""
|
|
750
|
+
The locality or city portion of the contact's home address.
|
|
751
|
+
"""
|
|
752
|
+
return self.getStringStream('__substg1.0_3A59')
|
|
753
|
+
|
|
754
|
+
@functools.cached_property
|
|
755
|
+
def homeAddressPostalCode(self) -> Optional[str]:
|
|
756
|
+
"""
|
|
757
|
+
The postal code portion of the contact's home address.
|
|
758
|
+
"""
|
|
759
|
+
return self.getStringStream('__substg1.0_3A5B')
|
|
760
|
+
|
|
761
|
+
@functools.cached_property
|
|
762
|
+
def homeAddressPostOfficeBox(self) -> Optional[str]:
|
|
763
|
+
"""
|
|
764
|
+
The number or identifier of the contact's home post office box.
|
|
765
|
+
"""
|
|
766
|
+
return self.getStringStream('__substg1.0_3A5E')
|
|
767
|
+
|
|
768
|
+
@functools.cached_property
|
|
769
|
+
def homeAddressStateOrProvince(self) -> Optional[str]:
|
|
770
|
+
"""
|
|
771
|
+
The state or province portion of the contact's home address.
|
|
772
|
+
"""
|
|
773
|
+
return self.getStringStream('__substg1.0_3A5C')
|
|
774
|
+
|
|
775
|
+
@functools.cached_property
|
|
776
|
+
def homeAddressStreet(self) -> Optional[str]:
|
|
777
|
+
"""
|
|
778
|
+
The street portion of the contact's home address.
|
|
779
|
+
"""
|
|
780
|
+
return self.getStringStream('__substg1.0_3A5D')
|
|
781
|
+
|
|
782
|
+
@functools.cached_property
|
|
783
|
+
def homeFax(self) -> Optional[_FAX_DICT]:
|
|
784
|
+
"""
|
|
785
|
+
Returns a ``dict`` of the data for the home fax.
|
|
786
|
+
|
|
787
|
+
Returns ``None`` if no fields are set.
|
|
788
|
+
|
|
789
|
+
Keys are "address_type", "email_address", "number",
|
|
790
|
+
"original_display_name", and "original_entry_id".
|
|
791
|
+
"""
|
|
792
|
+
data = {
|
|
793
|
+
'address_type': self.homeFaxAddressType,
|
|
794
|
+
'email_address': self.homeFaxEmailAddress,
|
|
795
|
+
'number': self.homeFaxNumber,
|
|
796
|
+
'original_display_name': self.homeFaxOriginalDisplayName,
|
|
797
|
+
'original_entry_id': self.homeFaxOriginalEntryId,
|
|
798
|
+
}
|
|
799
|
+
return data if any(data[x] for x in data) else None
|
|
800
|
+
|
|
801
|
+
@functools.cached_property
|
|
802
|
+
def homeFaxAddressType(self) -> Optional[str]:
|
|
803
|
+
"""
|
|
804
|
+
The type of address for the fax. MUST be set to "FAX" if present.
|
|
805
|
+
"""
|
|
806
|
+
return self.getNamedProp('80D2', ps.PSETID_ADDRESS)
|
|
807
|
+
|
|
808
|
+
@functools.cached_property
|
|
809
|
+
def homeFaxEmailAddress(self) -> Optional[str]:
|
|
810
|
+
"""
|
|
811
|
+
Contains a user-readable display name, followed by the "@" character,
|
|
812
|
+
followed by a fax number.
|
|
813
|
+
"""
|
|
814
|
+
return self.getNamedProp('80D3', ps.PSETID_ADDRESS)
|
|
815
|
+
|
|
816
|
+
@functools.cached_property
|
|
817
|
+
def homeFaxNumber(self) -> Optional[str]:
|
|
818
|
+
"""
|
|
819
|
+
Contains the number of the contact's home fax.
|
|
820
|
+
"""
|
|
821
|
+
return self.getStringStream('__substg1.0_3A25')
|
|
822
|
+
|
|
823
|
+
@functools.cached_property
|
|
824
|
+
def homeFaxOriginalDisplayName(self) -> Optional[str]:
|
|
825
|
+
"""
|
|
826
|
+
The normalized subject for the contact.
|
|
827
|
+
"""
|
|
828
|
+
return self.getNamedProp('80D4', ps.PSETID_ADDRESS)
|
|
829
|
+
|
|
830
|
+
@functools.cached_property
|
|
831
|
+
def homeFaxOriginalEntryId(self) -> Optional[EntryID]:
|
|
832
|
+
"""
|
|
833
|
+
The one-off EntryID corresponding to this fax address.
|
|
834
|
+
"""
|
|
835
|
+
return self.getNamedAs('80D5', ps.PSETID_ADDRESS, EntryID.autoCreate)
|
|
836
|
+
|
|
837
|
+
@functools.cached_property
|
|
838
|
+
def homeTelephoneNumber(self) -> Optional[str]:
|
|
839
|
+
"""
|
|
840
|
+
The number of the contact's home telephone.
|
|
841
|
+
"""
|
|
842
|
+
return self.getStringStream('__substg1.0_3A09')
|
|
843
|
+
|
|
844
|
+
@functools.cached_property
|
|
845
|
+
def homeTelephone2Number(self) -> Optional[Union[str, List[str]]]:
|
|
846
|
+
"""
|
|
847
|
+
The number(s) of the contact's second home telephone.
|
|
848
|
+
"""
|
|
849
|
+
return self.getSingleOrMultipleString('__substg1.0_3A2F')
|
|
850
|
+
|
|
851
|
+
@functools.cached_property
|
|
852
|
+
def initials(self) -> Optional[str]:
|
|
853
|
+
"""
|
|
854
|
+
The initials of the contact.
|
|
855
|
+
"""
|
|
856
|
+
return self.getStringStream('__substg1.0_3A0A')
|
|
857
|
+
|
|
858
|
+
@functools.cached_property
|
|
859
|
+
def instantMessagingAddress(self) -> Optional[str]:
|
|
860
|
+
"""
|
|
861
|
+
The instant messaging address of the contact.
|
|
862
|
+
"""
|
|
863
|
+
return self.getNamedProp('8062', ps.PSETID_ADDRESS)
|
|
864
|
+
|
|
865
|
+
@functools.cached_property
|
|
866
|
+
def isContactLinked(self) -> bool:
|
|
867
|
+
"""
|
|
868
|
+
Whether the contact is linked to other contacts.
|
|
869
|
+
"""
|
|
870
|
+
return bool(self.getNamedProp('80E0', ps.PSETID_ADDRESS))
|
|
871
|
+
|
|
872
|
+
@functools.cached_property
|
|
873
|
+
def isdnNumber(self) -> Optional[str]:
|
|
874
|
+
"""
|
|
875
|
+
The Integrated Services Digital Network (ISDN) telephone number of the
|
|
876
|
+
contact.
|
|
877
|
+
"""
|
|
878
|
+
return self.getStringStream('__substg1.0_3A2D')
|
|
879
|
+
|
|
880
|
+
@functools.cached_property
|
|
881
|
+
def jobTitle(self) -> Optional[str]:
|
|
882
|
+
"""
|
|
883
|
+
The job title of the contact.
|
|
884
|
+
"""
|
|
885
|
+
return self.getStringStream('__substg1.0_3A17')
|
|
886
|
+
|
|
887
|
+
@functools.cached_property
|
|
888
|
+
def language(self) -> Optional[str]:
|
|
889
|
+
"""
|
|
890
|
+
The language that the contact uses.
|
|
891
|
+
"""
|
|
892
|
+
return self.getStringStream('__substg1.0_3A0C')
|
|
893
|
+
|
|
894
|
+
@functools.cached_property
|
|
895
|
+
def lastModifiedBy(self) -> Optional[str]:
|
|
896
|
+
"""
|
|
897
|
+
The name of the last user to modify the contact file.
|
|
898
|
+
"""
|
|
899
|
+
return self.getStringStream('__substg1.0_3FFA')
|
|
900
|
+
|
|
901
|
+
@functools.cached_property
|
|
902
|
+
def location(self) -> Optional[str]:
|
|
903
|
+
"""
|
|
904
|
+
The location of the contact.
|
|
905
|
+
|
|
906
|
+
For example, this could be the building or office number of the contact.
|
|
907
|
+
"""
|
|
908
|
+
return self.getStringStream('__substg1.0_3A0D')
|
|
909
|
+
|
|
910
|
+
@functools.cached_property
|
|
911
|
+
def mailAddress(self) -> Optional[str]:
|
|
912
|
+
"""
|
|
913
|
+
The complete mail address of the contact.
|
|
914
|
+
"""
|
|
915
|
+
return self.getStringStream('__substg1.0_3A15')
|
|
916
|
+
|
|
917
|
+
@functools.cached_property
|
|
918
|
+
def mailAddressCountry(self) -> Optional[str]:
|
|
919
|
+
"""
|
|
920
|
+
The country portion of the contact's mail address.
|
|
921
|
+
"""
|
|
922
|
+
return self.getStringStream('__substg1.0_3A26')
|
|
923
|
+
|
|
924
|
+
@functools.cached_property
|
|
925
|
+
def mailAddressCountryCode(self) -> Optional[str]:
|
|
926
|
+
"""
|
|
927
|
+
The country code portion of the contact's mail address.
|
|
928
|
+
"""
|
|
929
|
+
return self.getNamedProp('80DD', ps.PSETID_ADDRESS)
|
|
930
|
+
|
|
931
|
+
@functools.cached_property
|
|
932
|
+
def mailAddressLocality(self) -> Optional[str]:
|
|
933
|
+
"""
|
|
934
|
+
The locality or city portion of the contact's mail address.
|
|
935
|
+
"""
|
|
936
|
+
return self.getStringStream('__substg1.0_3A27')
|
|
937
|
+
|
|
938
|
+
@functools.cached_property
|
|
939
|
+
def mailAddressPostalCode(self) -> Optional[str]:
|
|
940
|
+
"""
|
|
941
|
+
The postal code portion of the contact's mail address.
|
|
942
|
+
"""
|
|
943
|
+
return self.getStringStream('__substg1.0_3A2A')
|
|
944
|
+
|
|
945
|
+
@functools.cached_property
|
|
946
|
+
def mailAddressPostOfficeBox(self) -> Optional[str]:
|
|
947
|
+
"""
|
|
948
|
+
The number or identifier of the contact's mail post office box.
|
|
949
|
+
"""
|
|
950
|
+
return self.getStringStream('__substg1.0_3A2B')
|
|
951
|
+
|
|
952
|
+
@functools.cached_property
|
|
953
|
+
def mailAddressStateOrProvince(self) -> Optional[str]:
|
|
954
|
+
"""
|
|
955
|
+
The state or province portion of the contact's mail address.
|
|
956
|
+
"""
|
|
957
|
+
return self.getStringStream('__substg1.0_3A28')
|
|
958
|
+
|
|
959
|
+
@functools.cached_property
|
|
960
|
+
def mailAddressStreet(self) -> Optional[str]:
|
|
961
|
+
"""
|
|
962
|
+
The street portion of the contact's mail address.
|
|
963
|
+
"""
|
|
964
|
+
return self.getStringStream('__substg1.0_3A29')
|
|
965
|
+
|
|
966
|
+
@functools.cached_property
|
|
967
|
+
def managerName(self) -> Optional[str]:
|
|
968
|
+
"""
|
|
969
|
+
The name of the contact's manager.
|
|
970
|
+
"""
|
|
971
|
+
return self.getStringStream('__substg1.0_3A4E')
|
|
972
|
+
|
|
973
|
+
@functools.cached_property
|
|
974
|
+
def middleName(self) -> Optional[str]:
|
|
975
|
+
"""
|
|
976
|
+
The middle name(s) of the contact.
|
|
977
|
+
"""
|
|
978
|
+
return self.getStringStream('__substg1.0_3A44')
|
|
979
|
+
|
|
980
|
+
@functools.cached_property
|
|
981
|
+
def mobileTelephoneNumber(self) -> Optional[str]:
|
|
982
|
+
"""
|
|
983
|
+
The mobile telephone number of the contact.
|
|
984
|
+
"""
|
|
985
|
+
return self.getStringStream('__substg1.0_3A1C')
|
|
986
|
+
|
|
987
|
+
@functools.cached_property
|
|
988
|
+
def nickname(self) -> Optional[str]:
|
|
989
|
+
"""
|
|
990
|
+
The nickname of the contanct.
|
|
991
|
+
"""
|
|
992
|
+
return self.getStringStream('__substg1.0_3A4F')
|
|
993
|
+
|
|
994
|
+
@functools.cached_property
|
|
995
|
+
def officeLocation(self) -> Optional[str]:
|
|
996
|
+
"""
|
|
997
|
+
The location of the office that the contact works in.
|
|
998
|
+
"""
|
|
999
|
+
return self.getStringStream('__substg1.0_3A19')
|
|
1000
|
+
|
|
1001
|
+
@functools.cached_property
|
|
1002
|
+
def organizationalIDNumber(self) -> Optional[str]:
|
|
1003
|
+
"""
|
|
1004
|
+
The organizational ID number for the contact, such as an employee ID
|
|
1005
|
+
number.
|
|
1006
|
+
"""
|
|
1007
|
+
return self.getStringStream('__substg1.0_3A10')
|
|
1008
|
+
|
|
1009
|
+
@functools.cached_property
|
|
1010
|
+
def oscSyncEnabled(self) -> bool:
|
|
1011
|
+
"""
|
|
1012
|
+
Whether contact synchronization with an external source (such as a
|
|
1013
|
+
social networking site) is handled by the server.
|
|
1014
|
+
"""
|
|
1015
|
+
return bool(self.getPropertyVal('7C24000B'))
|
|
1016
|
+
|
|
1017
|
+
@functools.cached_property
|
|
1018
|
+
def otherAddress(self) -> Optional[str]:
|
|
1019
|
+
"""
|
|
1020
|
+
The complete other address of the contact.
|
|
1021
|
+
"""
|
|
1022
|
+
return self.getNamedProp('801C', ps.PSETID_ADDRESS)
|
|
1023
|
+
|
|
1024
|
+
@functools.cached_property
|
|
1025
|
+
def otherAddressCountry(self) -> Optional[str]:
|
|
1026
|
+
"""
|
|
1027
|
+
The country portion of the contact's other address.
|
|
1028
|
+
"""
|
|
1029
|
+
return self.getStringStream('__substg1.0_3A60')
|
|
1030
|
+
|
|
1031
|
+
@functools.cached_property
|
|
1032
|
+
def otherAddressCountryCode(self) -> Optional[str]:
|
|
1033
|
+
"""
|
|
1034
|
+
The country code portion of the contact's other address.
|
|
1035
|
+
"""
|
|
1036
|
+
return self.getNamedProp('80DC', ps.PSETID_ADDRESS)
|
|
1037
|
+
|
|
1038
|
+
@functools.cached_property
|
|
1039
|
+
def otherAddressLocality(self) -> Optional[str]:
|
|
1040
|
+
"""
|
|
1041
|
+
The locality or city portion of the contact's other address.
|
|
1042
|
+
"""
|
|
1043
|
+
return self.getStringStream('__substg1.0_3A5F')
|
|
1044
|
+
|
|
1045
|
+
@functools.cached_property
|
|
1046
|
+
def otherAddressPostalCode(self) -> Optional[str]:
|
|
1047
|
+
"""
|
|
1048
|
+
The postal code portion of the contact's other address.
|
|
1049
|
+
"""
|
|
1050
|
+
return self.getStringStream('__substg1.0_3A61')
|
|
1051
|
+
|
|
1052
|
+
@functools.cached_property
|
|
1053
|
+
def otherAddressPostOfficeBox(self) -> Optional[str]:
|
|
1054
|
+
"""
|
|
1055
|
+
The number or identifier of the contact's other post office box.
|
|
1056
|
+
"""
|
|
1057
|
+
return self.getStringStream('__substg1.0_3A64')
|
|
1058
|
+
|
|
1059
|
+
@functools.cached_property
|
|
1060
|
+
def otherAddressStateOrProvince(self) -> Optional[str]:
|
|
1061
|
+
"""
|
|
1062
|
+
The state or province portion of the contact's other address.
|
|
1063
|
+
"""
|
|
1064
|
+
return self.getStringStream('__substg1.0_3A62')
|
|
1065
|
+
|
|
1066
|
+
@functools.cached_property
|
|
1067
|
+
def otherAddressStreet(self) -> Optional[str]:
|
|
1068
|
+
"""
|
|
1069
|
+
The street portion of the contact's other address.
|
|
1070
|
+
"""
|
|
1071
|
+
return self.getStringStream('__substg1.0_3A63')
|
|
1072
|
+
|
|
1073
|
+
@functools.cached_property
|
|
1074
|
+
def otherTelephoneNumber(self) -> Optional[str]:
|
|
1075
|
+
"""
|
|
1076
|
+
Contains the number of the contact's other telephone.
|
|
1077
|
+
"""
|
|
1078
|
+
return self.getStringStream('__substg1.0_3A1F')
|
|
1079
|
+
|
|
1080
|
+
@functools.cached_property
|
|
1081
|
+
def pagerTelephoneNumber(self) -> Optional[str]:
|
|
1082
|
+
"""
|
|
1083
|
+
The contact's pager telephone number.
|
|
1084
|
+
"""
|
|
1085
|
+
return self.getStringStream('__substg1.0_3A21')
|
|
1086
|
+
|
|
1087
|
+
@functools.cached_property
|
|
1088
|
+
def personalHomePage(self) -> Optional[str]:
|
|
1089
|
+
"""
|
|
1090
|
+
The contact's personal web page UL.
|
|
1091
|
+
"""
|
|
1092
|
+
return self.getStringStream('__substg1.0_3A50')
|
|
1093
|
+
|
|
1094
|
+
@functools.cached_property
|
|
1095
|
+
def phoneticCompanyName(self) -> Optional[str]:
|
|
1096
|
+
"""
|
|
1097
|
+
The phonetic pronunciation of the contact's company name.
|
|
1098
|
+
"""
|
|
1099
|
+
return self.getNamedProp('802E', ps.PSETID_ADDRESS)
|
|
1100
|
+
|
|
1101
|
+
@functools.cached_property
|
|
1102
|
+
def phoneticGivenName(self) -> Optional[str]:
|
|
1103
|
+
"""
|
|
1104
|
+
The phonetic pronunciation of the contact's given name.
|
|
1105
|
+
"""
|
|
1106
|
+
return self.getNamedProp('802C', ps.PSETID_ADDRESS)
|
|
1107
|
+
|
|
1108
|
+
@functools.cached_property
|
|
1109
|
+
def phoneticSurname(self) -> Optional[str]:
|
|
1110
|
+
"""
|
|
1111
|
+
The phonetic pronunciation of the given name of the contact.
|
|
1112
|
+
"""
|
|
1113
|
+
return self.getNamedProp('802D', ps.PSETID_ADDRESS)
|
|
1114
|
+
|
|
1115
|
+
@functools.cached_property
|
|
1116
|
+
def postalAddressID(self) -> PostalAddressID:
|
|
1117
|
+
"""
|
|
1118
|
+
Indicates which physical address is the Mailing Address for this
|
|
1119
|
+
contact.
|
|
1120
|
+
"""
|
|
1121
|
+
return PostalAddressID(self.getNamedProp('8022', ps.PSETID_ADDRESS, 0))
|
|
1122
|
+
|
|
1123
|
+
@functools.cached_property
|
|
1124
|
+
def primaryFax(self) -> Optional[_FAX_DICT]:
|
|
1125
|
+
"""
|
|
1126
|
+
Returns a ``dict`` of the data for the primary fax.
|
|
1127
|
+
|
|
1128
|
+
Returns ``None`` if no fields are set.
|
|
1129
|
+
|
|
1130
|
+
Keys are "address_type", "email_address", "number",
|
|
1131
|
+
"original_display_name", and "original_entry_id".
|
|
1132
|
+
"""
|
|
1133
|
+
data = {
|
|
1134
|
+
'address_type': self.primaryFaxAddressType,
|
|
1135
|
+
'email_address': self.primaryFaxEmailAddress,
|
|
1136
|
+
'number': self.primaryFaxNumber,
|
|
1137
|
+
'original_display_name': self.primaryFaxOriginalDisplayName,
|
|
1138
|
+
'original_entry_id': self.primaryFaxOriginalEntryId,
|
|
1139
|
+
}
|
|
1140
|
+
return data if any(data[x] for x in data) else None
|
|
1141
|
+
|
|
1142
|
+
@functools.cached_property
|
|
1143
|
+
def primaryFaxAddressType(self) -> Optional[str]:
|
|
1144
|
+
"""
|
|
1145
|
+
The type of address for the fax. MUST be set to "FAX" if present.
|
|
1146
|
+
"""
|
|
1147
|
+
return self.getNamedProp('80B2', ps.PSETID_ADDRESS)
|
|
1148
|
+
|
|
1149
|
+
@functools.cached_property
|
|
1150
|
+
def primaryFaxEmailAddress(self) -> Optional[str]:
|
|
1151
|
+
"""
|
|
1152
|
+
Contains a user-readable display name, followed by the "@" character,
|
|
1153
|
+
followed by a fax number.
|
|
1154
|
+
"""
|
|
1155
|
+
return self.getNamedProp('80B3', ps.PSETID_ADDRESS)
|
|
1156
|
+
|
|
1157
|
+
@functools.cached_property
|
|
1158
|
+
def primaryFaxNumber(self) -> Optional[str]:
|
|
1159
|
+
"""
|
|
1160
|
+
Contains the number of the contact's primary fax.
|
|
1161
|
+
"""
|
|
1162
|
+
return self.getStringStream('__substg1.0_3A23')
|
|
1163
|
+
|
|
1164
|
+
@functools.cached_property
|
|
1165
|
+
def primaryFaxOriginalDisplayName(self) -> Optional[str]:
|
|
1166
|
+
"""
|
|
1167
|
+
The normalized subject for the contact.
|
|
1168
|
+
"""
|
|
1169
|
+
return self.getNamedProp('80B4', ps.PSETID_ADDRESS)
|
|
1170
|
+
|
|
1171
|
+
@functools.cached_property
|
|
1172
|
+
def primaryFaxOriginalEntryId(self) -> Optional[EntryID]:
|
|
1173
|
+
"""
|
|
1174
|
+
The one-off EntryID corresponding to this fax address.
|
|
1175
|
+
"""
|
|
1176
|
+
return self.getNamedAs('80B5', ps.PSETID_ADDRESS, EntryID.autoCreate)
|
|
1177
|
+
|
|
1178
|
+
@functools.cached_property
|
|
1179
|
+
def primaryTelephoneNumber(self) -> Optional[str]:
|
|
1180
|
+
"""
|
|
1181
|
+
Contains the number of the contact's primary telephone.
|
|
1182
|
+
"""
|
|
1183
|
+
return self.getStringStream('__substg1.0_3A1A')
|
|
1184
|
+
|
|
1185
|
+
@functools.cached_property
|
|
1186
|
+
def profession(self) -> Optional[str]:
|
|
1187
|
+
"""
|
|
1188
|
+
The profession of the contact.
|
|
1189
|
+
"""
|
|
1190
|
+
return self.getStringStream('__substg1.0_3A46')
|
|
1191
|
+
|
|
1192
|
+
@functools.cached_property
|
|
1193
|
+
def radioTelephoneNumber(self) -> Optional[str]:
|
|
1194
|
+
"""
|
|
1195
|
+
Contains the number of the contact's radio telephone.
|
|
1196
|
+
"""
|
|
1197
|
+
return self.getStringStream('__substg1.0_3A1D')
|
|
1198
|
+
|
|
1199
|
+
@functools.cached_property
|
|
1200
|
+
def referenceEntryID(self) -> Optional[EntryID]:
|
|
1201
|
+
"""
|
|
1202
|
+
Contains a value that is equal to the value of the EntryID of the
|
|
1203
|
+
Contact object unless the Contact object is a copy of an earlier
|
|
1204
|
+
original.
|
|
1205
|
+
"""
|
|
1206
|
+
return self.getNamedAs('85BD', ps.PSETID_COMMON, EntryID.autoCreate)
|
|
1207
|
+
|
|
1208
|
+
@functools.cached_property
|
|
1209
|
+
def referredByName(self) -> Optional[str]:
|
|
1210
|
+
"""
|
|
1211
|
+
The name of the person who referred this contact to the user.
|
|
1212
|
+
"""
|
|
1213
|
+
return self.getStringStream('__substg1.0_3A47')
|
|
1214
|
+
|
|
1215
|
+
@functools.cached_property
|
|
1216
|
+
def spouseName(self) -> Optional[str]:
|
|
1217
|
+
"""
|
|
1218
|
+
The name of the contact's spouse.
|
|
1219
|
+
"""
|
|
1220
|
+
return self.getStringStream('__substg1.0_3A48')
|
|
1221
|
+
|
|
1222
|
+
@functools.cached_property
|
|
1223
|
+
def surname(self) -> Optional[str]:
|
|
1224
|
+
"""
|
|
1225
|
+
The surname of the contact.
|
|
1226
|
+
"""
|
|
1227
|
+
return self.getStringStream('__substg1.0_3A11')
|
|
1228
|
+
|
|
1229
|
+
@functools.cached_property
|
|
1230
|
+
def tddTelephoneNumber(self) -> Optional[str]:
|
|
1231
|
+
"""
|
|
1232
|
+
The telephone number for the contact's text telephone (TTY) or
|
|
1233
|
+
telecommunication device for the deaf (TDD).
|
|
1234
|
+
"""
|
|
1235
|
+
return self.getStringStream('__substg1.0_3A4B')
|
|
1236
|
+
|
|
1237
|
+
@functools.cached_property
|
|
1238
|
+
def telexNumber(self) -> Optional[Union[str, List[str]]]:
|
|
1239
|
+
"""
|
|
1240
|
+
The contact's telex number(s).
|
|
1241
|
+
"""
|
|
1242
|
+
return self.getSingleOrMultipleString('__substg1.0_3A2C')
|
|
1243
|
+
|
|
1244
|
+
@functools.cached_property
|
|
1245
|
+
def userX509Certificate(self) -> Optional[List[bytes]]:
|
|
1246
|
+
"""
|
|
1247
|
+
A list of certificates for the contact.
|
|
1248
|
+
"""
|
|
1249
|
+
return self.getMultipleBinary('3A70')
|
|
1250
|
+
|
|
1251
|
+
@functools.cached_property
|
|
1252
|
+
def weddingAnniversary(self) -> Optional[datetime.datetime]:
|
|
1253
|
+
"""
|
|
1254
|
+
The wedding anniversary of the contact at 11:59 UTC.
|
|
1255
|
+
"""
|
|
1256
|
+
return self.getPropertyVal('3A410040')
|
|
1257
|
+
|
|
1258
|
+
@functools.cached_property
|
|
1259
|
+
def weddingAnniversaryEventEntryID(self) -> Optional[EntryID]:
|
|
1260
|
+
"""
|
|
1261
|
+
The EntryID of an optional Appointement object that represents the
|
|
1262
|
+
contact's wedding anniversary.
|
|
1263
|
+
"""
|
|
1264
|
+
return self.getNamedAs('804E', ps.PSETID_ADDRESS, EntryID.autoCreate)
|
|
1265
|
+
|
|
1266
|
+
@functools.cached_property
|
|
1267
|
+
def weddingAnniversaryLocal(self) -> Optional[datetime.datetime]:
|
|
1268
|
+
"""
|
|
1269
|
+
The wedding anniversary of the contact at 0:00 in the client's local
|
|
1270
|
+
time zone.
|
|
1271
|
+
"""
|
|
1272
|
+
return self.getNamedProp('80DF', ps.PSETID_ADDRESS)
|
|
1273
|
+
|
|
1274
|
+
@functools.cached_property
|
|
1275
|
+
def webpageUrl(self) -> Optional[str]:
|
|
1276
|
+
"""
|
|
1277
|
+
The contact's business web page url. SHOULD be the same as businessUrl.
|
|
1278
|
+
"""
|
|
1279
|
+
return self.getNamedProp('802B', ps.PSETID_ADDRESS)
|
|
1280
|
+
|
|
1281
|
+
@functools.cached_property
|
|
1282
|
+
def workAddress(self) -> Optional[str]:
|
|
1283
|
+
"""
|
|
1284
|
+
The complete work address of the contact.
|
|
1285
|
+
"""
|
|
1286
|
+
return self.getNamedProp('801B', ps.PSETID_ADDRESS)
|
|
1287
|
+
|
|
1288
|
+
@functools.cached_property
|
|
1289
|
+
def workAddressCountry(self) -> Optional[str]:
|
|
1290
|
+
"""
|
|
1291
|
+
The country portion of the contact's work address.
|
|
1292
|
+
"""
|
|
1293
|
+
return self.getNamedProp('8049', ps.PSETID_ADDRESS)
|
|
1294
|
+
|
|
1295
|
+
@functools.cached_property
|
|
1296
|
+
def workAddressCountryCode(self) -> Optional[str]:
|
|
1297
|
+
"""
|
|
1298
|
+
The country code portion of the contact's work address.
|
|
1299
|
+
"""
|
|
1300
|
+
return self.getNamedProp('80DB', ps.PSETID_ADDRESS)
|
|
1301
|
+
|
|
1302
|
+
@functools.cached_property
|
|
1303
|
+
def workAddressLocality(self) -> Optional[str]:
|
|
1304
|
+
"""
|
|
1305
|
+
The locality or city portion of the contact's work address.
|
|
1306
|
+
"""
|
|
1307
|
+
return self.getNamedProp('8046', ps.PSETID_ADDRESS)
|
|
1308
|
+
|
|
1309
|
+
@functools.cached_property
|
|
1310
|
+
def workAddressPostalCode(self) -> Optional[str]:
|
|
1311
|
+
"""
|
|
1312
|
+
The postal code portion of the contact's work address.
|
|
1313
|
+
"""
|
|
1314
|
+
return self.getNamedProp('8048', ps.PSETID_ADDRESS)
|
|
1315
|
+
|
|
1316
|
+
@functools.cached_property
|
|
1317
|
+
def workAddressPostOfficeBox(self) -> Optional[str]:
|
|
1318
|
+
"""
|
|
1319
|
+
The number or identifier of the contact's work post office box.
|
|
1320
|
+
"""
|
|
1321
|
+
return self.getNamedProp('804A', ps.PSETID_ADDRESS)
|
|
1322
|
+
|
|
1323
|
+
@functools.cached_property
|
|
1324
|
+
def workAddressStateOrProvince(self) -> Optional[str]:
|
|
1325
|
+
"""
|
|
1326
|
+
The state or province portion of the contact's work address.
|
|
1327
|
+
"""
|
|
1328
|
+
return self.getNamedProp('8047', ps.PSETID_ADDRESS)
|
|
1329
|
+
|
|
1330
|
+
@functools.cached_property
|
|
1331
|
+
def workAddressStreet(self) -> Optional[str]:
|
|
1332
|
+
"""
|
|
1333
|
+
The street portion of the contact's work address.
|
|
1334
|
+
"""
|
|
1335
|
+
return self.getNamedProp('8045', ps.PSETID_ADDRESS)
|