2008/5/30

Outlookの連絡先をldifファイルに変換する(Internet, Linux)

ThunderbirdはOutlookで作成した連絡先を直接インポートする機能がありますが、以下の不便な点があります。

  • Outlookを標準メーラーに指定してからThunderbirdでインポートする必要がある
  • Thunderbirdからldifファイルを出力するとMozilla独自のobjectclassである「mozillaAbPersonAlpha」を使用する(標準ではないのでいろいろ不便そう)

Outlookは2003,2007共に連絡先内の画像以外すべての情報をcsv形式にはエクスポートできるので、このcsvファイルをldif形式に変換するperlスクリプトを作成しました。

基本的には要カスタマイズです。このままでも使用できますが、出力したい属性と元データの対応は皆さん異なると思います。

いくつか普通は入っていないperlモジュールを利用していますので、適宜追加してください。

  • IO::File
  • Text::CSV
  • Text::Iconv
  • MIME::Base64

基本的なカスタマイズ項目は以下の通りです。

  • $basedn
    出力されたldifファイルをLDAPサーバに登録する際にdnに追加する値を指定します。
    特に適当な値のままでもldifファイルをメーラー等にインポートする場合は問題ありません。
  • $topdata
    出力するldifファイルの先頭に特に指定しておきたいメッセージを指定します。
    コメント情報でも良いですし、例のように連絡帳を登録するouの定義を書いてもかまいません。
  • $objectclass
    使用するobjectclassを指定します。この指定はdn:の次に自動的に挿入されます。
    サンプルで指定しているobjectclassは個人の住所録を指定するのに基本的な属性を網羅していると思います。
  • @attribute
    Outlookから出力したcsvファイルの各項目と属性との対応を記述します。
    サンプルでは「姓」「名」「メールアドレス」「電話番号」「携帯電話番号」「会社」「部署」「役職」を定義しています。
    csvファイルの項目は番号で指定します。一覧はサンプルの最後の方を参照してください。
  • $headskip
    csvファイルの先頭1行を読み飛ばします。通常は変更しません。
  • $topskip
    $topdataで指定したメッセージの出力制御を行います。
  • $conv
    csvファイルをSJIS->UTF-8に変換します。通常は変更しません。
  • $usemail
    Outlook Express等はUTF-8の日本語文字が含まれている属性を正しく変換できないようです。
    もしメールアドレスの形式が「名.姓@domainname.com」の場合(多くは社員用の連絡先一覧を作成する場合)、このアドレス部分の姓、名を使ってcn,sn,givenNameを設定します。

さあ、お待ちかねのサンプルスクリプトは以下です。

何か不明点があればコメントからお願いします。

ダウンロードはこちらから(o2ldif.gz)

#!/usr/bin/perl
#
# Outlook-CSV -> ldif Converter
#
# usage:o2ldif csvfile
#
# Copyright (C) 2008 by Y.Katakura
#
use IO::File;
use Text::CSV_XS;
use Text::Iconv;
use MIME::Base64;

unless ($ARGV[0]) {
    print "usage: o2ldif csvfile\n";
    exit 1;
}

# 追加を行いたいdnを指定
$basedn = 'ou=renraku,dc=example,dc=com';

# 本ldifファイルの先頭に明示的に出力したい内容を指定
$topdata = <<EOF;
dn: $basedn
objectClass: organizationalUnit
objectClass: top
ou: address

EOF

# 各要素追加に必要なobjectclassを指定
$objectclass = <<EOF;
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
EOF

# 設定したい属性を指定
# 数値は本ファイル末尾の対応表参照
@attribute = (
    ['dn', 96],
    ['givenName', 1],
    ['sn', 3],
    ['mail', 80],
    ['telephoneNumber', 37],
    ['mobile', 40],
    ['ou', 6],
    ['o', 5],
    ['title', 7],
    ['cn', 95]
    );

$headskip = 1; # ファイルの先頭行(タイトル行)をスキップ
$topskip = 0; # ファイル先頭に出力する $topdata 表示をスキップ
$usemail = 0; # メールアドレスからcnを作成(first.last@example.com形式)
$conv = 1; # 文字コードをSJIS->UTF-8に変換するフラグ

$converter = Text::Iconv->new("CP932", "UTF-8");
$csv = Text::CSV_XS->new({binary=>1});
$fh = IO::File->new($ARGV[0], 'r') || die "Can't open csv file";

unless ($topskip) {
    print $topdata;
}

