Advertisement
kwasinski

Script to Migrate pop3 mails to IMAP server

Apr 4th, 2014
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6.60 KB | None | 0 0
  1. #!perl
  2. use Mail::IMAPClient;
  3. use File::Path;
  4. use Data::Dumper;
  5. use Tie::File;
  6.  
  7. my $run_once = (($ARGV[2] eq 'run_once')? 1: 0);
  8. my $revert_import = (($ARGV[2] eq 'revert_import')? 1: 0);
  9. my $check_migration = (($ARGV[2] eq 'check_import')? 1: 0);
  10.  
  11. my %path_mails_to_export = ();
  12. my %user = (
  13.     mail => $ARGV[0],
  14.     passwd => $ARGV[1],
  15. );
  16.  
  17. print "\n". '-'x25,"##POP_TO_IMAP_1.5##",'-'x25, "\n";
  18. die 'Mail User and password requires to migrate!'  if !($user{mail} && $user{passwd});
  19.  
  20. $user{mailServer} = (($user{mail}) =~ m/\@(.+)$/? 'mail.'.$1: undef);
  21. die 'Can not indentify mail server'  if not defined $user{mailServer};
  22.  
  23. print 'Initializing IMAP Server and do connect...';
  24.  
  25. my %connect_config = (
  26.     Server   => $user{mailServer},
  27.     User     => $user{mail},
  28.     Password => $user{passwd},
  29. );
  30.  
  31. my $imap = new Mail::IMAPClient->new(%connect_config);
  32. print 'Cant connect to IMAP server!'
  33.     and exit if $imap && not $imap->IsConnected;
  34. print ' Done!'."\n"x2;
  35.  
  36. if ($revert_import) {
  37.     revert_import();
  38.     exit;
  39. }
  40.  
  41. if ($check_migration) {
  42.     check_migration();
  43.     exit;
  44. }
  45.  
  46. my $target_directory = 'inc/database';
  47. $email_path = mail_to_folder($user{mail});
  48.  
  49. #prepare files to port
  50. $target_directory .= '/'. $email_path;
  51.  
  52. #exiting
  53. print 'Can not find the specified email folder->'.$target_directory.'     Aborted!!', "\n"x2 and exit if !-d $target_directory;
  54.  
  55. opendir (my $mails_fh, $target_directory) || die 'Can not open '.$target_directory. 'for some reason    Aborting!';
  56. my $exclude_folders = join '|', qw{attachments _infos};
  57.  
  58. # print $exclude_folders and exit;
  59. my @folders_to_export = grep { !/^\./ && !/$exclude_folders/ } readdir($mails_fh)
  60.     and print 'Exclude folders: ', $exclude_folders."\n"x2;
  61.  
  62. print 'Parsing old mails folders...';
  63. #FIXME::Só ta lendo o primeiro folder
  64.  
  65. foreach (@folders_to_export){
  66.     my @files = ();
  67.     opendir (my $fh_mails, my $directories_to_parse =  "$target_directory/$_") || die 'Can not open '."$target_directory/$_". 'for some reason    Aborting!';
  68.     if (-d $target_directory) {
  69.         @files =  map { $directories_to_parse."/$_" } grep { !/^\./ } readdir $fh_mails;
  70.  
  71.     }
  72.  
  73.     @{$path_mails_to_export{$_}} = @files;
  74. }
  75. print ' Done!'."\n"x2;
  76.  
  77. #Going loco by doing this dude!
  78. my $count = 0 ;
  79. my %folders_to_file_fail = ();
  80. my $copy_done;
  81.  
  82. #########################
  83. ####### Acontece aqui ###
  84. #########################
  85. migrate(%path_mails_to_export);
  86. #########################
  87. #########################
  88. print '-'x55,"\n";
  89.  
  90. if (defined $copy_done) {
  91.     my $folders_fails = keys %folders_to_file_fail;
  92.     print "Can not migrate Thoses Files below:";
  93.  
  94.     foreach (@{$folders_fails}) {
  95.         print "Folder: $_\n";
  96.         print $folders_to_file_fail{$_}, "\n";
  97.     }
  98.  
  99.     print "Trying to Migrate again!\n";
  100.     #migrate(%folders_to_file_fail);
  101. }
  102.  
  103. print $count .' Files  imported on account-> '. $user{mail}, "\n";
  104. print '#'x50, "\n";
  105.  
  106. # functions!
  107. sub mail_to_folder {
  108.     my ($email) = @_;
  109.     return if not $email;
  110.  
  111.     my $email_path = $email;
  112.     $email_path =~ s{\@}{\_};
  113.  
  114.     return $email_path.'_173.201.191.20'  if !$@;
  115. }
  116.  
  117. sub fetch_mail_info($) {
  118.     my ($file_name) = @_;
  119.     my $file;
  120.     my $mail_date = '';
  121.  
  122.     -f $file_name || return;
  123.     tie my @file, 'Tie::File', $file_name || die 'Cant read the '. $file_name.' for some reason     Aborting!';
  124.     $file = join "\n", @file or return undef, undef;
  125.  
  126.     foreach(@file) {
  127.         $mail_date = ( $_ =~ m{^Date\:\s*(.+)$}m )? $1: undef;
  128.         if (defined $mail_date) {
  129.             if ($mail_date =~ m{(\d\d?)\s*(\w\w\w)\s*(\d\d\d\d)\s*(\d\d\:\d\d\:\d\d)\s*([\-|\+]\d\d\d\d)}){
  130.                 $mail_date = "$1-$2-$3 $4 $5";
  131.                 $mail_date = '0'.$mail_date  if $mail_date =~ m{^\d\-};
  132.  
  133.                 return $file, $mail_date;
  134.             }
  135.         }
  136.     }
  137. }
  138.  
  139. sub migrate($) {
  140.     my (%path_mails_to_export) = @_;
  141.     my @folders_to_export = keys %path_mails_to_export;
  142.  
  143.     foreach my $folder (@folders_to_export) {
  144.         my $folder_fail = ();
  145.         $copy_done = undef;
  146.         my $imap_mail_path = 'INBOX.Importados.'.ucfirst($folder);
  147.  
  148.         my $folder_exists = $imap->create($imap_mail_path) if !$imap->exists($imap_mail_path);
  149.         print "Folder $folder created!\n" if $folder_exists;
  150.         print "Folder $folder already exists! Can not Create!\n" if !$folder_exists;
  151.  
  152.         die 'Can not create INBOX/Importados'  if !$imap->exists($imap_mail_path);
  153.  
  154.         my @files_to_append = grep { -f } @{$path_mails_to_export{$folder}};
  155.         foreach (@files_to_append){
  156.             reconnect();
  157.  
  158.             my ($mail_file, $mail_date) = fetch_mail_info($_);
  159.  
  160.             if ( not defined $mail_file or not defined $mail_date) {
  161.                 print "Can not Copy:\n\t$_  \n\tERROR::because the mail file or mail date (or both) is undefined ---  Move to Next Mail File\n\n";
  162.                 push @{$folder_fail}, $_  if not defined $copy_done;
  163.                 next;
  164.             }
  165.  
  166.             print "Copying file:\n\t$_\n\tInto folder:\n\t $imap_mail_path";
  167.             $copy_done = $imap->append_string($imap_mail_path, $mail_file, undef, $mail_date) and print '       Done!',"\n"x2;
  168.  
  169.             push @{$folder_fail}, $_  if not defined $copy_done;
  170.  
  171.             sleep(0.3);
  172.             exit  if $run_once;
  173.         }
  174.  
  175.         push @{$folders_to_file_fail{$folder}}, @{$folder_fail}  if not defined $copy_done;
  176.         print scalar @files_to_append, ' files Copied into: '. $folder, "\n\n";
  177.         $count += scalar @files_to_append;
  178.     }
  179. }
  180.  
  181. sub revert_import() {
  182.     print 'Undo import to user: ', $user{mail}, "\n";
  183.     reconnect();
  184.     my @folders = $imap->folders('INBOX.Importados'); # hardcoded!
  185.     print 'There is no subdirectories in INBOX.Importados'."\n" and  return  if scalar @folders == 0;
  186.  
  187.     foreach my $folder (@folders) {
  188.         reconnect();
  189.  
  190.         print 'Deleting emails from Folder', $folder, "\n" ;
  191.         $imap->select($folder);
  192.  
  193.         my $uids_messages = $imap->messages($folder);
  194.         foreach (@{$uids_messages}) {
  195.             my $deleted = $imap->delete_message($_);
  196.             print 'Message UID: ', $_, ' Deleted From Folder: ', $folder, "\n"  if defined $deleted;
  197.         }
  198.         print "\n"x2, 'Deleting Folder ', $folder, "\n"x2;
  199.  
  200.         my $deleted = $imap->delete($folder);
  201.         print "Folder: $_ deleted"  if !$deleted;
  202.         print "Folder: $_ Not Deleted"  if defined $deleted;
  203.         print "\n";
  204.     }
  205.  
  206.     print 'Importation reverted!';
  207. }
  208.  
  209. sub check_migration() {
  210.     my $already_migrate = $imap->folders('INBOX.Importados');
  211.  
  212.     print $user{mail}, ' MIGRATED!'         if scalar @{$already_migrate} > 0;
  213.     print $user{mail}, ' NOT MIGRATED!'     if scalar @{$already_migrate} <= 0;
  214. }
  215.  
  216.  
  217. sub reconnect {
  218.     CONNECT:
  219.         $imap = new Mail::IMAPClient->new(%connect_config)
  220.             if !$imap->IsConnected;
  221.     goto CONNECT  if !$imap->IsConnected;
  222.  
  223.     return 1;
  224. }
  225.  
  226. __DATA__
  227. ::USAGE::
  228. deprecated::pop_to_imap.pl EMAIL SENHA [run_once, revert_import, check_import]
  229. perl_hash_mails_account.pl -> percorre um hash passando chave->valor como argumento para este arquivo
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement