先ほどのエントリでカレンダーは取り込めたので、次はアドレス帳の取り込みに挑戦です。
iPod TouchはvCard形式のデータ(.vcf)を取り込むことができることが分かったので、DatebookDB.pdbの時と同じようにAddressDB.pdbを.vcfに変換するスクリプトを探して見たところ「Tip: Perl script to turn AddressDB.pdb into a vcar... - Palm Support Community」で紹介されているAddressDB2VCard.plが使えそうだったので、これを使うことにしました。
が、一筋縄ではいかなかったのでその顛末をメモ。
† 5.10以降対応のスクリプトだった!
まず、実行に必要となるライブラリをCPANでインストールします。
# perl -MCPAN -e 'shell'
cpan> install Palm::Address
しかしながら、前述のスクリプトはperl 5.10以降でないと使うことができない、sayやgivenが使われているのでCentOS標準の5.8.8で実行すると下記のようなエラーが出てしまいます。
$ perl AddressDB2VCard.pl.org
Can't locate feature.pm in @INC (@INC contains: /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8 .) at AddressDB2VCard.pl.org line 16.
BEGIN failed--compilation aborted at AddressDB2VCard.pl.org line 16.
短いスクリプトですし、他に適当な方法もないので、これをperl 5.8でも実行出来るように下記のように書き換えてしまいます。また、このスクリプトは日本語に対してのフォローが全くないので、その部分の処理も付け加えています。具体的には、name、firstName、companyの各フィールドには、日本語版の場合には\001を区切り文字として、その後にふりがなが入っています。vCard Ver.3.0では氏名の読みはSORT-STRINGという属性にマッピングできるようなので、SORT-STRINGとして出力するようにしました。
$ diff -u AddressDB2VCard.pl.org AddressDB2VCard.pl
--- AddressDB2VCard.pl.org 2010-09-28 20:18:33.000000000 +0900
+++ AddressDB2VCard.pl 2010-09-28 21:31:21.000000000 +0900
@@ -13,7 +13,8 @@
use strict;
use warnings;
-use feature qw/ say switch state /;
+use Switch;
use Palm::Address;
@@ -42,22 +43,22 @@
$value =~ s/^\s+//xms;
$value =~ s/\s+$//xms;
- given ($field) {
- when ('name') { $rec{N} = $value }
- when ('firstName') { $rec{FN} = $value }
-
- when ('company') { $rec{ORG} = $value }
- when ('title') { $rec{TITLE} = $value }
-
- when ('address') { $rec{ADR}{address} = $value }
- when ('city') { $rec{ADR}{city} = $value }
- when ('state') { $rec{ADR}{state} = $value }
- when ('zipCode') { $rec{ADR}{zipCode} = $value }
- when ('country') { $rec{ADR}{country} = $value }
+ switch ($field) {
+ case ('name') { my @name = split(/\001/, $value) ; $rec{N} = $name[0] ; $rec{S} = $name[1] ; }
+ case ('firstName') { my @name = split(/\001/, $value) ; $rec{FN} = $name[0] ; $rec{FS} = $name[1] ; }
+
+ case ('company') { my @name = split(/\001/, $value) ; $rec{ORG} = $name[0] ; $rec{ORGS} = $name[1] ; }
+ case ('title') { $rec{TITLE} = $value }
+
+ case ('address') { $rec{ADR}{address} = $value }
+ case ('city') { $rec{ADR}{city} = $value }
+ case ('state') { $rec{ADR}{state} = $value }
+ case ('zipCode') { $rec{ADR}{zipCode} = $value }
+ case ('country') { $rec{ADR}{country} = $value }
- when ('note') { $rec{NOTE} = $value }
+ case ('note') { $rec{NOTE} = $value }
- when ( /^phone/xms || /^custom/xms ) {
+ case /^(phone|custom)/xms {
my $key = $value =~ /\@/xms ? 'EMAIL' : 'TEL';
my $l;
@@ -83,9 +84,9 @@
$l = 'CELL' if $value =~ s/\s*cell$//xms;
- #given ($l) {
- # when ( 'WORK' || 'HOME' || 'CELL' ) { }
- # when ('FAX') { $l = 'CELL' }
+ #switch ($l) {
+ # case ( 'WORK' || 'HOME' || 'CELL' ) { }
+ # case ('FAX') { $l = 'CELL' }
#}
}
@@ -96,24 +97,24 @@
};
}
- default { die "Unknown field [$field]" };
+ else { print "Unknown field [$field]: $value\n" };
}
}
if (%rec) {
no warnings 'uninitialized';
- say $fh 'BEGIN:VCARD';
- say $fh 'VERSION:3.0';
+ print $fh 'BEGIN:VCARD'."\n";
+ print $fh 'VERSION:3.0'."\n";
- say $fh "CATEGORIES:$rec{CATEGORIES}" if $rec{CATEGORIES};
- say $fh 'N:', join( ';', $rec{N}, $rec{FN} )
- if ( $rec{N} || $rec{FN} );
- say $fh "ORG:$rec{ORG}" if $rec{ORG};
- say $fh "TITLE:$rec{TITLE}" if $rec{TITLE};
+ print $fh "CATEGORIES:$rec{CATEGORIES}\n" if $rec{CATEGORIES};
+ print $fh 'N:', join( ';', $rec{N}, $rec{FN}, "\n" ) if ( $rec{N} || $rec{FN} );
+ print $fh 'SORT-STRING:', join( ' ', $rec{S}, $rec{FS}, "\n" ) if ( $rec{S} || $rec{FS} );
+ print $fh "ORG:$rec{ORG}\n" if $rec{ORG};
+ print $fh "TITLE:$rec{TITLE}\n" if $rec{TITLE};
foreach my $t ( 'TEL', 'EMAIL' ) {
foreach my $p ( @{ $rec{$t} } ) {
- say $fh "$t;TYPE=$p->{type}:$p->{data}";
+ print $fh "$t;TYPE=$p->{type}:$p->{data}\n";
}
}
@@ -127,11 +128,11 @@
$a->{country};
}
- say $fh "NOTE:$rec{NOTE}" if $rec{NOTE};
- say $fh 'END:VCARD';
+ print $fh "NOTE:$rec{NOTE}\n" if $rec{NOTE};
+ print $fh 'END:VCARD'."\n";
print $fh "\n";
}
}
close $fh;
-say ' done.';
+print ' done.'."\n";
これを下記のように実行するとvcard.vcfが得られます。これは文字コードの変換を行っていないので、CP932のデータです。vCard Ver.3.0 では文字コードがUTF-16に決められているようなので、nkfでUTF-1(LE,BOMあり)6に変換して import.vcf を作成します。これでも誕生日などうまく変換されないものもあるので、この部分は手作業でファイルを修正しました。
$ perl AddressDB2VCard.pl
$ nkf -w16L vcard.vcf > import.vcf
あとはこれをiPod Touchで受信できるメールアドレスに送りつけて、添付ファイルを開けばインポートできます。
最初は、vcfファイルをOutlookを通してインポートしようとしたのですが、なぜかこのファイルはOutlookでは読み込むことができませんでした。