while (not $fh->eof) {
    $row = $csv->getline($fh);

    if ($headskip) {
	$headskip = 0;
	next;
    }

    @fields = @$row;
    @data = ();
    for $val (@$row) {
	if ($conv) {
	    push(@data, $converter->convert($val));
	} else {
	    push(@data, $val);
	}
    }
    push(@data, "@data[3] @data[1]"); # [95]姓+名

    if ($usemail) {
	unless (@data[80]) { # emailがない場合はスキップ
	    next;
	}
	($firstname, $lastname) = split(/[\.@]/, @data[80]);
	$firstname = uc(substr($firstname,0,1)).lc(substr($firstname,1));
	$lastname = uc(substr($lastname,0,1)).lc(substr($lastname,1));
	@data[95] = "$firstname $lastname";
	@data[1] = $firstname;
	@data[3] = $lastname;
    }

    push(@data, "cn=@data[95],$basedn"); # [96]dn
        
    for $i (0..$#attribute) {
	$outval = @data[$attribute[$i][1]];
	$outkey = $attribute[$i][0].":";
	if ($outval =~ /[\x80-\xff]/) {
	    $outval = encode_base64($outval);
	    $outval =~ s/\n//g;
	    $outkey .= ":";
	}

	if ($outval) {
	    print "$outkey $outval\n";
	    if ($outkey =~ /^dn:/) { # dn:が来たら次にobjectclassを出力
		print $objectclass;
	    }
	}
    }
    print "\n";
}
exit 0;

##################
# @data 配列要素 #
##################
# 0=肩書き
# 1=名
# 2=ミドル ネーム
# 3=姓
# 4=敬称
# 5=会社名
# 6=部署
# 7=役職
# 8=番地 (会社)
# 9=住所 2 (会社)
# 10=住所 3 (会社)
# 11=市町村 (会社)
# 12=都道府県 (会社)
# 13=郵便番号 (会社)
# 14=国 (会社)/地域
# 15=番地 (自宅)
# 16=住所 2 (自宅)
# 17=住所 3 (自宅)
# 18=市町村 (自宅)
# 19=都道府県 (自宅)
# 20=郵便番号 (自宅)
# 21=国 (自宅)/地域
# 22=番地 (その他)
# 23=住所 2 (その他)
# 24=住所 3 (その他)
# 25=市町村 (その他)
# 26=都道府県 (その他)
# 27=郵便番号 (その他)
# 28=国 (その他)/地域
# 29=秘書の電話
# 30=会社 FAX
# 31=会社電話
# 32=会社電話 2
# 33=コールバック
# 34=自動車電話
# 35=会社代表電話
# 36=自宅 FAX
# 37=自宅電話
# 38=自宅電話 2
# 39=ISDN
# 40=携帯電話
# 41=その他の FAX
# 42=その他の電話
# 43=ポケットベル
# 44=通常の電話
# 45=無線電話
# 46=TTY/TDD
# 47=テレックス
# 48=ID 番号
# 49=Web ページ
# 50=アカウント
# 51=イニシャル
# 52=インターネット空き時間情報
# 53=キーワード
# 54=その他住所私書箱
# 55=ディレクトリ サーバー
# 56=プライベート
# 57=マネージャ
# 58=メモ
# 59=ユーザー 1
# 60=ユーザー 2
# 61=ユーザー 3
# 62=ユーザー 4
# 63=会社 ID
# 64=会社住所私書箱
# 65=会社名フリガナ
# 66=記念日
# 67=経費情報
# 68=言語
# 69=参照事項
# 70=子供
# 71=支払い条件
# 72=事業所
# 73=自宅住所私書箱
# 74=趣味
# 75=場所
# 76=職業
# 77=姓フリガナ
# 78=性別
# 79=誕生日
# 80=電子メール アドレス
# 81=電子メールの種類
# 82=電子メール表示名
# 83=電子メール 2 アドレス
# 84=電子メール 2 の種類
# 85=電子メール 2 表示名
# 86=電子メール 3 アドレス
# 87=電子メール 3 の種類
# 88=電子メール 3 表示名
# 89=配偶者
# 90=秘書の氏名
# 91=秘密度
# 92=分類
# 93=名前フリガナ
# 94=優先度
# 95=姓+名(本スクリプトにて自動生成)
# 96=dn(本スクリプトにて自動生成)
投稿者 yotan : 2008年5月30日 21:00| トラックバック(0)
アンケート
このエントリは・・・
とても役に立った
役に立った
どちらとも言えない
あまり役に立たなかった
全く役に立たなかった
コメント
コメントする

※コメント内にURLを書くとSPAM扱いとなります。2ch風に表記はOKです










名前、アドレスを登録しますか?