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