calypso_convert.pl 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #!/usr/bin/perl
  2. # calypso_import.pl
  3. # Author: Thorsten Maerz <info@netztorte.de>
  4. # License: GPL
  5. # Dependencies: MIME::Parser, LWP::MediaTypes from www.cpan.org
  6. # Converts mbox files as exported from Calypso to MH format. Regenerates
  7. # Calypso's folder structure and optionally includes the attachments.
  8. use strict ;
  9. our $mboxdir = '' || showhelp(); # enter path to exported mbox
  10. our $mboxfile = '' || showhelp(); # enter name of exported mbox
  11. our $outdir = '' || showhelp(); # enter destination path
  12. my $incl_attach = 1 ; # include attachments (needs CPAN modules)
  13. my $verbose = 1 ; # show some headers of processed mail
  14. my $testonly = 0 ; # dont create any files
  15. ################################################################################
  16. # no user servicable parts below :)
  17. if ($incl_attach) {
  18. use MIME::Parser;
  19. use LWP::MediaTypes qw(guess_media_type);
  20. }
  21. my $mbox = "$mboxdir/$mboxfile";
  22. my $calypso_hdr = 'From \?\?\?@\?\?\? '; #Mon Apr 17 00:37:38 2000
  23. my $hdr_Folder = 'X-CalypsoFolder:';
  24. my $hdr_HTML = 'X-CalypsoHtmlBody:';
  25. my $hdr_Account = 'X-CalypsoAccount:';
  26. my $hdr_Attach = 'X-Attachment:';
  27. my %mail_nr;
  28. my $create_dirs = 1 ; # create dirs from "X-Calypso-Folder:" header
  29. ################################################################################
  30. sub showhelp {
  31. die ( "You have not yet configured this script.\n"
  32. . "Please provide the correct path and file names, e.g\n"
  33. . "\tour \$mboxdir = 'Archive'\n"
  34. . "\tour \$mboxfile = 'mail.txt'\n"
  35. . "\tour \$outdir = 'Calypso'\n"
  36. . "at the top of $0\n"
  37. );
  38. }
  39. ################################################################################
  40. #
  41. # MAIN : scan $mbox linewise
  42. # Create a separate message for each $calypso_hdr found (MH format)
  43. # $attach_full = filename with path, $attach_short = original attachment name
  44. # $folder = Calypso folder
  45. #
  46. ################################################################################
  47. my ($folder, $html, $html_full, $html_short,
  48. $account, $attach, $attach_short, $attach_full);
  49. my @lines ;
  50. open (INBOX, "<".$mbox);
  51. while (<INBOX>) {
  52. s/\x0d\x0a//;
  53. s/\x0d//;
  54. s/\x0a//;
  55. if (m/^$calypso_hdr/) {
  56. if (@lines) {
  57. $mail_nr{$folder}++ ;
  58. shift @lines ; # remove blank line
  59. savemail();
  60. @lines = () ;
  61. $folder = $html = $html_full = $html_short = $account
  62. = $attach = $attach_short = $attach_full = "";
  63. }
  64. }
  65. else {
  66. if (/^$hdr_Folder /) { $folder = $' ;
  67. $folder =~ s/"//eg ;
  68. $folder =~ tr#\\#\/# ;
  69. }
  70. if (/^$hdr_HTML /) { $html = $' ;
  71. $html =~ s/"//eg ;
  72. $html =~ tr#\\#\/# ;
  73. if ($html =~ /; /) {
  74. $html_full = $` ;
  75. $html_short = $' ;
  76. }
  77. }
  78. if (/^$hdr_Account /) { $account = $' ;
  79. $account =~ s/"//eg ;
  80. }
  81. if (/^$hdr_Attach /) { $attach = $' ;
  82. $attach =~ s/"//eg ;
  83. $attach =~ tr#\\#\/# ;
  84. if ($attach =~ /; /) {
  85. $attach_full = $` ;
  86. $attach_short = $' ;
  87. }
  88. }
  89. push (@lines, $_ );
  90. }
  91. }
  92. close (INBOX);
  93. ################################################################################
  94. #
  95. # sub:savemail
  96. # Saves mail in @lines to $outdir/$folder/$mail_nr
  97. # Folder is created unless $testonly or (not $create_dirs) is set
  98. #
  99. ################################################################################
  100. sub savemail {
  101. my $mailname = $mail_nr{$folder};
  102. my %headers;
  103. my $ishead=1;
  104. my $lineno=0;
  105. my $targetdir="";
  106. # extract headers
  107. foreach (@lines) {
  108. my ($hdr,$cnt);
  109. $lineno++;
  110. m/^$/ and ($ishead="");
  111. if ( $ishead ) {
  112. if (m/: /) {
  113. ($hdr,$cnt) = ($`,$');
  114. $headers{$hdr}=$cnt;
  115. }
  116. }
  117. }
  118. if ($verbose) {
  119. print "MAIL : $mailname\n";
  120. print "FOLDER : $folder\n" if ($folder);
  121. print "HTML : $html_short ($html_full)\n" if ($html);
  122. print "ACCOUNT : $account\n" if ($account);
  123. print "ATTACH : $attach_short ($attach_full)\n" if ($attach);
  124. print "\n";
  125. }
  126. # write mail to folder
  127. if (! $testonly ) {
  128. if ($create_dirs) {
  129. $targetdir = $outdir.'/'.$folder ;
  130. my $curdir = '';
  131. foreach (split('/',$targetdir)) {
  132. $curdir .= $_ . '/';
  133. ( -d $curdir) || mkdir $curdir;
  134. }
  135. }
  136. open (OUTFILE, ">".$targetdir.'/'.$mailname);
  137. foreach (@lines) { print OUTFILE "$_\n" ; }
  138. close (OUTFILE);
  139. if ($incl_attach) {
  140. include_attachment($targetdir.'/'.$mailname);
  141. }
  142. }
  143. }
  144. ################################################################################
  145. # make inline attachment from external file
  146. # uses MIME::Parser, LWP::MediaTypes from www.cpan.org
  147. # (Currently leaves a blank attachment in converted mails. Feel free to
  148. # improve this script)
  149. sub include_attachment() {
  150. my $mailname = shift ;
  151. my $parser = new MIME::Parser ;
  152. my $entity ;
  153. my %attachments ;
  154. my %CID ;
  155. $parser->output_to_core(1); # dont save to harddisk
  156. $entity = $parser->parse_open($mailname);
  157. # look for external attachments
  158. foreach ($entity->head->get('X-Attachment')) {
  159. if (m/["']? # 1. start with " or ' (or none)
  160. ([^"';]+) # word till quote or separator
  161. ["']? # delete quote
  162. \s?;\s? # separator ; (opt. spaces)
  163. ["']? # 2. start (s.a.)
  164. ([^"';]+) #
  165. ["']?
  166. /x ) { $attachments{$1} = $2 ;
  167. }
  168. }
  169. foreach ($entity->head->get('X-CalypsoHtmlBody')) {
  170. if (m/["']? # 1. start with " or ' (or none)
  171. ([^"';]+) # word till quote or separator
  172. ["']? # delete quote
  173. \s?;\s? # separator ; (opt. spaces)
  174. ["']? # 2. start (s.o.)
  175. ([^"';]+) #
  176. ["']?
  177. /x ) { $attachments{$1} = $2 ;
  178. }
  179. }
  180. foreach ($entity->head->get('X-CalypsoHtmlImg')) {
  181. if (m/["']? # 1. start with " or ' (or none)
  182. ([^"';]+) # word till quote or separator
  183. ["']? # delete quote
  184. \s?;\s? # separator ; (opt. spaces)
  185. ["']? # 2. start (s.a.)
  186. ([^"';]+) #
  187. ["']?
  188. \s?;\s? # separator ; (opt. spaces)
  189. ["']? # 3. start (s.a.)
  190. ([^"';]+) #
  191. ["']?
  192. /x ) { $attachments{$1} = $3 ;
  193. $CID{$1} = $2 ;
  194. }
  195. }
  196. if (%attachments) {
  197. # read attachment
  198. foreach my $key (keys (%attachments)) {
  199. our $attachdir;
  200. my $type ;
  201. my $enc ;
  202. my $fnam = $key;
  203. $fnam =~ tr#\\#/# if -d '/' ; # correct path names on unix like OS
  204. $fnam = $mboxdir .'/'. $fnam ;
  205. $type = guess_media_type($fnam);
  206. if ( $type =~ m/text/i ) { $enc = "8bit" }
  207. else { $enc = "base64" }
  208. $entity->attach(Path => $fnam,
  209. Type => $type,
  210. Encoding => $enc,
  211. Filename => $attachments{$key}
  212. );
  213. }
  214. my $lines = $entity->as_string ;
  215. # correct images names in html messages
  216. foreach (keys (%CID)) {
  217. $lines =~ s/CID:$CID{$_}/$attachments{$_}/eg;
  218. }
  219. print $mailname."\n";
  220. # qx(mv $mailname $mailname.bak);
  221. open ( MAIL, ">".$mailname );
  222. print( MAIL $lines );
  223. close( MAIL );
  224. }
  225. }