MovableType5.04からWordPress3.1.2へ移行

8年お世話になったMovableType(以下MT)からWordpress(以下WP)へ移行した。

パーマリンクをそのまま引き継ぐ形での移行方法を取る人が多いようだが、MTはVer.2から使っていて、旧記事を残したままパーマリンクを変更したりもしているので検索して出てくる方法では移行できない。今回は301リダイレクトで移行してみた。移行元と移行先はそれぞれ

  • MTでの旧ブログ:”http://mmt.silvermoon.jp/”
  • WPでの新ブログ:”http://mmt.silvermoon.jp/”
  • MTでの旧ブログ移動先”http://mmt.silvermoon.jp/old_blog”

手順は

  1. MT管理画面で”記事のバックアップ”を行う。
  2. “http://mmt.silvermoon.jp/” で表示していたMTの記事を ”http://mmt.silvermoon.jp/old_blog” に移動。(失敗時にすぐ元に戻せるように再構築はせず、ディレクトリのコピーもしくはWebサーバの設定変更のみ。)
  3. http://mmt.silvermoon.jp/ でWPをセットアップ。サイトのアドレス (URL)、パーマリンク等を設定した後インポート。

とごくごく普通に移行。『Movable Type から WordPress への移行 – WordPress Codex 日本語版』の工程2まで、パーマリンク云々の前まで行う。

ここまで勢い良く進んでからruby 1.8.7で移行ツールを作成。まずはMySQL上のWordpressのDBの中身を眺めてみる。どうやら”wp_posts”テーブルの”guid”カラムに移行後のアドレスが入っているっぽい。これを利用して301リダイレクトの設定を自動生成してみる。

いじってみてわかったが、ツールを動かす前にWPでの過去記事の編集はしないこと。編集をすると自動セーブで大量に同じタイトルのレコードが生成されるらしい。また、”guid”は最初に設定された条件で生成されるらしく、途中でサイトURL、パーマリンクを変更しても変更されない(細かい仕様は知らないが)ため、気が変わった場合はDBごとまっさらにしてインストールしなおす方が良いと思う。

まずは旧ブログの記事一覧を取得する。サーバ内のMTトップディレクトリへのパスを”/var/ほげほげ”とすると

find /var/ほげほげ -name "*.html" > posts.list

これでMTの全記事が”posts.list”に入る。このうち”index.html”なものは、カテゴリーor月別アーカイブなので除外。

grep -v index.html posts.list | grep -v mt-static > postsonly.list

これでindex.html以外のリストができたはず。最後に適当なエディタで開き”archives.html”やMTの”readme.html”、テーマ関連ファイル”~themes/ほげほげ”等を削除。

スクリプトの処理内容は下記の通り。

  1. ディレクトリ名を元に各記事のMT公開URLを再構成
  2. 各MT記事へアクセスして記事名と公開日時を取得
  3. 記事名と公開日時を元にwp_postsからguidを取得
  4. guid(WPでのURL)へアクセスして記事名を取得、旧記事名と比較して正しければRedirect文を作成

下記のソースコードをmt2wp.rbとして保存。

※追記 Ruby 1.8.7と書くのを忘れてた(苦笑)

require 'rubygems'
require 'mechanize'
require "mysql"
require "kconv"

agent = Mechanize.new
agentComp = Mechanize.new
my = Mysql.init
my.options(Mysql::SET_CHARSET_NAME,'utf8')
# WordPressのDB情報(wp-config.phpと同じ)を書く
my.connect("localhost", "WordpressのDB名", "DBのユーザー名", "パスワード")

# ブログの名称
blogName = "MMT's Blog"
# ↓はタイトルが「記事名 - ブログ名」の場合。例えば「ブログ名 : 記事名」
# だった場合は『(blogName + " : ")』に変更。
reBlogName = Regexp.new(Regexp.quote(" - " + blogName))

# サーバー内のMovableTypeトップディレクトリへのパス
dirName = "/var/ほげほげ"
reDirName = Regexp.new(Regexp.quote(dirName))

