Added new option --all to archive all messages in a mailbox.
Updated documentation, and added a first simple unittest for this. Closes: #1764846.
This commit is contained in:
parent
2719645f2c
commit
f43cbb106d
|
@ -214,6 +214,9 @@ originating mailbox, which is left unchanged.
|
||||||
This is a complement to the \fB--delete\fR option, and mainly useful for
|
This is a complement to the \fB--delete\fR option, and mainly useful for
|
||||||
testing purposes.
|
testing purposes.
|
||||||
.TP
|
.TP
|
||||||
|
\fB --all\fR
|
||||||
|
Archive all messages, without distinction.
|
||||||
|
.TP
|
||||||
\fB --include-flagged\fR
|
\fB --include-flagged\fR
|
||||||
Normally messages that are flagged important are not archived or deleted. If
|
Normally messages that are flagged important are not archived or deleted. If
|
||||||
you specify this option, these messages can be archived or deleted just like
|
you specify this option, these messages can be archived or deleted just like
|
||||||
|
|
|
@ -195,6 +195,7 @@ class Options:
|
||||||
debug_imap = 0
|
debug_imap = 0
|
||||||
warn_duplicates = 0
|
warn_duplicates = 0
|
||||||
copy_old_mail = 0
|
copy_old_mail = 0
|
||||||
|
archive_all = 0
|
||||||
|
|
||||||
def parse_args(self, args, usage):
|
def parse_args(self, args, usage):
|
||||||
"""Set our runtime options from the command-line arguments.
|
"""Set our runtime options from the command-line arguments.
|
||||||
|
@ -214,7 +215,7 @@ class Options:
|
||||||
"filter-append=", "pwfile=", "dont-mangle",
|
"filter-append=", "pwfile=", "dont-mangle",
|
||||||
"preserve-unread", "quiet", "size=", "suffix=",
|
"preserve-unread", "quiet", "size=", "suffix=",
|
||||||
"verbose", "debug-imap=", "version",
|
"verbose", "debug-imap=", "version",
|
||||||
"warn-duplicate", "copy"])
|
"warn-duplicate", "copy", "all"])
|
||||||
except getopt.error, msg:
|
except getopt.error, msg:
|
||||||
user_error(msg)
|
user_error(msg)
|
||||||
|
|
||||||
|
@ -270,6 +271,8 @@ class Options:
|
||||||
if self.delete_old_mail:
|
if self.delete_old_mail:
|
||||||
user_error("found conflicting options --copy and --delete")
|
user_error("found conflicting options --copy and --delete")
|
||||||
self.copy_old_mail = 1
|
self.copy_old_mail = 1
|
||||||
|
if o == '--all':
|
||||||
|
self.archive_all = 1
|
||||||
if o in ('-V', '--version'):
|
if o in ('-V', '--version'):
|
||||||
print __version__ + "\n\n" + __copyright__
|
print __version__ + "\n\n" + __copyright__
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
@ -674,6 +677,7 @@ Options are as follows:
|
||||||
--delete delete rather than archive old mail (use with caution!)
|
--delete delete rather than archive old mail (use with caution!)
|
||||||
--copy copy rather than archive old mail
|
--copy copy rather than archive old mail
|
||||||
--include-flagged messages flagged important can also be archived
|
--include-flagged messages flagged important can also be archived
|
||||||
|
--all archive all messages
|
||||||
--no-compress do not compress archives with gzip
|
--no-compress do not compress archives with gzip
|
||||||
--warn-duplicate warn about duplicate Message-IDs in the same mailbox
|
--warn-duplicate warn about duplicate Message-IDs in the same mailbox
|
||||||
-v, --verbose report lots of extra debugging information
|
-v, --verbose report lots of extra debugging information
|
||||||
|
@ -996,6 +1000,8 @@ def is_smaller(message, size):
|
||||||
|
|
||||||
def should_archive(message):
|
def should_archive(message):
|
||||||
"""Return true if we should archive the message, false otherwise"""
|
"""Return true if we should archive the message, false otherwise"""
|
||||||
|
if options.archive_all:
|
||||||
|
return 1
|
||||||
old = 0
|
old = 0
|
||||||
time_message = guess_delivery_time(message)
|
time_message = guess_delivery_time(message)
|
||||||
if options.date_old_max == None:
|
if options.date_old_max == None:
|
||||||
|
@ -1341,8 +1347,6 @@ def _archive_imap(mailbox_name, final_archive_name):
|
||||||
stats = Stats(mailbox_name, final_archive_name)
|
stats = Stats(mailbox_name, final_archive_name)
|
||||||
cache = IdentityCache(mailbox_name)
|
cache = IdentityCache(mailbox_name)
|
||||||
imap_str = mailbox_name[mailbox_name.find('://') + 3:]
|
imap_str = mailbox_name[mailbox_name.find('://') + 3:]
|
||||||
imap_filter = build_imap_filter()
|
|
||||||
vprint("imap filter: '%s'" % imap_filter)
|
|
||||||
imap_username, imap_password, imap_server, imap_folder = \
|
imap_username, imap_password, imap_server, imap_folder = \
|
||||||
parse_imap_url(imap_str)
|
parse_imap_url(imap_str)
|
||||||
if not imap_password:
|
if not imap_password:
|
||||||
|
@ -1412,14 +1416,19 @@ def _archive_imap(mailbox_name, final_archive_name):
|
||||||
# Worst thing should be that we bail out FETCHing a message that has been
|
# Worst thing should be that we bail out FETCHing a message that has been
|
||||||
# deleted.
|
# deleted.
|
||||||
|
|
||||||
vprint("searching messages matching criteria")
|
if options.archive_all:
|
||||||
result, response = imap_srv.search(None, imap_filter)
|
message_list = range(1, total_msg_count+1)
|
||||||
if result != 'OK': unexpected_error("imap search failed; server says '%s'" %
|
else:
|
||||||
response[0])
|
imap_filter = build_imap_filter()
|
||||||
# response is a list with a single item, listing message sequence numbers
|
vprint("imap filter: '%s'" % imap_filter)
|
||||||
# like ['1 2 3 1016']
|
vprint("searching messages matching criteria")
|
||||||
message_list = response[0].split()
|
result, response = imap_srv.search(None, imap_filter)
|
||||||
vprint("%d messages are matching filter" % len(message_list))
|
if result != 'OK': unexpected_error("imap search failed; server says '%s'" %
|
||||||
|
response[0])
|
||||||
|
# response is a list with a single item, listing message sequence numbers
|
||||||
|
# like ['1 2 3 1016']
|
||||||
|
message_list = response[0].split()
|
||||||
|
vprint("%d messages are matching filter" % len(message_list))
|
||||||
|
|
||||||
# First, gather data for the statistics.
|
# First, gather data for the statistics.
|
||||||
if total_msg_count > 0:
|
if total_msg_count > 0:
|
||||||
|
|
|
@ -308,6 +308,15 @@ testing purposes.
|
||||||
</Para></ListItem>
|
</Para></ListItem>
|
||||||
</VarListEntry>
|
</VarListEntry>
|
||||||
|
|
||||||
|
<VarListEntry>
|
||||||
|
<Term>
|
||||||
|
<Option>--all</Option>
|
||||||
|
</Term>
|
||||||
|
<ListItem><Para>
|
||||||
|
Archive all messages, without distinction.
|
||||||
|
</Para></ListItem>
|
||||||
|
</VarListEntry>
|
||||||
|
|
||||||
<VarListEntry>
|
<VarListEntry>
|
||||||
<Term>
|
<Term>
|
||||||
<Option>--include-flagged</Option>
|
<Option>--include-flagged</Option>
|
||||||
|
|
|
@ -722,6 +722,42 @@ class TestArchiveMboxTimestamp(TestCaseInTempdir):
|
||||||
super(TestArchiveMboxTimestamp, self).tearDown()
|
super(TestArchiveMboxTimestamp, self).tearDown()
|
||||||
|
|
||||||
|
|
||||||
|
class TestArchiveMboxAll(TestCaseInTempdir):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestArchiveMboxAll, self).setUp()
|
||||||
|
archivemail.options.quiet = 1
|
||||||
|
archivemail.options.archive_all = 1
|
||||||
|
|
||||||
|
def testNew(self):
|
||||||
|
"""archiving --all messages in a new mailbox"""
|
||||||
|
for execute in ("package", "system"):
|
||||||
|
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 179))
|
||||||
|
self.mbox_mode = os.stat(self.mbox_name)[stat.ST_MODE]
|
||||||
|
self.copy_name = tempfile.mkstemp()[1]
|
||||||
|
shutil.copyfile(self.mbox_name, self.copy_name)
|
||||||
|
if execute == "package":
|
||||||
|
archivemail.archive(self.mbox_name)
|
||||||
|
elif execute == "system":
|
||||||
|
run = "./archivemail.py --all --quiet %s" % self.mbox_name
|
||||||
|
self.assertEqual(os.system(run), 0)
|
||||||
|
else:
|
||||||
|
sys.exit(1)
|
||||||
|
assert(os.path.exists(self.mbox_name))
|
||||||
|
self.assertEqual(os.path.getsize(self.mbox_name), 0)
|
||||||
|
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
|
||||||
|
self.assertEqual(self.mbox_mode, new_mode)
|
||||||
|
archive_name = self.mbox_name + "_archive.gz"
|
||||||
|
assert(os.path.exists(archive_name))
|
||||||
|
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
|
||||||
|
archive_name = self.mbox_name + "_archive"
|
||||||
|
assert(os.path.exists(archive_name))
|
||||||
|
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
archivemail.options.quiet = 0
|
||||||
|
archivemail.options.archive_all = 0
|
||||||
|
super(TestArchiveMboxAll, self).tearDown()
|
||||||
|
|
||||||
class TestArchiveMboxPreserveStatus(TestCaseInTempdir):
|
class TestArchiveMboxPreserveStatus(TestCaseInTempdir):
|
||||||
"""make sure the 'preserve_unread' option works"""
|
"""make sure the 'preserve_unread' option works"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
Loading…
Reference in New Issue