-
Notifications
You must be signed in to change notification settings - Fork 1
/
email_attachment_export.py
143 lines (122 loc) · 5.37 KB
/
email_attachment_export.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# -*- coding: utf-8 -*-
"""Module for exporting attachments from Outlook desktop Application."""
import os
import win32com.client
from datetime import datetime, timedelta
class Export:
"""Export base class."""
def __init__(self, dst=''):
"""Initialize an export.
Parameters
----------
dst: str
Location to place exported files (Default: Downloads folder).
"""
if not dst:
# Find path to user's Downloads folder
oShell = win32com.client.Dispatch("Wscript.Shell")
downloads = oShell.RegRead(
'HKEY_CURRENT_USER\\Software\Microsoft\\Windows'
'\\CurrentVersion\\Explorer\\User Shell Folders'
'\\{374DE290-123F-4565-9164-39C4925E467B}')
assert os.path.exists(downloads), 'downloads path does not exist'
self.dst = downloads
else:
assert os.path.exists(dst), 'destination path does not exist'
self.dst = dst
self.exported_files = []
def rename_file(self, file_index, new_name):
"""Rename a file in self.exported_files.
Parameters
----------
file_index: int
The index of the file in self.exported_files to be renamed.
new_name: str
The new name of the file.
"""
assert isinstance(file_index, int)
assert isinstance(new_name, str)
exported_file = self.exported_files[file_index]
# Separate folder path from filename
head, tail = os.path.split(exported_file)
# Get the current file extension
name, extension = os.path.splitext(tail)
# Create path for new filename
if '.' in new_name:
new_file = os.path.join(head, new_name)
else:
new_file = os.path.join(head, new_name + extension)
# Rename file
os.rename(exported_file, new_file)
# Drop old file from self.exported_files
self.exported_files.pop(file_index)
# Append new file to self.exported_files
self.exported_files.append(new_file)
class EmailExport(Export):
"""A class for email attachment exports."""
def export_email_attachment(self, subject, lookback=0,
inbox_subfolder=None,
date=None):
"""Export an attachment with a specific subject and lookback.
Parameters
----------
subject: str
A keyword to find in an email subject line.
lookback: int
The number of days to look back for an email (Default: 0 = today).
inbox_subfolder: str
The name of an Email inbox subfolder (Default: None).
date: tuple
A date used for filtering emails (Format: month, day, 4-d year).
Returns
----------
exported_files: list
The exported attachment paths.
"""
# Parse email inbox
outlook = win32com.client.Dispatch(
"Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6) # Go to the inbox folder "6"
# Specify a subfolder to search
if inbox_subfolder:
messages = inbox.Folders.Item(inbox_subfolder).Items
else:
messages = inbox.Items # Get all the messages
if lookback:
# Search emails x days ago
date = datetime.now() - timedelta(days=lookback)
start = datetime(date.year, date.month, date.day)\
.strftime('%m/%d/%Y 12:00AM')
end = datetime(date.year, date.month, date.day)\
.strftime('%m/%d/%Y 11:59PM')
date_filter = ("[LastModificationTime] >= \'{}\' AND "
"[LastModificationTime] <= \'{}\'"
.format(start, end))
elif date:
# Search emails on a specified date
start = datetime(date[-1], date[0], date[1])\
.strftime('%m/%d/%Y 12:00AM')
end = datetime(date[-1], date[0], date[1])\
.strftime('%m/%d/%Y 11:59PM')
date_filter = ("[LastModificationTime] >= \'{}\' AND "
"[LastModificationTime] <= \'{}\'"
.format(start, end))
else:
# If no lookback or date is specified search current day emails
date_filter = "@SQL=%today(DAV:getlastmodified)%"
# Emails between start and end dates
inbox_by_date = messages.Restrict(date_filter)
# Search email subjects for a specified keyword
subject_tag = ('http://schemas.microsoft.com/mapi/proptag/0x0037001E '
"ci_phrasematch '{}'".format(subject))
subject_filter = '@SQL={}'.format(subject_tag)
inbox_subject = inbox_by_date.Restrict(subject_filter)
# Download attachment
message = inbox_subject.GetLast() # Get last email from results
attachments = message.Attachments
# Download all attachments in email
for attachment in attachments:
attachment_path = os.path.join(self.dst, attachment.FileName)
attachment.SaveAsFile(attachment_path)
self.exported_files.append(attachment_path)
return self.exported_files