Skip to content

Commit e2b67d7

Browse files
Merge pull request #403 from TeamMsgExtractor/next-release
Version 0.48.0
2 parents 732414b + b236c77 commit e2b67d7

30 files changed

+561
-412
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
**v0.48.0**
2+
* Adjusted error handling for named properties to handle critical streams being missing and to allow suppression of those errors.
3+
* Adjusted error handling for named properties to allow silencing of errors caused by invalid references to the name stream. If `ErrorBehavior.NAMED_NAME_STREAM` is provided to the `MSGFile` instance, a warning will be logged and that entry will simply be dropped.
4+
* Adjusted error handling for signed messages to better check for issues with the signed attachment. This should make errors from violating the standard much easier to understand. These errors can be ignored, but the attachment will *not* be parsed as a signed attachment.
5+
* Minor docstring updates.
6+
* Minor adjustments to `OleWriter` to prepare the code for being able to write version 4 files. Version 3 files are currently the only one's supported, but much of the code had hard-coded values that could be replaced with variables and small conditionals. This will have very little performance impact, and should not be noticeable.
7+
* Improved comments on `OleWriter` to make private sections more understandable.
8+
* Changed `MessageSignedBase._rawAttachments` to `MessageSignedBase.rawAttachments` to provide non-private access in a reliable way.
9+
110
**v0.47.0**
211
* Changed the public API for `PropertiesStore` to improve the quality of its code. The properties type is now mandatory, and the intelligence field (and the related enum) has been removed.
312
* Additionally, the `toBytes` and `__bytes__` methods will both generate based on the contents of this class, allowing for new properties to be created and for existing properties to be modified or removed if the class is set to writable on creation.

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ your access to the newest major version of extract-msg.
259259
.. |License: GPL v3| image:: https://img.shields.io/badge/License-GPLv3-blue.svg
260260
:target: LICENSE.txt
261261

262-
.. |PyPI3| image:: https://img.shields.io/badge/pypi-0.47.0-blue.svg
263-
:target: https://pypi.org/project/extract-msg/0.47.0/
262+
.. |PyPI3| image:: https://img.shields.io/badge/pypi-0.48.0-blue.svg
263+
:target: https://pypi.org/project/extract-msg/0.48.0/
264264

265265
.. |PyPI2| image:: https://img.shields.io/badge/python-3.8+-brightgreen.svg
266266
:target: https://www.python.org/downloads/release/python-3810/

docs/_gen.py

