Showing posts with label Tool. Show all posts
Showing posts with label Tool. Show all posts

Mar 24, 2009

Cybozu2iCalのインストール方法

サイボウズオフィスのカレンダーをiCalendar形式に変換するスクリプトcybozu2icalのインストール方法が分からない、という方が多いみたいなので調べてみました。

その前に!cybozu2icalを0.34にアップデートしました。変更点などは以下を参照。

Cybozu2ICal - ogawa - サイボウズオフィス6のカレンダーをiCalendar形式に変換するスクリプト。 - Google Code

それではCentOS 5.2とUbuntu 8.10 (Intrepid)の場合のセットアップについて説明します。

CentOS 5.2

root権限で、LWPとCrypt-SSLeayをyumインストールした後、cpanコマンドを使って必要なモジュールをインストールします。依存するモジュールをインストールするか聞かれたらとにかく全部インストールしてください。

$ su
# yum install perl-libwww-perl perl-Crypt-SSLeay
# cpan DateTime YAML Data::ICal Class::Accessor Text::CSV
# exit

あとは適当なディレクトリでcybozu2ical-0.34.zipを展開して、config.yamlを作って、実行するだけです。

$ unzip cybozu2ical-0.34.zip
$ cd cybozu2ical-0.34
(config.yamlを作る)
$ ./cybozu2ical

Ubuntu 8.10 (Intrepid)

apt-getで必要なモジュールをインストールします。

$ sudo apt-get install libwww-perl libcrypt-ssleay-perl libdatetime-perl \
   libyaml-perl libdata-ical-perl libclass-accessor-perl libtext-csv-perl

あとは適当なディレクトリでcybozu2ical-0.34.zipを展開して、config.yamlを作って、実行するだけです。

$ unzip cybozu2ical-0.34.zip
$ cd cybozu2ical-0.34
(config.yamlを作る)
$ ./cybozu2ical

なぜcpanで全部インストールしないのかというと、私はPerlのコードをそこそこ書いていますが、パッケージ管理システムとしてのCPANが生理的に受け付けないからです。使わずに済ませたい、使うにしても最小限にしたいからです。

Jan 28, 2009

ical2caldav公開

iCalendar形式のカレンダーデータをCalDAVを使ってカレンダーサーバに突っ込むスクリプトを書きました。

ical2caldav-0.01.zip - ogawa - ical2caldav-0.01.zip - Google Code
ogawa - Revision 607: /trunk/ical2caldav

このスクリプトを使うと、iCalendar形式での出力に対応したカレンダーアプリケーションのデータを、簡単にGoogle Calendarに代表されるCalDAV対応のカレンダーサーバに統合できます。

応用的な使い方としては、サイボウズオフィスのカレンダーをcybozu2icalを使ってスクレイプし、そのデータをical2caldavを使ってGoogle Calendarに統合することもできます。

また、メールに添付されてきたiCal/vCalファイルをカレンダーサーバに自動的に追加する目的でも使えるでしょう。さまざまなイベントデータをカレンダーサーバに集約しやすくする(カレンダーサーバをwhiteboard的に使えるようにする)ことで、CalDAVクライアント(iCalやMozilla Sunbird)の利便性がより向上することを期待しています。

さて使い方ですが、config.yamlをこんな感じで書きます。

caldav_url: https://www.google.com/calendar/dav/calid/events/
caldav_user: user@gmail.com
caldav_passwd: password

calid (カレンダーID)の調べ方はCalDAV Developer's Guide - Google Calendar APIs and Tools - Google Codeの後半を読むと分かります。

あとはコマンドラインから以下のように呼び出します。

$ ical2caldav --filename /path/to/calendar.ics --conf /path/to/config.yaml

--filenameを省略すると標準入力から読み込みます。--confを省略するとスクリプトのあるディレクトリのconfig.yamlを読み込みます(多分)。以下は注意点。

  • まだまだ不完全です。Google Calendarで試した限りでは、統合できるデータとそうでないデータがあります。
  • iCalendarの各イベントにはUIDが必要です。UIDがないイベントは無視されます。
  • 上のダイアグラムを見て「サイボウズのカレンダーがGoogle Calendarに同期できるんだー」と思ってしまう、うっかりさんのあなたは(きっと天使のような方なのでしょうが)思慮が足りません。きっと実生活で痛い目を見ます、もう見てるかも。例えば、サイボウズ上でイベントを削除してもGoogle Calendar上では反映されません。移動は反映されると思いますが。

