View difference between Paste ID: CXtBLJb3 and zPXLgV5k
SHOW: | | - or go back to the newest paste.
1-
import email, getpass, imaplib, re, sys, os, os.path
1+
#!/usr/bin/env python
2
#
3-
count = 0
3+
##### EMAIL2FILE v1.3 BETA - UNTESTED! because i am tired and lazy.
4
##### AUTHOR: vvn
5-
emailaddr = raw_input("enter email --> ")
5+
##### VERSION RELEASE: november 27, 2014
6-
emailpass = getpass.getpass("enter password --> ")
6+
##### save email lists in plain text format in script directory with one address per line.
7
##### you can also include the password, if known. just use "[email protected], password" instead.
8-
#VALIDATE EMAIL USING REGEX
8+
##### if there are only a few email addresses, you can easily generate the file:
9-
match = re.search(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', emailaddr)
9+
##### open a terminal window to the script directory, then enter:
10
##### echo "[email protected]" >> emails.txt
11-
if match:
11+
##### repeat that command for each email you want to use, then enter "emails.txt" for the filename
12-
   count = 0
12+
##### word lists should be one word per line or you'll probably get some kind of format error.
13-
   print 'email is valid'
13+
##### TO RUN SCRIPT, open terminal to script directory and enter "python email2file.py"
14-
   print 'checking for gmail'
14+
##### works best on OSX and probably linux systems, but you can try it on windows.
15
##### i even tried to remove all the ANSI codes for you windows users, so you'd better use it!
16
##### each inbox message is saved as a txt file in its respective account's directory within the 'output' subdirectory
17-
   count = 1
17+
##### attachments saved either in user folder or user's 'attachments' subfolder
18-
   print 'invalid email address'
18+
##### questions? bugs? suggestions? contact vvn at: [email protected]
19-
   print 'bad attempts: ' + str(count)
19+
##### source code for stable releases should be available on my pastebin:
20
##### http://pastebin.com/u/eudemonics
21-
   if count > 0 and count < 4:         
21+
##### or on github: http://github.com/eudemonics/email2file
22-
      emailaddr = raw_input("enter email again --> ")
22+
##### git clone https://github.com/eudemonics/email2file.git email2file
23-
      match2 = re.search(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', emailaddr)
23+
##################################################
24-
      if match2:
24+
##################################################
25-
         print 'email is valid'
25+
##### USER LICENSE AGREEMENT & DISCLAIMER
26-
         emailpass = getpass.getpass("enter password --> ")
26+
##### copyright, copyleft (C) 2014  vvn <[email protected]>
27-
         print 'checking for gmail'
27+
#####
28
##### This program is FREE software: you can use it, redistribute it and/or modify
29
##### it as you wish. Copying and distribution of this file, with or without modification,
30-
         count = 2
30+
##### are permitted in any medium without royalty provided the copyright
31-
         print 'invalid email address'
31+
##### notice and this notice are preserved. This program is offered AS-IS,
32-
         print 'bad attempts: ' + str(count)
32+
##### WITHOUT ANY WARRANTY; without even the implied warranty of
33-
         emailaddr = raw_input("enter email again --> ")
33+
##### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34-
         match3 = re.search(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', emailaddr)
34+
##### GNU General Public License for more details.
35
##################################################
36-
         if match3:               
36+
##################################################
37-
            print 'email is valid'
37+
##### getting credited for my work is nice. so are donations.
38-
            emailpass = getpass.getpass("enter password --> ")
38+
##### BTC: 1M511j1CHR8x7RYgakNdw1iF3ike2KehXh
39-
            print 'checking for gmail'
39+
##### https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=26PWMPCNKN28L
40
##### but to really show your appreciation, you should buy my EP instead!
41
##### you can stream and purchase it at: dreamcorp.bandcamp.com
42-
            count = 3
42+
##### (you might even enjoy listening to it)
43-
            print 'invalid email address'
43+
##### questions, comments, feedback, bugs, complaints, death threats, marriage proposals?
44-
            print 'bad attempts: ' + str(count)
44+
##### contact me at:
45
##### vvn (at) notworth (dot) it
46-
            if count > 3:
46+
##### there be only about a thousand lines of code after this -->
47-
               print 'too many bad attempts'
47+
48-
               print 'aborting..'
48+
from __future__ import print_function
49
import email, base64, getpass, imaplib
50-
if 'gmail.com' in emailaddr:
50+
import re, sys, os, os.path, datetime, socket, time, logging
51
52-
   print 'GMAIL address found'
52+
colorintro = '''
53-
   print 'attempting logon'
53+
\033[34m=====================================\033[33m
54
----------\033[36m EMAIL2FILE v1.3 \033[33m----------
55-
   # connecting to IMAP
55+
-------------------------------------
56-
   server = imaplib.IMAP4_SSL('imap.gmail.com')
56+
-----------\033[35m author : vvn \033[33m------------
57
----------\033[32m [email protected] \033[33m----------
58
\033[34m=====================================\033[33m
59
----\033[37m support my work: buy my EP! \033[33m----
60
---\033[37m http://dreamcorp.bandcamp.com \033[33m---
61
---\033[37m facebook.com/dreamcorporation \033[33m---
62
------\033[32m thanks for the support! \033[33m------
63-
            print 'login successful, fetching emails..'
63+
\033[34m=====================================\n\033[0m
64
'''
65
66
cleanintro = '''
67-
         print 'error: login failure'
67+
=====================================
68-
         emailaddr = raw_input("please enter email again --> ")
68+
---------- EMAIL2FILE v1.3 ----------
69-
         matchcred = re.search(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', emailaddr)
69+
-------------------------------------
70
----------- author : vvn ------------
71-
         if matchcred:
71+
---------- [email protected] ----------
72-
            emailpass = getpass.getpass("enter password --> ")
72+
=====================================
73-
            print 'attempting logon again'
73+
---- support my work: buy my EP! ----
74
--- http://dreamcorp.bandcamp.com ---
75
--- facebook.com/dreamcorporation ---
76
------ thanks for the support! ------
77-
            print 'invalid email address'
77+
=====================================
78-
            emailaddr = raw_input("please enter email again --> ")
78+
'''
79-
            matchcred = re.search(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', emailaddr)
79+
80
global usecolor
81
global server
82
83
if os.name == 'nt' or sys.platform == 'win32':
84
   try:
85-
   server.list()
85+
      import colorama
86
      colorama.init()
87-
   # CHOOSE INBOX OR ALL MAIL BY COMMENTING AND UNCOMMENTING BELOW
87+
      usecolor = "color"
88-
   server.select('inbox') # connect to inbox
88+
      progintro = colorintro
89-
   #server.select('[Gmail]/All Mail') # connect to all mail folder
89+
   except:
90
      try:
91-
   result, uids = server.uid('SEARCH', None, "ALL")
91+
         import tendo.ansiterm
92
         usecolor = "color"
93-
   # search and return unique IDs (UIDs)
93+
         progintro = colorintro
94
      except:
95-
   for email_uid in uids[0].split():
95+
         usecolor = "clean"
96
         progintro = cleanintro
97-
      result, data = server.uid('FETCH', email_uid, '(RFC822)')
97+
98
else:
99-
      body = data[0][1] # raw text of entire email
99+
   usecolor = "color"
100
   progintro = colorintro
101-
      save_path = 'output'
101+
   
102-
      user_savename = emailaddr.rstrip("@gmail.com")
102+
print(progintro)
103-
      file_name = user_savename+"-"+email_uid+".txt"
103+
104-
      complete_name = os.path.join(save_path, file_name)
104+
time.sleep(0.9)
105
106-
      if os.path.isfile(complete_name):
106+
# CHECK IF SINGLE EMAIL (1) OR LIST OF MULTIPLE EMAIL ADDRESSES IS USED (2)
107-
         print complete_name + ' already exists, skipping..'
107+
print('''SINGLE EMAIL ADDRESS OR LIST OF MULTIPLE EMAIL ADDRESSES?
108
list of multiple email addresses must be in text format
109
with one email address per line, with optional password
110
after a comma ([email protected], password)
111-
         file = open(complete_name, 'w')
111+
''')
112-
         file.write(body)
112+
qtyemail = raw_input('enter 1 for single email or 2 for multiple emails --> ')
113-
         file.close()
113+
114
while not re.search(r'^[12]$', qtyemail):
115-
         print 'raw message data saved to new file: ' + complete_name
115+
   qtyemail = raw_input('invalid entry. enter 1 for a single email address, or enter 2 to specify a list of multiple email addresses in text format --> ')
116
   
117-
#############
117+
usewordlist = raw_input('do you want to use a word list rather than supply a password? enter Y/N --> ')
118-
   # TO FETCH MULTIPLE EMAILS AT ONCE
118+
119
while not re.search(r'^[nyNY]$', usewordlist):
120-
   #result, uids = server.uid('SEARCH', None, "ALL")
120+
   usewordlist = raw_input('invalid entry. enter Y to use word list or N to supply password --> ')
121
   
122-
   #fetch_ids = ','.join(uids[0].split())
122+
usesslcheck = raw_input('use SSL? Y/N --> ')
123-
   ##convert to comma separated list
123+
124
while not re.search(r'^[nyNY]$', usesslcheck):
125-
   #result, data = server.uid('FETCH', fetch_ids, '(RFC822)')
125+
   usesslcheck = raw_input('invalid selection. please enter Y for SSL or N for unencrypted connection. -->')
126-
   ##return all emails
126+
127
sslcon = 'yes'
128-
   #body = data[0][1]
128+
129-
   #print body
129+
if usesslcheck.lower() == 'n':
130-
#############
130+
   sslcon = 'no'
131
   
132-
#############
132+
133-
   # TO GET LATEST EMAIL BY UID
133+
   sslcon = 'yes'
134
               
135-
   #latest_email_uid = items[0].split()[-1]
135+
def checklogin(emailaddr, emailpass, sslcon):
136
137-
   #result, data = server.uid('FETCH', latest_email_uid, '(RFC822)')
137+
   global checkresp
138-
   ##fetch email body (RFC822) for latest UID
138+
   efmatch = re.search(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', emailaddr)
139
   if efmatch:
140-
   #body = data[0][1] # raw text of entire email
140+
      if usecolor == 'color':
141-
   #print body
141+
         validmail = '\033[32m\nemail is valid: %s \033[0m\n\n' % line
142-
#############
142+
143
         validmail = 'email is valid: %s ' % line
144-
#############
144+
      print(validmail)
145-
   # TO SEARCH LATEST SEQUENTIAL ID INSTEAD OF UNIQUE ID
145+
   else:
146
      print('invalid email format, skipping..')
147-
   #result, sids = mail.search(None, "ALL") 
147+
      pass
148-
   #ids = sids[0] # sids is a list
148+
149-
   #id_list = ids.split() # ids is a space separated string 
149+
   atdomain = re.search("@.*", emailaddr).group()
150-
   #latest_email_id = id_list[-1] # get the latest
150+
   emaildomain = atdomain[1:]
151
   
152-
   #result, data = mail.fetch(latest_email_id, "(RFC822)")
152+
   imap_server = 'imap.' + emaildomain
153-
   ## fetch the email body (RFC822) for the given ID
153+
   imap_port = 993
154
   
155-
   #body = data[0][1] # raw text of entire email
155+
   if 'no' in sslcon:
156-
#############
156+
      imap_port = 143
157
   
158-
   print 'inbox contents successfully saved to file. YAY!'
158+
      if 'gmail.com' in emaildomain:
159
         imap_port = 587
160-
   print 'logging out..'
160+
161
   if 'yes' in sslcon:
162-
   server.logout()
162+
      server = imaplib.IMAP4_SSL(imap_server)
163
      
164-
   print "logout successful. exiting.."
164+
   else:
165
      server = imaplib.IMAP4(imap_server, imap_port)
166
   
167
   checkresp = 'preconnect'
168-
   print 'GMAIL address not found. quitting..'
168+
   logging.info('INFO: attempting to connect to IMAP server to check login credentials for account %s' % emailaddr)
169
   
170
   try:
171
      
172
      loginstatus, logindata = server.login(emailaddr, emailpass)
173
174
      if 'OK' in loginstatus:
175
         print('LOGIN SUCCESSFUL: %s' % emailaddr)
176
         logging.info('INFO: LOGIN successful for account %s' % emailaddr)
177
         checkresp = 'OK'
178
         
179
      elif 'AUTHENTICATIONFAILED' in loginstatus:
180
         loginmsg = 'LOGIN FAILED: %s with %s' % (loginstatus, logindata)
181
         print(loginmsg)
182
         logging.error('ERROR: %s' % loginmsg)
183
         checkresp = 'AUTHENFAIL'
184
      
185
      elif 'PRIVACYREQUIRED' in loginstatus:
186
         loginmsg = 'LOGIN FAILED: %s with %s' % (loginstatus, logindata)
187
         print(loginmsg)
188
         logging.error('ERROR: %s' % loginmsg)
189
         checkresp = 'PRIVACYREQ'
190
      
191
      elif 'UNAVAILABLE' in loginstatus:
192
         loginmsg = 'LOGIN FAILED: %s with %s' % (loginstatus, logindata)
193
         print(loginmsg)
194
         logging.error('ERROR: %s' % loginmsg)
195
         checkresp = 'UNAVAIL'
196
         
197
      elif 'AUTHORIZATIONFAILED' in loginstatus:
198
         loginmsg = 'LOGIN FAILED: %s with %s' % (loginstatus, logindata)
199
         print(loginmsg)
200
         logging.error('ERROR: %s' % loginmsg)
201
         checkresp = 'AUTHORFAIL'
202
      
203
      elif 'EXPIRED' in loginstatus:
204
         loginmsg = 'LOGIN FAILED: %s with %s' % (loginstatus, logindata)
205
         print(loginmsg)
206
         logging.error('ERROR: %s' % loginmsg)
207
         checkresp = 'EXPIRED'
208
         
209
      elif 'CONTACTADMIN' in loginstatus:
210
         loginmsg = 'LOGIN FAILED: %s' % loginstatus
211
         print(loginmsg)
212
         logging.error('ERROR: %s' % loginmsg)
213
         checkresp = 'ADMINREQ'
214
      
215
      else:
216
         print('Unable to connect: %s' % emailaddr)
217
         logging.error('ERROR: %s' % loginstatus)
218
         checkresp = 'UNKNOWN'
219
         
220
   except server.error as e:
221
      pass
222
      print('IMAP SOCKET ERROR: %s' % str(e))
223
      logging.error('IMAPLIB ERROR: %s' % server.error)
224
      checkresp = 'ERROR'
225
   
226
   except server.timeout:
227
      pass
228
      print('Socket timeout')
229
      logging.error('ERROR: Socket timeout')
230
      checkresp = 'TIMEOUT'
231
         
232
   return checkresp
233
# END OF FUNCTION checklogin()
234
   
235
# FUNCTION TO CHECK FOR EMAIL FORMAT ERRORS BEFORE SUBMITTING TO SERVER
236
def checkformat(emailaddr):
237
238
   # START WHILE LOOP TO CHECK EMAIL FORMAT FOR ERRORS BEFORE ATTEMPTING LOGIN
239
   match = re.search(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', emailaddr)      
240
   while not match:
241
      emailformat = 'bad'
242
      if usecolor == 'color':
243
         print('\033[31m invalid email format \033[0m\n')
244
      else:
245
         print('invalid email format')
246
      emailaddr = raw_input('please enter email again --> ')
247
      emailpass = getpass.getpass('please enter password --> ')
248
   emailformat = 'good'
249
   return(emailformat)
250
# END OF FUNCTION checkformat()
251
252
# FUNCTION TO DECODE EMAIL BODY AND ATTACHMENTS
253
def decode_email(msgbody):
254
   
255
   msg = email.message_from_string(msgbody)
256
   
257
   if msg is None:
258
      decoded = msg
259
   
260
   decoded = msg
261
   text = ""
262
   att = False
263
   
264
   if msg.is_multipart():
265
      html = None
266
   
267
      for part in msg.get_payload():
268
   
269
         print("\033[31m%s, %s\033[0m" % (part.get_content_type(), part.get_content_charset()))
270
 
271
         if part.get_content_charset() is None:
272
            text = part.get_payload(decode=True)
273
            continue
274
 
275
         charset = part.get_content_charset()
276
 
277
         if part.get_content_type() == 'text/plain':
278
            text = unicode(part.get_payload(decode=True), str(charset), "ignore").encode('utf8', 'replace')
279
            enc = part['Content-Transfer-Encoding']
280
            if enc == "base64":
281
               text = part.get_payload()
282
               text = base64.decodestring(text)
283
 
284
         if part.get_content_type() == 'text/html':
285
            html = unicode(part.get_payload(decode=True), str(charset), "ignore").encode('utf8', 'replace')
286
                    
287
         if part.get_content_maintype() == 'multipart':
288
            continue
289
            
290
         elif part.get('Content-Disposition') is None:
291
            continue
292
            
293
         elif part.get_content_type() == "multipart/alternative":
294
            text = part.get_payload(decode=True)
295
            enc = part['Content-Transfer-Encoding']
296
            if part.get_content_type() == "text/plain":
297
                text = part.get_payload()
298
                if enc == "base64":
299
                    text = base64.decodestring(text)
300
            
301
         filename = part.get_filename()
302
         
303
         if bool(filename):
304
        
305
            rootdir = 'output'
306
            atdomain = re.search("@.*", emailaddr).group()
307
            emaildomain = atdomain[1:]
308
            i = len(emailaddr) - len(atdomain)
309
            user_savename = emailaddr[:i]
310
            # user_savename = emailaddr.rstrip(atdomain)
311
            subdir = user_savename+"_"+emaildomain
312
        
313
            detach_dir = os.path.join(rootdir, subdir)
314
            
315
            if not os.path.exists(detach_dir):
316
               os.makedirs(detach_dir, 0755)
317
        
318
            att_path = os.path.join(detach_dir, 'attachments', filename)
319
            
320
            if 'attachments' not in os.listdir(detach_dir):
321
               os.makedirs(detach_dir + '/attachments', 0755)
322
         
323
            att = True
324
325
            if not os.path.isfile(att_path):
326
               attfile = open(att_path, 'wb+')
327
               attfile.write(part.get_payload(decode=True))
328
               attfile.close()
329
               decoded = attfile
330
   
331
      if att is False:
332
         decoded = msg
333
               
334
         if html is None and text is not None:
335
            decoded = text.strip()
336
         
337
         elif html is None and text is None:
338
            decoded = msg
339
         
340
         else:
341
            decoded = html.strip()
342
         
343
   else:
344
      decoded = msg
345
         
346
   return decoded
347
# END OF FUNCTION decode_email()
348
               
349
# FUNCTION TO LOG ONTO IMAP SERVER FOR SINGLE EMAIL ADDRESS
350
def getimap(emailaddr, emailpass, sslcon):
351
352
   atdomain = re.search("@.*", emailaddr).group()
353
   emaildomain = atdomain[1:]
354
   
355
   imap_server = 'imap.' + emaildomain
356
   imap_port = 993
357
   
358
   if 'no' in sslcon:
359
      imap_port = 143
360
   
361
   if 'gmail.com' in atdomain and 'no' in sslcon:
362
      imap_port = 587
363
      
364
   if 'yes' in sslcon:
365
      server = imaplib.IMAP4_SSL(imap_server, imap_port)
366
      
367
   else:
368
      server = imaplib.IMAP4(imap_server, imap_port)
369
      
370
   attempts = 20
371
372
   while True and attempts > 0:
373
374
      try:
375
376
         loginstatus, logindata = server.login(emailaddr, emailpass)
377
   
378
         if loginstatus == 'OK':
379
   
380
            select_info = server.select('INBOX')
381
            status, unseen = server.search(None, 'UNSEEN')
382
            typ, listdata = server.list()
383
      
384
            if usecolor == 'color':
385
            
386
               print("\n\033[35m%d UNREAD MESSAGES\033[0m" % len(unseen))
387
               print()
388
               print('Response code: \n\n\033[32m', typ)
389
               print('\033[0m\nFOLDERS:\n\n\033[33m', listdata)
390
               print('\033[34m\n\nlogin successful, fetching emails.. \033[0m\n\n')
391
            
392
            else:
393
            
394
               print("%d UNREAD MESSAGES" % len(unseen))
395
               print()
396
               print('Response code: \n\n', typ)
397
               print('\nFOLDERS:\n\n', listdata)
398
               print('\n\nlogin successful, fetching emails.. \n\n')
399
              
400
            logging.info('INFO: LOGIN successful for %s.' % emailaddr)
401
            logging.info('INFO: %d unread messages.' % countunseen)
402
            logging.info('INFO: fetching all messages...')
403
            break
404
         
405
            # server.list()
406
         
407
            server.select()
408
409
            result, msgs = server.search(None, 'ALL')
410
         
411
            ids = msgs[0]
412
            id_list = ids.split()
413
      
414
            print(id_list)
415
   
416
            if usecolor == 'color':
417
418
               print('\033[37m------------------------------------------------------------\n\033[0m')
419
               
420
            else:
421
            
422
               print('------------------------------------------------------------')
423
         
424
            rootdir = 'output'
425
      
426
            printdate = str(datetime.date.today())
427
428
            prev_file_name = emailaddr+"-headerlist-"+printdate+".txt"
429
            prev_complete_name = os.path.join(rootdir, prev_file_name)
430
         
431
            for email_uid in id_list:
432
433
               result, rawdata = server.fetch(email_uid, '(RFC822)')
434
435
               rawbody = rawdata[0][1]
436
         
437
               m = email.message_from_string(rawbody)
438
               
439
               msgfrom = m['From'].replace('/', '-')
440
            
441
               body = decode_email(rawbody)
442
         
443
               emaildomain = atdomain[1:]
444
               j = len(emailaddr) - len(atdomain)
445
               user_save = emailaddr[:j]
446
      
447
               subdir =  user_save + "_" + emaildomain
448
               save_path = os.path.join(rootdir, subdir)
449
         
450
               if not os.path.exists(save_path):
451
                  os.makedirs(save_path)
452
            
453
               mbody = email.message_from_string(rawbody)
454
         
455
               if mbody.is_multipart():
456
         
457
                  ext = ".txt"
458
         
459
                  for mpart in mbody.get_payload():
460
            
461
                     if 'text' in mpart.get_content_type():
462
                        ext = ".txt"
463
                        isattach = False
464
                  
465
                        if mpart.get_content_type() == 'text/html':
466
                           ext = ".htm"
467
                           isattach = False
468
                  
469
                     else:
470
                        file_name = mpart.get_filename()
471
                        isattach = True
472
                
473
               else:
474
                  isattach = False
475
                  ext = ".txt"
476
                  
477
               if isattach is False:
478
                  file_name = user_save + "-" + email_uid + "-" + msgfrom[:25] + ext
479
        
480
               if file_name is None:
481
                  file_name = user_save + "-" + msgfrom[:25] + "-" + email_uid + ext
482
        
483
               complete_name = os.path.join(save_path, file_name)
484
               
485
               dtnow = datetime.datetime.now()
486
               dtyr = str(dtnow.year)
487
               dtmo = str(dtnow.month)
488
               dtday = str(dtnow.day)
489
               dthr = str(dtnow.hour)
490
               dtmin = str(dtnow.minute)
491
               
492
               dtdate = str(dtyr + "-" + dtmo + "-" + dtday)
493
               dttime = str(dthr + "." + dtmin)
494
                              
495
               if os.path.isfile(complete_name):
496
         
497
                  print('\n\033[33m' + complete_name + '\033[0m already exists, skipping.. \n\n')
498
            
499
               else:
500
            
501
                  if type(body) is str or type(body) is buffer and isattach is True:
502
                     print('\n\033[34mdownloading file: \033[33m' + str(file_name) + '\033[0m\n\n')
503
                     bodyfile = open(complete_name, 'wb+')
504
                     # bodyfile.seek(0)
505
                     bodyfile.write(body)
506
                     bodyfile.close()
507
               
508
                  else:
509
                     bodyfile = open(complete_name, 'wb+')
510
                     bodyfile.write("SENDER: \n")
511
                     bodyfile.write(msgfrom)
512
                     bodyfile.write('\n\n')
513
                     # bodyfile.write('Decoded:\n\n')
514
                     bodyfile.write(str(body))
515
                     bodyfile.write('\n\nRAW MESSAGE DATA:\n\n')
516
                     bodyfile.write(rawbody)
517
                     bodyfile.write('\n\n')
518
                     bodyfile.write('file saved: ' + dtdate + ', ' + dttime)
519
                     bodyfile.write('\n\n')
520
                     bodyfile.close()
521
      
522
                  if usecolor == 'color':
523
                  
524
                     print('\033[36m\033[1mmessage data saved to new file: \033[35m' + complete_name + '\033[0m\n')
525
               
526
                  else:
527
                  
528
                     print('message data saved to new file: ' + complete_name)
529
               
530
               if usecolor == 'color':
531
532
                  print('\033[37m------------------------------------------------------------\033[0m\n')
533
            
534
                  resp, data = server.fetch(email_uid, '(UID FLAGS BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])')
535
                  print('\033[35m' + email_uid + '\033[0m\n')
536
               
537
               else:
538
               
539
                  print('------------------------------------------------------------\n')
540
            
541
                  resp, data = server.fetch(email_uid, '(UID FLAGS BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])')
542
                  print(email_uid)
543
                  
544
               print(data[0][1] + '\n\n')
545
               msgpreview = data[0][1]
546
               
547
               if not os.path.isfile(prev_complete_name):
548
                  prevfile = open(prev_complete_name, 'wb+')
549
               #   prevfile.write('Email headers for: ' + emailaddr + '\n\n')
550
               #   prevfile.close()
551
                  
552
               with open(prev_complete_name, 'a+b') as prevfile:   
553
                  prevfile.write(email_uid)
554
                  prevfile.write("\n\n")
555
                  prevfile.write(msgpreview)
556
                  prevfile.write("\n\n")
557
                  # prevfile.close()
558
                            
559
            if usecolor == 'color':
560
            
561
               print('\033[32minbox contents successfully saved to file. YAY! \033[0m\n')
562
               
563
            else:
564
            
565
               print('inbox contents successfully saved to file. YAY!')
566
         
567
         if usecolor == 'color':
568
         
569
            print('list of message previews saved as: \033[31m' + prev_complete_name + '\033[0m \n')
570
            
571
         else:
572
         
573
            print('list of message previews saved as: ', prev_complete_name)
574
         
575
         print('logging out..\n')
576
            
577
         server.logout()
578
            
579
         print('logout successful. exiting..\n')
580
         attempts = -1
581
         break
582
      
583
      except imaplib.error:
584
      
585
         pass
586
587
      except socket.error as e:
588
      
589
         pass
590
         
591
         if usecolor == 'color':
592
            print('\033[35mfailed connecting to IMAP server.\033[0m\n')
593
            print('\033[31merror: \033[33m' + str(e) + '\033[0m\n\n')
594
595
         else:
596
         
597
            print('failed connecting to IMAP server.\n')
598
            print('error: ' + str(e) + '\n\n')
599
       
600
         if qtyemail == '1':
601
602
            attempts = attempts - 1
603
            emailaddr = raw_input('please enter email again --> ')
604
            emailpass = getpass.getpass('please enter password --> ')
605
      
606
            matchaddy = re.search(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', emailaddr)
607
               
608
            while not matchaddy and attempts > 1:
609
               print('\033[31m invalid email format \033[0m\n')
610
               attempts = attempts - 1
611
            
612
         continue
613
         
614
   if attempts is 0:
615
      print('too many logon failures. unable to log onto IMAP server. quitting..')
616
      sys.exit()
617
618
# IMAP CONNECTION USING MULTIPLE ADDRESSES
619
def getimapmulti(emailaddr, emailpass, sslcon, loginstatus):
620
         
621
   if 'OK' not in loginstatus:
622
   
623
      atdomain = re.search("@.*", emailaddr).group()
624
      emaildomain = atdomain[1:]
625
   
626
      imap_server = 'imap.' + emaildomain
627
      imap_port = 993
628
   
629
      if 'no' in sslcon:
630
         imap_port = 143
631
   
632
         if 'gmail.com' in emaildomain:
633
            imap_port = 587
634
      
635
      if 'yes' in sslcon:
636
         server = imaplib.IMAP4_SSL(imap_server)
637
      
638
      else:
639
         server = imaplib.IMAP4(imap_server, imap_port)
640
         
641
      loginstatus, logindata = server.login(emailaddr, emailpass)
642
      
643
   while True:
644
      try:
645
         select_info = server.select('INBOX')
646
         status, unseen = server.search(None, 'UNSEEN')
647
         
648
         typ, listdata = server.list()
649
         
650
         countunseen = len(unseen)
651
652
         if usecolor == 'color':
653
   
654
            print("\n\033[35m%d UNREAD MESSAGES\033[0m" % len(unseen))
655
            print()
656
            print('Response code: \n\n\033[32m', typ)
657
            print('\033[0m\nFOLDERS:\n\n\033[33m', listdata)
658
            print('\033[34m\n\nlogin successful, fetching emails.. \033[0m\n\n')
659
   
660
         else:
661
   
662
            print("%d UNREAD MESSAGES" % len(unseen))
663
            print()
664
            print('Response code: \n\n', typ)
665
            print('\nFOLDERS:\n\n', listdata)
666
            print('\n\nlogin successful, fetching emails.. \n\n')
667
            
668
                        # server.list()
669
      
670
            server.select()
671
            result, msgs = server.search(None, 'ALL')
672
      
673
            ids = msgs[0]
674
            id_list = ids.split()
675
   
676
            print(id_list)
677
678
            if usecolor == 'color':
679
680
               print('\033[37m------------------------------------------------------------\n\033[0m')
681
            
682
            else:
683
         
684
               print('------------------------------------------------------------')
685
      
686
            rootdir = 'output'
687
   
688
            printdate = str(datetime.date.today())
689
690
            prev_file_name = emailaddr+"-headerlist-"+printdate+".txt"
691
            prev_complete_name = os.path.join(rootdir, prev_file_name)
692
      
693
            for email_uid in id_list:
694
695
               result, rawdata = server.fetch(email_uid, '(RFC822)')
696
697
               rawbody = rawdata[0][1]
698
      
699
               m = email.message_from_string(rawbody)
700
            
701
               msgfrom = m['From'].replace('/', '-')
702
         
703
               body = decode_email(rawbody)
704
      
705
               emaildomain = atdomain[1:]
706
               j = len(emailaddr) - len(atdomain)
707
               user_save = emailaddr[:j]
708
   
709
               subdir =  user_save + "_" + emaildomain
710
               save_path = os.path.join(rootdir, subdir)
711
      
712
               if not os.path.exists(save_path):
713
                  os.makedirs(save_path)
714
         
715
               mbody = email.message_from_string(rawbody)
716
      
717
               if mbody.is_multipart():
718
      
719
                  ext = ".txt"
720
      
721
                  for mpart in mbody.get_payload():
722
         
723
                     if 'text' in mpart.get_content_type():
724
                        ext = ".txt"
725
                        isattach = False
726
               
727
                        if mpart.get_content_type() == 'text/html':
728
                           ext = ".htm"
729
                           isattach = False
730
               
731
                     else:
732
                        file_name = mpart.get_filename()
733
                        isattach = True
734
             
735
               else:
736
                  isattach = False
737
                  ext = ".txt"
738
               
739
               if isattach is False:
740
                  file_name = user_save + "-" + email_uid + "-" + msgfrom[:25] + ext
741
     
742
               if file_name is None:
743
                  file_name = user_save + "-" + msgfrom[:25] + "-" + email_uid + ext
744
     
745
               complete_name = os.path.join(save_path, file_name)
746
            
747
               dtnow = datetime.datetime.now()
748
               dtyr = str(dtnow.year)
749
               dtmo = str(dtnow.month)
750
               dtday = str(dtnow.day)
751
               dthr = str(dtnow.hour)
752
               dtmin = str(dtnow.minute)
753
            
754
               dtdate = str(dtyr + "-" + dtmo + "-" + dtday)
755
               dttime = str(dthr + "." + dtmin)
756
                           
757
               if os.path.isfile(complete_name):
758
      
759
                  if usecolor == 'color':
760
               
761
                     print('\n\033[33m' + complete_name + '\033[0m already exists, skipping.. \n\n')
762
         
763
                  else:
764
               
765
                     print(complete_name + 'already exists, skipping.. \n\n')
766
                  
767
               else:
768
         
769
                  if type(body) is str or type(body) is buffer and isattach is True:
770
               
771
                     if usecolor == 'color':
772
                        print('\n\033[34mdownloading file: \033[33m' + str(file_name) + '\033[0m\n\n')
773
                 
774
                     else:
775
                        print('downloading file: ' + str(file_name))
776
                     
777
                     bodyfile = open(complete_name, 'wb+')
778
                     # bodyfile.seek(0)
779
                     bodyfile.write(body)
780
                     bodyfile.close()
781
            
782
                  else:
783
                     bodyfile = open(complete_name, 'wb+')
784
                     bodyfile.write("SENDER: \n")
785
                     bodyfile.write(msgfrom)
786
                     bodyfile.write('\n\n')
787
                     # bodyfile.write('Decoded:\n\n')
788
                     bodyfile.write(str(body))
789
                     bodyfile.write('\n\nRAW MESSAGE DATA:\n\n')
790
                     bodyfile.write(rawbody)
791
                     bodyfile.write('\n\n')
792
                     bodyfile.write('file saved: ' + dtdate + ', ' + dttime)
793
                     bodyfile.write('\n\n')
794
                     bodyfile.close()
795
   
796
                  if usecolor == 'color':
797
               
798
                     print('\033[36m\033[1mmessage data saved to new file: \033[35m' + complete_name + '\033[0m\n')
799
            
800
                  else:
801
               
802
                     print('message data saved to new file: ' + complete_name)
803
            
804
               if usecolor == 'color':
805
806
                  print('\033[37m------------------------------------------------------------\033[0m\n')
807
         
808
                  resp, data = server.fetch(email_uid, '(UID FLAGS BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])')
809
                  print('\033[35m' + email_uid + '\033[0m\n')
810
            
811
               else:
812
            
813
                  print('------------------------------------------------------------\n')
814
         
815
                  resp, data = server.fetch(email_uid, '(UID FLAGS BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])')
816
                  print(email_uid)
817
               
818
               print(data[0][1] + '\n\n')
819
               msgpreview = data[0][1]
820
         
821
               if not os.path.isfile(prev_complete_name):
822
                  prevfile = open(prev_complete_name, 'wb+')
823
               #   prevfile.write('Email headers for: ' + emailaddr + '\n\n')
824
               #   prevfile.close()
825
            
826
               with open(prev_complete_name, 'a+b') as prevfile:   
827
                  prevfile.write(email_uid)
828
                  prevfile.write("\n\n")
829
                  prevfile.write(msgpreview)
830
                  prevfile.write("\n\n")
831
                  # prevfile.close()
832
                         
833
               if usecolor == 'color':
834
   
835
                  print('\033[32minbox contents successfully saved to file. YAY! \033[0m\n')
836
      
837
               else:
838
   
839
                  print('inbox contents successfully saved to file. YAY!')
840
      
841
            if usecolor == 'color':
842
               print('list of message previews saved as: \033[31m' + prev_complete_name + '\033[0m \n')
843
            else:
844
               print('list of message previews saved as: %s' % prev_complete_name)
845
            
846
            logging.info('INFO: inbox contents saved to file with preview file %s' % prev_complete_name)
847
            print('logging out..\n')
848
            logging.info('INFO: logging off IMAP server.')
849
            server.logout()
850
            print('logout successful. exiting application..\n')
851
            logging.info('INFO: logout successful for %s. exiting application.' % emailaddr)
852
            break
853
               
854
      except socket.error as e:
855
856
         pass
857
   
858
         if usecolor == 'color':
859
            print('\033[35mfailed connecting to IMAP server.\033[0m\n')
860
            print('\033[31merror: \033[33m' + str(e) + '\033[0m\n\n')
861
         else:
862
            print('failed connecting to IMAP server.\n')
863
            print('error: ' + str(e) + '\n\n')
864
 
865
         if qtyemail == '1':        
866
867
            emailaddr = raw_input('please enter email again --> ')
868
            emailpass = getpass.getpass('please enter password --> ')
869
            checkformat(emailaddr)
870
            
871
         continue
872
      
873
if qtyemail == '2':
874
   emaillistfile = raw_input('please copy the email list file to the script directory, then enter filename --> ')
875
   while not os.path.isfile(emaillistfile):
876
      emaillistfile = raw_input('the file path specified does not exist or is not accessible. please check the file and enter again --> ')
877
      
878
   if usewordlist.lower() == 'y':
879
      pwlistfile = raw_input('please copy word list file to the script directory, then enter the filename --> ')
880
      
881
      while not os.path.isfile(pwlistfile):
882
         pwlistfile = raw_input('the path to the word list file you entered is not valid. please check the file and enter again --> ')
883
         
884
   ef = open(emaillistfile, "r")
885
   for line in ef.readlines():
886
887
      line = line.strip()
888
889
      if usewordlist.lower() == 'n':
890
891
         if re.search(r'^[\,]$', line):
892
893
            linevals = line.split(",")
894
895
            lnemail = linevals[0]
896
            lnpass = linevals[1]
897
  
898
         else:
899
  
900
            lnemail = line
901
            print('using email address: ' + lnemail)
902
            lnpass = getpass.getpass('please enter password for above account --> ')
903
   
904
         loginok = checklogin(lnemail, lnpass, sslcon)
905
         
906
         echo(loginok)
907
         time.sleep(22)
908
         
909
         if 'OK' not in loginok:
910
            continue
911
          
912
         else:
913
            getimapmulti(lnemail, lnpass, sslcon, 'authorized')
914
            break
915
916
      else:
917
918
         lnemail = line
919
         print('using email address: ' + lnemail)
920
921
         pf = open(pwlistfile, "r")
922
923
         for lnpass in pf.readlines():
924
925
            loginok = checklogin(lnemail, lnpass, sslcon)
926
   
927
            if 'OK' not in loginok:
928
               continue
929
       
930
            else:
931
               getimapmulti(lnemail, lnpass, sslcon, 'authorized')
932
               break
933
 
934
elif qtyemail == '1' and usewordlist.lower() == 'n':
935
   try:
936
      print('trying IMAP connection to server: \033[36mimap.' + emaildomain + '\033[0m' )
937
      getimap(emailaddr, emailpass, sslcon)
938
   
939
   except socket.error as e:
940
      print('ERROR establishing IMAP connection: %s' % str(e))
941
      logging.error('SOCKET ERROR: %s' % str(e))
942
      logging.info('Program exit')
943
      sys.exit()
944
   
945
   except socket.timeout:
946
      print('ERROR: Socket timeout')
947
      logging.error('ERROR: Socket timeout')
948
      logging.info('Program exit')
949
      sys.exit()
950
951
else:
952
953
   emailaddr = raw_input('please enter email address --> ')
954
   
955
   #VALIDATE EMAIL USING REGEX
956
   match = re.search(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', emailaddr)
957
958
   if match:
959
      if usercolor == 'color':
960
         print('\033[32m\nemail is valid\033[0m\n\n')
961
      
962
      else:
963
         print('email is valid\n\n')
964
         
965
      atdomain = re.search("@.*", emailaddr).group()
966
      emaildomain = atdomain[1:]
967
968
   else:
969
      tries = 5
970
971
      while not match and tries > 0:
972
973
         if usecolor == 'color':
974
            print('\033[31minvalid email format\033[0m\n')
975
            print('bad attempts: \033[33m' + str(6 - tries) + '\033[0m\n')
976
            print('\033[36myou have ' + str(tries) + ' attempts remaining.\033[0m\n\n')
977
         
978
         else:
979
            print('invalid email format')
980
            print('bad attempts: ' + str(6 - tries))
981
            print('you have ' + str(tries) + 'attempts remaining.')
982
            
983
         emailaddr = raw_input('please enter email again --> ')
984
   
985
         if match:
986
            tries = -1
987
            break
988
      
989
         else:
990
            tries = tries - 1
991
     
992
      if match:
993
         if usecolor == 'color':
994
            print('\n\033[32m email is valid \033[0m\n\n')
995
         else:
996
            print('email is valid\n\n')
997
   
998
      else:
999
         if usecolor == 'color':
1000
            print('\033[31mERROR: unhandled exception. aborting..\033[0m\n')
1001
         else:
1002
            print('ERROR: unhandled exception. aborting..\n')
1003
         logging.error('ERROR: unhandled exception. aborting program.')
1004
         sys.exit()
1005
1006
      if tries is 0:
1007
         if usecolor == 'color':
1008
            print('\033[31m too many bad attempts using invalid format! \033[0m\n')
1009
         else:
1010
            print('too many bad attempts using invalid format!')
1011
            
1012
         logging.info('INFO: too many bad attempts using unproperly formatted email string. aborting program.')   
1013
         print('aborting..')
1014
         sys.exit()
1015
   
1016
   if usewordlist.lower == 'y':
1017
            
1018
      pf = open(pwlistfile, "r")
1019
    
1020
      for line in pf.readlines():
1021
    
1022
         emailpass = line
1023
         logging.info('INFO: checking login authentication for %s' % emailaddr)
1024
         loginok = checklogin(emailaddr, emailpass, sslcon)
1025
         loginok = str(loginok)
1026
       
1027
         if 'OK' not in loginok:
1028
            logging.info('INFO: bad password. skipping to next line.')
1029
            continue
1030
          
1031
         else:
1032
            logging.info('INFO: LOGIN to %s successful' % emailaddr)
1033
            server.select()
1034
            server.search(None, 'INBOX')
1035
            getimapmulti(emailaddr, emailpass, sslcon, 'authorized')
1036
            break
1037
         
1038
   else:
1039
   
1040
      emailpass = getpass.getpass('please enter password --> ')
1041
      getimap(emailaddr, emailpass,sslcon)
1042
   
1043
sys.exit()