extract-msg 0.56.0__tar.gz → 0.57.0__tar.gz
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-0.56.0 → extract_msg-0.57.0}/CHANGELOG.md +20 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/PKG-INFO +64 -51
- {extract_msg-0.56.0 → extract_msg-0.57.0}/README.rst +62 -50
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/__init__.py +3 -3
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/__main__.py +3 -1
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/lnk_obj_att.py +2 -2
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/web_att.py +1 -1
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/constants/__init__.py +1 -1
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/constants/ps.py +1 -1
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/constants/re.py +4 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/constants/st.py +2 -2
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/utils.py +24 -20
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/message_base.py +83 -6
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/msg.py +68 -19
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/ole_writer.py +2 -2
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/utils.py +12 -1
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/PKG-INFO +64 -51
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/requires.txt +3 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/setup.cfg +2 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/LICENSE.txt +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/MANIFEST.in +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/__init__.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/create_doc.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/inject_rtf.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/token.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/tokenize_rtf.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/__init__.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/attachment.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/attachment_base.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/broken_att.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/__init__.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/custom_handler.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/outlook_image_dib.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/outlook_image_meta.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/emb_msg_att.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/signed_att.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/unsupported_att.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/data/logging-config/logging-nt.json +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/data/logging-config/logging-posix.json +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/__init__.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/__init__.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_ce.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_cyrillic.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_greek.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_iceland.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_turkish.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_win874_dec.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_win950_dec.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/enums.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/exceptions.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/__init__.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/appointment.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/calendar.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/calendar_base.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/contact.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/journal.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_cancellation.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_exception.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_forward.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_related.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_request.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_response.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/message.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/message_signed.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/message_signed_base.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/post.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/sticky_note.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/task.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/task_request.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/null_date.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/open_msg.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/properties/__init__.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/properties/named.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/properties/prop.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/properties/properties_store.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/py.typed +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/recipient.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/__init__.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/_helpers.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/business_card.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/cfoas.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/contact_link_entry.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/dev_mode_a.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/dv_target_device.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/entry_id.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/misc_id.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/mon_stream.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/odt.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/ole_pres.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/ole_stream_struct.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/recurrence_pattern.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/report_tag.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/system_time.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/time_zone_definition.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/time_zone_struct.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/toc_entry.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/tz_rule.py +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/SOURCES.txt +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/dependency_links.txt +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/entry_points.txt +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/top_level.txt +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/requirements.txt +0 -0
- {extract_msg-0.56.0 → extract_msg-0.57.0}/setup.py +0 -0
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
**v0.57.0**
|
|
2
|
+
* [[Advisory GHSA-cxpg-prmv-g4pp](https://github.com/TeamMsgExtractor/msg-extractor/security/advisories/GHSA-cxpg-prmv-g4pp)] Fixed a vulnerability related to unchecked input passed out to wkhtmltopdf when converting the MSG file to PDF. Javascript is now strongly blocked from being enabled and will be stripped from the HTML where appropriate before reaching wkhtmltopdf. Additionally, the option `--wk-allow-external-files` on the command line (or `wkAllowExternalFiles` to `MessageBase.save()`) will be required for external files to be loaded into the HTML to convert. Without these, they will be stripped before reaching wkhtmltopdf for security.
|
|
3
|
+
* [[Advisory GHSA-mqxr-j8rh-p4q4](https://github.com/TeamMsgExtractor/msg-extractor/security/advisories/GHSA-mqxr-j8rh-p4q4)] Fixed an issue where an attacker controlled MSG file could take advantage of a poorly written section of code in the RTF deencapsulation function on the `extract-msg` side to waste massive amounts of time and memory resources.
|
|
4
|
+
* [[Advisory GHSA-rgjf-vmqv-8pv9](https://github.com/TeamMsgExtractor/msg-extractor/security/advisories/GHSA-rgjf-vmqv-8pv9)] Change the way multiple type properties are accessed for binary and string. This includes modifications to `MSGFile.getMultipleBinary()`, `MSGFile.getMultipleString()`, and `MSGFile.exists()` to significantly reduce wasted times for malicious files. Malicious files previously could cause extract-msg to do unnecessarily large numbers of calls to `MSGFile.exists()` which previously did not use caching to speed up its search.
|
|
5
|
+
* Changed `MSGFile.listDir()` to return a tuple of tuples to prevent it's cache results from being tampered with.
|
|
6
|
+
* Fixed an issue with `MSGFile.listDir()` that caused it to not cache in certain circumstances when it should always cache.
|
|
7
|
+
* Fixed a check in `MSGFile.getMultipleBinary()` that executed wrong and did not properly check for bad data.
|
|
8
|
+
* Fixed `MSGFile._getTypedSteam()` to correctly parse binary and string streams when an entry is missing.
|
|
9
|
+
* Fixed `StandardViolationError` being raised without checking error behavior in `MSGFile.getMultipleBinary()` and `MSGFile.getMultipleString()`.
|
|
10
|
+
* Added check for standard violation in `MSGFile.getMultipleString()` that is raised (or logged, depending on error behavior) if a string stream is missing a null byte. This also doesn't strip the last character in the stream if it is not null.
|
|
11
|
+
* Added length check log to `MSGFile.getMultipleBinary()` and `MSGFile.getMultipleString()` that checks to see if the expected length for each stream matches what the length stream says. If not, it logs a warning about the mismatch, but does not consider this a gross violation of the standard.
|
|
12
|
+
* Changed how `MessageBase.deencapsulatedRtf` handles RTF data without a closing brace.
|
|
13
|
+
* Fixed wrong return being used in `extract_msg.encoding.utils.singleByteEncode()` and `extract_msg.encoding.utils.variableByteEncode()`.
|
|
14
|
+
* Fixed missing return in `extract_msg.encoding.utils.singleByteEncode()`.
|
|
15
|
+
* Fixed wrong parameter names for codec types made in `extract_msg.encoding.utils.createSBEncoding()` and `extract_msg.encoding.utils.createVBEncoding()`.
|
|
16
|
+
* Fix some values being incorrectly returned from encode/decode functions in `extract_msg.encoding.utils`.
|
|
17
|
+
|
|
18
|
+
**v0.56.1**
|
|
19
|
+
* [[TeamMsgExtractor #484](https://github.com/TeamMsgExtractor/msg-extractor/issues/484)] Corrected the way the HTML body is decoded in `MessageBase.asEmailMessage()` to prevent encoding errors.
|
|
20
|
+
|
|
1
21
|
**v0.56.0**
|
|
2
22
|
* [[TeamMsgExtractor #478](https://github.com/TeamMsgExtractor/msg-extractor/issues/478)] Expand allowable versions of `ebcdic` to include `2.x`. The 2.0 release is a pure technical release with no functional changes; it only drops support for Python 2 and 3.8. The lower bound is unchanged so installs on Python 3.8 will continue to resolve to `ebcdic 1.1.1`.
|
|
3
23
|
* [[TeamMsgExtractor #469](https://github.com/TeamMsgExtractor/msg-extractor/issues/469)] Expanded `beautifulsoup` to allow for versions up to `5.*.*`. I was previously hesitant to do so because they sometimes do what seems like non backwards compatible changes in minor versions, but it looks like this should be fine.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: extract_msg
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.57.0
|
|
4
4
|
Summary: Extracts emails and attachments saved in Microsoft Outlook's .msg files
|
|
5
5
|
Home-page: https://github.com/TeamMsgExtractor/msg-extractor
|
|
6
6
|
Download-URL: https://github.com/TeamMsgExtractor/msg-extractor/archives/master
|
|
@@ -14,9 +14,10 @@ Provides-Extra: mime
|
|
|
14
14
|
Provides-Extra: image
|
|
15
15
|
Provides-Extra: encoding
|
|
16
16
|
Provides-Extra: readthedocs
|
|
17
|
+
Provides-Extra: test
|
|
17
18
|
License-File: LICENSE.txt
|
|
18
19
|
|
|
19
|
-
|License: GPL v3| |PyPI3| |PyPI2| |Read the Docs|
|
|
20
|
+
|License: GPL v3| |PyPI3| |PyPI2| |Downloads| |Read the Docs|
|
|
20
21
|
|
|
21
22
|
extract-msg
|
|
22
23
|
=============
|
|
@@ -32,7 +33,7 @@ Documentation can be found in the code, on the `wiki`_, and on the
|
|
|
32
33
|
NOTICE
|
|
33
34
|
======
|
|
34
35
|
0.29.* is the branch that supports both Python 2 and Python 3. It is now only
|
|
35
|
-
receiving
|
|
36
|
+
receiving security fixes and will not be receiving feature updates.
|
|
36
37
|
|
|
37
38
|
0.39.* is the last versions that supported Python 3.6 and 3.7. Support for those
|
|
38
39
|
was dropped to allow the use of new features from 3.8 and because the life spans
|
|
@@ -77,55 +78,59 @@ Currently, the README is in the process of being redone. For now, please
|
|
|
77
78
|
refer to the usage information provided from the program's help dialog:
|
|
78
79
|
::
|
|
79
80
|
|
|
80
|
-
usage: extract_msg [-h] [--use-content-id] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] [--out OUTPATH] [--use-filename] [--dump-stdout] [--html]
|
|
81
|
-
[--
|
|
82
|
-
[--
|
|
83
|
-
|
|
81
|
+
usage: extract_msg [-h] [--use-content-id] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] [--out OUTPATH] [--use-filename] [--dump-stdout] [--html]
|
|
82
|
+
[--pdf] [--wk-path WKPATH] [--wk-options [WKOPTIONS ...]] [--wk-allow-external-files] [--prepared-html] [--charset CHARSET] [--raw] [--rtf]
|
|
83
|
+
[--allow-fallback] [--skip-body-not-found] [--zip ZIP] [--save-header] [--attachments-only] [--skip-hidden] [--no-folders] [--skip-embedded]
|
|
84
|
+
[--extract-embedded] [--overwrite-existing] [--skip-not-implemented] [--out-name OUTNAME | --glob] [--ignore-rtfde] [--progress] [-s]
|
|
85
|
+
[msg ...]
|
|
84
86
|
|
|
85
87
|
extract_msg: Extracts emails and attachments saved in Microsoft Outlook's .msg files. https://github.com/TeamMsgExtractor/msg-extractor
|
|
86
88
|
|
|
87
89
|
positional arguments:
|
|
88
|
-
|
|
90
|
+
msg An MSG file to be parsed.
|
|
89
91
|
|
|
90
92
|
options:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
--
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
93
|
+
-h, --help show this help message and exit
|
|
94
|
+
--use-content-id, --cid
|
|
95
|
+
Save attachments by their Content ID, if they have one. Useful when working with the HTML body.
|
|
96
|
+
--json Changes to write output files as json.
|
|
97
|
+
--file-logging Enables file logging. Implies --verbose level 1.
|
|
98
|
+
-v, --verbose Turns on console logging. Specify more than once for higher verbosity.
|
|
99
|
+
--log LOG Set the path to write the file log to.
|
|
100
|
+
--config CONFIGPATH Set the path to load the logging config from.
|
|
101
|
+
--out OUTPATH Set the folder to use for the program output. (Default: Current directory)
|
|
102
|
+
--use-filename Sets whether the name of each output is based on the MSG filename.
|
|
103
|
+
--dump-stdout Tells the program to dump the message body (plain text) to stdout. Overrides saving arguments.
|
|
104
|
+
--html Sets whether the output should be HTML. If this is not possible, will error.
|
|
105
|
+
--pdf Saves the body as a PDF. If this is not possible, will error.
|
|
106
|
+
--wk-path WKPATH Overrides the path for finding wkhtmltopdf.
|
|
107
|
+
--wk-options [WKOPTIONS ...]
|
|
108
|
+
Sets additional options to be used in wkhtmltopdf. Should be a series of options and values, replacing the - or -- in the beginning with + or ++ respectively. For example: --wk-options "+O Landscape"
|
|
109
|
+
--wk-allow-external-files
|
|
110
|
+
Enables external files to appear in the PDF output. WARNING: This allows wkpdftohtml to make url requests that are unchecked, and as such may be a security vulnerability in untrusted emails. Only use this option if you trust the source of the MSG file.
|
|
111
|
+
--prepared-html When used in conjunction with --html, sets whether the HTML output should be prepared for embedded attachments.
|
|
112
|
+
--charset CHARSET Character set to use for the prepared HTML in the added tag. (Default: utf-8)
|
|
113
|
+
--raw Sets whether the output should be raw. If this is not possible, will error.
|
|
114
|
+
--rtf Sets whether the output should be RTF. If this is not possible, will error.
|
|
115
|
+
--allow-fallback Tells the program to fallback to a different save type if the selected one is not possible.
|
|
116
|
+
--skip-body-not-found
|
|
117
|
+
Skips saving the body if the body cannot be found, rather than throwing an error.
|
|
118
|
+
--zip ZIP Path to use for saving to a zip file.
|
|
119
|
+
--save-header Store the header in a separate file.
|
|
120
|
+
--attachments-only Specify to only save attachments from an MSG file.
|
|
121
|
+
--skip-hidden Skips any attachment marked as hidden (usually ones embedded in the body).
|
|
122
|
+
--no-folders Stores everything in the location specified by --out. Requires --attachments-only and is incompatible with --out-name.
|
|
123
|
+
--skip-embedded Skips all embedded MSG files when saving attachments.
|
|
124
|
+
--extract-embedded Extracts the embedded MSG files as MSG files instead of running their save functions.
|
|
125
|
+
--overwrite-existing Disables filename conflict resolution code for attachments when saving a file, causing files to be overwritten if two attachments with the same
|
|
126
|
+
filename are on an MSG file.
|
|
127
|
+
--skip-not-implemented, --skip-ni
|
|
128
|
+
Skips any attachments that are not implemented, allowing saving of the rest of the message.
|
|
129
|
+
--out-name OUTNAME Name to be used with saving the file output. Cannot be used if you are saving more than one file.
|
|
130
|
+
--glob, --wildcard Interpret all paths as having wildcards. Incompatible with --out-name.
|
|
131
|
+
--ignore-rtfde Ignores all errors thrown from RTFDE when trying to save. Useful for allowing fallback to continue when an exception happens.
|
|
132
|
+
--progress Shows what file the program is currently working on during it's progress.
|
|
133
|
+
-s, --stdin Read file from stdin (only works with one file at a time).
|
|
129
134
|
|
|
130
135
|
**To use this in your own script**, start by using:
|
|
131
136
|
|
|
@@ -140,7 +145,7 @@ From there, open the MSG file:
|
|
|
140
145
|
msg = extract_msg.openMsg("path/to/msg/file.msg")
|
|
141
146
|
|
|
142
147
|
Alternatively, if you wish to send a msg binary string instead of a file
|
|
143
|
-
to the ``extract_msg.openMsg`` Method:
|
|
148
|
+
to the ``extract_msg.openMsg()`` Method:
|
|
144
149
|
|
|
145
150
|
::
|
|
146
151
|
|
|
@@ -256,14 +261,18 @@ Credits
|
|
|
256
261
|
|
|
257
262
|
`Philippe Lagadec`_ - Python OleFile module developer.
|
|
258
263
|
|
|
264
|
+
`Seamus Tuohy`_ - Developer of the Python RTFDE module. Gave first examples of how to use the module and has worked with Destiny to ensure functionality.
|
|
265
|
+
|
|
266
|
+
`Kadhiraven EG`_ - Discovery of and assistance with vulnerability in PDF conversion, including assistance with updating security policies and notifying the public about the vulnerability.
|
|
267
|
+
|
|
259
268
|
`Joel Kaufman`_ - First implementations of the json and filename flags.
|
|
260
269
|
|
|
261
270
|
`Dean Malmgren`_ - First implementation of the setup.py script.
|
|
262
271
|
|
|
263
|
-
`Seamus Tuohy`_ - Developer of the Python RTFDE module. Gave first examples of how to use the module and has worked with Destiny to ensure functionality.
|
|
264
|
-
|
|
265
272
|
`Liam`_ - Significant reorganization and transfer of data.
|
|
266
273
|
|
|
274
|
+
|
|
275
|
+
|
|
267
276
|
And thank you to everyone who has opened an issue and helped us track down those pesky bugs.
|
|
268
277
|
|
|
269
278
|
Extra
|
|
@@ -278,12 +287,15 @@ your access to the newest major version of extract-msg.
|
|
|
278
287
|
.. |License: GPL v3| image:: https://img.shields.io/badge/License-GPLv3-blue.svg
|
|
279
288
|
:target: LICENSE.txt
|
|
280
289
|
|
|
281
|
-
.. |PyPI3| image:: https://img.shields.io/badge/pypi-0.
|
|
282
|
-
:target: https://pypi.org/project/extract-msg/0.
|
|
290
|
+
.. |PyPI3| image:: https://img.shields.io/badge/pypi-0.57.0-blue.svg
|
|
291
|
+
:target: https://pypi.org/project/extract-msg/0.57.0/
|
|
283
292
|
|
|
284
293
|
.. |PyPI2| image:: https://img.shields.io/badge/python-3.8+-brightgreen.svg
|
|
285
294
|
:target: https://www.python.org/downloads/release/python-3810/
|
|
286
295
|
|
|
296
|
+
.. |Downloads| image:: https://img.shields.io/pypi/dm/extract-msg.svg
|
|
297
|
+
:target: https://pypistats.org/packages/extract-msg
|
|
298
|
+
|
|
287
299
|
.. |Read the Docs| image:: https://readthedocs.org/projects/msg-extractor/badge/?version=latest
|
|
288
300
|
:target: https://msg-extractor.readthedocs.io/en/stable/?badge=latest
|
|
289
301
|
:alt: Documentation Status
|
|
@@ -295,6 +307,7 @@ your access to the newest major version of extract-msg.
|
|
|
295
307
|
.. _Dean Malmgren: https://github.com/deanmalmgren
|
|
296
308
|
.. _Joel Kaufman: https://github.com/joelkaufman
|
|
297
309
|
.. _Liam: https://github.com/LiamPM5
|
|
310
|
+
.. _Kadhiraven EG: https://github.com/JOKER-53
|
|
298
311
|
.. _Seamus Tuohy: https://github.com/seamustuohy
|
|
299
312
|
.. _Discord: https://discord.com/invite/B77McRmzdc
|
|
300
313
|
.. _Buy Me a Coffee: https://www.buymeacoffee.com/DestructionE
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|License: GPL v3| |PyPI3| |PyPI2| |Read the Docs|
|
|
1
|
+
|License: GPL v3| |PyPI3| |PyPI2| |Downloads| |Read the Docs|
|
|
2
2
|
|
|
3
3
|
extract-msg
|
|
4
4
|
=============
|
|
@@ -14,7 +14,7 @@ Documentation can be found in the code, on the `wiki`_, and on the
|
|
|
14
14
|
NOTICE
|
|
15
15
|
======
|
|
16
16
|
0.29.* is the branch that supports both Python 2 and Python 3. It is now only
|
|
17
|
-
receiving
|
|
17
|
+
receiving security fixes and will not be receiving feature updates.
|
|
18
18
|
|
|
19
19
|
0.39.* is the last versions that supported Python 3.6 and 3.7. Support for those
|
|
20
20
|
was dropped to allow the use of new features from 3.8 and because the life spans
|
|
@@ -59,55 +59,59 @@ Currently, the README is in the process of being redone. For now, please
|
|
|
59
59
|
refer to the usage information provided from the program's help dialog:
|
|
60
60
|
::
|
|
61
61
|
|
|
62
|
-
usage: extract_msg [-h] [--use-content-id] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] [--out OUTPATH] [--use-filename] [--dump-stdout] [--html]
|
|
63
|
-
[--
|
|
64
|
-
[--
|
|
65
|
-
|
|
62
|
+
usage: extract_msg [-h] [--use-content-id] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] [--out OUTPATH] [--use-filename] [--dump-stdout] [--html]
|
|
63
|
+
[--pdf] [--wk-path WKPATH] [--wk-options [WKOPTIONS ...]] [--wk-allow-external-files] [--prepared-html] [--charset CHARSET] [--raw] [--rtf]
|
|
64
|
+
[--allow-fallback] [--skip-body-not-found] [--zip ZIP] [--save-header] [--attachments-only] [--skip-hidden] [--no-folders] [--skip-embedded]
|
|
65
|
+
[--extract-embedded] [--overwrite-existing] [--skip-not-implemented] [--out-name OUTNAME | --glob] [--ignore-rtfde] [--progress] [-s]
|
|
66
|
+
[msg ...]
|
|
66
67
|
|
|
67
68
|
extract_msg: Extracts emails and attachments saved in Microsoft Outlook's .msg files. https://github.com/TeamMsgExtractor/msg-extractor
|
|
68
69
|
|
|
69
70
|
positional arguments:
|
|
70
|
-
|
|
71
|
+
msg An MSG file to be parsed.
|
|
71
72
|
|
|
72
73
|
options:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
--
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
74
|
+
-h, --help show this help message and exit
|
|
75
|
+
--use-content-id, --cid
|
|
76
|
+
Save attachments by their Content ID, if they have one. Useful when working with the HTML body.
|
|
77
|
+
--json Changes to write output files as json.
|
|
78
|
+
--file-logging Enables file logging. Implies --verbose level 1.
|
|
79
|
+
-v, --verbose Turns on console logging. Specify more than once for higher verbosity.
|
|
80
|
+
--log LOG Set the path to write the file log to.
|
|
81
|
+
--config CONFIGPATH Set the path to load the logging config from.
|
|
82
|
+
--out OUTPATH Set the folder to use for the program output. (Default: Current directory)
|
|
83
|
+
--use-filename Sets whether the name of each output is based on the MSG filename.
|
|
84
|
+
--dump-stdout Tells the program to dump the message body (plain text) to stdout. Overrides saving arguments.
|
|
85
|
+
--html Sets whether the output should be HTML. If this is not possible, will error.
|
|
86
|
+
--pdf Saves the body as a PDF. If this is not possible, will error.
|
|
87
|
+
--wk-path WKPATH Overrides the path for finding wkhtmltopdf.
|
|
88
|
+
--wk-options [WKOPTIONS ...]
|
|
89
|
+
Sets additional options to be used in wkhtmltopdf. Should be a series of options and values, replacing the - or -- in the beginning with + or ++ respectively. For example: --wk-options "+O Landscape"
|
|
90
|
+
--wk-allow-external-files
|
|
91
|
+
Enables external files to appear in the PDF output. WARNING: This allows wkpdftohtml to make url requests that are unchecked, and as such may be a security vulnerability in untrusted emails. Only use this option if you trust the source of the MSG file.
|
|
92
|
+
--prepared-html When used in conjunction with --html, sets whether the HTML output should be prepared for embedded attachments.
|
|
93
|
+
--charset CHARSET Character set to use for the prepared HTML in the added tag. (Default: utf-8)
|
|
94
|
+
--raw Sets whether the output should be raw. If this is not possible, will error.
|
|
95
|
+
--rtf Sets whether the output should be RTF. If this is not possible, will error.
|
|
96
|
+
--allow-fallback Tells the program to fallback to a different save type if the selected one is not possible.
|
|
97
|
+
--skip-body-not-found
|
|
98
|
+
Skips saving the body if the body cannot be found, rather than throwing an error.
|
|
99
|
+
--zip ZIP Path to use for saving to a zip file.
|
|
100
|
+
--save-header Store the header in a separate file.
|
|
101
|
+
--attachments-only Specify to only save attachments from an MSG file.
|
|
102
|
+
--skip-hidden Skips any attachment marked as hidden (usually ones embedded in the body).
|
|
103
|
+
--no-folders Stores everything in the location specified by --out. Requires --attachments-only and is incompatible with --out-name.
|
|
104
|
+
--skip-embedded Skips all embedded MSG files when saving attachments.
|
|
105
|
+
--extract-embedded Extracts the embedded MSG files as MSG files instead of running their save functions.
|
|
106
|
+
--overwrite-existing Disables filename conflict resolution code for attachments when saving a file, causing files to be overwritten if two attachments with the same
|
|
107
|
+
filename are on an MSG file.
|
|
108
|
+
--skip-not-implemented, --skip-ni
|
|
109
|
+
Skips any attachments that are not implemented, allowing saving of the rest of the message.
|
|
110
|
+
--out-name OUTNAME Name to be used with saving the file output. Cannot be used if you are saving more than one file.
|
|
111
|
+
--glob, --wildcard Interpret all paths as having wildcards. Incompatible with --out-name.
|
|
112
|
+
--ignore-rtfde Ignores all errors thrown from RTFDE when trying to save. Useful for allowing fallback to continue when an exception happens.
|
|
113
|
+
--progress Shows what file the program is currently working on during it's progress.
|
|
114
|
+
-s, --stdin Read file from stdin (only works with one file at a time).
|
|
111
115
|
|
|
112
116
|
**To use this in your own script**, start by using:
|
|
113
117
|
|
|
@@ -122,7 +126,7 @@ From there, open the MSG file:
|
|
|
122
126
|
msg = extract_msg.openMsg("path/to/msg/file.msg")
|
|
123
127
|
|
|
124
128
|
Alternatively, if you wish to send a msg binary string instead of a file
|
|
125
|
-
to the ``extract_msg.openMsg`` Method:
|
|
129
|
+
to the ``extract_msg.openMsg()`` Method:
|
|
126
130
|
|
|
127
131
|
::
|
|
128
132
|
|
|
@@ -238,14 +242,18 @@ Credits
|
|
|
238
242
|
|
|
239
243
|
`Philippe Lagadec`_ - Python OleFile module developer.
|
|
240
244
|
|
|
245
|
+
`Seamus Tuohy`_ - Developer of the Python RTFDE module. Gave first examples of how to use the module and has worked with Destiny to ensure functionality.
|
|
246
|
+
|
|
247
|
+
`Kadhiraven EG`_ - Discovery of and assistance with vulnerability in PDF conversion, including assistance with updating security policies and notifying the public about the vulnerability.
|
|
248
|
+
|
|
241
249
|
`Joel Kaufman`_ - First implementations of the json and filename flags.
|
|
242
250
|
|
|
243
251
|
`Dean Malmgren`_ - First implementation of the setup.py script.
|
|
244
252
|
|
|
245
|
-
`Seamus Tuohy`_ - Developer of the Python RTFDE module. Gave first examples of how to use the module and has worked with Destiny to ensure functionality.
|
|
246
|
-
|
|
247
253
|
`Liam`_ - Significant reorganization and transfer of data.
|
|
248
254
|
|
|
255
|
+
|
|
256
|
+
|
|
249
257
|
And thank you to everyone who has opened an issue and helped us track down those pesky bugs.
|
|
250
258
|
|
|
251
259
|
Extra
|
|
@@ -260,12 +268,15 @@ your access to the newest major version of extract-msg.
|
|
|
260
268
|
.. |License: GPL v3| image:: https://img.shields.io/badge/License-GPLv3-blue.svg
|
|
261
269
|
:target: LICENSE.txt
|
|
262
270
|
|
|
263
|
-
.. |PyPI3| image:: https://img.shields.io/badge/pypi-0.
|
|
264
|
-
:target: https://pypi.org/project/extract-msg/0.
|
|
271
|
+
.. |PyPI3| image:: https://img.shields.io/badge/pypi-0.57.0-blue.svg
|
|
272
|
+
:target: https://pypi.org/project/extract-msg/0.57.0/
|
|
265
273
|
|
|
266
274
|
.. |PyPI2| image:: https://img.shields.io/badge/python-3.8+-brightgreen.svg
|
|
267
275
|
:target: https://www.python.org/downloads/release/python-3810/
|
|
268
276
|
|
|
277
|
+
.. |Downloads| image:: https://img.shields.io/pypi/dm/extract-msg.svg
|
|
278
|
+
:target: https://pypistats.org/packages/extract-msg
|
|
279
|
+
|
|
269
280
|
.. |Read the Docs| image:: https://readthedocs.org/projects/msg-extractor/badge/?version=latest
|
|
270
281
|
:target: https://msg-extractor.readthedocs.io/en/stable/?badge=latest
|
|
271
282
|
:alt: Documentation Status
|
|
@@ -277,6 +288,7 @@ your access to the newest major version of extract-msg.
|
|
|
277
288
|
.. _Dean Malmgren: https://github.com/deanmalmgren
|
|
278
289
|
.. _Joel Kaufman: https://github.com/joelkaufman
|
|
279
290
|
.. _Liam: https://github.com/LiamPM5
|
|
291
|
+
.. _Kadhiraven EG: https://github.com/JOKER-53
|
|
280
292
|
.. _Seamus Tuohy: https://github.com/seamustuohy
|
|
281
293
|
.. _Discord: https://discord.com/invite/B77McRmzdc
|
|
282
294
|
.. _Buy Me a Coffee: https://www.buymeacoffee.com/DestructionE
|
|
@@ -11,7 +11,7 @@ https://github.com/TeamMsgExtractor/msg-extractor
|
|
|
11
11
|
|
|
12
12
|
# --- LICENSE.txt --------------------------------------------------------------
|
|
13
13
|
#
|
|
14
|
-
# Copyright 2013-
|
|
14
|
+
# Copyright 2013-2026 Matthew Walker and Destiny Peterson
|
|
15
15
|
#
|
|
16
16
|
# This program is free software: you can redistribute it and/or modify
|
|
17
17
|
# it under the terms of the GNU General Public License as published by
|
|
@@ -27,8 +27,8 @@ https://github.com/TeamMsgExtractor/msg-extractor
|
|
|
27
27
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
28
28
|
|
|
29
29
|
__author__ = 'Destiny Peterson & Matthew Walker'
|
|
30
|
-
__date__ = '2026-
|
|
31
|
-
__version__ = '0.
|
|
30
|
+
__date__ = '2026-10-24'
|
|
31
|
+
__version__ = '0.57.0'
|
|
32
32
|
|
|
33
33
|
__all__ = [
|
|
34
34
|
# Modules:
|
|
@@ -63,6 +63,7 @@ def main(argv: List[str] = sys.argv) -> None:
|
|
|
63
63
|
'useMsgFilename': args.useFilename,
|
|
64
64
|
'wkOptions': args.wkOptions,
|
|
65
65
|
'wkPath': args.wkPath,
|
|
66
|
+
'wkAllowExternalFiles': args.allowExternalFiles,
|
|
66
67
|
'zip': _zip,
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -101,7 +102,7 @@ def main(argv: List[str] = sys.argv) -> None:
|
|
|
101
102
|
msg.saveAttachments(**kwargs)
|
|
102
103
|
else:
|
|
103
104
|
msg.save(**kwargs)
|
|
104
|
-
except Exception
|
|
105
|
+
except Exception:
|
|
105
106
|
try:
|
|
106
107
|
print(f'Error with file "{x}": {traceback.format_exc()}')
|
|
107
108
|
except UnicodeEncodeError:
|
|
@@ -111,5 +112,6 @@ def main(argv: List[str] = sys.argv) -> None:
|
|
|
111
112
|
if createdZip:
|
|
112
113
|
_zip.close()
|
|
113
114
|
|
|
115
|
+
|
|
114
116
|
if __name__ == '__main__':
|
|
115
117
|
main(sys.argv)
|
{extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/lnk_obj_att.py
RENAMED
|
@@ -7,7 +7,7 @@ __all__ = [
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
from functools import cached_property
|
|
10
|
-
from typing import
|
|
10
|
+
from typing import Optional, TYPE_CHECKING
|
|
11
11
|
|
|
12
12
|
from . import registerHandler
|
|
13
13
|
from .custom_handler import CustomAttachmentHandler
|
|
@@ -106,4 +106,4 @@ class LinkedObjectAttachment(CustomAttachmentHandler):
|
|
|
106
106
|
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
registerHandler(LinkedObjectAttachment)
|
|
109
|
+
registerHandler(LinkedObjectAttachment)
|
|
@@ -66,7 +66,7 @@ HEADER_FORMAT_VALUE_TYPE = Union[str, Tuple[Union[str, None], bool], None]
|
|
|
66
66
|
# Basically a dict of HEADER_FORMAT_TYPE and dicts containing them.
|
|
67
67
|
HEADER_FORMAT_TYPE = Optional[Dict[str, Union[HEADER_FORMAT_VALUE_TYPE, Dict[str, HEADER_FORMAT_VALUE_TYPE]]]]
|
|
68
68
|
SAVE_TYPE = Tuple[SaveType, Union[List[str], str, None]]
|
|
69
|
-
MSG_PATH = Union[str, List[str], Tuple[str]]
|
|
69
|
+
MSG_PATH = Union[str, List[str], Tuple[str, ...]]
|
|
70
70
|
# Type used for the getXAs methods' overrideClass argument.
|
|
71
71
|
OVERRIDE_CLASS = Union[Type[_T], Callable[[Any], _T]]
|
|
72
72
|
|
|
@@ -43,4 +43,4 @@ PSETID_AIRSYNC: Final[str] = '{71035549-0739-4DCB-9163-00F0580DBBDF}'
|
|
|
43
43
|
PSETID_SHARING: Final[str] = '{00062040-0000-0000-C000-000000000046}'
|
|
44
44
|
PSETID_XMLEXTRACTEDENTITIES: Final[str] = '{23239608-685D-4732-9C55-4C95CB4E8E33}'
|
|
45
45
|
PSETID_ATTACHMENT: Final[str] = '{96357F7F-59E1-47D0-99A7-46515C183B54}'
|
|
46
|
-
PSETID_CALENDAR_ASSISTANT: Final[str] = '{11000E07-B51B-40D6-AF21-CAA85EDAB1D0}'
|
|
46
|
+
PSETID_CALENDAR_ASSISTANT: Final[str] = '{11000E07-B51B-40D6-AF21-CAA85EDAB1D0}'
|
|
@@ -4,6 +4,7 @@ Regular expression constants.
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
__all__ = [
|
|
7
|
+
'CSS_URL',
|
|
7
8
|
'HTML_BODY_START',
|
|
8
9
|
'HTML_SAN_SPACE',
|
|
9
10
|
'INVALID_FILENAME_CHARS',
|
|
@@ -52,3 +53,6 @@ RTF_BODY_STRIP_INIT: Final[_RE_BYTES_TYPE] = re.compile(rb'(\\htmlrtf[^0{}][^{}]
|
|
|
52
53
|
# Preprocessing steps to simplify the RTF.
|
|
53
54
|
RTF_BODY_STRIP_PRE_CLOSE: Final[_RE_BYTES_TYPE] = re.compile(rb'(\\htmlrtf1? ?}\\htmlrtf0 ?)|(\\htmlrtf1? ?[^0{}][^{}]*?} ?\\htmlrtf0 ?)')
|
|
54
55
|
RTF_BODY_STRIP_PRE_OPEN: Final[_RE_BYTES_TYPE] = re.compile(rb'\\htmlrtf1? ?{[^{}]*?\\htmlrtf0 ?')
|
|
56
|
+
|
|
57
|
+
# Used for stripping urls from CSS.
|
|
58
|
+
CSS_URL: Final[_RE_STR_TYPE] = re.compile(r'url\(\s*["\']?(https?:\/\/[^"\')\s]+)["\']?\s*\)', re.I)
|
|
@@ -93,7 +93,7 @@ ST_BE_UI8: Final[struct.Struct] = struct.Struct('>B')
|
|
|
93
93
|
ST_BE_UI16: Final[struct.Struct] = struct.Struct('>H')
|
|
94
94
|
ST_BE_UI32: Final[struct.Struct] = struct.Struct('>I')
|
|
95
95
|
ST_BE_UI64: Final[struct.Struct] = struct.Struct('>Q')
|
|
96
|
-
ST_BE_F32: Final[struct.Struct]
|
|
96
|
+
ST_BE_F32: Final[struct.Struct] = struct.Struct('>f')
|
|
97
97
|
ST_BE_F64: Final[struct.Struct] = struct.Struct('>d')
|
|
98
98
|
# Structs that use the system byte order, where consistency on a single system
|
|
99
99
|
# is all that matters. Mainly used for quick casts between signed and unsigned.
|
|
@@ -107,4 +107,4 @@ ST_SBO_UI32: Final[struct.Struct] = struct.Struct('@I')
|
|
|
107
107
|
ST_SBO_UI64: Final[struct.Struct] = struct.Struct('@Q')
|
|
108
108
|
# Struct for an RGB value that, in little endian, would be an int written in hex
|
|
109
109
|
# as 0x00BBGGRR.
|
|
110
|
-
ST_RGB: Final[struct.Struct] = struct.Struct('<BBBx')
|
|
110
|
+
ST_RGB: Final[struct.Struct] = struct.Struct('<BBBx')
|