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,168 @@
|
|
|
1
|
+
__all__ = [
|
|
2
|
+
'DVTargetDevice',
|
|
3
|
+
]
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import struct
|
|
7
|
+
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from ._helpers import BytesReader
|
|
11
|
+
from .dev_mode_a import DevModeA
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class DVTargetDevice:
|
|
15
|
+
"""
|
|
16
|
+
Specifies information about a device that renders the presentation data.
|
|
17
|
+
|
|
18
|
+
The creator of this data structure MUST NOT assume that it will be
|
|
19
|
+
understood during processing.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, data: Optional[bytes]):
|
|
23
|
+
self.__driverName = None
|
|
24
|
+
self.__deviceName = None
|
|
25
|
+
self.__portName = None
|
|
26
|
+
self.__extDevMode = None
|
|
27
|
+
|
|
28
|
+
if not data:
|
|
29
|
+
return
|
|
30
|
+
reader = BytesReader(data)
|
|
31
|
+
|
|
32
|
+
# We have 4 fields to read, and *technically* they may not all even be
|
|
33
|
+
# present, given that this structure can be 4 bytes? Reading all of
|
|
34
|
+
# these is also much more complicated than other structures, as they can
|
|
35
|
+
# technically overlap. We are just going to be *much* more lenient about
|
|
36
|
+
# this structure.
|
|
37
|
+
offset1 = offset2 = offset3 = offset4 = -1
|
|
38
|
+
try:
|
|
39
|
+
offset1 = reader.readUnsignedShort()
|
|
40
|
+
offset2 = reader.readUnsignedShort()
|
|
41
|
+
offset3 = reader.readUnsignedShort()
|
|
42
|
+
offset4 = reader.readUnsignedShort()
|
|
43
|
+
except IOError:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
if offset1 != -1 and offset1 < len(data):
|
|
47
|
+
reader.seek(offset1)
|
|
48
|
+
try:
|
|
49
|
+
self.__driverName = reader.readByteString()
|
|
50
|
+
except IOError:
|
|
51
|
+
self.__driverName = reader.read()
|
|
52
|
+
if not self.__driverName:
|
|
53
|
+
self.__driverName = None
|
|
54
|
+
|
|
55
|
+
if offset2 != -1 and offset2 < len(data):
|
|
56
|
+
reader.seek(offset2)
|
|
57
|
+
try:
|
|
58
|
+
self.__deviceName = reader.readByteString()
|
|
59
|
+
except IOError:
|
|
60
|
+
self.__deviceName = reader.read()
|
|
61
|
+
if not self.__deviceName:
|
|
62
|
+
self.__deviceName = None
|
|
63
|
+
|
|
64
|
+
if offset3 != -1 and offset3 < len(data):
|
|
65
|
+
reader.seek(offset3)
|
|
66
|
+
try:
|
|
67
|
+
self.__portName = reader.readByteString()
|
|
68
|
+
except IOError:
|
|
69
|
+
self.__portName = reader.read()
|
|
70
|
+
if not self.__portName:
|
|
71
|
+
self.__portName = None
|
|
72
|
+
|
|
73
|
+
if offset4 != -1 and offset4 < len(data):
|
|
74
|
+
reader.seek(offset4)
|
|
75
|
+
try:
|
|
76
|
+
devmode = DevModeA(reader.read(56))
|
|
77
|
+
if devmode:
|
|
78
|
+
self.__extDevMode = devmode
|
|
79
|
+
except IOError:
|
|
80
|
+
self.__extDevMode = None
|
|
81
|
+
|
|
82
|
+
def __bytes__(self) -> bytes:
|
|
83
|
+
ret = self.toBytes()
|
|
84
|
+
if not isinstance(ret, bytes):
|
|
85
|
+
raise TypeError(f'Cannot convert {self.__class__.__name__} instance to bytes.')
|
|
86
|
+
return ret
|
|
87
|
+
|
|
88
|
+
def toBytes(self) -> Optional[bytes]:
|
|
89
|
+
if not (self.driverName or self.deviceName or self.portName or self.extDevMode):
|
|
90
|
+
return None
|
|
91
|
+
currentPosition = 8
|
|
92
|
+
|
|
93
|
+
offset1 = 8 if self.__driverName else 0
|
|
94
|
+
if self.__driverName:
|
|
95
|
+
currentPosition += len(self.__driverName) + 1
|
|
96
|
+
|
|
97
|
+
offset2 = currentPosition if self.__deviceName else 0
|
|
98
|
+
if self.__deviceName:
|
|
99
|
+
currentPosition += len(self.__deviceName) + 1
|
|
100
|
+
|
|
101
|
+
offset3 = currentPosition if self.__portName else 0
|
|
102
|
+
if self.__portName:
|
|
103
|
+
currentPosition += len(self.__portName) + 1
|
|
104
|
+
|
|
105
|
+
extDevModeBytes = bytes(self.__extDevMode) if self.__extDevMode else None
|
|
106
|
+
offset4 = currentPosition if extDevModeBytes else 0
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
ret = struct.pack('<HHHH', offset1, offset2, offset3, offset4)
|
|
110
|
+
except struct.error:
|
|
111
|
+
raise ValueError('DVTargetDevice structure contains too much data.')
|
|
112
|
+
if self.__driverName:
|
|
113
|
+
ret += self.__driverName + b'\x00'
|
|
114
|
+
if self.__deviceName:
|
|
115
|
+
ret += self.__deviceName + b'\x00'
|
|
116
|
+
if self.__portName:
|
|
117
|
+
ret += self.__portName + b'\x00'
|
|
118
|
+
if extDevModeBytes:
|
|
119
|
+
ret += extDevModeBytes
|
|
120
|
+
|
|
121
|
+
return ret
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def driverName(self) -> Optional[bytes]:
|
|
125
|
+
"""
|
|
126
|
+
Optional ANSI string that contains a hunt on how to display or print
|
|
127
|
+
presentation data.
|
|
128
|
+
"""
|
|
129
|
+
return self.__driverName
|
|
130
|
+
|
|
131
|
+
@driverName.setter
|
|
132
|
+
def driverName(self, data: Optional[bytes]) -> None:
|
|
133
|
+
self.__driverName = None if not data else data
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def deviceName(self) -> Optional[bytes]:
|
|
137
|
+
"""
|
|
138
|
+
Optional ANSI string that contains a hunt on how to display or print
|
|
139
|
+
presentation data.
|
|
140
|
+
"""
|
|
141
|
+
return self.__deviceName
|
|
142
|
+
|
|
143
|
+
@deviceName.setter
|
|
144
|
+
def deviceName(self, data: Optional[bytes]) -> None:
|
|
145
|
+
self.__deviceName = None if not data else data
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def portName(self) -> Optional[bytes]:
|
|
149
|
+
"""
|
|
150
|
+
Optional ANSI string that contains any arbitrary value.
|
|
151
|
+
"""
|
|
152
|
+
return self.__portName
|
|
153
|
+
|
|
154
|
+
@portName.setter
|
|
155
|
+
def portName(self, data: Optional[bytes]) -> None:
|
|
156
|
+
self.__portName = None if not data else data
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
def extDevMode(self) -> Optional[DevModeA]:
|
|
160
|
+
"""
|
|
161
|
+
Optional ANSI string that contains a hunt on how to display or print
|
|
162
|
+
presentation data.
|
|
163
|
+
"""
|
|
164
|
+
return self.__extDevMode
|
|
165
|
+
|
|
166
|
+
@extDevMode.setter
|
|
167
|
+
def extDevMode(self, data: Optional[DevModeA]) -> None:
|
|
168
|
+
self.__extDevMode = None if not data else data
|