Perlがどうもな、という人にはcurlコマンドをお勧めしておきます。

$ curl -H 'If-None-Match: *' -u user@gmail.com:passwd -X PUT -T calendar.ics \
  https://www.google.com/calendar/dav/calid/events/

ただし、この方法ではイベントを一件のみ含むiCalendarファイルしか登録できません。これに対してical2caldavは、iCalendarファイルを読み込んでイベントごとにiCalendarファイルを生成し、それを順次CalDAVにPUTするという操作を内部的に実行してくれます。

Sep 8, 2008

Cybozu2iCal 0.32公開

度々で申し訳ないデスが、cybozu2icalを0.32にアップデートしました。

Cybozu2ICal - ogawa - サイボウズオフィス6のカレンダーをiCalendar形式に変換するスクリプト。 - Google Code

主な変更点は、

  • 終日イベントが正しく終日イベントとして認識されないバグがあったので修正しました。
  • UIDが一定になるように修正しました。

後者について補足します。

元々各イベントのUIDは、サイボウズが出力する「イベントのID」、「イベントのタイムスタンプ」と、「ホスト名」から生成するようにしていました。が、サイボウズの出力するタイムスタンプは作成時刻ではなくAPIのリクエスト時刻になるという問題があり、このままだとiCalendarファイルを生成する度に異なるUIDを持つイベントを生成することになってしまいます(ちなみにiCalendarファイルのDTSTAMPとCREATEDが生成ごとに異なるのも同じ理由です)。このため、一部のUIDを真面目にハンドリングするiCalendarアプリで問題が起きる可能性がありました。

この問題に関して、私はサイボウズのつまらないバグの一つと解釈していてバージョンアップでいずれ対策されるだろうと思っていました。だから放置してきたのですが、今回サイボウズオフィス7でも対策されていないことに気がついたので、cybozu2ical側で対応することにしました。つまり、「イベントのID」と「ホスト名」のみからUIDを生成するようにしました。

Aug 29, 2008

Cybozu2iCal 0.30公開 改め0.31公開

サイボウズオフィスのカレンダーアイテムを取得して、iCalendar形式に変換するスクリプト、Cybozu2iCalを更新しました。

Cybozu2ICal - ogawa - Google Code

0.20から0.30へのアップデートでは、ようやく重い腰を上げてサイボウズオフィス7に対応(参考: Ogawa::Buzz: サイボウズオフィス7の SyncCalendarと ApiCalendar)してみました。

config.yamlで使えるオプションが2つ追加されています。

calendar_driver
どのAPIを使ってカレンダー情報を取得するかを指定します。現状ではApiCalendar(デフォルト)かSyncCalendar(サイボウズオフィス6専用)のいずれかを指定できます。サイボウズオフィス6を使っている場合にはSyncCalendarを指定しておくと高速化されます。
date_range
取得するカレンダー情報の日付範囲を指定します。date_rangeにNを指定すると、今日のN日前からN日後までの範囲のアイテムのみをサイボウズオフィスから取得して処理します。デフォルトのdate_rangeは「30」です。この機能はcalendar_driverとしてApiCalendarを指定している場合のみ有効です。

注意点は以下の通り。

  • ApiCalendarではバナー予定は取得できません。
  • date_rangeに大きな数値を指定すると処理に非常に時間がかかります。DoS攻撃と間違われないようにマイルドな数値を指定することをお勧めします。
  • ほとんどテストしていないので人柱よろしくお願いします。

追記 (2008-08-30):

さっそくですが、致命的なバグを報告していただいたので修正した0.31を公開しておきます。

Jun 23, 2008

MT4向けコマンドライン・バックアップツール

MTOS/MT 4.0からバックアップ機能[1]が導入されましたが、コマンドラインでバックアップできないのでcronとかで叩くこともできず、意義が半減してしまっています。

なのでコマンドライン・ツールを作ってみました。その名も「backup」!!

MT4Backup - ogawa - MTOS/MT 4向けコマンドライン・バックアップツール。 - Google Code

$MT_DIR/toolsあたりに放り込んでおけば、コマンドラインでスナップショットを取れます。

$ cd $MT_DIR
$ tools/backup

毎日スナップショットを取りたければcronでてきとーにどぞー。

