Skip to content

Commit fb49fb9

Browse files
Covers #448, fix logic, more complete form of #447
1 parent db44074 commit fb49fb9

4 files changed

Lines changed: 39 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
* Fix an issue in `extract_msg.utils.msgPathToString()` that prevented backslashes from being replaced with forward slashes.
44
* Change the behavior of `extract_msg.utils.minutesToDurationStr()` to properly use plurals.
55
* Fixed issue in `extract_msg.utils.unwrapMsg()` that would prevent it from working on signed messages due to an API change.
6+
* Added new exception `MimetypeFailureError`.
7+
* Modified the logic of `MessageBase.asEmailMessage()` to use `AttachmentBase/SignedAttachment.name` instead of `getFilename()` which only exists on AttachmentBase.
8+
* Modified the logic of `MessageBase.htmlBodyPrepared()` to properly put the mimetype in image tags to ensure rendering. Logic was also modified to use `encode` instead of `prettify` to reduce computation and output size.
69

710
**v0.52.0**
811
* [[TeamMsgExtractor #444](https://github.com/TeamMsgExtractor/msg-extractor/issues/444)] Fix typo in string that prevented HTML body from generating from the plain text body properly.

extract_msg/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2828

2929
__author__ = 'Destiny Peterson & Matthew Walker'
30-
__date__ = '2024-10-24'
30+
__date__ = '2024-11-23'
3131
__version__ = '0.53.0'
3232

3333
__all__ = [

extract_msg/exceptions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ class InvalidPropertyIdError(ExMsgBaseException):
9292
The provided property ID was invalid.
9393
"""
9494

95+
class MimetypeFailureError(ExMsgBaseException):
96+
"""
97+
The mimetype was unable to be properly determined when it was mandatory.
98+
"""
99+
95100
class NotWritableError(ExMsgBaseException):
96101
"""
97102
Modification was attempted on an instance that is not writable.

extract_msg/msg_classes/message_base.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
)
4040
from ..exceptions import (
4141
ConversionError, DataNotFoundError, DeencapMalformedData,
42-
DeencapNotEncapsulated, IncompatibleOptionsError, WKError
42+
DeencapNotEncapsulated, IncompatibleOptionsError, MimetypeFailureError,
43+
WKError
4344
)
4445
from .msg import MSGFile
4546
from ..structures.report_tag import ReportTag
@@ -178,7 +179,7 @@ def asEmailMessage(self) -> EmailMessage:
178179
if att.dataType:
179180
if hasattr(att.dataType, 'asEmailMessage'):
180181
# Replace the extension with '.eml'.
181-
filename = att.getFilename()
182+
filename = att.name or ''
182183
if filename.lower().endswith('.msg'):
183184
filename = filename[:-4] + '.eml'
184185
msgMain.add_attachment(
@@ -1198,12 +1199,35 @@ def htmlBodyPrepared(self) -> Optional[bytes]:
11981199
for tag in tags:
11991200
# Iterate through the attachments until we get the right one.
12001201
cid = tag['src'][4:]
1201-
data = next((attachment.data for attachment in self.attachments if attachment.cid == cid), None)
1202+
att = next((attachment for attachment in self.attachments if hasattr(attachment, 'cid') and attachment.cid == cid), None)
12021203
# If we found anything, inject it.
1203-
if data:
1204-
tag['src'] = (b'data:image;base64,' + base64.b64encode(data)).decode('utf-8')
1204+
if att and isinstance(att.data, bytes):
1205+
# Try to get the mimetype. If we can't, see if the item has an
1206+
# extension and guess the mimtype for a few known ones.
1207+
mime = att.mimetype
1208+
if not mime:
1209+
ext = (att.name or '').split('.')[-1].lower()
1210+
if ext == 'png':
1211+
mime = 'image/png'
1212+
elif ext == 'jpg' or ext == 'jpeg':
1213+
mime = 'image/jpeg'
1214+
elif ext == 'gif':
1215+
mime = 'image/gif'
1216+
elif ext == 'tiff' or ext == 'tif':
1217+
mime = 'image/tif'
1218+
elif ext == 'bmp':
1219+
mime = 'image/bmp'
1220+
elif ext == 'svg':
1221+
mime = 'image/svg+xml'
1222+
# Final check.
1223+
if mime:
1224+
tag['src'] = (b'data:' + mime.encode() + b';base64,' + base64.b64encode(att.data)).decode('utf-8')
1225+
else:
1226+
# We don't know what to actually put for this item, and we
1227+
# really should never end up here, so throw an error.
1228+
raise MimetypeFailureError('Could not get the mimetype to use for htmlBodyPrepared.')
12051229

1206-
return soup.prettify('utf-8')
1230+
return soup.encode('utf-8')
12071231

12081232
@functools.cached_property
12091233
def htmlInjectableHeader(self) -> str:

0 commit comments

Comments
 (0)