サーバー構築日記 Linuxサーバー編 (4) はてなダイアリー=>WordPress移行編

どう見てもLinuxサーバーの構築日記ではないような気がしますが、とりあえず移行編です。

この作業ですが、ほかのサイトでも余りやったことがないらしく作業そのものがとっても大変でした。

かなりいろいろな置換やらスクリプトやらを使いますので注意をしてください。

WordPressのセットアップはがんばって

ほかのサイトでもやっていますのでそちらを参考に。インストールして各種プラグインをインストールして設定を行います。

なお、今回のインストールでは以下のプラグインを使います。

また、この作業をするときはファイルキャッシュ系のプラグインは一旦停止しておいてください。

まずははてなダイアリーからデータをエクスポート

データ管理の画面よりブログのエクスポートを行います。 このとき、エクスポート形式でMovable Type形式を選択してください。

この形式のまままずはローカルにダウンロードします。

初期置換作業

そのままだとWordPressにインポートしてもいろいろと崩れてしまうのでそれを防ぐために置換を行います。

今回使うのはVisualStudioです。なぜこれかというと正規置換時のとあるオプションが必要なためです。 同じオプションを持っているならVisualStudioにこだわる必要はありませんが・・・。

VisualStudio上で行うのはpreタグ関連(pre記法、スーパーpre記法、スーパーpre記法(シンタックス・ハイライト))の置換です。

いらない要素を一気に吹っ飛ばしてWordPress上のSyntaxHighlighterに変換します。 スーパーpre記法は基本的にpreタグになっているだけなので無視してかまいません。

シンタックス・ハイライトがかかるとpreタグに特定のclassがつくのでそれを目安に置換します。 すべて判別するのは後回しにしてとりあえずC++として処理します。

置換前(非正規置換) 置換後
<pre class=”syntax-highlight”> [cpp]

閉じタグ側は後で処理します。 あとはシンタックス・ハイライトの属性を削除します。

置換前(正規置換) 置換後
\<span\ class\=\”syn[A-Z].#\”\>{.#}\<\/span\> \1

このときに.#という記法を使えないと後がやっかいです。ちなみに#は+の文字列の長さ最小限版です。

+だと同一行にハイライトがあると範囲がオーバーするので使えません。この正規置換表現はVisualStudio独自の拡張なのでほかではあまりないと思います。

あとはtex参照アドレスの変更です。texを使っているときははてな内のmimetex.cgiを使っているので移行時には自身のサーバーにmimetex.cgiを用意してそちらを指す必要があります。

mimetexのコードを拾ってきて適当にコンパイル(gccや一部画像ライブラリが必要)すればできますので、それをcgiとして実行可能なディレクトリにおいてそれを指すようにします。

置換前(非正規置換) 置換後
http://d.hatena.ne.jp/cgi-bin/mimetex.cgi http://(WordPress内からアクセスできるcgiのURL)/mimetex.cgi

残りの面倒な置換はphpスクリプトで

まずは一段階目です。

<?php

$hatenaarticle_d = 'http://d.hatena.ne.jp/(はてなダイアリー所有者名)/%04d%02d%02d';
$hatenaarticle_n = 'http://d.hatena.ne.jp/(はてなダイアリー所有者名)/%04d%02d%02d/p%d';
$wparticle = 'http://(WordPressのblogURL)/?p=%d';

$data = file('(はてなダイアリー所有者名).txt');

$cnt = 1; $lastdate= ''; $datecount = array();

$dateok = true; $commentin = false;
foreach($data as $line){
  if(ereg('^DATE\:',$line) &amp;&amp; $dateok){
    list($str,$date,$time) = explode(' ',$line);
    list($month,$day,$year) = explode('/',$date);
    if($lastdate != $date){ array_push($datecount,sprintf('%04d,%02d,%02d,%d',$year,$month,$day,$cnt)); $lastdate = $date; }
    else{ $datecount[count($datecount) - 1] = sprintf('%04d,%02d,%02d,%d',$year,$month,$day,$cnt); }
    $cnt++;
  }
  else if(ereg('^AUTHOR\:',$line)){
    if($commentin){ $commentin = false; }
    else{ $dateok = true; }
  }
  else if(ereg('^COMMENT\:',$line)){
    $commentin = true;
    $dateok = false;
  }
}

