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(本スクリプトにて自動生成)

2008/5/24

グリップエンドを交換(マジェスティ)

マジェスティ(SG20J/4D9)の標準ハンドルについているグリップエンド(バーエンド)は特殊です。

今までのYAMAHAのバイク殆どがパイプに直接ねじが切ってあったのですが、新マジェスティはパイプ内に6mmのねじ穴が埋め込まれています。

ワイズギアの「ビレット バーエンドキャップ メッキ」はなんとか付きそうだったので買ってみたのですが「遊び」部分が広く格好が悪くて却下。結局はHONDA車用のグリップエンドがぴったりと付きました。

 P1000016
【純正品。ウエイトはあるので実用的ですが格好悪い】

 P1000018
【明らかにワイズギアのは長いですが…】

 P1000017
【やっぱりアンバランスです。イケてません】

 P1000019
【HONDA車用のグリップエンド(ネジ径6mm)を購入】

 P1000021
【ぴったりの長さでした!イケています】

というわけで、なぜか4D9にはYAMAHA用のグリップエンドは付きませんでしたが、HONDA用がぴったりでした。

そういえばJOGのグリップエンドもHONDAのが流用できるってどこかで見たことがあります。

元々ノーマルハンドルの角度や高さは気に入っており、ハンドル交換まではするつもりがなかったので、今までいまいちだった純正のグリップエンドが交換できて良かったです。

さて、、、ワイズギアの使わなかったグリップエンドはどうしようかな。。。

2008/5/18

スマートキーケースを105円で作る(マジェスティ)

マジェスティ(SG20J/4D9)をキャンペーン中に買うと「SOMES」製オリジナルキーケースが貰えたのですが、私は残念ながらキャンペーン後に買ったので貰えませんでした(別の特典は受けましたけどね)。

mixiで参加しているマジェスティのコミュニティーで、ダイソーで買ったネームタグが大きさぴったりだという情報を仕入れたので買ってきて自分なりに加工してみました。

ネームタグには開くと名前が見える様に小窓がついており、ネームタグとして使う分には便利なのですが、中にスマートキーを入れると小窓が半開きになってしまい、また透明なビニールもただ中に挟んであるだけなので、この穴からスマートキーが飛び出してしまいます。

DSCF2195
【ネームタグとしては良くできている】

このネームタグは2つ入りで105円です。なので、二つとも二枚に下ろして裏側同士を再度縫い直してみました。

DSCF2194 
【ミシン縫いなので簡単にはがれます】

DSCF2196
【微妙な仕上がり】

私は普段リモコンによるアンサーバックもシートオープンもしないので、ボタンは使えなくても問題ありませんが、手探りで押すことは可能だと思います。

既に他の鍵とぶつかり合って傷だらけなのですが、しばらくこのケースを使ってみたいと思います。

 DSCF2200
【ちょっとかさばるか?】

【2008/06/01追記】

さらに本日ダイソーに入ったら、ipod等を保護するニット調の小袋があったので買ってみました。

DSCF2213
【こっちの方がいいかも】