From 941509bd6305c1c6b007fae6188d18fc3b7f6992 Mon Sep 17 00:00:00 2001 From: Mark Feit Date: Tue, 25 Dec 2018 18:07:00 -0500 Subject: [PATCH 1/3] Allow password to be read from a file --- imapbackup.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/imapbackup.py b/imapbackup.py index 3dad901..324afca 100644 --- a/imapbackup.py +++ b/imapbackup.py @@ -4,9 +4,10 @@ __version__ = "1.4h" __author__ = "Rui Carmo (http://taoofmac.com)" __copyright__ = "(C) 2006-2018 Rui Carmo. Code under MIT License.(C)" -__contributors__ = "jwagnerhki, Bob Ippolito, Michael Leonhard, Giuseppe Scrivano , Ronan Sheth, Brandon Long, Christian Schanz, A. Bovett" +__contributors__ = "jwagnerhki, Bob Ippolito, Michael Leonhard, Giuseppe Scrivano , Ronan Sheth, Brandon Long, Christian Schanz, A. Bovett, Mark Feit" # = Contributors = +# http://github.com/markfeit: Allow password to be read from a file # http://github.com/jwagnerhki: fix for message_id checks # A. Bovett: Modifications for Thunderbird compatibility and disabling spinner in Windows # Christian Schanz: added target directory parameter @@ -101,6 +102,28 @@ BLANKS_RE = re.compile(r'\s+', re.MULTILINE) # Constants UUID = '19AF1258-1AAF-44EF-9D9A-731079D6FAD7' # Used to generate Message-Ids + +def string_from_file(value): + """ + Read a string from a file or return the string unchanged. + + If the string begins with '@', the remainder of the string + will be treated as a path to the file to be read. Precede + the '@' with a '\' to treat it as a literal. + """ + + assert isinstance(value, basestring) + + if not value or value[0] not in ["\\", "@"]: + return value + + if value[0] == "\\": + return value[1:] + + with open(os.path.expanduser(value[1:]), 'r') as content: + return content.read().strip() + + def download_messages(server, filename, messages, config): """Download messages from folder and append to mailbox""" @@ -381,7 +404,9 @@ def print_usage(): print " Python's SSL module doesn't check the cert chain." print " -s HOST --server=HOST Address of server, port optional, eg. mail.com:143" print " -u USER --user=USER Username to log into server" - print " -p PASS --pass=PASS Prompts for password if not specified." + print " -p PASS --pass=PASS Prompts for password if not specified. If the first" + print " character is '@', treat the rest as a path to a file" + print " containing the password. Leading '\' makes it literal." print " -t SECS --timeout=SECS Sets socket timeout to SECS seconds." print " --thunderbird Create Mozilla Thunderbird compatible mailbox" print " --nospinner Disable spinner (makes output log-friendly)" @@ -440,7 +465,10 @@ def process_cline(): elif option in ("-u", "--user"): config['user'] = value elif option in ("-p", "--pass"): - config['pass'] = value + try: + config['pass'] = string_from_file(value) + except Exception as ex: + errors.append("Can't read password: %s" % (str(ex))) elif option in ("-t", "--timeout"): config['timeout'] = value elif option == "--thunderbird": From 0b1351717ccd584498fba1bb802e7c80dc41c17e Mon Sep 17 00:00:00 2001 From: Mark Feit Date: Tue, 25 Dec 2018 18:08:41 -0500 Subject: [PATCH 2/3] Ignore mbox files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index ded6067..1c5848f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ nosetests.xml .mr.developer.cfg .project .pydevproject + +# Things that might show up during testing +*.mbox From d820b7a83216c756034f4f74701cf9e666581140 Mon Sep 17 00:00:00 2001 From: Mark Feit Date: Tue, 25 Dec 2018 18:10:51 -0500 Subject: [PATCH 3/3] Format dates in From lines more like most mail programs do --- imapbackup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imapbackup.py b/imapbackup.py index 324afca..dc1ca9a 100644 --- a/imapbackup.py +++ b/imapbackup.py @@ -159,7 +159,7 @@ def download_messages(server, filename, messages, config): for msg_id in messages.keys(): # This "From" and the terminating newline below delimit messages # in mbox files - buf = "From nobody %s\n" % time.strftime('%a %m %d %H:%M:%S %Y') + buf = "From nobody %s\n" % time.strftime('%a %b %d %H:%M:%S %Y') # If this is one of our synthesised Message-IDs, insert it before # the other headers if UUID in msg_id: