Showing posts with label Blogger. Show all posts
Showing posts with label Blogger. Show all posts

May 18, 2009

Bloggerへの移行を完了しました

Movable TypeからBloggerへの移行を開始して約三週間、ようやくすべてのエントリーを移行し終わりました。一日50件ずつですから、18,000件もあれば一年かかってしまう計算です。mt2bloggerの実用性は限定的ですね。

早いとこGoogleにインデックスしてもらうために、Google ウェブマスター ツールにサイトマップを登録してみました。

Bloggerでは、以下のようにフィードURLにパラメータを与えると、投稿日順に500件ずつAtomフィードを取り出すことができます。

  • http://hoge.blogspot.com/feeds/posts/default?orderby=published&max-results=500&redirect=false
  • http://hoge.blogspot.com/feeds/posts/default?orderby=published&max-results=500&start-index=501&redirect=false
  • http://hoge.blogspot.com/feeds/posts/default?orderby=published&max-results=500&start-index=1001&redirect=false
  • ...

なのでこれを必要なだけサイトマップとして登録してやれば、すべてのエントリをクロール対象として登録することができます。

Apr 28, 2009

Bloggerへの移行を開始しました

Bloggerへの移行を開始しました。旧URL (http://as-is.net/blog/) にアクセスするとこのブログにリダイレクトされるはずです。

「開始しましたって?」と疑問に思われるかもしれません。実は面倒くさいことに巻き込まれています。

基本的には下の記事で書いたmt2bloggerを使って移行します。

Ogawa::Buzz: MTからBloggerへの移行についての覚え書き(2)

が。

スパムブログ対策のため、Blogger Data APIはスロットリングされており、一日あたり50件までしかポストできません。しかもこの制限に2回引っかかるとアカウントがロックされます。ロックされてもWeb UI経由ならCAPTCHAコードを入力することでポストできます(そうじゃないとこの記事自体ポストできませんよね)。

「ロック解除の確認をリクエスト」というところからリクエストすれば2営業日くらいで解除されます。一旦解除されれば、それ以降アカウントロックされることはなくなりますが、一日あたり50件という制限は残ります。残りのすべてのエントリをBloggerに移行するにはひと月近くかかることになります。

そういうわけで気長に移行するつもりです。

Apr 17, 2009

MTからBloggerへの移行についての覚え書き(2)

Ogawa::Buzz: MTからBloggerへの移行についての覚え書き(1)の続き。

Blogger Data APIを使ってMTからBloggerにデータを移行することもできます。

ひとまず、Blogger Data APIを使った簡単な移行ツールをPerlで書いてみました。

mt2blogger - Google Code

以下のように実行します。

$ ./mt2blogger --blog_id=1 --username=foo@gmail.com --password=passwd \
  --postURI=http://www.blogger.com/feeds/<blogger_blog_id>/posts/default

postURIに指定するのは、Bloggerブログのヘッダの<link rel="service.post">に書いてあるURLです。

このスクリプトを実行すると、公開状態のMTエントリをBloggerに一件ずつポストした上で、各MTエントリのkeywordsフィールドにポストされたエントリのEditURIを格納します(keywordsフィールドに何か格納されていた場合上書きします)。EditURIは下のような形式になっているはずです。

http://www.blogger.com/feeds/<blogger_blog_id>/posts/default/<blogger_post_id>

このEditURIを使うことで、MTエントリとBloggerポストの間のリンケージを実現できます。例えば、下のような簡単なプログラムで移動前後のURLを表示できます。

#!/usr/bin/perl -w
use strict;
use warnings;
use lib qw( lib extlib );

use MT;
my $mt      = MT->new;
my $blog_id = 1;

use MT::Entry;
my $iter = MT::Entry->load_iter(
    {
        blog_id => $blog_id,
        status  => MT::Entry::RELEASE(),
    },
    {
        sort      => 'authored_on',
        direction => 'ascend',
    }
);

use LWP::Simple;
use XML::Atom::Entry;
while ( my $entry = $iter->() ) {
    my $editURI = $entry->keywords or next;
    my $content = get($editURI);
    my $gentry  = XML::Atom::Entry->new( Stream => \$content );
    my @link =
      grep { $_->rel eq 'alternate' && $_->type eq 'text/html' } $gentry->link;
    print $entry->permalink . ' -> ' . $link[0]->href . "\n";
}

1;

いいじゃん、できるじゃんと言いたいところですが、現状のBlogger Data APIは完全なものではありません。コメントを追加するAPIは存在するのですが、生成されたコメントのオーナーがAPIのauthenticated userになってしまいます。mt2bloggerでコメントの移行を実装していないのはそのためです。この点に関してはいずれAPIが修正されるのを待って、実装しようと思っています。

MTからBloggerへの移行についての覚え書き(1)

MTからBloggerにデータを移行する方法はおおまかに言って2つあります。一つは「設定」→「基本」→「ブログツール」の「ブログをインポート」を使う方法、もう一つは言わずもがなですが、Blogger Data APIを使う方法です。この覚え書きでは前者について説明します。

何らかの方法でMTデータをBloggerのインポートファイル形式(Atomフィード形式)で書き出しておき、「設定」→「基本」→「ブログツール」の「ブログをインポート」でインポートすれば、MTからBloggerにデータを移行できます。MTのエクスポートファイルをBloggerのインポートファイルに変換するPythonスクリプトもあります。

google-blog-converters-appengine - Google Code

ただし、このスクリプトはまだまだ品質が低いです。多言語の取り扱いが不完全、コメントデータがインポートできない、すべてのエントリのフォーマッタとしてconvert_breaksを使うことを前提にしている、などの問題があります。コメントデータを無視して良いなら、わざわざこのツールを使わなくてもMTのインデックステンプレートとして以下のものを使っても同じ効果が得られます。

<?xml version="1.0" encoding="<$mt:PublishCharset$>"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title><$mt:BlogName remove_html="1" encode_xml="1"$></title>
    <link rel="alternate" type="text/html" href="<$mt:BlogURL encode_xml="1"$>" />
    <link rel="self" type="application/atom+xml" href="<$mt:Link template="feed_recent"$>" />
    <id>tag:<$mt:BlogHost exclude_port="1" encode_xml="1"$>,<$mt:TemplateCreatedOn format="%Y-%m-%d"$>:<$mt:BlogRelativeURL encode_xml="1"$>/<$mt:BlogID$></id>
    <updated><mt:Entries lastn="1"><$mt:EntryModifiedDate utc="1" format="%Y-%m-%dT%H:%M:%SZ"$></mt:Entries></updated>
    <mt:If tag="BlogDescription"><subtitle><$mt:BlogDescription remove_html="1" encode_xml="1"$></subtitle></mt:If>
    <generator>Blogger</generator>
<mt:Entries lastn="2000">
<entry>
    <title><$mt:EntryTitle remove_html="1" encode_xml="1"$></title>
    <link rel="alternate" type="text/html" href="<$mt:EntryPermalink encode_xml="1"$>" />
    <id><$mt:EntryAtomID$></id>
    <published><$mt:EntryDate utc="1" format="%Y-%m-%dT%H:%M:%SZ"$></published>
    <updated><$mt:EntryModifiedDate utc="1" format="%Y-%m-%dT%H:%M:%SZ"$></updated>
    <author>
        <name><$mt:EntryAuthorDisplayName encode_xml="1"$></name>
        <mt:If tag="EntryAuthorURL"><uri><$mt:EntryAuthorURL encode_xml="1"$></uri></mt:If>
    </author>
    <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/blogger/2008/kind#post" />
    <mt:EntryCategories><category term="<$mt:CategoryLabel encode_xml="1"$>" scheme="http://www.blogger.com/atom/ns#" /></mt:EntryCategories>
    <mt:EntryIfTagged><mt:EntryTags><category term="<$mt:TagName normalize="1" encode_xml="1"$>" scheme="http://www.blogger.com/atom/ns#" /></mt:EntryTags></mt:EntryIfTagged>
    <content type="html" xml:lang="<$mt:BlogLanguage ietf="1"$>" xml:base="<$mt:BlogURL encode_xml="1"$>"><$mt:EntryBody encode_xml="1"$><$mt:EntryMore encode_xml="1"$></content>
</entry>
</mt:Entries>
</feed>

この方法には致命的な問題があります。それは(まとめてインポートしてしまうので)後からMTの元のエントリとBloggerのエントリを対応づける方法がなくなってしまうことです。古いURLから新しいURLへリダイレクトすることができませんし、後からコメントをインポートする方法が見つかったとしても、どのBloggerのエントリに対応づければよいのか分からなくなってしまいます。個人的にはお勧めできません。

Apr 15, 2009

Feed Redirection機能を試す

Google BloggerのFeed Redirectionは、フィードURLへのアクセスを指定したURLにリダイレクトできる機能です。

Feed Redirection - Blogger Help

でもちょっと考えると分かるんですが、リダイレクト先をFeedBurner URLにしておき、FeedBurner側では元のフィードURLを指すようにしておくと、ループしますよね。

どうなるんでしょうね。エントリをポストしてもFeedBurnerフィードは更新されないのでしょうか、無限増殖するのでしょうか。あるいは特定のUserAgentからアクセスした時だけリダイレクトされずに中身をGETできるようになっていて、正常に更新されるのでしょうか。

このエントリが正しく見られたとすれば、正常に更新されているということになります。

追記: 正常に更新されているようですね。ただ、Google Readerの更新が超遅いです。なんで?

Apr 14, 2009

Line Breaksの取り扱いに悩む

Google Bloggerの問題の一つは改行の取り扱い。

How are line breaks treated? - Blogger Help

「設定」→「フォーマット設定」→「改行の変換」で改行を<br />に展開できるかどうか制御できます。ここで問題があります。

  • 変換規則が貧弱。Movable Typeのconvert_breaksが提供しているフォーマット規則よりかなり貧弱です。例えば、MTでは<pre>〜</pre>内の改行を変換しないなどといった除外規則がありますし、改行文字が2文字続くと直前の文を<p>〜</p>で囲むなどといった比較的インテリジェントな処理規則もあります。それに比べて、Google Bloggerの「改行を変換」はかなりnaiiveです。
  • 改行の変換の設定がグローバル。つまり、エントリごとに変換するかどうかを制御できません。言い換えると、MTから持ってくるデータは「改行を変換しない」、Bloggerで書くエントリは「改行を変換する」といった使い分けはできません。

平たく言うと、2つのアプローチがあります。

  • 改行を変換する。MTから持ってくるデータは正常にフォーマットされませんが、諦めることになります。
  • 改行を変換しない。その代わり、MTから持ってくるデータは、convert_breaksフォーマッタでフォーマット(他のフォーマッタを使っている場合にはそのフォーマッタでフォーマット)してからインポートし、Google Bloggerでエントリを書くときに手でマークアップすることになります。後者の作業は致命的に煩雑ですが、適当なアプリケーションを使ってエントリを書けば済む問題でもあります。

というわけで、後者のアプローチを採るのが私にとっては正着でしょう。

Apr 13, 2009

Hatena Starの設置

とりあえずHatena Starを設置してみました。

テンプレートに簡単なJavaScriptを書くだけですが、Google Bloggerに特有の事情があります。それはテンプレートには正しくHTMLしか書けないということです。このため、テンプレートにJavaScriptのコードを普通に書くと「'」が「&quote;」に自動的に変換されてしまったりします。ものすごく読みにくくなります。

そういうわけで、<![CDATA[...]]>でコード部分を囲んでやるのがコツ。

こんな感じですね。

<script type="text/javascript" src="http://s.hatena.ne.jp/js/HatenaStar.js"></script>
<script type="text/javascript">
//<![CDATA[
Hatena.Star.Token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
Hatena.Star.SiteConfig = {
 entryNodes: {
   'div.post': {
     uri: 'h3 a',
     title: 'h3',
     container: 'h3'
   }
 }
};
//]]>
</script>

Movable TypeからGoogle Bloggerへの移行をこっそり目指すブログ、始めました。

こっそりですが、Movable TypeからGoogle Bloggerへの移行を目論んでいます。ここのところレンタルサーバの信頼性の低さに苦労させられていて、それならばいっそreliableでpersistentなストレージとしてBloggerを使ってしまえと思ったからです。いろいろあって連休明けくらいまでに移行を完了する、もしくは移行を諦める、予定です。

私のブログのMTの記事を楽しみにされている読者がいることは十分理解しています。MTのユーザを辞めるわけではないので今後もプラグインなどの記事も書くつもりです。さしあたっては、MTからBloggerへのtransparentな移行を実現するためのツールをどんどん作っては公開していく予定です。

ちなみに私は、MTやWordpressがユーザをロックインしてしまうことを結構問題視しています。

こうしたAll-in-oneシステムでは、ユーザインタフェース、バックエンドのデータストア、アクセスサーバなどの構成要素の一部に機能や性能や信頼性上の問題があったとしても、それぞれを独立の問題として解決することができません。例えば、アクセス数が異常に増加したとき、必要なのはアクセスサーバの性能向上であって、データストアに投資するのは無駄です。また、気の利いたユーザインタフェースが使いたいだけなのに、データストアが共有できないのなら一方のシステムから他方のシステムに移行しなくてはなりません。

Google(や他の企業)が信頼性があって高速なデータストアやCDNを提供するのであれば、そうしたインフラを有効に使ったブログシステム・CMSとしてMTを再設計するのが今後の方向性かなと思っています。もちろん、AppEngine上にMTを移植するというstraightforwardな解もありだと思いますけどね。

Jan 8, 2007

Google Bloggerで独自ドメインブログがより簡単に

何やらGoogle Bloggerで、(従来のFTPを使った方法ではなく)DNSのCNAMEレコードを使って独自ドメインのブログを実現する機能が追加されたようだ。

Blogger ヘルプ : How do I use a custom domain name on my blog?

これはOgawa::Buzz: Gmail for your domainを試験利用中というエントリーで仄めかしておいた方法と同じだね。

例えば、独自ドメイン「domain.name」を取得しているものとする(厳密にはdomain.nameゾーンを自由に編集できるものとする)。このとき「http://blogger.domain.name/」というURLで(Bloggerの)ブログを公開したければ、まずDNSのdomain.nameゾーンに、

blogger  CNAME  ghs.google.com

というエントリーを加え、次にBloggerの管理画面で「設定 > 公開中」の設定を「カスタム ドメインで公開」するよう変更するだけでよい。あとはblogger.domain.nameへのリクエストは全部ghs.google.comがハンドルしてよきにはからってくれる。


率直に言うと、まだPyra Labsだった頃から提供されていた、「FTPを使ってファイルをBloggerサーバからユーザサーバにコピーすることで独自ドメインのブログを実現するよ」っていう方法は、ちょっとあり得ないくらい阿呆すぎた。このサービスを利用するためだけに、ユーザは、望みもしないのにサーバ上でFTPサーバを動作させなくてはならなかったし、そのログインアカウントをPyra/Googleに教える必要があった。

それに比べると今回提供されたCNAMEレコードを使う方法はずっとスマートで、DNSのレコード以外のすべてをGoogleにホストさせてしまえる。とても楽ちんだ。

欠点があるとすれば、この方法ではすでに利用しているURLのサブディレクトリにブログを配することができないことと、CNAMEレコードの編集が幾分難しいこと。前者はどうしようもないが、後者はGoogle Apps for your domainあたりの流れをウォッチしている分には、GoogleがeNom registrarになるかそこそこ大手のeNom registrarと協業するか(買うか)して、もう少しtransparentなサービスとして提供してくれるようになる可能性はあると思っている。

で、前も書いたけど、これと同じ方法ははてなダイアリーや他のブログサービスでも実現できるはず。なんでやらないんだろうね。

Aug 16, 2006

Blogger Data API

Google Blogger(Blogger: Create your Blog Now -- FREE)が新しくなっていたっぽいので、作り直してみた。

smallCaps

レイアウトをDrag & Dropで変更できるようになったとか、アクセス制御やラベル(タグ)をサポートしたとか、フィード配信でいろいろできるようになったとか、あたりが見た目の変更点。少し使った限りでは、(1) 各ページにあるべきブログのトップページへのリンクがない超分かりにくい、(2) アップロードした画像ファイルを削除する方法がない(ような気がする、かなりそんな気がする)、(3) 日本語ラベルが正しく機能しない、(4) テンプレートを切り替えたときにレイアウトマネージャが不穏な動きをする、というあたりが気になった。

なのだが、やはり目玉は、Google Calendarと同様、Google data API (GData)に対応したBlogger Data APIだ。

Ogawa::Buzz: Google Calendar data API

やっぱこれだよね!

ざっくり見た限り、commentsを操作するAPIについて言及していないようだ。commentsにもpostsと同様にGData feedが定義されているので、同じように操作できるのかもしれない。

このあたりがクリアになりかつ時間があれば、Movable Typeのダンプ形式からBloggerにコンバートするツールを作ってみようかな。

簡単なテストコード。Ogawa::Buzz: Google Calendar data APIとの違いは、ClientLogin Requestのservice名を「blogger」するっていうだけ。

#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use Encode;
use constant GAUTH_URL => 'https://www.google.com/accounts/ClientLogin';
 
my $email = 'user@gmail.com';
my $passwd = 'passwd';
my $feed_url = 'http://beta.blogger.com/feeds/###################/posts/full';
 
my $entry = <<'ENTRY';
<entry xmlns='http://www.w3.org/2005/Atom'>
  <published>2006-06-09T10:27:00.000-07:00</published>
  <updated>2006-06-09T10:31:55.120-07:00</updated>
  <title type='text'>Marriage!</title>
  <content type='xhtml'>
    <div xmlns="http://www.w3.org/1999/xhtml">
      <p>Mr. Darcy has <em>proposed marriage</em> to me!</p>
      <p>He is the last man on earth I would ever desire to marry.</p>
      <p>Whatever shall I do?</p>
    </div>
  </content>
  <author>
    <name>Elizabeth Bennet</name>
    <email>liz@gmail.com</email>
  </author>
</entry>
ENTRY
Encode::_utf8_off($entry);
 
my $ua = LWP::UserAgent->new();
my $auth = $ua->post(GAUTH_URL, {
    Email => $email,
    Passwd => $passwd,
    source => 'companyName-applicationName-versionID',
    service => 'blogger'
});
my($auth_token) = $auth->content =~ m/Auth=(.+)/;
 
my $req = HTTP::Request->new(POST => $feed_url);
$req->header('Authorization', 'GoogleLogin auth=' . $auth_token);
$req->content_type('application/atom+xml');
$req->content_length(length $entry);
$req->content($entry);
my $res = $ua->request($req);
print $res->status_line . "\n";
 
if ($res->is_redirect && $res->header('Location')) {
    $req->uri($res->header('Location'));
    print $ua->request($req)->status_line . "\n";
}