$repfrom = array('&lt;h5&gt;','&lt;/h5&gt;','&lt;h4&gt;','&lt;/h4&gt;','&amp;#34','&amp;#38','&amp;#40','&amp;#41','&amp;#42','&amp;#60,'&amp;#62','&amp;#91','&amp;#92');
$repto = array('&lt;h3&gt;','&lt;/h3&gt;','&lt;h2&gt;','&lt;/h2&gt;','&quot;','&amp;amp;','(',')','*','&amp;lt;','&amp;gt;','[','\');

$cnt = 1; $to = 0;
foreach($datecount as $item){
  list($year,$month,$day,$next) = explode(',',$item);
  for($i = 1,$j = $cnt;$j &lt;= $next;$i++,$j++){
    array_push($repfrom,sprintf($hatenaarticle_n,$year,$month,$day,$i));
    array_push($repto,sprintf($wparticle,$j));
  }
  array_push($repfrom,sprintf($hatenaarticle_d,$year,$month,$day));
  array_push($repto,sprintf($wparticle,$cnt));
  $cnt = $next + 1;
}
$wfh = fopen('intermidiate.txt','w');

foreach($data as $line){
  if(ereg('^DATE\:',$line)){
    $linedata = explode(' ',$line);
    if(count($linedata) == 4){
      list($hour,$min,$sec) = explode(':',$linedata[2]);
      if(strcmp(rtrim($linedata[3]),'PM') == 0){ $line = sprintf('DATE: %s %02d:%02d:%02d' . &quot;\n&quot;,$linedata[1],$hour + 12,$min,$sec); }
      else{ $line = sprintf('DATE: %s %02d:%02d:%02d' . &quot;\n&quot;,$linedata[1],$hour,$min,$sec); }
    }
  }
  else{ $line = str_replace($repfrom,$repto,$line); }
  fwrite($wfh,$line);
}

fclose($wfh);
?>

(はてなダイアリー所有者名)と(WordPressのblogURL)は実際の名前に変更してください。

また、WordPress側のリンクの書き方も限定していますのでそれに注意してください。

このスクリプト自身も簡易です。完全にうまくいくとは限りませんので注意してください。

発想としては

  1. 各記事が書かれた時間からインポートされたときの記事番号を逆算する。このとき、コメント部分を省く処理が必要
  2. 置換が必要なタグ、記号を初期設定
  3. はてなダイアリー上の自身への記事のリンクをインポート後のWordPressの記事のリンクに変換するための置換を設定
  4. 行を読み出して置換。ただし、日付表記に限り「AM」「PM」の表記を削除した形に変換

とやります。あくまで、インポートされたデータと言うことでタグやら何やらが正常にエスケープされているとの仮定です。 この時点でほとんどの置換が完了します。

あとはシンタックス・ハイライトに関わる部分の置換です。

<?php

$data = file('intermidiate.txt');
$wfh = fopen('result.txt','w');

$premode = false; $iscpp = false; $from = array(&quot;\t&quot;,'&amp;lt;','&amp;gt;','&amp;amp;'); $to = array('@@@@','&lt;','&gt;','&amp;');
foreach($data as $line){
  if(strcmp(trim($line),'[' . 'cpp' . ']') == 0){ $premode = true; $iscpp = true; }
  else if(strcmp(trim($line),'&lt;pre&gt;') == 0){ $premode = true; $iscpp = false; }
  else if(strcmp(trim($line),'&lt;/pre&gt;') == 0){
   $premode = false;
   if($iscpp){ $line = '[' . '/cpp' . ']' . &quot;\n&quot;; }
  }
  else if($premode){ $line = str_replace($from,$to,$line); }
  fwrite($wfh,$line);
}
fclose($wfh);
?>

ちなみに置換構文内でcppタグがばらばらになっているのはSyntaxHighlighterにひっかかってしまうからです。

で、preタグ中に限り各表記をわざと元に戻しています。これはインポート中に各記号が変換される(タブ文字は消去される)ための処理です。

ちなみに@@@@としていますが、これは記事内で絶対に重複しないような文字記号列、という意味です。ほかのものでもかまいません。

また、preタグの閉じる部分に限り元々syntax-highlightがあった場合は閉じる方も変換しています。

最後にインポート処理

まずはインポート前にすべての記事が無いことを確認します。あったときは強制的に削除してください。

つまるところ、投稿一覧を見たときに記事が完全にない状態にしてください。

その後はSQLにより記事番号をリセットします。WordPressのデータベースにアクセスできる状態にして(接頭辞をwpとすると)

ALTER TABLE `wp_posts` AUTO_INCREMENT = 1;

とします。

そして記事をインポートします。記事のインポートは「Movable Type and TypePad」から行います。

あとは直接アップロードするなり/wp-content/の下にresult.txtをmt_export.txtに名前を変更してアップロードしてインポートを行います。

最後にタブ文字から変換された文字記号列を元に戻します。

UPDATE `wp_posts` set post_content = replace(post_content,'@@@@','\t');

これで完了です。ちなみにファイルキャッシュ系が有効になっているとこの置換に気がつかずにpreタグ内のテキストにこの記号列が大量に登場する、ということになりますので。

とりあえず一段落

あとは記事を見ながら間違っている表記を修正するなりCSSを調整するなりすればいいと思います。

特にSyntaxHighlighterに渡す形式をとりあえずcppとしているので個々に直す必要があると思います。

普通の記事ではなく技術系の記事を書いていたが為に起こったいろいろな置換でした・・・。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

この記事のトラックバック用URL