| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #!perl
- #
- # ADR 2 CSV
- # Opera Mail 'adr' to Thunderbird 'csv' contacts file converter.
- # Version 1
- # by Dwayne J Pivac @ OMI Ltd.
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- # See the GNU General Public License for more details.
- #
- #
- use strict;
- use warnings;
- use File::Spec;
- my $in = ($ARGV[0]);
- if ( ((!$in)) || ((!-e $in)) ) {
- die "Usage: perl adr2csv.pl /path/to/file.adr\nError: Input file not found.\n";
- }
- # Initial output path
- (my $out_path = $in) =~ s/\.[^.]+$/\.csv/;
- # Versioning logic
- if ( (-e $out_path) ) {
- my $found = (0);
- my ($base, $ext) = ($out_path =~ /^(.*)\.(csv)$/);
-
- for (my $i = (1); ($i <= 99); $i++) {
- my $suffix = sprintf("_%02d", $i);
- my $test_path = ($base . $suffix . "." . $ext);
- if ( (!-e $test_path) ) {
- $out_path = ($test_path);
- $found = (1);
- last;
- }
- }
-
- if ( (!$found) ) {
- die "Error: Reached limit of 99 versioned files.\nPlease clean up the directory.\n";
- }
- }
- my %headers_map = (
- # Thnderbird header => Opera Mail header
- "01_Display Name" => "NAME",
- "02_Primary Email" => "MAIL",
- "03_Home Phone" => "PHONE",
- "04_Fax Number" => "FAX",
- "05_Web Page 1" => "URL",
- "06_Notes" => "DESCRIPTION",
- "07_Nickname" => "SHORT NAME",
- "08_Home Address" => "POSTALADDRESS",
- "09_Custom 1" => "PICTUREURL",
- "10_Secondary Email" => "MAIL"
- );
- # Slurp data and close input file immediately
- open(my $fh_in, '<', $in) or die "Could not open $in: $!";
- my @contact_data = (<$fh_in>);
- close($fh_in);
- open(my $fh_out, '>', $out_path) or die "Could not open $out_path: $!";
-
- my @sorted_headers = (sort(keys(%headers_map)));
- my @clean_headers = (map { (my $h = $_) =~ s/^\d+_(.*)/$1/; $h } @sorted_headers);
-
- print $fh_out join(",", map { qq("$_") } @clean_headers) . "\n";
-
- my %contact;
- my $is_contact = (0);
-
- for my $line (@contact_data) {
- chomp($line);
- $line =~ s/^\s+//;
-
- if ( ($line =~ /^#(\w+)/) ) {
- my $section = ($1);
- if ( (($is_contact)) && ((%contact)) ) {
- &write_row($fh_out, \%contact, \%headers_map, \@sorted_headers);
- }
- %contact = ();
- $is_contact = ( ($section eq 'CONTACT') ? (1) : (0) );
- next;
- }
-
- if ( (($is_contact)) && (($line =~ /^([^=]+)=(.*)/)) ) {
- $contact{$1} = ($2);
- }
- }
-
- # Final record check
- if ( (($is_contact)) && ((%contact)) ) {
- &write_row($fh_out, \%contact, \%headers_map, \@sorted_headers);
- }
- close($fh_out);
- print "Converted $in to $out_path\n";
- sub write_row {
- my ($fh, $dat, $m, $h) = (@_);
- my @row;
- for my $header (@$h) {
- my $adr_key = ($m->{$header});
- my $val = ($dat->{$adr_key} // '');
-
- $val =~ s/\x02+/\n/g;
- if ( ($adr_key eq 'MAIL') ) {
- my @emails = (split(/\n+/, $val));
- if ( ($header =~ /Primary/) ) {
- $val = ($emails[0] // '');
- }
- elsif ( ($header =~ /Secondary/) ) {
- $val = ($emails[1] // '');
- }
- }
- $val =~ s/\r\n/\n/g;
- $val =~ s/\r/\n/g;
- $val =~ s/"/""/g;
- push(@row, qq("$val"));
- }
-
- print $fh join(",", @row) . "\n";
- }
|