Skip to content

Commit 3074f0a

Browse files
committed
add simple documentation on summary and some minor enhancements
1 parent 67a5dcd commit 3074f0a

5 files changed

Lines changed: 43 additions & 6 deletions

File tree

README.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ A sample `.mbox` file is provided to you, but you can obtain export your own mai
3636

3737

3838
```python
39+
from emailnetwork.extract import MBoxReader
3940
reader = MBoxReader('path-to-mbox.mbox')
4041
print(f'{len(reader)} emails in the sample mbox.')
4142

@@ -56,6 +57,7 @@ emails = reader.extract()
5657

5758
For graph visualization:
5859
```py
60+
from emailnetwork.extract import MBoxReader
5961
# Read from .mbox
6062
MBOX_PATH = f'{os.path.dirname(__file__)}/tests/test.mbox'
6163
reader = MBoxReader(MBOX_PATH)
@@ -89,6 +91,34 @@ headers.histogram()
8991
```
9092
Because `HeaderCounter` is a subclass of Python's `Counter`, you can also perform operations such as `headers.most_common(8)` to get the 8 most-common headers from the `mbox` file.
9193

94+
If you want to find all email headers with the word "spam" in it (e.g spam score, other antispam mechanism), you can use Python's `filter()` function:
95+
```python
96+
reader = MBoxReader('path-to-mbox')
97+
headers = HeaderCounter(reader)
98+
spamheaders = list(filter(lambda v: "spam" in v.lower(), headers.keys()))
99+
# return:
100+
# ['X-Spam-Checked-In-Group', 'X-Microsoft-Antispam-PRVS', 'X-Microsoft-Antispam-Untrusted', 'X-Microsoft-Antispam-Message-Info-Original', 'X-Forefront-Antispam-Report-Untrusted', 'x-ms-exchange-antispam-messagedata', 'X-Microsoft-Antispam', 'X-Microsoft-Antispam-Message-Info', 'X-Forefront-Antispam-Report', 'X-Mimecast-Spam-Score', 'x-microsoft-antispam-prvs', 'x-microsoft-antispam', 'x-microsoft-antispam-message-info', 'x-forefront-antispam-report']
101+
```
102+
103+
#### Mailbox Summary
104+
105+
To get a simple barchart on the distribution of email domains in your `.mbox`, you can create a `DomainSummary` object and call the `.plot()` function:
106+
107+
```python
108+
from emailnetwork.summary import DomainSummary
109+
summary = DomainSummary(reader)
110+
summary.plot()
111+
```
112+
113+
![](assets/summaryplot.png)
114+
115+
You can also return a `Counter()` (a subclass of `dict`) instead of a plot:
116+
117+
```python
118+
summary.summary
119+
# return:
120+
# Counter({'supertype.ai': 203, 'hubspot.com': 115, 'gmail.com': 75, 'google.com': 53, 'adcolony.com': 38, 'fbworkmail.com': 35, 'elementor.com': 29, 'payoneer.com': 15, 'gogame.net': 14, 'zoomd.com': 13, 'am.atlassian.com': 10, 'theafternaut.com': 6, 'alegrium.com': 5, 'accounts.google.com': 4, 'e.atlassian.com': 4, 'tnbaura.com': 4, 'support.lazada.sg': 4, '3kraters.com': 3, 'go.facebookmail.com': 2, 'docs.google.com': 2, 'mail.hellosign.com': 2, 'algorit.ma': 2, 'supertype.atlassian.net': 2, 'ucdconnect.ie': 2, 'mc.facebookmail.com': 1, 'inplacesoftware.com': 1, 'aura.co': 1, 'atlassian.com': 1, 'greenhouse.io': 1})
121+
```
92122
##### Why Python 3.7+?
93123
Python 3.7+ is required because the package is written to take advantage of many features of Python 3.7 and above.
94124

@@ -125,7 +155,9 @@ All tests are located in the `/tests/` directory.
125155

126156
## Authors and Copyright
127157

128-
Samuel Chan, Supertype [https://supertype.ai](https://supertype.ai)
158+
Samuel Chan, Supertype [Supertype](https://supertype.ai)
159+
160+
Vincentius Christopher Calvin, Supertype [https://supertype.ai](https://supertype.ai)
129161

130162
If you find the code useful in your project, please link to this repository in your citation.
131163

assets/summaryplot.png

158 KB
Loading

emailnetwork/extract.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,14 @@ def filter_emails(self, emailaddress=None, datestring=None, dateoperator="=="):
137137

138138

139139
if __name__ == '__main__':
140-
# reader = MBoxReader('/Users/samuel/Footprints/samuel-supertype.mbox')
141-
reader = MBoxReader('/Users/vincentiuscalvin/Documents/Supertype/mbox-dataset/Ori_Sample_01.mbox')
140+
reader = MBoxReader('/Users/samuel/Footprints/samuel-supertype.mbox')
141+
# reader = MBoxReader('/Users/vincentiuscalvin/Documents/Supertype/mbox-dataset/Ori_Sample_01.mbox')
142+
headers = HeaderCounter(reader)
143+
k = headers.keys()
144+
spamheaders = list(filter(lambda v: "spam" in v.lower(), k))
145+
146+
summary = DomainSummary(reader)
147+
142148
email = reader.mbox[1]
143149
emailmsg = extract_meta(email)
144150
emailbody = extract_body(email)

emailnetwork/tests/test_graph.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import os
2-
from unittest import TestCase
3-
from unittest import mock
2+
from unittest import TestCase, mock
43

54
from emailnetwork.extract import MBoxReader
65
# from emailnetwork.graph import plot_single_email

emailnetwork/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def clean_subject(subject):
3838
except:
3939
return subject.decode('utf-8').strip()
4040
else:
41-
return subject.strip()
41+
return subject.strip().replace('\r\n', '')
4242

4343

4444
def clean_body(email):

0 commit comments

Comments
 (0)