Lines changed: 141 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,142 @@
1-
"""
2-
Helper script for generating the necessary RST files.
3-
"""
4-
5-
import os
6-
import pathlib
7-
8-
from typing import Dict, List, NamedTuple, Tuple
9-
10-
11-
DIRECTORY = pathlib.Path(__file__).parent
12-
13-
14-
class Package(NamedTuple):
15-
"""
16-
A class representing one of the subpackages of a module.
17-
"""
18-
modules: List[str]
19-
packages: List[str]
20-
21-
22-
23-
def _readProject(root) -> Dict[str, Dict[str, bool]]:
24-
"""
25-
Searches a project for Python files, using their locations to create a
26-
dictionary of module paths and their submodules/subpackages. Submodules/subpackages will be a dictionary, where the key is the name and the
27-
"""
28-
# This whole function could almost certainly be optimized, but I'll worry
29-
# about that some other time.
30-
root = pathlib.Path(root)
31-
rootName = root.name
32-
ret = {rootName: {}}
33-
for x in root.glob('**/*.py'):
34-
# Ignore internal files.
35-
if x.name.startswith('_'):
36-
continue
37-
38-
# Get all parent components.
39-
parents = []
40-
parent = x.parent
41-
while parent != root:
42-
parents.append(parent.name)
43-
parent = parent.parent
44-
45-
# Check if any of the parents start with an underscore. If they do,
46-
# ignore the current path.
47-
if any(y.startswith('_') for y in parents):
48-
continue
49-
50-
parents.append(rootName)
51-
52-
parents.reverse()
53-
54-
# Add the subpackages and submodules.
55-
for index, name in enumerate(parents[1:]):
56-
path = '.'.join(parents[:index + 1])
57-
if path not in ret:
58-
ret[path] = {}
59-
if name not in ret[path]:
60-
ret[path][name] = True
61-
if (path := '.'.join(parents)) not in ret:
62-
ret[path] = {}
63-
ret[path][x.name] = False
64-
65-
return ret
66-
67-
68-
def _makePackage(name: str, data: Dict[str, bool]) -> Package:
69-
return Package([f'{name}.{x}' for x in data if not data[x]], [f'{name}.{x}' for x in data if data[x]])
70-
71-
72-
def run():
73-
for x in getAutoGenerated():
74-
os.remove(DIRECTORY / x)
75-
project = readProject(DIRECTORY.parent / 'extract_msg')
76-
for x, y in project.items():
77-
generateFile(x, y)
78-
79-
writeAutoGenerated((x + '.rst' for x in project))
80-
81-
82-
def generateFile(name: str, package: Package):
83-
with open(DIRECTORY / (name + '.rst'), 'w') as f:
84-
# Header.
85-
temp = name.replace('_', '\\_') + ' package'
86-
f.write(f'{temp}\n{"=" * len(temp)}\n\n')
87-
88-
# Subpackages.
89-
if package.packages:
90-
f.write('Subpackages\n-----------\n\n')
91-
f.write('.. toctree::\n')
92-
f.write(' :maxdepth: 4\n\n')
93-
f.write(' ' + '\n '.join(package.packages))
94-
f.write('\n\n')
95-
96-
# Submodules.
97-
if package.modules:
98-
f.write('Submodules\n----------\n\n')
99-
for module in package.modules:
100-
temp = module.replace('_', '\\_') + ' module'
101-
f.write(f'{temp}\n{"-" * len(temp)}\n\n')
102-
f.write(f'.. automodule:: {module}\n')
103-
f.write(' :members:\n')
104-
f.write(' :undoc-members:\n')
105-
f.write(' :show-inheritance:\n\n')
106-
107-
# Module contents.
108-
f.write('Module contents\n---------------\n\n')
109-
f.write(f'.. automodule:: {name}\n')
110-
f.write(' :members:\n')
111-
f.write(' :undoc-members:\n')
112-
f.write(' :show-inheritance:\n')
113-
114-
115-
def getAutoGenerated() -> List[str]:
116-
"""
117-
Retrieves the list of previously autogenerated files.
118-
"""
119-
with open(DIRECTORY / '_autogen.txt', 'r') as f:
120-
return [x.strip() for x in f if x]
121-
122-
123-
def readProject(root) -> Dict[str, Package]:
124-
"""
125-
Returns a dictionary of package names to Package instances for a project.
126-
"""
127-
initialRead = _readProject(root)
128-
return {x: _makePackage(x, y) for x, y in initialRead.items()}
129-
130-
131-
def writeAutoGenerated(files: List[str]) -> None:
132-
"""
133-
Writes the _autogen.txt file.
134-
"""
135-
with open(DIRECTORY / '_autogen.txt', 'w') as f:
136-
f.write('\n'.join(files))
137-
138-
139-
if __name__ == '__main__':
1+
"""
2+
Helper script for generating the necessary RST files.
3+
"""
4+
5+
import os
6+
import pathlib
7+
8+
from typing import Dict, List, NamedTuple, Tuple
9+
10+
11+
DIRECTORY = pathlib.Path(__file__).parent
12+
13+
14+
class Package(NamedTuple):
15+
"""
16+
A class representing one of the subpackages of a module.
17+
"""
18+
modules: List[str]
19+
packages: List[str]
20+
21+
22+
23+
def _readProject(root) -> Dict[str, Dict[str, bool]]:
24+
"""
25+
Searches a project for Python files, using their locations to create a
26+
dictionary of module paths and their submodules/subpackages. Submodules/subpackages will be a dictionary, where the key is the name and the
27+
"""
28+
# This whole function could almost certainly be optimized, but I'll worry
29+
# about that some other time.
30+
root = pathlib.Path(root)
31+
rootName = root.name
32+
ret = {rootName: {}}
33+
for x in root.glob('**/*.py'):
34+
# Ignore internal files.
35+
if x.name.startswith('_'):
36+
continue
37+
38+
# Get all parent components.
39+
parents = []
40+
parent = x.parent
41+
while parent != root:
42+
parents.append(parent.name)
43+
parent = parent.parent
44+
45+
# Check if any of the parents start with an underscore. If they do,
46+
# ignore the current path.
47+
if any(y.startswith('_') for y in parents):
48+
continue
49+
50+
parents.append(rootName)
51+
52+
parents.reverse()
53+
54+
# Add the subpackages and submodules.
55+
for index, name in enumerate(parents[1:]):
56+
path = '.'.join(parents[:index + 1])
57+
if path not in ret:
58+
ret[path] = {}
59+
if name not in ret[path]:
60+
ret[path][name] = True
61+
if (path := '.'.join(parents)) not in ret:
62+
ret[path] = {}
63+
ret[path][x.name] = False
64+
65+
return ret
66+
67+
68+
def _makePackage(name: str, data: Dict[str, bool]) -> Package:
69+
return Package([f'{name}.{x}' for x in data if not data[x]], [f'{name}.{x}' for x in data if data[x]])
70+
71+
72+
def run():
73+
for x in getAutoGenerated():
74+
os.remove(DIRECTORY / x)
75+
project = readProject(DIRECTORY.parent / 'extract_msg')
76+
for x, y in project.items():
77+
generateFile(x, y)
78+
79+
writeAutoGenerated((x + '.rst' for x in project))
80+
81+
82+
def generateFile(name: str, package: Package):
83+
with open(DIRECTORY / (name + '.rst'), 'w') as f:
84+
# Header.
85+
temp = name.replace('_', '\\_') + ' package'
86+
f.write(f'{temp}\n{"=" * len(temp)}\n\n')
87+
88+
# Subpackages.
89+
if package.packages:
90+
f.write('Subpackages\n-----------\n\n')
91+
f.write('.. toctree::\n')
92+
f.write(' :maxdepth: 4\n\n')
93+
f.write(' ' + '\n '.join(package.packages))
94+
f.write('\n\n')
95+
96+
# Submodules.
97+
if package.modules:
98+
f.write('Submodules\n----------\n\n')
99+
for module in package.modules:
100+
if module.endswith('.py'):
101+
module = module[:-3]
102+
temp = module.replace('_', '\\_') + ' module'
103+
f.write(f'{temp}\n{"-" * len(temp)}\n\n')
104+
f.write(f'.. automodule:: {module}\n')
105+
f.write(' :members:\n')
106+
f.write(' :undoc-members:\n')
107+
f.write(' :show-inheritance:\n\n')
108+
109+
# Module contents.
110+
f.write('Module contents\n---------------\n\n')
111+
f.write(f'.. automodule:: {name}\n')
112+
f.write(' :members:\n')
113+
f.write(' :undoc-members:\n')
114+
f.write(' :show-inheritance:\n')
115+
116+
117+
def getAutoGenerated() -> List[str]:
118+
"""
119+
Retrieves the list of previously autogenerated files.
120+
"""
121+
with open(DIRECTORY / '_autogen.txt', 'r') as f:
122+
return [x.strip() for x in f if x]
123+
124+
125+
def readProject(root) -> Dict[str, Package]:
126+
"""
127+
Returns a dictionary of package names to Package instances for a project.
128+
"""
129+
initialRead = _readProject(root)
130+
return {x: _makePackage(x, y) for x, y in initialRead.items()}
131+
132+
133+
def writeAutoGenerated(files : List[str]) -> None:
134+
"""
135+
Writes the _autogen.txt file.
136+
"""
137+
with open(DIRECTORY / '_autogen.txt', 'w') as f:
138+
f.write('\n'.join(files))
139+
140+
141+
if __name__ == '__main__':
140142
run()

