New option --archive-name, alias -a, to hard-code the archive filename

This commit is contained in:
Nikolaus Schulz 2010-07-31 17:44:22 +02:00
parent 04bf8eaa23
commit 3a9a5cd4b8
3 changed files with 64 additions and 19 deletions

View File

@ -64,6 +64,10 @@ Version 0.8.0 - UNRELEASED
strips the dot off the archive name. In particular, this makes working strips the dot off the archive name. In particular, this makes working
with Maildir++ subfolders more convenient. Closes: feature request with Maildir++ subfolders more convenient. Closes: feature request
#604281. #604281.
* New option --archive-name, or short -a, to hard-code an archive filename.
Like the --suffix and --prefix options, it is expanded with strftime().
This option conflicts with archiving multiple mailboxes. Closes: feature
request #1306538.
Version 0.7.2 - 9 November 2007 Version 0.7.2 - 9 November 2007

View File

@ -174,6 +174,7 @@ class Options:
archive_prefix = None archive_prefix = None
archive_suffix = None archive_suffix = None
archive_default_suffix = "_archive" archive_default_suffix = "_archive"
archive_name = None
days_old_max = 180 days_old_max = 180
date_old_max = None date_old_max = None
delete_old_mail = False delete_old_mail = False
@ -211,13 +212,14 @@ class Options:
""" """
try: try:
opts, args = getopt.getopt(args, '?D:S:Vd:hno:F:P:qs:p:uv', opts, args = getopt.getopt(args, '?D:S:Vd:hno:F:P:qs:p:a:uv',
["date=", "days=", "delete", "dry-run", "help", ["date=", "days=", "delete", "dry-run", "help",
"include-flagged", "no-compress", "output-dir=", "include-flagged", "no-compress", "output-dir=",
"filter-append=", "pwfile=", "dont-mangle", "filter-append=", "pwfile=", "dont-mangle",
"preserve-unread", "quiet", "size=", "suffix=", "preserve-unread", "quiet", "size=", "suffix=",
"prefix=", "verbose", "debug-imap=", "version", "prefix=", "archive-name=", "verbose",
"warn-duplicate", "copy", "all"]) "debug-imap=", "version", "warn-duplicate",
"copy", "all"])
except getopt.error, msg: except getopt.error, msg:
user_error(msg) user_error(msg)
@ -261,6 +263,8 @@ class Options:
self.archive_suffix = a self.archive_suffix = a
if o in ('-p', '--prefix'): if o in ('-p', '--prefix'):
self.archive_prefix = a self.archive_prefix = a
if o in ('-a', '--archive-name'):
self.archive_name = os.path.expanduser(a)
if o in ('-S', '--size'): if o in ('-S', '--size'):
self.min_size = string.atoi(a) self.min_size = string.atoi(a)
if o in ('-u', '--preserve-unread'): if o in ('-u', '--preserve-unread'):
@ -282,7 +286,7 @@ class Options:
sys.exit(0) sys.exit(0)
return args return args
def sanity_check(self): def sanity_check(self, args):
"""Complain bitterly about our options now rather than later""" """Complain bitterly about our options now rather than later"""
if self.output_dir: if self.output_dir:
check_sane_destdir(self.output_dir) check_sane_destdir(self.output_dir)
@ -297,6 +301,9 @@ class Options:
if self.pwfile: if self.pwfile:
if not os.path.isfile(self.pwfile): if not os.path.isfile(self.pwfile):
user_error("pwfile %s does not exist" % self.pwfile) user_error("pwfile %s does not exist" % self.pwfile)
if self.archive_name and len(args) > 1:
user_error("the --archive-name cannot be used with multiple " \
"mailboxes")
def date_argument(self, string): def date_argument(self, string):
"""Converts a date argument string into seconds since the epoch""" """Converts a date argument string into seconds since the epoch"""
@ -648,6 +655,7 @@ Options are as follows:
-F, --filter-append=STRING append arbitrary string to the IMAP filter string -F, --filter-append=STRING append arbitrary string to the IMAP filter string
-p, --prefix=NAME prefix for archive filename (default: none) -p, --prefix=NAME prefix for archive filename (default: none)
-s, --suffix=NAME suffix for archive filename (default: '%s') -s, --suffix=NAME suffix for archive filename (default: '%s')
-a, --archive-name=NAME specify complete archive filename
-S, --size=NUM only archive messages NUM bytes or larger -S, --size=NUM only archive messages NUM bytes or larger
-n, --dry-run don't write to anything - just show what would be done -n, --dry-run don't write to anything - just show what would be done
-u, --preserve-unread never archive unread messages -u, --preserve-unread never archive unread messages
@ -683,7 +691,7 @@ Website: http://archivemail.sourceforge.net/ """ % \
print usage print usage
sys.exit(1) sys.exit(1)
options.sanity_check() options.sanity_check(args)
for mailbox_path in args: for mailbox_path in args:
archive(mailbox_path) archive(mailbox_path)
@ -1631,27 +1639,32 @@ def commit_archive(archive, final_archive_name):
def make_archive_name(mailbox_name): def make_archive_name(mailbox_name):
"""Derive archive name and (relative) path from the mailbox name.""" """Derive archive name and (relative) path from the mailbox name."""
# allow the user to embed time formats such as '%B' in the prefix or suffix string # allow the user to embed time formats such as '%B' in the archive name
if options.date_old_max == None: if options.date_old_max == None:
tm = time.localtime(time.time() - options.days_old_max*24*60*60) tm = time.localtime(time.time() - options.days_old_max*24*60*60)
else: else:
tm = time.localtime(options.date_old_max) tm = time.localtime(options.date_old_max)
prefix = suffix = "" prefix = suffix = ""
if options.archive_prefix is None and options.archive_suffix is None: if options.archive_name:
suffix = options.archive_default_suffix
else:
if options.archive_prefix:
prefix = time.strftime(options.archive_prefix, tm)
if options.archive_suffix:
suffix = time.strftime(options.archive_suffix, tm)
if re.match(r'imaps?://', mailbox_name.lower()):
archive_head = "" archive_head = ""
archive_tail = mailbox_name.rsplit('/', 1)[-1] archive_tail = time.strftime(options.archive_name, tm)
else: else:
archive_head, archive_tail = os.path.split(mailbox_name) if options.archive_prefix is None and options.archive_suffix is None:
if not prefix: suffix = options.archive_default_suffix
# Don't create hidden archives, e.g. when processing Maildir++ subfolders else:
archive_tail = archive_tail.lstrip('.') if options.archive_prefix:
prefix = time.strftime(options.archive_prefix, tm)
if options.archive_suffix:
suffix = time.strftime(options.archive_suffix, tm)
if re.match(r'imaps?://', mailbox_name.lower()):
archive_head = ""
archive_tail = mailbox_name.rsplit('/', 1)[-1]
else:
archive_head, archive_tail = os.path.split(mailbox_name)
if not prefix:
# Don't create hidden archives, e.g. when processing Maildir++
# subfolders
archive_tail = archive_tail.lstrip('.')
if options.output_dir: if options.output_dir:
archive_head = options.output_dir archive_head = options.output_dir
archive_name = os.path.join(archive_head, prefix + archive_tail + suffix) archive_name = os.path.join(archive_head, prefix + archive_tail + suffix)