10 0 * * * (cd $MT_DIR; tools/backup)

主なオプションを書いておきます。

--help
ヘルプを表示します。
--verbose
痛いメッセージを表示します。
--dir=<dir>
バックアップを作るディレクトリを指定します。指定しないとmt-config.cgiで指定したTempDirディレクトリに出力します。TempDirのデフォルト値は「/tmp」になっているはずです。
--blog_ids=<1,2,3>
バックアップするブログのIDを指定します。カンマで区切れば複数指定できます。このオプションを指定しないと全ブログがバックアップされます。
--size=<num>
指定されたKbytes単位ごとにバックアップファイルを分割します。指定しないと分割しません。
--archive=zip|tgz
アーカイブ形式を指定するとバックアップファイルを一つのファイルにまとめてアーカイブファイルを作ります。何も指定しなければアーカイブしません(manifest, xml, アセットデータのファイルが作られます)。

4.2系でしか試していません。MT::Roleのダンプが不完全かもしれません。→原因が分かったの修正してあります。

まだまだ開発版なので、At your own riskでどぞー。

Hackathonネタにしてもよかったんですが、それだと4.2に同梱される見込みが「ゼロ」になっちゃいますからね(行けそうもないしね)。

追記: とりあえずmtos-devに投げてみました。将来的にはMTOS/MTディストリビューションへのマージを狙います。

Oct 18, 2007

Cybozu2iCal 0.20公開

サイボウズオフィス6のカレンダーアイテムを取得して、iCalendar形式に変換するスクリプト、Cybozu2iCalを更新しました。

Cybozu2ICal - ogawa - Google Code

樋口さんから以下の記事にインスパイヤされ、新たなオリジナリティを加えてキャラクター化機能追加したものです。

Quick Hack [サイボウズのスケジュールをiPod Touchに同期させてみた] - higuchi.com blog
手段と目的が逆転しているかも [Cybozu2ICalの改造 その2] - higuchi.com blog

このバージョンから、Google Calendarに読み込ませるiCalendarファイルを生成する場合には、「--compat-google-calendar」オプションを明示的に指定する必要があります(以前のバージョンではデフォルトでそうなっていました)。

Jun 18, 2007

Cybozu2iCal 0.13公開

サイボウズオフィス6のカレンダーアイテムを取得して、iCalendar形式に変換するスクリプト、Cybozu2iCalをまた久々に更新しました。

Cybozu2ICal - ogawa - Google Code

0.10でサイボウズカレンダーの反復イベントに対応し、0.12ではそれをリファインしましたが、0.13では反復イベントの一部を削除、または日付・時刻を変更した場合にも正しくカレンダー表示できるようにEXDATE(iCalendar spec: 4.8.5.1 Exception Date/Times)に対応しました。また、各イベントにUIDというユニークIDを付与するようにしました。これにより、Google Calendarなどで一つのイベントが重複して表示される問題が解決するものと期待しています。

詳しい変更点は上記リンクから。

テストが不足していますので、問題点やコメントがあればこのエントリーのコメント欄にでもお書きください。

関連:
Ogawa::Buzz: Cybozu2iCal 0.12公開
Ogawa::Buzz: Cybozu2iCal 0.10公開
Ogawa::Buzz: Cybozu Office 6のカレンダーを Google Calendarで表示する

Mar 22, 2007

Cybozu2iCal 0.12公開

サイボウズオフィス6のカレンダーアイテムを取得して、iCalendar形式に変換するスクリプト、Cybozu2iCalを久々に更新しました。

Cybozu2ICal - ogawa - Google Code

0.10でサイボウズカレンダーの反復イベントに対応したつもりだったのですが、どうも不十分だったようでいくつかフィードバックをいただきました。遅くなりましたが、0.12ではそれらの対策をしたつもりなのでご確認いただければと思います。

RFC2445: Internet Calendaring and Scheduling Core Object Specification (iCalendar)を読むと、反復条件(RRULE)では、終了日時UNTILは「日付」または「UTC時刻」で指定することになっています。0.11までは、すべての反復イベントに対してUNTILに「日付」のみを指定していましたが、0.12ではなるべく標準に即すべく、時刻指定のある反復イベントのUNTILはUTC時刻で指定し、時刻指定のない反復イベントのUNTILは日付で指定するようにしました。

