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,329 @@
1
+ """
2
+ Internal utilities for extract_msg.encoding.
3
+ """
4
+
5
+ __all__ = [
6
+ 'variableByteDecode',
7
+ 'variableByteEncode',
8
+ ]
9
+
10
+
11
+ import codecs
12
+
13
+ from typing import Dict, Tuple
14
+
15
+
16
+ def createVBEncoding(codecName: str, decodingTable: Dict[int, str]) -> codecs.CodecInfo:
17
+ """
18
+ Creates the classes for a variable byte encoding, returning the CodecInfo
19
+ instance associated with it.
20
+
21
+ Currently only supports encodings with up to 2 bytes per character.
22
+
23
+ :param codecName: The name of the codec being created.
24
+ :param decodingTable: The table to use for decoding data. Will be used to
25
+ create the encodingTable.
26
+ """
27
+ # Create the encoding table. If there are duplicate keys, they will use the
28
+ # last one introduced. Iterating in reverse means the lowest possible value
29
+ # for a character will be the one used.
30
+ encodingTable = {
31
+ value: bytes((key,)) if key < 256 else bytes((key >> 8, key & 0xFF))
32
+ for key, value in reversed(decodingTable.items()) if value is not None
33
+ }
34
+
35
+ # Create the classes.
36
+ class Codec(codecs.Codec):
37
+ def encode(self, text, errors='strict'):
38
+ return variableByteEncode(codecName, text, errors, encodingTable)
39
+
40
+ def decode(self, data, errors='strict'):
41
+ return variableByteDecode(codecName, data, errors, decodingTable)
42
+
43
+ class IncrementalEncoder(codecs.IncrementalEncoder):
44
+ def encode(self, text, final=False):
45
+ return variableByteEncode(codecName, text, self.errors, encodingTable)[0]
46
+
47
+ class IncrementalDecoder(codecs.IncrementalDecoder):
48
+ def decode(self, data, final=False):
49
+ return variableByteDecode(codecName, data, self.errors, decodingTable)[0]
50
+
51
+ class StreamWriter(Codec, codecs.StreamWriter):
52
+ pass
53
+
54
+ class StreamReader(Codec, codecs.StreamReader):
55
+ pass
56
+
57
+ # Return the CodecInfo instance.
58
+ return codecs.CodecInfo(
59
+ name=codecName,
60
+ encode=Codec().encode,
61
+ decode=Codec().decode,
62
+ incrementalencoder=IncrementalEncoder,
63
+ incrementaldecoder=IncrementalDecoder,
64
+ streamwriter=StreamWriter,
65
+ streamreader=StreamReader,
66
+ )
67
+
68
+
69
+ def createSBEncoding(codecName: str, decodingTable: Dict[int, str]) -> codecs.CodecInfo:
70
+ """
71
+ Creates the classes for a single byte encoding, returning the CodecInfo
72
+ instance associated with it.
73
+
74
+ Currently only supports encodings with up to 2 bytes per character.
75
+
76
+ :param codecName: The name of the codec being created.
77
+ :param decodingTable: The table to use for decoding data. Will be used to
78
+ create the encodingTable.
79
+ """
80
+ # Create the encoding table. If there are duplicate keys, they will use the
81
+ # last one introduced. Iterating in reverse means the lowest possible value
82
+ # for a character will be the one used.
83
+ encodingTable = {
84
+ value: bytes((key,))
85
+ for key, value in reversed(decodingTable.items()) if value is not None
86
+ }
87
+
88
+ # Create the classes.
89
+ class Codec(codecs.Codec):
90
+ def encode(self, text, errors='strict'):
91
+ return singleByteEncode(codecName, text, errors, encodingTable)
92
+
93
+ def decode(self, data, errors='strict'):
94
+ return singleByteDecode(codecName, data, errors, decodingTable)
95
+
96
+ class IncrementalEncoder(codecs.IncrementalEncoder):
97
+ def encode(self, text, final=False):
98
+ return singleByteEncode(codecName, text, self.errors, encodingTable)[0]
99
+
100
+ class IncrementalDecoder(codecs.IncrementalDecoder):
101
+ def decode(self, data, final=False):
102
+ return singleByteDecode(codecName, data, self.errors, decodingTable)[0]
103
+
104
+ class StreamWriter(Codec, codecs.StreamWriter):
105
+ pass
106
+
107
+ class StreamReader(Codec, codecs.StreamReader):
108
+ pass
109
+
110
+ # Return the CodecInfo instance.
111
+ return codecs.CodecInfo(
112
+ name=codecName,
113
+ encode=Codec().encode,
114
+ decode=Codec().decode,
115
+ incrementalencoder=IncrementalEncoder,
116
+ incrementaldecoder=IncrementalDecoder,
117
+ streamwriter=StreamWriter,
118
+ streamreader=StreamReader,
119
+ )
120
+
121
+
122
+ def singleByteDecode(codecName: str, data, errors: str, decodeTable: Dict[int, str]) -> Tuple[str, int]:
123
+ """
124
+ Function for decoding single-byte codecs.
125
+
126
+ :param codecName: The name of the codec, used for error messages.
127
+ :param data: A bytes-like object to decode.
128
+ :param errors: The error behavior to use.
129
+ :param decodeTable: The mapping of values to use. Continuation bytes MUST be
130
+ defined in the table, but SHOULD be set to None. This allows for the
131
+ function to detect what bytes are valid for continuation.
132
+ """
133
+ if len(data) == 0:
134
+ return ('', 0)
135
+
136
+ errorHandler = codecs.lookup_error(errors)
137
+ output = ''
138
+
139
+ iterator = enumerate(data)
140
+ start = 0
141
+
142
+ for start, byte in iterator:
143
+ if byte in decodeTable:
144
+ output += decodeTable[byte]
145
+ else:
146
+ err = UnicodeDecodeError(codecName,
147
+ data,
148
+ start,
149
+ start + 1,
150
+ 'character maps to <undefined>',
151
+ )
152
+ rep = errorHandler(err)
153
+ output += rep[0]
154
+ for _ in range(rep[1] - start - 1):
155
+ try:
156
+ next(iterator)
157
+ except StopIteration:
158
+ break
159
+
160
+ return (output, len(output))
161
+
162
+
163
+ def singleByteEncode(codecName: str, data, errors: str, encodeTable: Dict[str, bytes]) -> Tuple[bytes, int]:
164
+ """
165
+ Function for encoding variable-byte codecs that use one or two bytes per
166
+ character.
167
+
168
+ :param codecName: The name of the codec, used for error messages.
169
+ :param data: A bytes-like object to decode.
170
+ :param errors: The error behavior to use.
171
+ :param encodeTable: The mapping of values to use.
172
+ """
173
+ if len(data) == 0:
174
+ return
175
+
176
+ errorHandler = codecs.lookup_error(errors)
177
+ output = b''
178
+ iterator = enumerate(data)
179
+ start = 0
180
+ for start, char in iterator:
181
+ if char in encodeTable:
182
+ output += encodeTable[char]
183
+ else:
184
+ err = UnicodeEncodeError(codecName,
185
+ data,
186
+ start,
187
+ start + 1,
188
+ 'illegal multibyte sequence',
189
+ )
190
+ rep = errorHandler(err)
191
+ output += rep[0]
192
+ # Skip the specified number of characters.
193
+ for _ in range(rep[1] - start - 1):
194
+ try:
195
+ next(iterator)
196
+ except StopIteration:
197
+ break
198
+
199
+
200
+
201
+ def variableByteDecode(codecName: str, data, errors: str, decodeTable: Dict[int, str]) -> Tuple[str, int]:
202
+ """
203
+ Function for decoding variable-byte codecs that use one or two bytes per character.
204
+
205
+ Checks if a character is less than ``0x80``, mapping it directly if so.
206
+ Otherwise, it reads the next byte and combines the two before looking up the
207
+ new value.
208
+
209
+ :param codecName: The name of the codec, used for error messages.
210
+ :param data: A bytes-like object to decode.
211
+ :param errors: The error behavior to use.
212
+ :param decodeTable: The mapping of values to use. Continuation bytes MUST be
213
+ defined in the table, but SHOULD be set to None. This allows for the
214
+ function to detect what bytes are valid for continuation.
215
+ """
216
+ if len(data) == 0:
217
+ return ('', 0)
218
+
219
+ errorHandler = codecs.lookup_error(errors)
220
+ output = ''
221
+
222
+ iterator = enumerate(data)
223
+ start = 0
224
+
225
+ for start, byte in iterator:
226
+ # Variable byte should be an integer here.
227
+ if byte < 0x80:
228
+ if byte in decodeTable:
229
+ output += decodeTable[byte]
230
+ else:
231
+ err = UnicodeDecodeError(codecName,
232
+ data,
233
+ start,
234
+ start + 1,
235
+ 'character maps to <undefined>',
236
+ )
237
+ rep = errorHandler(err)
238
+ output += rep[0]
239
+ # Skip the specified number of characters.
240
+ for _ in range(rep[1] - start - 1):
241
+ try:
242
+ next(iterator)
243
+ except StopIteration:
244
+ break
245
+ elif byte not in decodeTable:
246
+ err = UnicodeDecodeError(codecName,
247
+ data,
248
+ start,
249
+ start + 1,
250
+ 'invalid start byte',
251
+ )
252
+ rep = errorHandler(err)
253
+ output += rep[0]
254
+ # Skip the specified number of characters.
255
+ for _ in range(rep[1] - start - 1):
256
+ try:
257
+ next(iterator)
258
+ except StopIteration:
259
+ break
260
+
261
+ else:
262
+ try:
263
+ byte = (byte << 8) | next(iterator)[1]
264
+ if byte in decodeTable:
265
+ output += decodeTable[byte]
266
+ else:
267
+ err = UnicodeDecodeError(codecName,
268
+ data,
269
+ start,
270
+ start + 2,
271
+ 'character maps to <undefined>',
272
+ )
273
+ rep = errorHandler(err)
274
+ output += rep[0]
275
+ # Skip the specified number of characters.
276
+ for _ in range(rep[1] - start - 1):
277
+ next(iterator)
278
+ except StopIteration:
279
+ err = UnicodeDecodeError(codecName,
280
+ data,
281
+ start,
282
+ start + 1,
283
+ 'unexpected end of data',
284
+ )
285
+ rep = errorHandler(err)
286
+ output += rep[0]
287
+ break
288
+ # No more data, so that's all that needs to happen.
289
+ return (output, start)
290
+
291
+
292
+ def variableByteEncode(codecName: str, data, errors: str, encodeTable: Dict[str, bytes]) -> Tuple[bytes, int]:
293
+ """
294
+ Function for encoding variable-byte codecs that use one or two bytes per
295
+ character.
296
+
297
+ :param codecName: The name of the codec, used for error messages.
298
+ :param data: A bytes-like object to decode.
299
+ :param errors: The error behavior to use.
300
+ :param encodeTable: The mapping of values to use.
301
+ """
302
+ if len(data) == 0:
303
+ return
304
+
305
+ errorHandler = codecs.lookup_error(errors)
306
+ output = b''
307
+ iterator = enumerate(data)
308
+ start = 0
309
+
310
+ for start, char in iterator:
311
+ if char in encodeTable:
312
+ data += encodeTable[char]
313
+ else:
314
+ err = UnicodeEncodeError(codecName,
315
+ data,
316
+ start,
317
+ start + 1,
318
+ 'illegal multibyte sequence',
319
+ )
320
+ rep = errorHandler(err)
321
+ output += rep[0]
322
+ # Skip the specified number of characters.
323
+ for _ in range(rep[1] - start - 1):
324
+ try:
325
+ next(iterator)
326
+ except StopIteration:
327
+ break
328
+
329
+ return (output, start + 1)