diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2019-11-19 14:24:18 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2019-11-19 14:24:18 -0700 |
commit | dbb78c50b157f00fc15bb668fc82f90ab7170110 (patch) | |
tree | 8b9692cfa3ab98df048c43c873d9c546a65f4500 /lib | |
parent | 033748acdf7ef1ba00a91b35d3cf0671d0603ac5 (diff) | |
download | dotfiles-dbb78c50b157f00fc15bb668fc82f90ab7170110.tar.gz |
rewrite expand-annex-mboxes in perl, fixing a bug
Archived mboxes with a '.' in the name, before the file extension,
were not being expanded.
This should also improve performance.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/perl5/Local/Homedir/Mail.pm | 70 |
1 files changed, 65 insertions, 5 deletions
diff --git a/lib/perl5/Local/Homedir/Mail.pm b/lib/perl5/Local/Homedir/Mail.pm index 7b2a0bcf..b8140e05 100644 --- a/lib/perl5/Local/Homedir/Mail.pm +++ b/lib/perl5/Local/Homedir/Mail.pm @@ -20,11 +20,15 @@ use strict; use warnings; use constant THIRTYONE => 31 * 24 * 60 * 60; +use File::Spec::Functions qw(catfile); +use File::Temp qw(tempdir); +use File::Path qw(remove_tree); use IO::Compress::Gzip qw(gzip $GzipError); +use IO::Uncompress::Gunzip qw(gunzip $GunzipError); use Mail::Box::Manager; use Exporter 'import'; -our @EXPORT_OK = qw( archive_to_mbox ); +our @EXPORT_OK = qw( archive_to_mbox expand_mbox ); sub archive_to_mbox { my ($source_path, $mbox_path, $expanded_path) = @_; @@ -73,10 +77,66 @@ sub archive_to_mbox { gzip($mbox_path, "$mbox_path.gz") or die "gzip failed: $GzipError\n"; unlink $mbox_path if -e "$mbox_path.gz"; - chmod 500, "$expanded_path/cur", "$expanded_path/new", - "$expanded_path/tmp"; - chmod 400, - glob "$expanded_path/cur/* $expanded_path/new/* $expanded_path/tmp/*"; + make_maildir_readonly($expanded_path); +} + +sub expand_mbox { + my ($source_path, $expanded_path) = @_; + my $lockfile = $expanded_path . ".lock"; + + # check whether we got halfway there, or we finished it + if (-e $lockfile) { + remove_tree($expanded_path); + unlink $lockfile; + } elsif (-e $expanded_path) { + return; + } + + # lock this one + open my $touch_fh, '>', $lockfile; + close $touch_fh; + + # unzip it to (what is hopefully a) tmpfs, since Mail::Box can + # only accept a path to an unzipped mbox + my $dir = tempdir(CLEANUP => 1, DIR => "/tmp"); + chmod 0700, $dir; + my $unzipped = catfile($dir, "unzip.mbox"); + gunzip($source_path, $unzipped) or die "gunzip failed: $GunzipError\n"; + + my $mgr = Mail::Box::Manager->new(); + my $source = $mgr->open( + $unzipped, + access => 'r', + keep_dups => 1, + type => 'mbox' + ); + my $expanded = $mgr->open( + $expanded_path, + access => 'a', + create => 1, + keep_dups => 1, + type => 'maildir' + ); + + foreach my $message ($source->messages()) { + $message->label(flagged => 0, seen => 1); + $mgr->copyMessage($expanded, $message); + } + $mgr->closeAllFolders; + make_maildir_readonly($expanded_path); + + # mark as done + unlink $lockfile; + + # nuke the tempdir now to avoid running out of ramdisk if we're + # expanding a lot of mboxes + remove_tree($dir); +} + +sub make_maildir_readonly { + chmod 0500, catfile($_[0], "cur"), catfile($_[0], "new"), + catfile($_[0], "tmp"); + chmod 0400, glob "$_[0]/cur/* $_[0]/new/* $_[0]/tmp/*"; } 1; |