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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276 | #------------------------------------------------------------------------------
# Name: attdownload.py
# Author: Suresh Kumar MP
# Last Modified: 09/29/06
# Description: This python script monitors the IMAP mail server for the given
# account and moves the mails with attachments to "Downloadedmails"
# folder in server after downloading the attachments to the individual
# directories on localmachine with a timestamp.
#------------------------------------------------------------------------------
import getopt, getpass, os, sys, time
import imaplib
import email, email.Errors, email.Header, email.Message, email.Utils
from time import strftime
from time import sleep
Usage = """Usage: %s --user <user> --password <password> --frequency <polling frequency> <imap-server>
--user Provide <user> for authentication on <imap-server>
--password Password for the given user
--frequency Provide the mail server polling frequency in seconds
Example: attdownload.py --user username --password password --frequency 300 10.133.23.124
"""
AttachDir = '.' # Attachment Directory Path
DeleteMessages = 0
SaveAttachments = 1 # Save all attachments found
User = None # IMAP4 user
Password = None # User password
Frequency = None # Mail server polling frequency
exists = 0
name = 0
def usage(reason=''):
sys.stdout.flush()
if reason: sys.stderr.write('\t%s\n\n' % reason)
head, tail = os.path.split(sys.argv[0])
sys.stderr.write(Usage % tail)
sys.exit(1)
def args():
try:
optlist, args = getopt.getopt(sys.argv[1:], '?',['user=', 'password=', 'frequency='])
except getopt.error, val:
usage(val)
global SaveAttachments
global User
global Password
global Frequency
for opt,val in optlist:
if opt == '--user':
User = val
elif opt == '--password':
Password = val
elif opt == '--frequency':
Frequency = float(val)
else:
usage()
if len(args) != 1:
usage()
return args[0]
def write_file(filename, addr, data):
os.chdir(addr)
fd = open(filename, "wb")
fd.write(data)
fd.close()
def gen_filename(name, mtyp, addr, date, n):
timepart = strftime("%d %b %y %H_%M_%S")
file = email.Header.decode_header(name)[0][0]
file = os.path.basename(file)
print "Saved attachment " + file + " from " + addr
print "\n"
path = os.path.join(AttachDir, file)
pre, ext = os.path.splitext(file)
pre = pre + "_" + timepart
path = '%s%s' % (os.path.join(AttachDir, pre), ext)
return path
def error(reason):
sys.stderr.write('%s\n' % reason)
sys.exit(1)
def walk_parts(msg, addr, date, count, msgnum):
for part in msg.walk():
if part.is_multipart():
continue
dtypes = part.get_params(None, 'Content-Disposition')
if not dtypes:
if part.get_content_type() == 'text/plain':
continue
ctypes = part.get_params()
if not ctypes:
continue
for key,val in ctypes:
if key.lower() == 'name':
filename = gen_filename(val, part.get_content_type(), addr, date, count)
break
else:
continue
else:
attachment,filename = None,None
for key,val in dtypes:
key = key.lower()
if key == 'filename':
filename = val
if key == 'attachment':
attachment = 1
if not attachment:
continue
filename = gen_filename(filename, part.get_content_type(), addr, date, count)
try:
data = part.get_payload(decode=1)
except:
typ, val = sys.exc_info()[:2]
warn("Message %s attachment decode error: %s for %s ``%s''"
% (msgnum, str(val), part.get_content_type(), filename))
continue
if not data:
warn("Could not decode attachment %s for %s"
% (part.get_content_type(), filename))
continue
if type(data) is type(msg):
count = walk_parts(data, addr, date, count, msgnum)
continue
if SaveAttachments:
exists = "0"
try:
curdir= os.getcwd()
list = os.listdir('.\\')
for name in list:
if name == addr:
exists = "1"
break
if exists == "1":
write_file(filename, addr, data)
os.chdir(curdir)
else:
os.mkdir(addr)
write_file(filename, addr, data)
os.chdir(curdir)
exists == "0"
os.chdir(curdir)
except IOError, val:
error('Could not create "%s": %s' % (filename, str(val)))
count += 1
return count
def process_message(text, msgnum):
try:
msg = email.message_from_string(text)
except email.Errors.MessageError, val:
warn("Message %s parse error: %s" % (msgnum, str(val)))
return text
date = msg['Date'] or 'Thu, 18 Sep 2006 12:02:27 +1000'
date = time.strftime('%Y_%m_%d.%T', email.Utils.parsedate(date))
addr = email.Utils.parseaddr(msg['From'])[1]
attachments_found = walk_parts(msg, addr, date, 0, msgnum)
if attachments_found:
return ''
else:
return None
def read_messages(fd):
data = []; app = data.append
for line in fd:
if line[:5] == 'From ' and data:
yield ''.join(data)
data[:] = []
app(line)
if data:
yield ''.join(data)
def process_server(host):
global DeleteAttachments
try:
mbox = imaplib.IMAP4(host)
except:
typ,val = sys.exc_info()[:2]
error('Could not connect to IMAP server "%s": %s'
% (host, str(val)))
if User or mbox.state != 'AUTH':
user = User or getpass.getuser()
if Password == "":
pasw = getpass.getpass("Please enter password for %s on %s: "
% (user, host))
else:
pasw = Password
try:
typ,dat = mbox.login(user, pasw)
except:
typ,dat = sys.exc_info()[:2]
if typ != 'OK':
error('Could not open INBOX for "%s" on "%s": %s'
% (user, host, str(dat)))
mbox.select('Inbox')
#mbox.select(readonly=(DeleteMessages))
typ, dat = mbox.search(None, 'ALL')
mbox.create("DownloadedMails")
deleteme = []
for num in dat[0].split():
typ, dat = mbox.fetch(num, '(RFC822)')
if typ != 'OK':
error(dat[-1])
message = dat[0][1]
if process_message(message, num) == '':
deleteme.append(num)
if deleteme == []:
print "\n"
print "No mails with attachment found in INBOX"
deleteme.sort()
for number in deleteme:
mbox.copy(number, 'DownloadedMails')
mbox.store(number, "+FLAGS.SILENT", '(\\Deleted)')
mbox.expunge()
mbox.close()
mbox.logout()
def main():
file_or_server = args()
print "\n"
print "Monitoring the Mail server " + file_or_server + " for account " + User
while 1:
process_server(file_or_server)
printfre = str(Frequency)
print "Sleeping for " + printfre + " seconds..."
sleep(Frequency)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
|
Suresh, Thanks for your script!
It fails on Unix-like systems though. Line 145 is windows specific:
I’m not aware what path exactly you are trying to list? There should be a platform-agnostic way to achieve this.
Thanks for your reply,
Eric