また、この修正をしてもGoogle Calendarには時刻指定のない反復イベントの終了日時が一日早まってしまうバグがある様子です。私の勘違いなのかもしれませんが。

2007年3月21日から25日までの終日イベントは以下のように指定できるはずです。

DTSTART;VALUE=DATE:20070321
DTEND;VALUE=DATE:20070322
RRULE:FREQ=DAILY;UNTIL=20070325

しかし、Google Calendarでは24日までのイベントとして認識されていまいます。なんとなく、UNTILの日付(20070325)を時刻(20070325T000000)として解釈しているような気がします。

ところが、こんな具合に、

DTSTART;VALUE=DATE:20070321
DTEND;VALUE=DATE:20070322
RRULE:FREQ=DAILY;UNTIL=20070325;WKST=SU

RRULEにWKST=SUオプション(週の開始を「日曜」とするオプション)を指定すると、Google Calendarの問題が回避できることを発見したので、cybozu2ical 0.12はこの回避策を採用しています。

関連:
Ogawa::Buzz: Cybozu2iCal 0.10公開
Ogawa::Buzz: Cybozu Office 6のカレンダーを Google Calendarで表示する

Nov 10, 2006

Cybozu2iCal 0.10公開

サイボウズオフィス6のカレンダーアイテムを取得して、iCalendar形式に変換するスクリプト、Cybozu2iCalを割と大幅に更新したので、そのご報告。

Cybozu2ICal - ogawa - Google Code

大きな変更点は二つあって、ひとつはサイボウズオフィス6からカレンダーデータを取得・パーズする処理を分離して、WWW::CybozuOffice6::Calendarモジュールを作ったということです。

WWW::CybozuOffice6::Calendarモジュールは、下記のsubversionリポジトリから単体でも取得できます。

ogawa - Revision 618: /trunk/WWW-CybozuOffice6-Calendar

私がこのモジュールを作ったのは、iCalendarに変換するだけじゃなくてGData APIを叩くアプリにも使いたいと思ったからです。もちろん、Plaggerなどからサイボウズオフィス6を利用する場合にも使えるでしょう。Plagger事情に疎いので、もうCustomFeed Pluginとしてネリネリ作っちゃっててみんな使ってるよーということになっているかもしれませんが、「そんなこと知ったことか、俺コードの俺再利用性が重要なんだ」という方向で。

もうひとつの変更点は、ついにようやく反復カレンダーイベントに対応したということです。

iCalendarのRRULEは常人の理解を超えているのでずっと敬遠してきました(RRULE, RDATEをフルサポートするカレンダーソフトウェアってまじすごいよ)。が、冷静にサイボウズが対応している反復イベントのパターンを観察してみていたら、割と単純なRRULEだけで済むことが分かってきたので、対応してみました。おざなりなものですが。

テストが十分ではないのでおそらく不具合(特にRRULE)が結構あると思います。人柱希望の方はどうかお試しください。

関連:
Ogawa::Buzz: Cybozu Office 6のカレンダーを Google Calendarで表示する

2006-11-19追記:
以下の点を修正した0.11を公開しました。

  • 終了時刻が指定されない場合に開始時刻が10分遅れになるバグがあったので修正しました。
  • 終了時刻が「24:00」と指定された場合に「23:59:59」に丸める処理を追加しました。これはそもそもCybozuの問題ですが。
  • 開始・終了時刻が不正な範囲にある場合のエラー処理を追加しました。

Oct 29, 2006

PaginatedFeed公開

Movable Typeで、Pagination機能付きのRSSやAtomを生成するツールを作ったので公開しておきます。

PaginatedFeed - ogawa - Pagination機能付きのRSSやAtomを生成するMovable Typeアプリケーション。 - Google Code

Movable TypeでAtomフィードやRSSフィードを静的に生成するとき、最新の指定個数のエントリーしか対象にならないのが面白くないとは思いませんか。私には、こうした安直な「部分フィード」はいわば生成コストや取得コストの軽減に特化された形式であって、対象コンテンツセットの「表現」としての性質は必ずしも芳しくないのではないか、と思えてなりません。例えば、部分フィードを元に対象コンテンツ全体を把握することも対象コンテンツの更新内容全体を把握することもできませんし、部分フィードを対象とした検索エンジンはブログ空間を対象とした検索エンジンとはなり得ません。

