2016/01/21(木)adiaryへの移行で苦労したところ

2016/01/21 19:22

このブログははてなダイアリーはてなブログWordPress→はてなブログと移転を繰り返し、今月の11日からadiaryで書いています。

今回の移転にあたって、adiaryの設置そのものは簡単にできたのですが、過去のブログ記事のインポートにはかなり苦労させられました。以前のブログからエクスポートしたファイルを単純にインポートするだけでは上手く行かなかったからです。

同じような境遇の方のお役に立てるかもしれませんので、その苦闘の記録を残しておきたいと思います。

はてなダイアリー

架空の日付を修正する

はてなダイアリーは自由な日付で投稿することができ、実在しない日付で記事を書くことも可能です。この仕様を活かして、0000年00月00日の記事として自己紹介やブログの説明を書くという光景も見られました。

adiaryでは非実在日の投稿はできないので、そのような記事については実在の日付に変更する必要があります。とはいえ、私はそんな投稿はしていないはず……と思ったら、前川勝彦さんについて書いたときに11月31日という日付を使っていました。どうりで同じ場所でインポートエラーが出続けると思ったんだ。

残念ながら現在の主要なOSでは前川標準時は採用されていないため、投稿日時を日本標準時である12月1日に修正します。

不正な時刻を修正する

はてなダイアリーのエクスポートファイルは、午前0時台、午後0時台の表記方法に誤りがあります。本来、午前0時を表現するのは以下のどちらかの形式でなければいけません。

01/01/2016 12:00:00 AM
01/01/2016 00:00:00

ところが、はてなダイアリーのエクスポートファイルでは以下のようになってしまいます。

01/01/2016 00:00:00 AM

私の感覚では「午前12時」より「午前0時」という表現のほうがしっくり来ますが、こういうルールなのですから仕方がありません。テキストエディタの一括置換で正しい表記に修正します。

:%s;\v(DATE: \d{2}/\d{2}/\d{4}) 00:(\d{2}:\d{2} [AP]M);\1 12:\2;g

投稿日時を実時間に変換する

私がはてなダイアリーを使っていたときには、「日付の変わる時間」を午前6時に設定していました。この設定では、1月11日の午前0時から午前6時までに書いた記事は、前日の1月10日のものとして扱われます。

この仕様は、エクスポートファイル上では残念ながら破綻してしまいます。たとえば、実時間の2016年1月11日の午前1時に書いた記事をエクスポートすると、投稿日時は以下のように出力されてしまうのです。

DATE: 01/10/2016 01:00:00 AM

これ以外に表現のしようがないのはわかりますが、実時間としても投稿時間としても微妙な出力になってしまいました。これをいったん実時間に置き換えたいと思います。今回はさすがに正規表現による置換では難しかったので、簡単なPythonプログラムを作成しました。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import datetime
import re
import sys

FORMAT = '%m/%d/%Y %I:%M:%S %p'
PATTERN = re.compile(r'^DATE: (\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2} [AP]M)')

def convert(in_file_name, out_file_name):
    with open(in_file_name, 'r') as in_file, open(out_file_name, 'w') as out_file:
        for line in in_file.readlines():
            out_string = line
            match = PATTERN.search(line)
            if match:
                posted = datetime.datetime.strptime(match.group(1), FORMAT)
                if datetime.time(0, 0, 0) <= posted.time() < datetime.time(6, 0, 0):
                    posted += datetime.timedelta(days=1)
                    out_string = 'DATE: %s\n' % posted.strftime(FORMAT)
            out_file.write(out_string)

if __name__ == '__main__':
    convert(sys.argv[1], sys.argv[2])

エイプリルフールに対応する

エイプリルフールにネタめいたことを書くようになってから、毎年4月1日の記事は実時間の4月1日0時に投稿しています。これらの記事が先ほどのPythonプログラムで4月2日に変換されてしまいました。

こちらに関してはそれほど数も多くないので、自分の目で確認しながら一つずつ手で修正します。

はてなブログ(第1期)

残念ながら生のエクスポートファイルは残っていませんでした。この時期の記事については、次項のWordPressのエクスポートファイルであわせてインポートします。

WordPress

古い記事を削除する

このファイルでは、はてなブログ(第1期)とWordPressの記事をインポートしますので、それ以前のはてなダイアリーの記事をばっさり削除します。

Movable Type形式に変換する

WordPressからはてなブログ(第2期)に移行するとき、エクスポートファイルをWordPress形式からMovable Type形式に変換するWebサービスを使わせてもらいました。ところが、そのサービスは投稿日時をなぜかwp:post_dateではなくwp:post_date_gmtから取得しており、本来の日時から9時間ずれた時刻でインポートされてしまいました。

今回は同じ轍を踏まないよう、自作のプログラムで変換を行います。

GitHub - 7pairs/wp2mt

adiaryはWordPress形式のファイルも扱えるので、変換せずにそのままインポートすればよかった……ということにたった今気がつきました。でも、気がつかなかったふりをして先に進めます。

はてなブログ(第2期)

古い記事を削除する

はてなダイアリー、はてなブログ(第1期)、WordPressの記事をばっさり削除します。

記事の順番を逆転させる

はてなブログのエクスポートファイルは新しい記事から順に上から並んでいますので、このファイルをそのままadiaryにインポートすると、新しい記事のほうが若いIDで作成されてしまいます。

対応のために記事の順番を逆転させるプログラムを作ろうかとも思いましたが、VirtualBox環境に構築したローカルのadiaryにいったんインポートして、その内容をMovable Type形式でエクスポートすれば用が足りることに気がつきました。この手順で古い順に並んだファイルを作成します。

インポート

以下の手順でadiaryへのインポートを行いました。

  1. ブログの基本設定の「日付変更時間」を午前6時に設定する
  2. 「日付変更時間の処理」を午前6時にし、はてなダイアリーのファイルをインポートする
  3. ブログの基本設定の「日付変更時間」を午前0時に設定する
  4. 「日付変更時間の処理」を午前0時にし、WordPressのファイルをインポートする
  5. 「日付変更時間の処理」を午前0時にし、はてなブログ(第2期)のファイルをインポートする
  6. ブログの基本設定の「日付変更時間」を午前6時に設定する

インポートが正常に行われたことを確認するため、全記事をadiary形式でエクスポートし、そのファイルに対して以下のコマンドを発行します。

$ grep "^4198。移行対象の2004年7月14日から2016年1月10日までは4198日間ですから、すべての記事が望んでいる日付でインポートされていることを確認できました。