BLOGTIMES
2010/09/28

AddressDB.pdb を .vcf ファイルに変換する

  ios  palm  perl 
このエントリーをはてなブックマークに追加

先ほどのエントリでカレンダーは取り込めたので、次はアドレス帳の取り込みに挑戦です。

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として出力するように*1しました。

$ 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 を作成します。これでも誕生日などうまく変換されないものもあるので、この部分は手作業でファイルを修正*2しました。

$ perl AddressDB2VCard.pl $ nkf -w16L vcard.vcf > import.vcf

あとはこれをiPod Touchで受信できるメールアドレスに送りつけて、添付ファイルを開けばインポートできます。
最初は、vcfファイルをOutlookを通してインポートしようとしたのですが、なぜかこのファイルはOutlookでは読み込むことができませんでした。

  • *1: companyの読みは入れる部分がないので捨ててしまいます
  • *2: vcfファイルの中身はテキストですので、編集は比較的容易です。

トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/3825
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form

コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。

OpenID を使ってログインすることができます。

Identity URL: Yahoo! JAPAN IDでログイン