思い切って全エントリーを含むフィードを生成するというソリューションもあり得ますが、フィードが巨大になるため、再構築を行うWebサーバの負荷、(HTTP Compressionを使ったにせよ)トラフィック、その巨大フィードを利用するクライアントプログラム・サービスの負荷が問題となります。

一方で、OpenSearchのレスポンスフィード(要素)やGoogle Blogger betaのAtomフィードは、openSearchというXML名前空間を使ったフィードのPaginationを実現しています。

これと同じことがMovable Typeでも実現できればよいのではないか、じゃあ作っちゃえ、と思って作ったのがPaginatedFeedです。PaginatedFeedでは、表示したいエントリーのオフセットと件数を指定してフィードを生成できます。また、フィードにOpenSearchレスポンスに必要な要素を追加するのに便利ないくつかのテンプレートタグを実現しています。

興味のある方は上記リンクよりどうぞ。

Jun 5, 2006

mt-keywords2tags / mt-cats2tags公開

エントリーの「キーワード」を、MT 3.3以降でネイティブにサポートされた「タグ」にコンバートするCGIスクリプトを公開します。

MTKeywords2Tags - ogawa - Google Code

Movable Type 3.3以降では、ネイティブにTaggingをサポートするようになりましたが、それ以前のバージョン用に作られたTaggingプラグインの多く(Tags Plugin, Tagwire Plugin, Tags.Appなど)は、エントリーのキーワード欄をタグ入力欄として使用してきました。

このCGIスクリプトは、エントリーのキーワードをMT 3.3ネイティブなタグに変換することで、従来のTaggingプラグインユーザのネイティブタグへの移行を支援するものです。


さらに!

エントリーの「カテゴリーラベル」を、MT 3.3以降でネイティブにサポートされた「タグ」にコンバートするCGIスクリプトも公開します。

MTCats2Tags - ogawa - Google Code

このCGIスクリプトは、エントリーのカテゴリーラベルをMT 3.3ネイティブなタグに変換することで、従来「カテゴリー」を活用してきたユーザのネイティブタグへの移行を容易にするものです。

ところでSQLiteでは、mt-search.cgiによるタグサーチがうまく機能せずにロードが1に張り付いてしまう現象が観測された。MySQLで試した限りは問題ないので、少し調べる必要がありそう。
Ogawa::Buzz: MT 3.31 SQLiteがベラボーに遅い件について。がことの真相。

Jan 14, 2006

DBコンバート後に受信済みのトラックバックを参照できない問題への対処

このブログで長らく公開してきたmt-db-convert.cgi、およびMovable Type 3.2に同梱のmt-db2sql.cgiに大きめのバグを発見しました。どちらのツールでもコンバート後にすでに受信済みのトラックバックを参照できないという問題が生じ得ます。

現在下記にて配布している0.20以降のバージョンでは、すでに対策済みです。

Ogawa::Buzz: mt-db-convert.cgi: MTデータベースの相互変換 CGIスクリプト

過去に一度でもmt-db-convert.cgiかmt-db2sql.cgiを使ってデータベースを変換したことがある場合には、(顕在化していなくても)潜在的には問題がある可能性があります。不安を煽っても仕方がないので、問題の有無を検査したり、データベースを訂正するためのプログラムも用意しましたので、症状に心当たりがある人は試してみるとよいでしょう。

問題の詳細

mt-db2sql.cgiもmt-db-convert.cgiも、新規のデータベースを作成して元のデータベースからMT::Object単位でコピーしていきます(MTではブログを表現する大抵のデータ構造がMT::Objectのサブクラスとして表現されています)。コピーはサブクラス(オブジェクトの種類)ごとにまずAuthorクラスのオブジェクトを順にコピーし、次にBlogクラスを、さらにCategory, Comment, Entry (中略) Trackback, TBPing (後略)をそれぞれコピーしていきます。

ところが、MT::ObjectのうちEntryとCategoryの保存時には、対象のオブジェクトがトラックバック可能な場合、データベースにTrackbackオブジェクトがあるかどうか問い合わせ、なければ新規に生成して保存するようになっています。

これはトラックバック可能な新規エントリーを作成したりする場合には正常に機能します。一方、コンバート時にTrackbackクラスより先にEntryクラスをコピーすることを考えると多少事情が異なります。新規データベースにはTrackbackオブジェクトは存在しませんから、まずEntryコピー時にTrackbackオブジェクトを一通り新規生成した後、さらにTrackbackコピー時にそれが上書きされることになります。この結果、あるEntryオブジェクトに対応するTrackbackオブジェクトが複数存在する状態が作られます。

