Created
January 4, 2020 19:03
-
-
Save alexfouche/9f48d19785a005d56de7e225da372cd1 to your computer and use it in GitHub Desktop.
Import all the messages from many mailboxes (also the ones in subfolders) into one maildir mailbox, into named folders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!perl | |
use common::sense; | |
#use feature qw(say); | |
use Mail::Box::MailDir; | |
use Mail::Box::Manager; | |
use Config::General qw(ParseConfig SaveConfig); | |
use Date::Manip qw(UnixDate Date_Cmp); | |
use Getopt::Std; | |
# | |
# Parse options | |
# | |
my %opts = (); | |
getopts('c:s:d:v', \%opts); | |
unless ($opts{s} && $opts{d} ) { | |
say "Usage:"; | |
say "[-c <config_file_path>] -s <source_mailbox_folderdir> -d <destination_imap_folder> [-v]"; | |
say 'If no config file, take "~/.transfer_mail_to_folders.conf" as default'; | |
exit 1; | |
} | |
my $config_file = glob ( ($opts{c}) ? $opts{c} : "~/.transfer_mail_to_folders.conf" ); | |
my $source_mailbox_folderdir = $opts{s}; | |
my $dest_imap_folder = $opts{d}; | |
my $verbose = 1 if ($opts{v}); | |
# | |
# Parse config file | |
# | |
my %conf=(); | |
my $timestamp_name = "timestamp_$dest_imap_folder"; | |
unless(-f $config_file && (%conf = ParseConfig($config_file) ) && defined $conf{destination_maildir} ) { | |
$conf{destination_maildir} = "~/.transfer_mail_maildir"; | |
$conf{$timestamp_name} = "Jan 1 00:00:00 1973"; | |
SaveConfig($config_file, \%conf); | |
print "No configuration was found in file $config_file\n"; | |
print "A sample configuration has been generated and stored in $config_file\n"; | |
print " If it is not what you wanted, delete $config_file and modify the \$config_file variable in this script.\n"; | |
exit 2; | |
} | |
if (!defined $conf{$timestamp_name} || Date_Cmp($conf{$timestamp_name}, "Jan 1 0:0:0 1971") <=0 ) { | |
$conf{$timestamp_name} = "Jan 1 0:0:0 1973"; | |
SaveConfig($config_file, \%conf); | |
} | |
# | |
# Process mailbox | |
# | |
my $stopped_at_timestamp=UnixDate($conf{$timestamp_name},"%s") ; | |
my $new_stop_timestamp=$stopped_at_timestamp; | |
my $s_mgr = Mail::Box::Manager->new; | |
sub process_mailbox_folders { | |
my ($inbox,$outbox, $sub_name,$is_sub) = @_; | |
# safeguard | |
#return if ($sub_name eq 'INBOX'); | |
my ($insub,$outsub); | |
if ($is_sub == 0) { | |
$insub = $s_mgr->open(folder => glob($source_mailbox_folderdir), access => 'r', save_on_exit => 0); | |
$outsub = Mail::Box::Maildir->new(folderdir => glob( $conf{destination_maildir}), folder => "=$dest_imap_folder", access => 'rw', create=>1, save_on_exit => 1); | |
}else{ | |
$insub = $inbox->openSubFolder($sub_name, access => 'r', save_on_exit => 0); | |
$outsub = $outbox->openSubFolder($sub_name); | |
} | |
foreach my $msg ($insub->messages) { | |
my $msg_timestamp = $msg->timestamp; | |
next if ($msg_timestamp <= $stopped_at_timestamp); | |
print "$msg_timestamp ". $sub_name .': ' . $msg->subject .'...' if ($verbose); | |
$msg->label(seen=>0); | |
$msg->labelsToStatus; | |
$msg->copyTo($outsub); | |
$new_stop_timestamp = $msg_timestamp if ($msg_timestamp>$new_stop_timestamp); | |
print "OK\n" if ($verbose); | |
} | |
process_mailbox_folders($insub, $outsub, $_, 1) foreach ($insub->listSubFolders(skip_empty=>1)); | |
$outsub->close; | |
$insub->close(write => 'NEVER'); | |
} | |
process_mailbox_folders('','','' ,0) ; # 0 means we need to open initial root folder (typically 'INBOX') | |
# | |
# Save timestamp and quit | |
# | |
print "Stopped at timestamp ". scalar( localtime $new_stop_timestamp) if ($verbose); | |
$conf{$timestamp_name} = localtime $new_stop_timestamp; | |
SaveConfig($config_file, \%conf); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment