Repository navigation
Expand file tree
/
Copy pathimapgrab3.py
More file actions
executable file
·630 lines (572 loc) · 27 KB
/
Copy pathimapgrab3.py
File metadata and controls
executable file
·630 lines (572 loc) · 27 KB
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
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
#!/usr/bin/env python
# coding=utf-8
# Updated to work with Python 3 by Christian König-Kersting, 2020
# Tested with python 3.7.7 and getmail 5.14
# Version set to 0.2.0
# IMAP Grab
# Version 0.2.0
import subprocess
import copy
import os
import sys
import imaplib
from optparse import OptionParser
try:
from imapclient import imap_utf7
except ImportError:
imap_utf7 = None
ig_version_short = "0.2.0"
# Copyleft:
# This program was first written by Daniel Roesler (diafygi) in
# January 2009. It is released under the Gnu Public License v2
# (GPLv2) as Free Software. Enjoy.
# <http://www.gnu.org/licenses/gpl-2.0.txt>
# Contact:
# diafygi [curvy thing] gmail [period] com
# <http://daylightpirates.org/>
# Description:
# imapgrab is a program that allows you to log into an IMAP server
# and download selected mailboxes (i.e. folders/labels) to mbox or
# maildir files.
# You can also list the folders on that server. It is basically a
# wrapper for getmail (a mail downloading program). When done
# downloading selected mailboxes, you end up with one .mbox file
# or maildir folder per mailbox.
# Features:
# -Mbox or Maildir download formats, Mbox by default
# -SSL connections possible
# -multiple select mailboxes may be downloaded in one command
# -all available folders may be downloaded
# -folders may be excepted when above is enabled
# -when mbox file is detected, only new mail is downloaded, but
# this can be changed (with -a)
# -special option to except Google Mail (Gmail) folders from download
# Dependancies:
# getmail 4.8.2 or higher
# python 2.5.2 or higher
# Usage:
# imapgrab3.py [-ldaSvMB] [-s] SERVER [-P] PORT [-u] USERNAME [-p] PASSWORD [-m] "BOX1,BOX2,..." [-f] DIRECTORY
# Possible arguments:
# --list, -l List the mailboxes available for download
# --download, -d Download mailboxes to separate files/folders
# --mbox, -B Download into Mbox format (optional, default)
# --maildir, -M Download into Maildir format (optional)
# --all, -a Force download all mail in a mailbox (optional)
# --ssl, -S Use SSL connection (optional)
# --server, -s IP or domain of server (required)
# --port, -P Port of server (optional)
# --username, -u Username for account (required)
# --password, -p Password for account (required)
# --mailboxes, -m Comma separated list of mailboxes to download
# (i.e. "Box1, Box2, Box3")
# ("{,}" for non-separating commas)
# ("_ALL_" for all mailboxes)
# ("_ALL_, -Box1" to except Box1 from _ALL_)
# ("_ALL_, -_Gmail_" to except [Gmail]* and [Google Mail]* folders)
# ("_Gmail_" for all [Gmail]/* or [Google Mail]/* folders)
# (required for -d)
# --folder, -f Path to folder
# (optional, creates imapgrab folder in current directory as default)
# --localuser, -L User that writes to the mailboxes
# (use only when involking imapgrab as root)
# --quiet, -q Don't display any output
# --verbose, -v Verbose output
# --debug Print debug output
# --version Print version
# --about Display detailed info
# --help, -h Print help with command options
# Examples:
# 1) List available mailboxes
# imapgrab3.py -l -s imap.example.com -u username -p password
# 2) Download "box1" and "box2" from server imap.example.com (save "box1.mbox" and "box2.mbox")
# imapgrab3.py -d -s imap.example.com -u username -p password -m "box1, box2"
# 3) Download all mailboxes except "box3"
# imapgrab3.py -d -s imap.example.com -u username -p password -m "_ALL_, -box3"
# 4) Download all Gmail custom labels and INBOX (none of the [Gmail]* mailboxes)
# imapgrab3.py -d -S -s imap.gmail.com -u username -p password -m "_ALL_, -_Gmail_"
# 5) Download Gmail label "receipts"
# imapgrab3.py -d -S -s imap.gmail.com -u username -p password -m "receipts"
ig_version_long = "imapgrab " + ig_version_short
ig_about = "IMAP Grab - Version " + ig_version_short + \
"\nWritten by Daniel Roesler (diafygi)\nReleased under GNU Public License v2\n<http://www.gnu.org/licenses/gpl-2.0.txt>"
def imapgrab():
ig_cmd = OptionParser(
usage="%prog [-ldaSv] [-s] SERVER [-P] PORT [-u] USERNAME [-p] PASSWORD [-m] \"BOX1,BOX2,...\" [-f] DIRECTORY",
description="Description: ImapGrab connects to a imap server and downloads mail from selected mailboxes to mbox files. Released under GPLv2.")
ig_cmd.add_option("-l", "--list", action="store_true",
help="List the mailboxes available for download")
ig_cmd.add_option("-d", "--download", action="store_true",
help="Download mailboxes to separate files/folders")
ig_cmd.add_option("-B", "--mbox", action="store_true",
help="Download into Mbox format (optional, default)")
ig_cmd.add_option("-M", "--maildir", action="store_true",
help="Download into Maildir format (optional)")
ig_cmd.add_option("-a", "--all", action="store_true",
help="Force download all mail in a mailbox (optional)")
ig_cmd.add_option("-S", "--ssl", action="store_true",
help="Use SSL connection (optional)")
ig_cmd.add_option("-s", "--server", dest="server",
help="IP or domain of server (required)")
ig_cmd.add_option("-P", "--port", dest="port",
help="Port of server (optional)")
ig_cmd.add_option("-u", "--username", dest="username",
help="Username for account (required)")
ig_cmd.add_option("-p", "--password", dest="password",
help="Password for account (required)")
ig_cmd.add_option("-m", "--mailboxes", dest="mailboxes",
help="Comma separated list of mailboxes to download (i.e. \"Box1, Box2, Box3\") ('{,}' for non-separating commas) ('_ALL_' for all mailboxes, '-Box1' to except Box1 from _ALL_) (required for -d)")
ig_cmd.add_option("-I", "--imap-search", dest="imap_search",
help="Optional IMAP SEARCH criteria for getmail (e.g. 'SINCE 01-Jan-2020 BEFORE 01-Feb-2020'). Useful to bypass Yahoo large-folder FETCH limits.")
ig_cmd.add_option("-f", "--folder", dest="folder",
help="Path to folder (optional, creates imapgrab folder in current directory as default)")
ig_cmd.add_option("-L", "--localuser", dest="localuser",
help="User that writes to the mailboxes. (only use when invoking imapgrab as root)")
ig_cmd.add_option("-q", "--quiet", action="store_true",
help="Don't display any output")
ig_cmd.add_option("-v", "--verbose", action="store_true",
help="Verbose output")
ig_cmd.add_option("--debug", action="store_true",
help="Print debug output")
ig_cmd.add_option("--version", action="store_true", help="Print version")
ig_cmd.add_option("--about", action="store_true",
help="Display detailed info")
(ig_options, ig_args) = ig_cmd.parse_args()
# debug shows parsed command
if (ig_options.debug is True):
print("DEBUG_000: parsed options:\n", ig_options, "\nDEBUG: parsed arguments:\n",
ig_args)
# verbose shows title
if (ig_options.quiet is not True and ig_options.version is not True and ig_options.about is not True):
print("IMAP Grab " + ig_version_short + "\n---")
# show version number
if ig_options.version is True:
if (ig_options.debug is True):
print("DEBUG_001: printing version number")
if (ig_options.verbose is True):
print("Printing version number:")
print(ig_version_long)
# show about display
elif ig_options.about is True:
if (ig_options.debug is True):
print("DEBUG_002: printing about display")
if (ig_options.verbose is True):
print("Printing about display:")
print(ig_about)
# check for list or download
elif (ig_options.list is True) or (ig_options.download is True):
# ERROR if both list and download are used
if (ig_options.list is True) and (ig_options.download is True):
if (ig_options.debug is True):
print("DEBUG_003: both -l and -d were parsed")
if (ig_options.verbose is True):
print("Both -l and -d were parsed")
print(
"ERROR: Cannot list mailboxes (--list or -l) and download backup (--download or -d) at the same time.")
# ERROR if username/password/server
elif ig_options.username is None:
print("ERROR: No username set (--username or -u)")
elif ig_options.password is None:
print("ERROR: No password set (--password or -p)")
elif ig_options.server is None:
print("ERROR: No server set (--server or -s)")
# --list, call list function
elif ig_options.list is True:
if (ig_options.debug is True):
print("DEBUG_004: -l parsed, calling list function")
if (ig_options.verbose is True):
print("List option selected")
ig_list = IG_list_mailboxes(ig_options)
if (ig_options.quiet is not True):
print("List of mailboxes available:")
for i in ig_list:
print(i)
# --download, call download function
elif ig_options.download is True:
if (ig_options.debug is True):
print("DEBUG_005: -d parsed, calling download function")
if (ig_options.verbose is True):
print("Download option selected")
IG_backup_mail(ig_options)
# ERROR and show help
else:
if (ig_options.debug is True):
print("DEBUG_006: no options entered")
print("Needs --list or --download option.")
ig_cmd.print_help()
return True
# FUNCTION- LIST MAILBOXES
def IG_list_mailboxes(ig_options):
# Open IMAP connection
if ig_options.ssl is True:
if (ig_options.debug is True):
print("DEBUG_007: -S parsed, connecting via SSL")
if (ig_options.verbose is True):
print("Connecting to IMAP server via SSL")
if ig_options.port is None:
ig_options.port = 993
else:
ig_options.port = int(ig_options.port)
ig_imap = imaplib.IMAP4_SSL(ig_options.server, ig_options.port)
else:
if (ig_options.debug is True):
print("DEBUG_008: no -S parsed, connecting with no SSL")
if (ig_options.verbose is True):
print("Connecting to IMAP server")
if ig_options.port is None:
ig_options.port = 143
else:
ig_options.port = int(ig_options.port)
ig_imap = imaplib.IMAP4(ig_options.server, ig_options.port)
# Login to IMAP Server
if (ig_options.debug is True):
print("DEBUG_010: sending username/password to server")
if (ig_options.verbose is True):
print("Logging into IMAP server")
ig_imap.login(ig_options.username, ig_options.password)
if (ig_options.debug is True):
print("DEBUG_011: connected to IMAP server")
# Get mailboxes list
ig_list_raw = []
ig_list = []
imap_list = ig_imap.list()
# print ig_imap.status("mailbox", "(MESSAGES)") #Returns number of messages in a mailbox, maybe I'll use it later
if (ig_options.debug is True):
print("DEBUG_012: got list of mailboxes:")
print(imap_list)
# Parses out mailbox names from other metadata
for i in imap_list[1]:
ig_list_raw.append(i.split(b'" ', 1)[1])
# Decode mailbox name: IMAP LIST returns modified UTF-7 (e.g. "&-" means "&").
# If we utf-8-decode only, getmail may UTF-7-encode again and break SELECT.
for i in ig_list_raw:
if isinstance(i, bytes):
# Strip surrounding quotes while still bytes
if len(i) >= 2 and i[:1] == b'"' and i[-1:] == b'"':
i = i[1:-1]
if imap_utf7 is not None:
try:
i = imap_utf7.decode(i)
except Exception:
i = i.decode("utf-8", "replace")
else:
# Minimal fallback: &- is the UTF-7 encoding of &
i = i.decode("utf-8", "replace").replace("&-", "&")
else:
if len(i) >= 2 and i[0] == "\"" and i[-1] == "\"":
i = i[1:-1]
if imap_utf7 is not None:
try:
i = imap_utf7.decode(i.encode("ascii", "surrogateescape"))
except Exception:
pass
else:
i = i.replace("&-", "&")
ig_list.append(i)
# Logout of IMAP server
ig_imap.logout()
if (ig_options.debug is True):
print("DEBUG_013: logged out of server")
return ig_list
# FUNCTION- BACKUP MAIL
def IG_backup_mail(ig_options):
# Remove verbose/debug options for list function call
ig_list_options = copy.copy(ig_options)
ig_list_options.debug = None
ig_list_options.verbose = None
# Call list function
if (ig_options.verbose is True):
print("Getting list of mailboxes")
if (ig_options.debug is True):
print("DEBUG_014: getting list of mailboxes:")
ig_list = IG_list_mailboxes(ig_list_options)
if (ig_options.debug is True):
print(ig_list)
# Set default port
if ig_options.port is None and ig_options.ssl is True:
ig_options.port = "993"
if ig_options.port is None and ig_options.ssl is None:
ig_options.port = "143"
# Error if no list of mailboxes
if ig_options.mailboxes is None:
print("ERROR: no mailboxes selected for download (use -m or --mailboxes option)")
return
# Create list from -m
# Use {,} for a literal comma inside a mailbox name (e.g. FB{,} Google{,} Yelp).
ig_download_str_rm_comma = ig_options.mailboxes.replace("{,}", "<!comma!>")
if (ig_options.debug is True):
print(
"DEBUG_015: removed non-separating commas: \"" + ig_download_str_rm_comma + "\"")
ig_download_list_raw = ig_download_str_rm_comma.split(",")
ig_download_list_fix_comma = []
for i in ig_download_list_raw:
ig_download_list_fix_comma.append(i.replace("<!comma!>", ","))
def _parse_mailbox_token(token):
# Only trim leading whitespace from comma-separated -m parsing
# (e.g. "Box1, Box2"). Keep trailing spaces — Yahoo allows names
# like "1 A All Spreadsheets ".
name = token.lstrip(" \t")
if len(name) >= 2 and name[0] == "\"" and name[-1] == "\"":
name = name[1:-1]
return name
def _resolve_mailbox_name(name, available):
"""Map a user-supplied mailbox name to the server's exact spelling."""
if name in available:
return name
stripped = name.strip()
if stripped in available:
return stripped
for n in available:
if n.strip() == stripped:
return n
# Wire-form "&-" (modified UTF-7 for "&") vs decoded "&"
alt = stripped.replace("&-", "&")
if alt in available:
return alt
for n in available:
if n.strip() == alt:
return n
if imap_utf7 is not None:
try:
decoded = imap_utf7.decode(stripped.encode("ascii", "surrogateescape"))
if decoded in available:
return decoded
except Exception:
pass
return name
ig_download_list = []
for i in ig_download_list_fix_comma:
ig_download_list.append(_parse_mailbox_token(i))
# Gmail exceptions
gmail_list = ['[Gmail]', '[Gmail]/All Mail', '[Gmail]/Drafts', '[Gmail]/Sent Mail', '[Gmail]/Spam',
'[Gmail]/Starred', '[Gmail]/Trash', '[Gmail]/Bin', '[Gmail]/Important',
'[Google Mail]', '[Google Mail]/All Mail', '[Google Mail]/Drafts', '[Google Mail]/Sent Mail',
'[Google Mail]/Spam', '[Google Mail]/Starred', '[Google Mail]/Trash']
# Work out exceptions for _ALL_
if "_ALL_" in ig_download_list:
ig_exceptions_list = []
for i in ig_download_list:
if i == "-_Gmail_":
for j in gmail_list:
ig_exceptions_list.append(j)
elif i[0] == "-":
ig_exceptions_list.append(i[1:])
ig_download_list = [
x for x in ig_list if x not in ig_exceptions_list]
# Work out exceptions for _Gmail_
if "_Gmail_" in ig_download_list:
ig_download_list.remove("_Gmail_")
if "[Gmail]" in ig_list:
for i in gmail_list[1:7]:
ig_download_list.append(i)
elif "[Google Mail]" in ig_list:
for i in gmail_list[8:14]:
ig_download_list.append(i)
else:
print("ERROR: Gmail doesn't appear to be in your list of mailboxes")
# Remove duplicates from download list
ig_download_list = sorted(set(ig_download_list))
# Resolve each -m name to the server's exact mailbox spelling (trailing
# spaces, etc.) before availability checks and getmail config generation.
ig_download_list = [_resolve_mailbox_name(i, ig_list) for i in ig_download_list]
# Compare list from -m to available mailboxes
if (ig_options.verbose is True):
print("List of mailboxes selected to download:")
print(ig_download_list)
if (ig_options.debug is True):
print("DEBUG_017: List of mailboxes to download:")
print(ig_download_list)
if (ig_options.debug is True):
print("DEBUG_018: checking -m list against available mailboxes on server")
if (ig_options.verbose is True):
print("Checking available mailboxes on server")
ig_all_found = []
for i in ig_download_list:
for n in ig_list:
if i == n:
ig_all_found.append(i)
if len(ig_all_found) != len(ig_download_list):
missing = [x for x in ig_download_list if x not in ig_all_found]
print("ERROR: The following mailboxes weren't available:")
print(missing)
print(
"ERROR: Some of the mailboxes you selected are not available for download. Use list option (-l or --list) to see availabe mailboxes.")
sys.exit(1)
if (ig_options.debug is True):
print("DEBUG_019: found all items in -m")
# Create directory for storage
if ig_options.folder is None:
ig_options.folder = os.getcwd() + os.sep + "imapgrab"
if (ig_options.debug is True):
print(
"DEBUG_020: no -f parsed, using current directory: " + ig_options.folder + os.sep + "imapgrab")
# Remove last slash if it exists
elif ig_options.folder[-1] is os.sep:
ig_options.folder = ig_options.folder[0:(len(ig_options.folder) - 1)]
# Check to see if directory exists
if os.path.exists(ig_options.folder) is not True:
# Make folder path from root
if (ig_options.folder[0] is not os.sep):
ig_options.folder = os.getcwd() + os.sep + ig_options.folder
if (ig_options.debug is True):
print(
"DEBUG_021: folder does not exist, creating new folder in " + ig_options.folder)
if (ig_options.verbose is True):
print("Creating folder for backup")
os.makedirs(ig_options.folder)
else:
if (ig_options.debug is True):
print("DEBUG_022: directory already exists")
# Create rc files for getmail
if (ig_options.debug is True):
print("DEBUG_023: creating rc files for getmail")
if (ig_options.verbose is True):
print("Creating download config files in " + ig_options.folder)
for i in ig_download_list:
i_str = i.decode() if isinstance(i, bytes) else i
# Create needed folders
if os.sep in i_str:
folders = i_str.split(os.sep)
filename = folders[-1]
fpath = ig_options.folder
# Check to see if folder exists, create if not
for f in range(0, len(folders) - 1):
fpath = fpath + os.sep + folders[f]
if os.path.exists(fpath) is not True:
if (ig_options.debug is True):
print(
"DEBUG_024: creating \"" + folders[f] + "\" folder since it doesn't exist")
if (ig_options.verbose is True):
print(
"\"" + folders[f] + "\" folder doesn't exist, creating folder")
os.mkdir(fpath)
else:
fpath = ig_options.folder
filename = i_str
# Open file
rc_file = open(fpath + os.sep + filename + ".rc", "w")
# Write config lines to file
rc_file.write("[retriever]\n")
if ig_options.ssl is True:
rc_file.write("type = SimpleIMAPSSLRetriever\n")
else:
rc_file.write("type = SimpleIMAPRetriever\n")
rc_file.write("server = " + ig_options.server + "\n")
rc_file.write("port = " + ig_options.port + "\n")
rc_file.write("username = " + ig_options.username + "\n")
rc_file.write("password = " + ig_options.password + "\n")
rc_file.write("mailboxes = (\"" + i_str + "\",)\n")
if ig_options.imap_search:
rc_file.write("imap_search = " + ig_options.imap_search + "\n")
rc_file.write("\n")
rc_file.write("[destination]\n")
if ig_options.localuser is not None:
rc_file.write("user = " + ig_options.localuser + "\n")
if ig_options.maildir is True:
rc_file.write("type = Maildir\n")
rc_file.write("path = " + fpath + os.sep +
filename + os.sep + "\n\n")
else:
rc_file.write("type = Mboxrd\n")
rc_file.write("path = " + fpath + os.sep + filename + ".mbox\n\n")
rc_file.write("[options]\n")
if ig_options.all is not True:
rc_file.write("read_all = false\n")
if ig_options.debug is True:
rc_file.write("verbose = 2\n")
# Close file
rc_file.close()
# Debug/Verbose explainations
if (ig_options.verbose is True):
print("Created \"" + fpath + os.sep + filename + ".rc\"")
if (ig_options.debug is True):
print("DEBUG_024: Contents of \"" +
fpath + os.sep + filename + ".rc\":")
print("--------------------")
print(open(fpath + os.sep + filename + ".rc", "r").read())
print("--------------------")
if ig_options.maildir is True:
# Create maildir directory if doesn't exist
maildir_directories = ["", "new" + os.sep,
"cur" + os.sep, "tmp" + os.sep]
for f in maildir_directories:
if os.path.isdir(fpath + os.sep + filename + os.sep + f) is not True:
if (ig_options.verbose is True):
print(
"Maildir directory doesn't exist, creating \"" + fpath + os.sep + filename + os.sep + f + "\"")
if (ig_options.debug is True):
print(
"DEBUG_025: \"" + fpath + os.sep + filename + os.sep + f + "\" doesn't exist, creating")
os.mkdir(fpath + os.sep + filename + os.sep + f)
else:
if (ig_options.verbose is True):
print(
"Maildir directory already exists, using \"" + fpath + os.sep + filename + os.sep + f + "\"")
if (ig_options.debug is True):
print(
"DEBUG_026: \"" + fpath + os.sep + filename + os.sep + f + "\" exists")
else:
# Create mbox file if doesn't exist
if os.path.isfile(fpath + os.sep + filename + ".mbox") is not True:
if (ig_options.verbose is True):
print(
"Mbox file doesn't exist, creating \"" + fpath + os.sep + filename + ".mbox\"")
if (ig_options.debug is True):
print(
"DEBUG_025: \"" + fpath + os.sep + filename + ".mbox\" doesn't exist")
open(fpath + os.sep + filename + ".mbox", "w").close()
else:
if (ig_options.verbose is True):
print(
"Mbox file already exists, using \"" + fpath + os.sep + filename + ".mbox\"")
if (ig_options.debug is True):
print("DEBUG_026: \"" + fpath + os.sep +
filename + ".mbox\" exists")
# Call getmail command
download_failed = False
for mailbox in ig_download_list:
mailbox_str = mailbox.decode() if isinstance(mailbox, bytes) else mailbox
# Build folder path to .rc files created previously
if os.sep in mailbox_str: # Check to see if there are folders in mailbox name
folders = mailbox_str.split(os.sep)
filename = folders[-1]
path_from_folder = ""
for f in range(0, len(folders) - 1): # Add folder path in mailbox name
path_from_folder = path_from_folder + os.sep + folders[f]
else:
path_from_folder = ""
filename = mailbox_str
# Set getmail command and options for getmail command
cmd = "getmail"
rc_file_loc = path_from_folder + os.sep + filename + ".rc"
# Remove first os.sep
rc_file_loc = rc_file_loc[1:]
# Set local user permissions if needed
if ig_options.localuser is not None:
####### Can't use os.chown() because it's not recursive...unless there's something I don't know.#############
os.system("chown -R " + ig_options.localuser +
" " + ig_options.folder)
# Call getmail command
if (ig_options.verbose is True):
print(
"Calling getmail to retrieve mail for mailbox \"" + ig_options.folder + os.sep + path_from_folder + os.sep + filename + "\"")
if (ig_options.quiet is not True):
print("Downloading mailbox \"" + mailbox_str + "\"")
if (ig_options.debug is True):
print(
"DEBUG_027: calling \"" + cmd + " -g " + ig_options.folder + " -r " + rc_file_loc + "\"")
if ig_options.verbose is True or ig_options.debug is True:
getmail_status = subprocess.call(
[cmd, "-g", ig_options.folder, "-r", rc_file_loc])
else:
getmail_status = subprocess.call(
[cmd, "--quiet", "-g", ig_options.folder, "-r", rc_file_loc])
if getmail_status != 0:
download_failed = True
os.remove(ig_options.folder + os.sep + rc_file_loc)
# Print complete
if download_failed:
sys.exit(1)
if (ig_options.quiet is not True):
print("Downloads complete")
if __name__ == "__main__":
imapgrab()