docs/extract_msg.attachments.custom_att_handler.rst

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,26 @@ extract\_msg.attachments.custom\_att\_handler package
44
Submodules
55
----------
66

7-
extract\_msg.attachments.custom\_att\_handler.custom\_handler.py module
8-
-----------------------------------------------------------------------
7+
extract\_msg.attachments.custom\_att\_handler.custom\_handler module
8+
--------------------------------------------------------------------
99

10-
.. automodule:: extract_msg.attachments.custom_att_handler.custom_handler.py
10+
.. automodule:: extract_msg.attachments.custom_att_handler.custom_handler
1111
:members:
1212
:undoc-members:
1313
:show-inheritance:
1414

15-
extract\_msg.attachments.custom\_att\_handler.lnk\_obj\_att.py module
16-
---------------------------------------------------------------------
15+
extract\_msg.attachments.custom\_att\_handler.lnk\_obj\_att module
16+
------------------------------------------------------------------
1717

18-
.. automodule:: extract_msg.attachments.custom_att_handler.lnk_obj_att.py
18+
.. automodule:: extract_msg.attachments.custom_att_handler.lnk_obj_att
1919
:members:
2020
:undoc-members:
2121
:show-inheritance:
2222

23-
extract\_msg.attachments.custom\_att\_handler.outlook\_image\_dib.py module
24-
---------------------------------------------------------------------------
23+
extract\_msg.attachments.custom\_att\_handler.outlook\_image\_dib module
24+
------------------------------------------------------------------------
2525

26-
.. automodule:: extract_msg.attachments.custom_att_handler.outlook_image_dib.py
26+
.. automodule:: extract_msg.attachments.custom_att_handler.outlook_image_dib
2727
:members:
2828
:undoc-members:
2929
:show-inheritance:

0 commit comments

Comments
 (0)