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 the timestamp.
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
|
Tags: files
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