例えば、Entryが3個あり、それぞれに関連付けられたTrackbackオブジェクトのidが1,3,5であるという状態を仮定します。Entryのコピー時にはidが1,2,3のTrackbackオブジェクトが新規生成され、Trackbackのコピー時にはidが1,3,5のTrackbackオブジェクトが作成されます。したがって、新しいデータベースには1,2,3,5という4つのTrackbackオブジェクトが作られることになります。

さて、Movable TypeのTrackbackクラスは、エントリーやカテゴリーのトラックバックインタフェースの抽象ですが、EntryオブジェクトとTBPingオブジェクト(受信した個々のトラックバックデータ)を関連付ける役割もあります。さらに悪いことには、関連付ける際にMovable TypeはIDの一番小さいTrackbackオブジェクトしか参照しません。したがって、参照されなかったTrackbackオブジェクトに関連付けられたTBPingオブジェクトも参照されません。この結果として、過去に受信したTBPingとEntryとを関連付けられなくなります。

この問題を避けるには、コピー時に必ずTrackbackクラスを先にコピーするか、Entryに対応付けられたTrackbackオブジェクトが複数あっても正常に動作するように本体プログラムを修正する必要があります。

冒頭でも述べたように、mt-db-convert.cgiの0.20以降では前者の対処を行ってあります。mt-db2sql.cgiへの対処はOgawa::Buzz: MT 3.2日本語版 Unofficial Patchに追加しました。

検査・修正用プログラム

簡単なデータベースの検査・修正用のプログラムを用意しました。

mt-tbfixer.cgi

上記のCGIスクリプトをmt.cgiなどと同じディレクトリにアップロードし、実行権限を与えて、ブラウザなどから起動してください。

何もオプションを与えなければデータベースの検査をしてくれます。

MT::Trackback(id=194) conflicts with (id=198) for entry 928
   MT::TBPing(id=998) can be moved from MT::Trackback(id=194) to (id=198)
   MT::Trackback(id=194) can be removed
MT::Trackback(id=118) conflicts with (id=129) for entry 859
   MT::Trackback(id=118) can be removed
...
 
15 conflicts are found in MT::Trackback!
5 conflicts are found in MT::TBPing!

この例では、mt-db-convert.cgiやmt-db2sql.cgiの実行時に誤って作られたTrackbackオブジェクトが15個あり、それらのトラックバックインタフェースに送信された5件のTBPingオブジェクトがあることが分かります。前者の値が0ならばまったく問題はありません。

次にデータベースの訂正を行うには、まずデータベースのバックアップを取ってください

バックアップしましたね?

いいんですね?

…では続けます。今度は「http://.../mt-tbfixer.cgi?__mode=fix」のように「?__mode=fix」というオプションを付けて起動します。

MT::Trackback(id=194) conflicts with (id=198) for entry 928
   MT::TBPing(id=998) is moved from MT::Trackback(id=194) to (id=198)
   MT::Trackback(id=194) is removed
MT::Trackback(id=118) conflicts with (id=129) for entry 859
   MT::Trackback(id=118) is removed
...
 
15 conflicts are found and fixed in MT::Trackback!
5 conflicts are found and fixed in MT::TBPing!
 
You should perform rebuilding for all MT contents.

と表示された時点で修正作業は終了しています。最後にすべてのページを再構築すれば、コンバートの際に見えなくなっていたトラックバックが表示されていることでしょう。

注: このスクリプトはテストが相当不足しています。チャレンジャーをお待ちしています。
注: このスクリプトはカテゴリーのトラックバックインタフェースを考慮していません。今のところ重要度が低いと考えて先送りしていますが、そのうち実装します。

Jul 16, 2005

mt-db-convert.cgi: MTデータベースの相互変換 CGIスクリプト

Movable TypeのデータベースをDB間で相互にコンバートするCGIスクリプトを公開します。

MT_Database_Converter - ogawa - Google Code