# 新しいWordpressのURL
newURL = "http://mmt.silvermoon.jp"
re = Regexp.new(Regexp.quote(newURL))

# 旧MovableTypeのURL
oldBlog = "http://mmt.silvermoon.jp/old_blog"

while line = gets
        begin
                # ファイルへのパスからURLへ変換
                agent.get(line.sub(reDirName, oldBlog))
                rescue Timeout::Error
                        puts " Timeout::Error with " + line.sub(reDirName, oldBlog)
                rescue Mechanize::ResponseCodeError => e
                case e.response_code
                when "404"
                        puts " 404 Notfound with " + line.sub(reDirName, oldBlog)
                else
                        puts " HTTP Error:" + e.response_code + " with " + line.sub(reDirName, oldBlog)
                end
        end

        # 正しく書くならURLがおかしくてアクセス不能な場合はここ以下をスキップすべきであるが実害はないし面倒くさいのでやらない。
        # httpファイルのtitleから記事名取得
        s = agent.page.title.to_s.strip
        # 「記事名 - ブログ名」が取得されるはずなので、記事名のみに。
        s = s.sub(reBlogName, "")

        # RSSフィールドから公開日時を取得
        # 各環境で若干変わるはずなので、旧ブログのソースを見て下記の「dc:date=」などを適宜変更
        elem =  agent.page.root.inner_html.scan(/dc:date=\"\d{4}-\d{1,2}-\d{1,2}T\d{1,2}:\d{1,2}:\d{1,2}\+09:00\"/).to_s()
        d = elem.scan(/\d{4}-\d{1,2}-\d{1,2}/).to_s() + " " + elem.scan(/\d{1,2}:\d{1,2}:\d{1,2}/).to_s()

#       puts "Search with " + "\t" + agent.page.title.to_s.strip + "\t" + s.strip + "\t" + d # Mysql検索パラメータ表示(デバッグ用,挙動がおかしい場合はコメントアウトして確認)
        # DB検索
        res = my.query("select guid from wp_posts where post_date = \'#{d}\' and post_title like \'%#{Mysql.quote s.strip}\%'")

#       puts "#{res.num_rows}" # 検索結果の数表示(デバッグ用)
        case res.num_rows
        when 0
                # 一意な記事が無いということなので、検索パラメータがおかしいか記事のインポートに失敗しているはず
                puts "No post name of:" + s + "\t" + "No post ID" + "\t" + line.strip + "\t" + "No URL on wordpress"
        else
                if res.num_rows >= 2
                        #同名、同時刻の記事が二つ以上インポートされてる。もしくはバグによる検索ミス
                        puts "Result # " + "#{res.num_rows}" + ": Search Err"# 検索結果の数表示
                end
                # 念の為、移行先のURLへアクセスできるか確認。必要なければputs "Redirect~"行意外をコメントアウト
                res.each do |row|
                        begin
                                agentComp.get(row[0].sub(re, newURL))
                                rescue Timeout::Error
                                        puts " Timeout::Error " + row[0].sub(re, newURL)
                                rescue Mechanize::ResponseCodeError => e
                                        case e.response_code
                                        when "404"
                                                puts " 404 Notfound " + row[0].sub(re, newURL)
                                        else
                                                puts " HTTP Error:" + e.response_code + " " + row[0].sub(re, newURL)
                                end
                        end
                        # 移行先の記事名と元記事名の比較
                        comp = agentComp.page.title.to_s.strip.split(" | ")
                        if comp[0].strip.toutf8 == s.strip.toutf8
                            # 結果出力
                            # 301リダイレクトにしたくないときは下記の"permanent"を削除
                            puts "Redirect permanent " + line.strip.to_s().sub(reDirName, "") + " " + row[0]
                        else
                            puts "URL is invalid " + row[0] + ": title :  " + s.strip.toutf8
                        end

                end
        end
end

必要箇所(DB情報、blogName、reBlogName、newURL、oldBlog)を変更して実行。

ruby mt2wp.rb postonly.list

これで処理結果が出てくる。エラーを潰してきれいな結果のみになったら

ruby mt2wp.rb postsonly.list > Redirect.list

これで”Redirect.list”にmod_alias形式のリストが出来るので中身を確認。

wc -l postsonly.list Redirect.list

正しくインポートされていれば行数が同じになるはず。”.htaccess”に書くなりなんなりして終了。

※mt2wp.rbはGPLとする。

iPad雑感

週末、たっぷりとはいえないまでもいじり回したiPad。
でかいiPod touchとか思っていたらとんでもない、大スクリーン用にかなり細かく調整したと見え非常に使いやすい。ノートPCの出番はほとんどなくなった。しかも速い。仕事用のMacBookより確実に速い。SSD積めば互角になるかな?そのぐらい速い。開発用途やFlash使いたいとかでも無い限り、ほとんどiPadで事足りる。コピペがちょっとつらいけどBlog書きも問題無く出来る。

既に大量のレポートが上がってるので、下記のCDiPさんのまとめで見てもらえば良いとして、他の気づいたことを。
iPhone/iPad D’s Focus【20100404版】〜iPad発売記念リンクまとめ | 覚醒する?Club D’s iPad&iPhone 3GS – CDiP 1.02

まず産経新聞アプリが神。

DSCF0375.JPG

権利的に問題の無さそうなテレビ欄を撮ってみたが、この解像度。普通に読める(笑)
ちなみにこれはiPadアプリではなく、iPhoneアプリ。だからメニューとかは文字がギザギザになっちゃうのだが、新聞本体は高解像度になってる。産経新聞もYappaも想定してなかったんだろうなぁ。多分WebKitとかQuartzとかそこいらのAPIを叩くと自動的に高解像度になっちゃうってことなんだろうけど、おかげでかなり快適に産経新聞が読める。無料で。

使い始めて困ったのがGoogleカレンダーとの同期。Google SyncがiPadをmobile deviceとして扱ってくれないので、Google Syncではカレンダー一個しかsync出来ない。CalDAV使えば5個まで同期できるのだが、iPad上で何個もコピペするのは面倒。しかもiPadでGoogleカレンダーにアクセスするとiPhone用ページが表示されちゃってカレンダーIDを参照できないので、Mac/PCからアクセスして、メールか何かでiPadに送るしかない。面倒すぎてまだやってない。
“iPhone CalDAV”Google検索結果

2010/4/7追記:本日確認したところ、ちゃんとiPadもGoogle syncで複数カレンダー対応するようになってた。さすがGoogle仕事が速い(笑)

眠くなってきたので以下箇条書き。

  • Bluetoothキーボードが使える。
  • スクリーンが異様に反射するので屋外に持っていくならノングレアフィルムが欲しい。
  • 片手で持ち続けてると結構重い。
  • 仰向けで寝っ転がると使いづらい。
  • 爪が伸びてるとタイプしにくい。
  • カナの10キー入力が無い。10キーでなくても良いが、”あいうえお”入力は日本の年寄り子供には重要なので、日本発売前には付けるべき。
  • iBooksでは英英辞書がポップアップする。古典の無料本がたくさんあるので、多読用教材としても使える。(ちなみにKindleアプリには辞書機能は付いてない。ハードウェアとしてのKindleには付いている。)
  • ビデオは字幕も出せるらしい。

等々。完璧ではないが、改善されていくだろうことはiPhoneの例を考えても明らかなので、あまり気にしてはいない。

もしかしたら現状最大の問題点は、二歳の娘が虎視眈々とiPadを狙っていることかもしれない(笑)

無料iPadアプリ備忘録

発売2日前に迫ったiPad。
厳しい情報統制で有名なAppleだが、ここへ来て自らなぜか発売前にAppストアをオープンした。せっかく開けてくれたのだからとのぞいてみれば、結構興味深いラインナップが見えて来た。

土曜日購入したらインストールしてみようと思う無料Appをピックアップ。あくまでも自家用ではあるが、誰かの役に立つことがあればということでBlog化してみる。

ABC Player for iPad
これは結構すごい。LOSTをはじめとする現在放映中のTV番組を過去話含めiPadでストリーミング視聴できる。
米国ではABC含め三大ネットワークのCBS、NBC、それに順ずるFox等各ネットワークのWebサイトで、自らTV番組をHD配信しているのだが、当然のようにFlashビューアーでの配信がなされているためiPadでは視聴できない。その専用アプリを発売日にぶつけてくるとはさすがJobsが大株主のDisneyグループABC。このページにデモムービーがあるので見てみるヨロシ。
iTune App Storeへのリンク

Netflix for iPad
次は会員数1000万人以上を要するネット宅配ビデオレンタルNetflix。最近はPCだけでなくXBoxやPS3向けのストリーミング式レンタルも展開中。おかげで店舗型の古き良きビデオレンタル屋が続々廃業中。ちなみに本社はAppleにも近いロスガトス。契約は必要だがiPadで直接ストリーミングが受けられるそうだ。公式ページが無いのでAppストアの写真でどうぞ。
iTune App Storeへのリンク

USA TODAY for iPhone(iPadページはまだ無い)
米国の全国紙USA TODAYのiPadアプリ。App Storeの写真を見る限り、新聞のレイアウトそのものではないようだ。Webページが元になったレイアウトと思われる。産経新聞Appのようにコンテンツダウンロードすればオフラインでも読めるらしい。
iTune App Storeへのリンク

THE WALL STREET JOURNAL for iPad
言わずと知れたWall Street Journal。どうやら無料アプリでは一部しか読めないようだ。iPadプランという購読契約ができるようで、契約しないと全部は読めないらしい。
iTune App Storeへのリンク

NYT Editors’ Choice
The New York Timesの限定記事版iPad App。これは無料らしい。有料の全記事版Appはもうちょっとたってから登場するという話。
iTune App Storeへのリンク

BBC News for iPad
英国の国営放送局BBCニュース。これもコンテンツダウンロードすればオフラインで読め、1分間ビデオ等も見れるらしい。スペイン語、ロシア語、アラビア語記事も読めるそうだ。
iTune App Storeへのリンク

AP News
AP通信のApp。地図上で見たい地域を選んでニュースを閲覧できるという世界的な通信社らしいApp。膨大な写真、ビデオライブラリから厳選された素材も見れる。パーソナライズ可能。
iTune App Storeへのリンク

Toy Story Read-Along
Disneyの大量Appリリースの一中のお試し版的存在。無料なのでお子様がいる方は是非。
有料のToy Story 2 Read-Alongも同時リリース。
iTune App Storeへのリンク

Craigsphone – craigslist for iPad
友達も電化製品も車も家も仕事もなんでも見つかる巨大ローカル情報交換掲示板craigslistのApp。
本家のWebページはテキストベースのそっけない構成なんだけど、このアプリは空き部屋情報を地図上にプロットしてくれたりと本家より高機能な気配。
iTune App Storeへのリンク

※4/2 kindle発表を記念して電子書籍系を追記

Kindle for iPad
iPadがカラー版Kindleに!
独禁法の関係で、Appleはkindleを排除できないという噂が本当だったのか、Appleの懐が意外に広かったのか、真相は知る由も無いがとにかく来た。AmazonとしてはiPadにも出しておくのが正解。これでAmazonの市場支配率は磐石のものとなるだろう。同じ値段ならAmazonで買っておけば、PC、Mac、Kindle、iPhone、iPadで同じ本が読めて、”しおり”も共有できる。となるとApple、Barnes & Noble、Sonyの三社は価格、もしくは使い勝手で攻めなければならなくなり、結果として米国の電子出版が相当進化するだろう。
個人的な予測だと、書籍、漫画はAmazon、雑誌系はiPad App(iBooksではなく)が主戦場になるんじゃないかと思ってるが、はたしてどうなることか。この辺は書き出したらたくさん書ける気がするが今日のところはこの辺で(笑)
iTune App Storeへのリンク

iBooks
Appleのオンラインブックストア。Winnie-the-Pooh (クマのプーさん)がおまけについてくるそうな。※北米限定
Barnes & NobleのnookもiPad Appを出してくるみたいだし、Appleがそれを拒否できないとしたら相当ツライ戦いになると思う。価格で攻めるなり、更なる付加価値で攻めるなり、次の一手が見物。
ついでに言えばSonyもせっかく良い方向に向かえたかと思った矢先にこの難局。体質的に相当無理だとは思うけど、今すぐiPad Appを出すしかないと思う。もしくはオンライン書店の事業は諦めてハード屋に戻るか、二つに一つ、ここが正念場だと思う。
iTune App Storeへのリンク

Marvel Comics for iPad
Disney傘下Marvel Comics社のコミックビューアー。アプリ中でコミックを購入できる。なんでiBooksの中で展開しないのかと思ったが、このビデオを見るとUIをコミック向けに作りこんだような感じか?悪くないと思う。

iTune App Storeへのリンク

Sunny Bowl in Mountain View

文体すら忘れたほどすっかり筆不精のmmtでございます。
既に何回目かわからないけどリハビリがてら軽い記事でも(笑)

数ヶ月前にMountain View方面を通りかかった際に発見したレストラン、Sunny Bowl。

ここは非常に素晴らしい店。何が素晴らしいかというと、ただ美味いだけではなく、米国で探すのが困難な”さっぱり”食が食べられるということ。

DSCF0098.JPG

かなり大胆にアレンジされたビビンバで、上にはナムル主体ではなく主に生野菜が乗ってくる。感覚としては一時期流行ったサラダうどんのような。

DSCF0101.JPG

餃子。これが非常に普通の日本の焼き餃子(笑)

DSCF0103.JPG

チヂミ。結構美味しい。

DSCF0107.JPG

Tuna Sashimiを俯瞰で。元は韓国料理だという証拠かキムチが付いてくる。
Tuna Sashimiというよりもハワイのポキ。結構美味しかった。

DSCF0108.JPG

Beef大盛り。大盛りを頼むと、メインの具だけ倍量になる。

DSCF0104.JPG

Tuna Sashimiアップ。

BeefとTuna Sashimi以外の具は以下の通り。4、5、8あたりでベジタリアンも安心(笑)

  Topping
Regular
Large
1 Beef $6.41 Add $0.92
2 Chicken $6.41 Add $0.92
3 Shrimp & Fish Cake $7.33 Add $1.84
4 Tofu & Broccoli $5.50 Add $0.92
5 Asparagus (on #4) $6.41 Add $0.92
6 Egg Batter Fish $7.33 Add $1.84
7 Tuna Sashimi $8.24 Add $2.75
8 Seaweed Salad $6.41 Add $0.92

さっぱりメシが食べたくなった人にお薦めです。量は結構あるけど(苦笑)

Sunny Bowl
1477 Plymouth Street #C, Mountain View, CA 94043
Phone: 650-625-0361

Open Hour
Mon – Fri: 11AM – 9PM
Sat: 12PM – 9PM
Sunday: Close

http://www.sunnybowl.com/

http://www.yelp.com/biz/sunny-bowl-mountain-view

絵文字が北米版iPhoneで使えるようになった!

iPhoneOS3.0ではMobileMeでiPhoneを探す機能や、ボイスメモで録音したデータをメール添付できること等々非常に便利になった。待望のコピー&ペーストは、実は写真もコピーできるので、アルバムで写真長押ししてコピーしてメール作成画面でペーストすれば複数枚の写真をいっぺんに送ることが出来るようにもなった。さらに地味な改良点ではあるが、海外iPhopneでも絵文字が使えるようになった。たいして使わないと思うが、使えないよりは使えた方が良い。Appleも今後は変な出し惜しみはしないでもらいたい(笑)
そういえばiPhoneを探す機能に、メッセージを表示または音を鳴らすという機能があるのだが、かなり大きなアラーム音付きでメッセージが送れるのでおもしろい。これはSMSじゃ無くてインターネット上で送ってるんだろうか?うちでは妻のiPhoneもMobileMeのアカウント共用してるので意外と常用しちゃうかも(笑)

 


WordPress theme: Kippis 1.15