tags 349068 patch pending tags 247340 patch pending thanks Hi there,
Please find attached patches for fixing the overwriting of symlinks [1], and adding a --prefix switch to archivemail [2], along with relevant test cases. Let me know if you'd like any changes for them to be accepted upstream. Cheers, Serafeim [1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=349068 [2] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=247340
--- ../archivemail.upstream/archivemail 2007-11-09 15:00:43.000000000 +0000 +++ archivemail 2008-08-10 11:04:46.000000000 +0100 @@ -483,6 +483,15 @@ """Return the current size of the mbox file""" return os.path.getsize(self.mbox_file_name) + def get_link_target(self, file_name): + """Return the supplied file name if not a link; else its target.""" + prev = file_name + while os.path.islink(file_name): + prev = file_name + file_name = os.readlink(file_name) + if os.path.isabs(file_name): + return file_name + return os.path.abspath(os.path.join(os.path.dirname(prev), file_name)) class RetainMbox(Mbox): """Class for holding messages that will be retained from the original @@ -521,6 +530,7 @@ mode = os.stat(self.__final_name)[stat.ST_MODE] os.chmod(self.mbox_file_name, mode) + self.__final_name = self.get_link_target(self.__final_name) vprint("renaming '%s' to '%s'" % (self.mbox_file_name, self.__final_name)) try: os.rename(self.mbox_file_name, self.__final_name) @@ -611,6 +621,7 @@ final_name = self.__final_name if not options.no_compress: final_name = final_name + ".gz" + final_name = self.get_link_target(final_name) vprint("renaming '%s' to '%s'" % (self.mbox_file_name, final_name)) try:
--- ../archivemail.upstream/test_archivemail.py 2007-11-09 14:14:41.000000000 +0000 +++ /tmp/test_archivemail.py 2008-08-10 23:38:30.000000000 +0100 @@ -99,6 +99,30 @@ ############ Mbox Class testing ############## +class TestMboxSymLinkResolution(TestCaseInTempdir): + def setUp(self): + super(TestMboxSymLinkResolution, self).setUp() + self.mbox_file_name = make_mbox() + self.mbox = archivemail.Mbox(self.mbox_file_name) + + def testAbsoluteSymlink(self): + """resolve an absolute symlink in a different directory""" + link_name = "%s/symlink-to-mbox" % tempfile.mkdtemp() + os.symlink(self.mbox_file_name, link_name) + link_target = self.mbox.get_link_target(link_name) + self.assertEqual(self.mbox_file_name, link_target) + + def testRelativeSymlink(self): + """resolve a relative symlink in a different directory""" + link_dir = tempfile.mkdtemp() + link_name = "%s/symlink-to-mbox" % link_dir + run = "cd %s && ln -s ../%s %s" % (link_dir,\ + os.path.basename(self.mbox_file_name),\ + os.path.basename(link_name)) + self.assertEqual(os.system(run), 0) + link_target = self.mbox.get_link_target(link_name) + self.assertEqual(self.mbox_file_name, link_target) + class TestMboxIsEmpty(TestCaseInTempdir): def setUp(self): super(TestMboxIsEmpty, self).setUp()
--- ../archivemail.upstream/archivemail 2007-11-09 15:00:43.000000000 +0000 +++ archivemail 2008-08-10 22:37:03.000000000 +0100 @@ -171,6 +171,7 @@ class Options: """Class to store runtime options, including defaults""" + archive_prefix = None archive_suffix = "_archive" days_old_max = 180 date_old_max = None @@ -207,12 +208,13 @@ """ try: - opts, args = getopt.getopt(args, '?D:S:Vd:hno:F:P:qs:uv', + opts, args = getopt.getopt(args, '?D:S:Vd:hno:F:P:qs:uvp:', ["date=", "days=", "delete", "dry-run", "help", "include-flagged", "no-compress", "output-dir=", "filter-append=", "pwfile=", "dont-mangle", "preserve-unread", "quiet", "size=", "suffix=", - "verbose", "version", "warn-duplicate", "copy"]) + "verbose", "version", "warn-duplicate", "copy", + "prefix="]) except getopt.error, msg: user_error(msg) @@ -252,6 +254,8 @@ self.dry_run = 1 if o in ('-q', '--quiet'): self.quiet = 1 + if o in ('-p', '--prefix'): + self.archive_prefix = a if o in ('-s', '--suffix'): self.archive_suffix = a if o in ('-S', '--size'): @@ -662,6 +666,7 @@ -o, --output-dir=DIR directory to store archives (default: same as original) -P, --pwfile=FILE file to read imap password from (default: None) -F, --filter-append=STRING append arbitrary string to the IMAP filter string + -p, --prefix=NAME prefix for archive filename (default: none) -s, --suffix=NAME suffix for archive filename (default: '%s') -S, --size=NUM only archive messages NUM bytes or larger -n, --dry-run don't write to anything - just show what would be done @@ -1102,6 +1107,9 @@ final_archive_name = mailbox_name.split('/')[-1] + parsed_suffix else: final_archive_name = mailbox_name + parsed_suffix + if options.archive_prefix: + final_archive_name = os.path.join(os.path.dirname(final_archive_name),\ + options.archive_prefix + os.path.basename(final_archive_name)) if options.output_dir: final_archive_name = os.path.join(options.output_dir, os.path.basename(final_archive_name))
--- ../archivemail.upstream/test_archivemail.py 2007-11-09 14:14:41.000000000 +0000 +++ ./test_archivemail.py 2008-08-10 23:27:01.000000000 +0100 @@ -858,6 +858,54 @@ archivemail.options.archive_suffix = "_archive" super(TestArchiveMboxSuffix, self).tearDown() +class TestArchiveMboxPrefix(TestCaseInTempdir): + """make sure the 'prefix' option works""" + def setUp(self): + super(TestArchiveMboxPrefix, self).setUp() + archivemail.options.quiet = 1 + + def testPrefix(self): + """archiving with specified --prefix arguments""" + for prefix in ["blah-"]: + for execute in ("system_long", "system_short", "package"): + self.setUp() + days_old_max = 180 + self.mbox_name = make_mbox(messages=3, + hours_old=(24 * (days_old_max+1))) + self.copy_name = tempfile.mkstemp()[1] + shutil.copyfile(self.mbox_name, self.copy_name) + if execute == "system_long": + run = "./archivemail.py --quiet --prefix='%s' %s" % \ + (prefix, self.mbox_name) + self.assertEqual(os.system(run), 0) + elif execute == "system_short": + run = "./archivemail.py --quiet -p'%s' %s" % \ + (prefix, self.mbox_name) + self.assertEqual(os.system(run), 0) + elif execute == "package": + archivemail.options.archive_prefix = prefix + archivemail.archive(self.mbox_name) + else: + sys.exit(1) + assert(os.path.exists(self.mbox_name)) + self.assertEqual(os.path.getsize(self.mbox_name), 0) + + archive_name = os.path.join(os.path.dirname(self.mbox_name),\ + prefix + os.path.basename(self.mbox_name) +\ + "_archive.gz") + assert(os.path.exists(archive_name)) + self.assertEqual(os.system("gzip -d %s" % archive_name), 0) + archive_name = re.sub("\.gz$", "", archive_name) + assert(os.path.exists(archive_name)) + assert(filecmp.cmp(archive_name, self.copy_name, shallow=0)) + os.remove(archive_name) + self.tearDown() + + def tearDown(self): + archivemail.options.quiet = 0 + archivemail.options.archive_prefix = None + super(TestArchiveMboxPrefix, self).tearDown() + class TestArchiveDryRun(TestCaseInTempdir): """make sure the 'dry-run' option works"""