Movable TypeのデータベースをBerkeleyDB、MySQL、PostgreSQL、SQLiteの間で相互に変換するCGIスクリプトです。テスト環境から本番環境への移行、プラグインの開発、そしてDBのアップグレードなど、データベースを一方から他方に移行したい場合に役に立ちます。DB間の相互変換は、従来からMovable Typeに付属しているmt-db2sql.cgiと拙作のOgawa::Buzz: mt-sql2db.cgi: mt-db2sql.cgiの逆変換CGIスクリプトを組み合わせれば実現できましたが、このスクリプトはそれを単体で実現します。また、mt-sql2db.cgiにあったバグをいくつか修正してあります。

今年の3月くらいには作ってあったのですが、mt-db2sql.cgiのコードを再利用しているので公開を見送っていました。この度ようやくSix Apartの言質が取れたので公開する次第です。

Nov 28, 2004

MT-ShrinkFInfo

Movable Type 3.1でしばしば問題となる、肥大化したfileinfo.dbをshrinkするための簡単なツールを公開します。3.14以降のバージョンでは不要です。

MTShrinkFInfo - ogawa - Google Code

Movable Type 3.1でBerkeleyDBを使っている場合、再構築を繰り返すたびにfileinfo.dbが肥大化するという問題が知られています(TITO's Web Page: Movable Type「fileinfo.db」の肥大化)。具体的には、MTは再構築のたびに古いFileInfoオブジェクトを削除して、新しいFileInfoオブジェクトを生成しますが、このときBerkeleyDBを使っている場合に限って、(1) 古いFileInfoオブジェクトの消去をし損なう場合があること、(2) 削除してもfileinfo.dbファイルの空き領域が開放されないこと、がこの肥大化の原因となっています。

mt-shrinkfinfo.cgiは、この肥大化したfileinfo.dbをshrinkするための簡単なツールです。Movable TypeのPerl APIを使って実現されているため、直接DBイメージファイルを削除したりする方法に比べて安全であり、また容易です。

Aug 9, 2004

mt-sql2db.cgi: mt-db2sql.cgiの逆変換 CGIスクリプト

コネタが続きますが、このエントリでは、MySQLなどに保存しているMovable TypeのデータをBerkeleyDBにコピーするための自作CGIスクリプト(mt-sql2db.cgi)を紹介します。

mt-sql2db.cgi

0.01(2004.08.09): 公開。

レンタルサーバなどでMySQLなどを使っている場合、どうしてもデータをロストする危険を感じないわけにはいきません。実際廉価なレンタルサーバでのSQLサーバ利用は「at your own risk」と明記されている場合が非常に多く、サービスの継続性にも不安を感じます。

一方で、Movable TypeはBerkeleyDB形式で作ったデータをSQLに変換する機能は提供しますが、その逆の機能は提供しません。確かに一旦SQLに変換してしまえば、Ogawa::Buzz: LolipopのMySQLデータベースを簡単バックアップするCGIスクリプトに書いたようにSQLデータをバックアップすること自体は簡単です(しかもreadableだし、portableだし、だし)。が、そうして取ったバックアップからリカバリーしたい場合、リカバリー側環境でSQLサーバが無事に使えれば問題はないですが、そうでなければMovable Typeを継続して使うことができないということになります。

こうした事情もあり、最近頓にトラブルの多いBerkeleyDBからMySQLに移行したいがBerkeleyDBに戻せないのは困るという理由で二の足を踏んでいる、という人は割に多いのではないでしょうか? そんな人の背中を押すのがこのスクリプトの目的です。

このスクリプトは、端的に言ってMovable Type 3.0に付属のmt-db2sql.cgiの逆変換機能を提供します。mt.cfgでDBI ObjectDriverを指定しているときに、データベースに格納してあるすべてのMT Objectを読み込んではDBM形式で保存していく、というただそれだけのスクリプトです。

使い方

基本的な使い方は以下の通りです。

  1. 上記リンクよりCGIスクリプトをダウンロードして、mt-sql2db.cgiという名前で保存します。
  2. mt.cgiなどが置かれているディレクトリにアップロードし、mt.cgiなどと同様に実行権限を与えます。
  3. mt.cfgでObjectDriver、Database、DBUser、DBHost、(BerkeleyDBが使用するディレクトリを指定する)DataSourceが適切に設定されていることを確認してください。また、DataSourceで指定したディレクトリを作るのも忘れずに。
  4. ブラウザからmt-sql2db.cgiにアクセスしてCGIを実行してください。SQLサーバのデータがDataSourceで指定したディレクトリにBerkeleyDB形式でダンプされるはずです。
  5. 無事に済んだら、mt.cfgのObjectDriverの行をコメントアウトしてBerkeleyDBでの動作確認をしてください。

このツールはもう少し応用的な使い道もできます。

megu's blogのmeguさんにコメント欄でご示唆いただいたように、異なるSQLサーバ間のデータ形式変換にも使えます。例えば、MySQLで作ったデータを一旦BerkeleyDB形式に変換(このエントリのmt-sql2db.cgi)し、次にBerkeleyDB形式のデータをPostgreSQL形式に変換(MT3.0付属のmt-db2sql.cgi)することで、MySQL→PostgreSQLの移行ができます(vice versa)。

もちろん両スキーマ間の変換をする方が確実かつ高速なのは言うまでもないですが、この方法ならSQLの知識なしに(あるいはそれ専用のツールを使うことなしに)変換できるというメリットがあります。

注意点

  • エントリーの数が増えると非常に時間がかかるようになります。所要時間はおおよそエントリー数の2乗に比例すると考えてください。辛抱が肝心です。
  • レンタルサーバなどではスクリプトの実行時間が長くかかり過ぎると途中終了する場合があります。その場合にはこのツールは使えません。ちなみにLolipopではこのブログはバックアップできませんでした
  • BerkeleyDBへのバックアップは、mt.cfgのDataSourceで指定しているディレクトリに行います。すでにこのディレクトリにバックアップが存在する場合上書きされます
  • Known bugですが、Link this template to a file(このテンプレートにリンクするファイル)を指定しているテンプレートがあるとスクリプトが失敗することがあります。これはBerkeleyDBにsaveしようとする際に対象ファイルへのアクセスが発生するためです。原因は分かっていますが、面倒なので対処しません。
  • MySQLとPostgreSQLとSQLiteで動作することを確認しています。
  • MT2.6X~MT3.1Xでしか動作確認しておりません。
  • ご利用は計画的におながいいたします。念には念を入れてバックアップしてください。

Aug 6, 2004

mt-resave-entries.cgi: basenameを正しく設定するためのCGIスクリプト

このエントリでは、MT 2.6X利用時に作成したエントリのbasename(通常NULLになっているはず)を設定するための自作CGIスクリプト(mt-resave-entries.cgi)を紹介します。

mt-resave-entries.cgi

0.01(2004.08.06): 公開。
0.02(2004.08.09): entry_idでソートするのを忘れてました。

このスクリプトは、basenameがNULLになっているエントリをidの若いものから順番にloadしてはsaveしていくことでbasenameを再設定します。なぜこのツールが必要なのかについては、Ogawa::Buzz: Movable Type 3.0のIndividual Entry Archiveの命名方式の問題点で説明していますのでご参照ください。

エントリの作成時刻は元のままですが、更新時刻はCGIを実行したときのものに更新されます。これは仕様です。ご利用はくれぐれもノークレーム、ノーリターンでおながいします。

使い方

  1. 上記リンクよりCGIスクリプトをダウンロードして、mt-resave-entries.cgiという名前で保存します。
  2. mt.cgiなどが置かれているディレクトリにアップロードし、mt.cgiなどと同様に実行権限を与えます。
  3. ブラウザからmt-resave-entries.cgiにアクセスしてCGIを実行してください。basenameがNULLのエントリがあれば再保存して新しいbasenameを付与していきます。

Advancedな使い方

このCGIはついうっかり設定されてしまったbasenameを再設定する目的にも使えます。例えば、英語版を使っていて意味不明のbasenameを付けられてしまった場合や暫定的に付けたタイトルを元に不本意なbasenameを付けられてしまった場合などは、この方法で対処できます。ただし作業は高度になりますので腕に覚えのない方は止めておくべきです。

まず、対象のエントリのbasenameを一旦NULLに変更します。ここではMySQLを使用しているものと仮定します。以下のSQL文をコマンドラインインタフェースないしphpMyAdminを使って実行します。

UPDATE mt_entry SET entry_basename=NULL WHERE entry_id=XXX

XXXは対象のエントリのIDです。すべてのエントリを再設定したいのであれば、WHERE節を記述する必要はありません。UPDATEが無事済んだら(1秒もかからないと思います)、
次にmt-resave-entries.cgiを実行すればbasenameを再設定することができます。