View File

@ -434,6 +434,15 @@ class TestOptionParser(unittest.TestCase):
archivemail.options.parse_args(["-p", prefix], "") archivemail.options.parse_args(["-p", prefix], "")
self.assertEqual(archivemail.options.archive_prefix, prefix) self.assertEqual(archivemail.options.archive_prefix, prefix)
def testOptionArchivename(self):
"""--archive-name and -a options are parsed correctly"""
for name in ("custom", ".withdot", "custom_%Y", "%Y/joe"):
archivemail.options.parse_args(["--archive-name="+name], "")
self.assertEqual(archivemail.options.archive_name, name)
archivemail.options.archive_name = None
archivemail.options.parse_args(["-a", name], "")
self.assertEqual(archivemail.options.archive_name, name)
def testOptionDryrun(self): def testOptionDryrun(self):
"""--dry-run option is parsed correctly""" """--dry-run option is parsed correctly"""
archivemail.options.parse_args(["--dry-run"], "") archivemail.options.parse_args(["--dry-run"], "")
@ -938,6 +947,25 @@ class TestArchiveMboxPrefix(unittest.TestCase):
archivemail.options.quiet = False archivemail.options.quiet = False
archivemail.options.archive_prefix = None archivemail.options.archive_prefix = None
class TestArchiveName(unittest.TestCase):
def setUp(self):
archivemail.options.quiet = True
def testArchiveName(self):
"""test the --archive-name option"""
archive_names = ("custom", ".withdot", "custom_%Y", "%Y/joe")
mbox = "foobar"
for name in archive_names:
archivemail.options.archive_name = name
days = archivemail.options.days_old_max
tm = time.localtime(time.time() - days*24*60*60)
name = time.strftime(name, tm)
self.assertEqual(archivemail.make_archive_name(mbox), name)
def tearDown(self):
archivemail.options.quiet = False
archivemail.options.archive_name = None
class TestArchiveAffixes(unittest.TestCase): class TestArchiveAffixes(unittest.TestCase):
def setUp(self): def setUp(self):
self.mbox = "harbsch" self.mbox = "harbsch"