XAMPP(LAMPP)にMovable Type 5(MT5)をインストール

Movable Type 5を触ってみたくなって、
XAMPP(LAMPP)にMovable Type 5(MT5)を
インストールしたので作業メモ。

個人ライセンスのダウンロードはこちらから

unzipで解凍後に、lamppのディレクトリにmv
インストール先は/opt/lampp/htdocs/mtとした。
$ unzip MT-5_01-ja.zip
$ mv MT-5.01-ja /opt/lampp/htdocs/mt
perlのPATHが/usr/bin/perlになっているので、
lamppのperl pathになるように一括置換
$ find . -name "*" -type f | xargs sed -i "s|/usr/bin/perl|/opt/lampp/bin/perl|g"
あとは、http://localhost/mtにブラウザアクセス。
指示にしたがってユーザなどを設定すればOK。

高速に動かしたい場合は別途mod_perlの設定等が必要。

参考:
MovableTypeをめっちゃ高速化する20の方法。

「フリー〈無料〉からお金を生みだす新戦略」を読了


フリー〜〈無料〉からお金を生みだす新戦略を読了しました。

出張中の飛行機移動中にずっと読んでました。
具体的な「フリー」に関連する事例をもとに書いているので、
分厚いけど一気に読めました。

特に、Yahoo!メールとGmailのフリー戦争のくだりは、興味深かったです。

最近のブログに対するアクセス解析

1月中旬くらいまで、アクセスが落ちました。
正月気分であまり検索されなかったのか、
記事がいまいちだったのかは不明。
最近は持ち直してきたので、一安心。

8月からブログを毎日更新している中で、
ネタを1つに絞ってそのジャンルで1位のブログになろう、と
意気込んで書きつづけましたが、あっさり9月くらいに断念して
いろいろなネタを書いてます。

で、いろんなネタを書いてみて、人気がある内容の傾向が
見えてきた気がするので、ざっくりまとめてみる。
こんな感じになりました。YUI3は面白いんだけどな。
日本ではjqueryがかなり人気のようです。

人気っていても、検索してコピペで動くコードを探しにきてる、
といった印象があります。
ここらへんを逆手にとって、サンプルコードをがんがん書いていこうかと
思う次第。

直近では、twitter系のコンテンツも人気、特に、OAuthまわりの
検索ワードが多いです。みんななにかTwitterをつかって開発
しているのかもしれません。

subversion から git に完全移行。Dropbox でバックアップ

自宅で開発しているときに、今までは以下のようにしていました。
  • subversionでコード管理
  • バックアップのために、リポジトリはレンタルサーバへ
  • こまめにコミットして、開発機とレンタルサーバで2重化
最近は、gitをよく使うようになったので、
githubを使ってコードのバックアップをとっていました。

githubは便利なんでいいんですが、容量が300Mまで(だったかな?)
という制限があったり、コードが公開されてしまうので、
全部のコードをgithubで管理するのは不可能だな、と思っていました。

というわけで、以下のようなフローに変更
  • バージョン管理はgitで行う。svnは使わない。(頭が混乱するから)
  • gitのリポジトリを、Dropbox上のディレクトリで行う
すごくシンプルになりました。
# Dropboxを公開設定にしないように気をつけるのと、
# パスワード系も生では保存しないように注意はしておくとして。

goobye, subversion.

Google が MapReduceの特許を取得したようです

GoogleがMapReduce特許を取得。Googleは用途についてコメントせず

記事の通り、Googleが特許をふりかざすことはないような気はしますが、
取得した目的が見えないと、一抹の不安が残ります。

中国関連でごたごたしているので、背景にあるのかもしれません。
完全に憶測ですが。

最近、家で趣味開発をしていますが、面白いサービスを作るには、
大量のデータを保持して、そこから新たな価値を生み出す、という
手法が王道だと思いはじめてきました。

例えば、本のレビューサイトを立ち上げたのでみんな書き込みヨロ、
ってしても、誰も書き込まないと思うのです。書き込む動機がないから。

自分である程度初期データをつっこむとして、量はたかが知れているので、
サイトのUIが斬新だったり、新しい切り口があったとしても、
世の中に伝搬して行くのはかなりの時間が要すると思います。

そこで、ネットにある情報を(著作権などに違反しない程度に)かき集めて、
今まで別の場所にあった情報をマッシュアップしたりすることにより、
付加価値をつけ、ユーザに見せる、という手法が簡単で手っ取り早いかな、と。

大量のデータを個人で扱うのには、現状の最良の選択肢が、
hadoopだと思っていたところのこのニュースだったので、
びびりました。 今後の続報にも注意しておこうと思います。

-----

大量のデータを集めて再加工しサービス化する、という手法に反する例が、
Twitterだと思ってます。
よくこんなシステム作ったもんだよな、と不思議に思います。
この話は、また別の機会に書きたいと思います。

分散KVS kumofs がリリースされました

分散Key-Valueストア「kumofs」を公開しました!

msgpackの作者が、分散Key-Valueストアライブラリを公開しました。

key-valueストアについては、こちらが参考になります。

kumofsの技術ドキュメントはこちら
気になる点は以下。
Set操作が失敗すると(ネットワーク障害などの理由で)、そのkeyに対応するvalueは不定になります。そのkeyは再度Setするか、Deleteするか、Getしないようにしてください。
Setに失敗したら、明示的にDeleteすべきかな?
でも、ネットワーク障害なら、Deleteも失敗する気がする。

一度、Set/Deleteが失敗してしまったら、そのKEYに対するデータが
不定であるかの確認をどうするかが問題だな。
別のプロセスなどが、Getした値が壊れていないことがわかるchecksum的な
ものをvalueにあらかじめいれておく、とか?
・Tokyo Cabinet >= 1.4.10
内部的にTCを使っているようです。
TCの知識が少ないので、まずはTCの勉強から、か。
kumofsは AMD Athlon64 X2 5000+ を搭載したサーバーを1台使って、1秒間に約5万回のGet操作を処理できます
早すぎワロタ。
kumoは、空に浮かぶを意味しています。雲は落ちないです。fsは、予想に反してfast storageの略です。
「雲は落ちないです」うまい。

あとは、保存済みKEYの一覧を取得する方法がどうにかして
実現できないものか、と思う次第。

KEY名の前方一致検索ができると完璧な感じ
どうにかして利用者側で満足できる方法がないか、を
現在考え中。

Google checkout で ハイチ募金完了

Google crisis response : ハイチの災害救援活動にご協力ください

この前は、Yahoo!ポイントで50ポイントほど募金しましたが、
Googleも募金を募集していたので、はじめてGoogle checkoutで
募金をしてみました。

Google checkoutの募金の場合、最低額が5ドルからだったので、
ちょっとためらってしまった。

はじめての利用だったので、
  • 住所の入力
  • カード番号の入力
の2つが必要だったが、特につまづかないで、簡単に募金できました。
Googleアカウントに紐付けられるようで、以後はログイン確認するだけで
簡単に決済が可能になります。

あ、1つ注意なのが、今回募金したunicefは、英語の住所しか受け付けていない
みたいなので、住所登録は日本語と英語の2つを登録しておきました。

住所情報がエラーだと、チェックアウトボタンを押せないUIになってました。
親切設計。

Paypalもいいけど、Google checkoutもいいなー。

jqueryでclass属性を追加するときの注意

jqueryで、属性を追加したい時は、以下の用に書きます。
$('').attr({href:"http://yahoo.jp/",target:"_new"}).html('ヤフー');

attr()でまとめて属性をつけるのが楽。
ただし、class属性をつけたいときは、
addClass()を使わないと、IEやSafariでは動かなくなるので、
注意が必要。
$('
').addClass("copyright").html('tanarky all rights reserved');
まったく知らなかったので、備忘録としてメモしておきます。

Base58について勉強 その2 ネタ元発見+他のBaseNについて

Base58について勉強+Encode::Base58コード解読
で、Base58のコードを解析したが、
ネタ元はどこかとTwitterで問い合わせたところ、
速攻で答えをいただきました。

http://twitter.com/akitada/statuses/8094771189
http://www.flickr.com/groups/api/discuss/72157616713786392/

ポイントは、
Base58 is like base62 [0-9a-zA-Z] with some characters removed to make it less confusing when printed. (namely 0, O, I, and l).
ですね。ショートURLなんで、手で入力されることを考えて、
見た目が似ている
数字のゼロと英語のオーを外したり、
同様に英語のアイとエルを外してます。

kellanタンの優しさに惚れた。

ついでに、BaseNも調べたので、リンクをぺたり
Base64
A–Z, a–z, 0–9 までの62文字と、記号2つ (+ , /) 、さらにパディング(余った部分を詰める)のための記号として = が用いられる
Base62
the characters AZ, az, and 09.
TPOにあわせて選択しましょう、ってことですね。
気をつかえる大人、カコイイ

Base58について勉強+Encode::Base58コード解読

最近流行りのショートURLサービスについて、
どういうロジックなのか興味をもっていたので、
探してみたところ、Base58という単語にいきつきました。

参考:
flic.kr で使われている base58 のデコードを行う javascript のコードCommentsAdd Star
Flickrの短縮URLをRubyで生成

要は、内部的にDBなどでデータを管理するときに、
IDとして数値を採番することはよくあると思うが、
それをもとに、IDの数値をそのまま文字列としてURLなどを作ると、
(ID=12345678901234567890だとする。長い。)

http://example.com/ID/12345678901234567890

と、長くなってしまう。
そこで、可逆化エンコードであるbase58を使うと、

http://example.com/ID/uE87b9NPNGu

と短く表現できる、ということのようです。
(アクセスが着たときに、文字列→数値への変換をサーバ側で行う)

動作確認やロジックを学ぶには、perlのEncode::Base58のソースを
読むのが一番わかりやすかった。(perl使いの自分には。)
miyagawa氏作成のコードです。使い方と動作確認コードは以下。
satoshi@debian:~/git/sample-codes/perl/base58$ cat test.pl
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

use Encode::Base58;

my $num = 12345678901234567890; # big number

warn "そのまま表示 :\t\t".         $num;
warn "base58 encode:\t\t".         encode_base58($num);
warn "base58 encode->decode:\t". decode_base58(encode_base58($num));
warn "ちゃんともどるか確認 :\t". decode_base58(encode_base58($num))/100000;
satoshi@debian:~/git/sample-codes/perl/base58$ perl test.pl
そのまま表示 :          1.23456789012346e+19 at test.pl line 11.
base58 encode:          uE87b9NPNGu at test.pl line 12.
base58 encode->decode:  1.23456789012346e+19 at test.pl line 13.
ちゃんともどるか確認 :  123456789012346 at test.pl line 14.
コードを読んでみて理解を深めてみた。

1. 短縮URLに用いる文字を定義する(@alpha)
2. その文字がいくつの数字を表すか決める
my %alpha = map { $_ => $i++ } @alpha;
3. encodeするときは、@alphaの定義されてる文字数で割り続けて、
   余りを文字列として表現する
while ($num > 0) {
    my $remain = $num % $base;
    $num = int($num / $base);
    $res = $alpha[$remain] . $res;
}
4. decodeするときは、1文字ずつ下位から取り出し、足し上げる
while (length $str > 0) {
    my $digit = chop $str;
    $decoded += $multi * $alpha{$digit};
    $multi   *= $base;
}

※ chopは下位から1文字ずつ取り出し、元の文字列を削る

@alphaの定義部分を増やせばもっと短くできそうだが、
flickrはこの定義みたいですね。なにか理由があるのか?
# "_"とか"."も入れてみたいと思ったり。

ロジックは勉強になったので、自分もこれからつかってみるぞ、と。

MeCabをインストールする on Debian lenny

使ってみたくなったので、開発機のDebian(lenny)にMeCabをインストールした。
$ sudo aptitude install mecab mecab-ipadic-utf8 mecab-jumandic-utf8 mecab-utils libmecab1
UTF8な環境で使いたい人は、
MeCabのデフォルトはeuc-jpなので、
***-utf8をインストールするのがポイント。
satoshi@debian:~$ mecab
すもももももももものうち
すもも  名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も      助詞,係助詞,*,*,*,*,も,モ,モ
もも    名詞,一般,*,*,*,*,もも,モモ,モモ
も      助詞,係助詞,*,*,*,*,も,モ,モ
もも    名詞,一般,*,*,*,*,もも,モモ,モモ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
うち    名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS
Perfect!

TODO:
- perlの環境を整える
- 辞書のカスタマイズ方法などを調査する
- Twitterの投稿をクロールしてコンテンツ解析する
- Google IMEの辞書とMeCabを融合できるか調査

AmazonのアフィリエイトURL公式仕様(2009/02時点の仕様)

AmazonのアフィリエイトURLを作成する方法が、
自分の中でだいぶ古い方法を理解していて、
うまくアフィリエイトが付かなかった、ということがあったので、
ブログでさらしてみます。

公式リンク方法:https://affiliate.amazon.co.jp/gp/associates/help/t121/a1?ie=UTF8&pf_rd_t=501&pf_rd_m=AN1VRQENFRJN5&pf_rd_p=&pf_rd_s=center-6&pf_rd_r=&pf_rd_i=assoc_join_getstarted_seventh

これが正しいやりかたです。
検索するといろいろなブログで方法を解説されてますが、
やはり、こういうのは公式サイトを見るのが一番。

商品個別リンクの場合は、
http://www.amazon.co.jp/dp/[ASIN]?tag=[ASSOCIATE_TAG]&linkCode=as1&creative=6339
が正しいやり方のようです。
linkCodeとcreativeパラメータが必須かどうかは不明ですが、
どこで蹴られるかわからないので、つけておくべきですね。

商品URLの場合は、linkCode=as1
それ以外の場合は、linkCode=ure
なのは、どういう意味があるのかも謎です。

お金がもらえないのは残念過ぎるので、したがっておきます。

jquery-1.4がリリースされました

jquery-1.4がリリースされました。
http://jquery14.com/day-01/jquery-14

一部の処理で大幅な速度改善がされたようです。


remove(), empty(), html()に対して、大幅な速度改善が見られます。
html()は特によく使う関数なので、
体感速度は今までよりさらに早くなるのではないか、と期待できます。

今回のリリース時に、jqueryの中の人が公開生質問をうける、という
イベントがあったみたいです。
http://jquery14.com/day-01/jquery-14-live-qa

また、googleのCDNもすでに対応済であることを確認しました。
http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js

GET /ajax/libs/jquery/1.4.0/jquery.min.js HTTP/1.1
Host: ajax.googleapis.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; ja; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6
Accept: */*
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost:10080/tanarky/yomiowatter/
If-Modified-Since: Thu, 14 Jan 2010 01:36:01 GMT
Cache-Control: max-age=0

HTTP/1.x 304 Not Modified
Date: Sat, 16 Jan 2010 23:52:36 GMT
Expires: Sun, 16 Jan 2011 23:52:36 GMT
Cache-Control: public, must-revalidate, proxy-revalidate, max-age=31536000
Age: 1707
Last-Modified: Thu, 14 Jan 2010 01:36:01 GMT
Content-Length: 0
Server: GFE/2.0
X-XSS-Protection: 0 

BloggerにYahoo!ショッピングのカテゴリランキングモジュールを表示させる

ブログを書くたびに、アフィリエイト商品を選んで張り付けるのは
めんどくさいもんです。

というわけで、
Yahoo!ショッピングのカテゴリーランキングAPIを使って、
自動でアフィリエイトモジュールを表示させるTipsです。

1. まずは、テンプレートのバックアップを取っておきます
   ダッシュボードから、レイアウト→HTMLの編集、から
   テンプレートのダウンロード、でローカルに保存しておく

2. ↑のページから、ウィジェットのテンプレートの展開、をON

3. jqueryを使うので、ページのトップで読み込みます。貼り付ける場所は、
   </b:skin> という箇所を検索し、その下に張り付けます。
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1.3");</script>
<script type="text/javascript" src="http://www.geocities.jp/tanarky/jquery/js/plugins/jquery-jtemplates.js"></script>
4. 以下のコードを、張り付けます。貼り付ける場所は、
   <b:if cond="data:post.hasJumpLink">という箇所を検索し、
  その上に張り付けます。
<!-- カテゴリランキングモジュール BEGIN -->
<div expr:id='&quot;cm&quot;+data:post.id'></div>
<script type="text/javascript" src="http://www.geocities.jp/tanarky/blogger/tanarky/js/shopping_ranking.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    BLOGPARTS.show('Ranking', {
        affiliate_type: 'yid', // 各自変更
        affiliate_id: 'NqNP7flCUN49xU3KOQg-', // 各自変更
        // カメラ,一眼レフ,PS3,ウルトラモバイルノート,ノートパソコン,メモリーカード,ロードバイク,フィギュア,Nintendo DSソフト
        category_ids: [2443,4875,5075,14251,14242,24,3184,2137,5086], // あなたの好きなカテゴリIDを入力
        max: 3,
        appid: 'vbQglqGxg65YDwPxyXTnUvxZxonbuDAc1Y1griEo2dV8piOpR9nvOJmdP6dHiA--',
        tag: '#cm<data:post.id/>',
        seed: <data:post.id/>
    });
});
</script>
<!-- カテゴリランキングモジュール END -->
5. テンプレートを保存して、ページを確認する

これで、このページにあるように、
カテゴリランキング上位3件の画像を自動で表示できます。
どのカテゴリが選択されるかは、category_idsで指定した
カテゴリから、投稿IDによって決まります。

注意:
App IDを必ず自分のものに書き換えてください
Yahooアフィリエイトのみ対応しています。Value Commerceアフィリエイトは対象外です。
アフィリエイトIDは自分のものに書き換えてください。
カテゴリIDも自分の好みのIDに書き換えてください。
デザイン崩れなど、自己責任でおねがいします。

perlでHTTP DELETE methodでリクエストしたいときのサンプル

perlでHTTP DELETE methodでリクエストしたいシチュエーションに
遭遇したので、サンプルコードと動作確認環境をさらしてみます。

サンプルは以下
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

use HTTP::Request;
use LWP::UserAgent;

# 動作確認環境 on google app engine
my $url = 'http://tanargle.appspot.com/rest_test';
my $ua = new LWP::UserAgent;
# DELETE を指定する
my $request = new HTTP::Request(DELETE => $url);

# -----------------------------------------------------
# google app engineの本番Webサーバは、DELETE method
# contentを指定すると、400 bad requestを返
# SDKの場合はエラーにならない
# ----------------------------------------------------
#my $body = 'foo=bar&hoge=fuga';
#$request->content($body);
my $response = $ua->request($request);
print $response->content();
http://tanargle.appspot.com/rest_testは
Google App Engine上の動作確認用環境です。
ご自由に利用してもらってかまいませんが、
予告無しで環境を落とすかもしれないのでご了承ください。

で、実行すると、
$ perl delete.pl
DELETE Methodを受け付けました
うまくいくと↑のようなメッセージが返ってきます。

コメントで書いた通り、DELETE methodでcontent bodyを指定すると
Google App Engineの本番環境だと、400 bad requestが返ってくるので
注意です。SDKだと普通に処理を実行してくれるので、本番に上げたときに
エラーになって、若干はまりました。

googleに報告してみようかな。

perlでHTTP PUT methodでリクエストしたいときのサンプル

perlでHTTP PUT methodでリクエストしたいシチュエーションに
遭遇したので、サンプルコードと動作確認環境をさらしてみます。

サンプルは以下
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

use HTTP::Request;
use LWP::UserAgent;

# 動作確認環境 on google app engine
my $url  = 'http://tanargle.appspot.com/rest_test';
my $ua   = new LWP::UserAgent;
# PUT を指定する
my $request = new HTTP::Request(PUT => $url);
my $body    = 'foo=bar&hoge=fuga';
$request->content($body);

my $response = $ua->request($request);
print $response->content();
http://tanargle.appspot.com/rest_testは
Google App Engine上の動作確認用環境です。
ご自由に利用してもらってかまいませんが、
予告無しで環境を落とすかもしれないのでご了承ください。

で、実行すると、
$ perl put.pl
PUT Methodを受け付けました
うまくいくと↑のようなメッセージが返ってきます。

TwitterのSearch APIを見ていて気がついたこと

Twitter Search APIのドキュメントを見ていて
気がついたことをだらだらと書いてみる。

例えば、「ヤフオク」で検索した時に、検索結果が返ってくる。
この時、最新のIDが*****だったとすると、次に、
since_id=*****をつけると、*****以降に更新された分の結果だけを
取得することが出来る。

これは、APIを利用する側が差分更新をするための機能なのだが、
差分更新をするために指定するパラメータが、
if-modified-since的に日時+時刻を指定するのではなく、
IDを指定させるところが面白いな、と思った。


差分更新の時に、時刻ではなくIDを指定させる、ということは、
Twitterのデータは最新のつぶやきの方が、
大きいIDが付いていることが保証されている、ということになる。

実際、流れているつぶやきを見ていると、確かに、
新しいつぶやきの方が大きいIDが付与されている。

つまり、Twitterのつぶやきは、
1つのでっかいQueue(配列)のような形で保存されている、
ということなんだろう。

IDが数値なので、その配列の*****番目、ということだろうか。
auto_incrementとしてIDが付与されるとすると、
atomicに処理しなければならず、ロック処理が大変な気がする。

単純に投稿日時(+micro秒)とかからIDを発行しているなら
ロックも必要ないが、投稿タイミング的にかぶってしまう可能性が
でてきてしまう。

このIDはどのタイミングで、誰が発行するものなのか、
かなり知りたいので、ご存知の方がいたら教えてもらいたいっす。

google app engineでリクエストのQuery Stringの値を取得する

google app engineでリクエストのQuery Stringの値を取得するには、
get()を使う。ドキュメントはこちら

サンプルコードは以下。
# -*- coding: utf-8 -*-                                                                                                                                     
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class Page(webapp.RequestHandler):
  def get(self):
    # Query Stringにあるfooパラメータの値を取得る
    # fooパラメータが存在しない場合はデフォルト空文字とする
    foo  = self.request.get('foo', '')

    if foo == "":
      self.response.out.write("fooパラメータはありません。残念。")
    else:
      self.response.out.write("fooパラメータは「%s」です" % foo.encode('utf-8'))
application = webapp.WSGIApplication([('/', Page)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
pythonのunicode型とstr型でちょっとつまづきました。
参考リンク:
http://lab.hde.co.jp/2008/08/pythonunicodeencodeerror.html
http://blog.livedoor.jp/sharemi/archives/924410.html


google app engineで任意のhttp statusコードを返す

google app engineで任意のhttp status コードを返すときには、
set_status()を使うらしい。

以下、サンプルコード
# -*- coding: utf-8 -*-
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class Page(webapp.RequestHandler):
  def get(self):
    # http status code(200 ok, 400 bad requestなど)を設定
    self.response.set_status(400)

    # http response headerを設定
    self.response.headers["Content-type"] = 'application/json';

    # http response bodyを設定
    self.response.out.write("""                                                                                                                             
{"status":"ng", "message":"request params is invalid"}""")

application = webapp.WSGIApplication([('/', Page)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
これで、400 bad requestと任意のhttp response bodyを返すことが出来る。


ドキュメントはこちら

twitterのAPI制限が 150req/hour から 1500req/hourにアップ

去年の話ですが、Twitter API 2.0 のアクセス制限が
150req/hour から 1500req/hourにアップしたようです。

http://www.readwriteweb.com/archives/twitter_20_api_rate_change_could_lead_to_a_world_o.php

Twitter's Director of Platform Ryan Sarver followed up on earlier public announcements this weekend with an email to developers explaining plans to raise the limit on the number of times an application can request information from Twitter for a single user to 10 times what it is today (from 150 req/hr to 1500/hr), and to offer everyone the same kind of paid access to the full "fire hose" of user updates that Google and Bing enjoy. People who build cool Twitter apps say this is very big news.
1500req/hour ということは、3秒に1回(1200req/hour)までなら範囲内です。
3秒に1回が許容されるなら、Stream API を利用するまでもない、と思ったり。

せっかくなので、何か作ってみようと思います。

perl の単体テストの雛形を書いてみた

最近はいろんな言語を書くので、たまにperlに戻ってくると、
単体試験の準備をどうやってやるのか忘れるので、
とりあえず、シンプルなパターンとして、備忘録がてらメモ。

サンプルコードはこちら
ポイントは以下
  • lib以下にperlのクラスを置く
  • t/以下に、(テストを実施する順番)_(テスト名).tという形式でファイルを置く
  • Makefileに、t/に対してproveコマンドを実行するように記述
これで、make testと入力すればテスト実行できる

↑成功


↑失敗

手元の環境では、何にも設定しなくて、緑やら赤やらで表示されました。
Happy!

h2xsとか使うのも手だけど、とりあえず、自分で1から書いてみた。
今後さらにブラッシュアップしていきます。

javascriptで文字列から同じ名前の関数を実行する

perlでよくやるんですが、
#!/usr/bin/perl

use strict;
use warnings;

my $obj = new Foo;
$obj->func('foo'); # 'foo'という文字列を渡すと、foo()を実行してくれる

package Foo;

sub new {
    my ($class) = @_;
    return bless {}, $class;
}

sub func {
    my ($self, $name) = @_;
    $self->$name(); # ここが肝
}

sub foo {
    my ($self, $name) = @_;
    warn "OK";
}
と書くと、
satoshi@debian:~/$ perl func.pl
OK at func.pl line 23.
と、文字列から同じ名前の関数を実行することができます。
これと似たようなことをjavascriptでやってみたくなったので、
備忘録がてらメモします。

evalを使う方法とか、何パターンかあったけど、
採用したのは以下の方法。
var Obj = {};
Obj.func = function (type, params){
    if(typeof this[type] == 'function'){
        this[type](params);
    }
};
Obj.foo = function (params){ console.log('foo function') };
Obj.func('foo', {});
もっといい方法がないか、引き続き調査してみる。

perl CPAN Module Daemon::Generic がお手軽な件について

定期的な処理をしようとしたときは、普通はスクリプトを書いて、
crontabで定期的に実行されるようにするのが一般的だと思う。

この方法で定期的な処理を実装すると
crontabは最短で毎分間隔での起動になるため、
数秒〜数十秒間隔で処理を実行したい場合には使えない。

今回、自宅開発中に、数秒〜数十秒間隔で処理を実行したい
シチュエーションに遭遇したので、daemonを起動し、
1つの処理が終わったらsleep処理をいる方式で、
定期的な処理を実装してみることにした。

daemonを1から書き始めると大変なので、CPANモジュールを
あさったところ、ちょうどよさそうなモジュール発見

Daemon::Generic
Daemon::Generic::While1

サンプルコードはこちら
gd_run_body部分にロジックを実行すればOK。

起動方法は、
$ perl generic.pl start
停止方法、再起動方法は、それぞれ、
$ perl generic.pl stop
$ perl generic.pl restart
と、いたって直感的な操作で起動/停止/再起動が
できるようになっています。
デフォルトで、ログは/var/log/messagesに吐かれる
挙動になっています。

firefox on debian lenny で flash ページを表示すると落ちる

意気揚々とFirefoxをインストールしてみたんですが、
Flashコンテンツがあるページを表示すると、
毎回ではないけど、なかなかの頻度でFirefoxが落ちるので
どうしたものかな、と色々調べながら対策をしました。
で、結局めんどくさくなって、flash機能をOFFにしました。
これでまったく落ちなくなったので、やはり、Flashが
落ちる原因、ということで間違いないので、引き続き
調査してみます。

firefox-3.5系をDebian lennyにinstall

iceweaselはfirefoxの商標だけ入れ替えたものなんですが、
バージョンが3.0と古く、最近挙動も重くなってきたので、
chromeに一部乗り換えたのですが、extensionもいまいち
そろいきっていないので、iceweaselからfirefoxに乗り換えました。

手順としては以下の通り

1. iceweaselを削除
sudo aptitude remove iceweasel
2. firefoxをダウンロード
3. こちらの手順で解凍したファイルを配置する
  3.1 /usr/lib以下で解凍
  3.2 /usr/bin/firefox -> /usr/lib/firefox/firefox に symbolic link
4. こちらのファイルをデスクトップに置いてショートカットアイコンを作る
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Name[en_US]=Firefox
Exec=/usr/bin/firefox
Icon=/usr/lib/firefox/icons/mozicon50.xpm
StartupNotify=true
5. ↑のファイルに以下の行を追加
Name[ja]=Firefox
これでだいたいOK。
iceweaselは削除しますが、プロファイルディレクトリ(通常は$HOME/.mozilla以下)
は残るはずなので、特に再設定は必要ないはずです。

使ってみた感想は、だいぶ高速化を体感できてます。
これで開発効率アップです。うれしい。

Bloggerのダッシュボードで最新の機能を使う(blogger in draft)

Bloggerの編集/投稿機能で、最新の機能は
Blogger in draftからアクセスからアクセスすると使えるようになる。

2010/01現在で、
  • Picasa web アルバムから画像を引用して投稿できる機能
  • Google辞書で定義されている単語の意味を引用できる機能
  • 地図上の場所を添付できる機能
  • 動画をアップロードできる機能
などがある。

常にBlogger in draftを使いたい人は、トップ画面で、
Blogger in Draft をデフォルトのダッシュボードにします。」
のチェックを入れればOK

自分は Blogger in Draftを使っていますが特に不具合らしき現象もないです。

Twitterの内容をBlogに投稿するサービス twtr2src

twtr2srcは、
Twitter の一日のつぶやきをまとめてメールで送ってくれるサービスです。
登録すると、毎日午前 0 時から順に、前日分の自分のつぶやきを、
指定したメールアドレスに送ってくれます。

Bloggerの場合、メールでの自動投稿に対応しているので、
組み合わせることにより、TwitterにPostするだけで、
ブログが自動で更新されるようになります。

手順は以下の通り。
  1. twtr2srcにアクセス
  2. 右上にあるリンクからOAuthログイン
  3. ログインに成功したら、一旦、更新したいBloggerブログにログイン
  4. 設定→メールとモバイルで、Mail2Bloggerのメールアドレスを設定する
  5. ↑で入力したメールアドレスをtwtr2srcの設定画面>Auto Postingに入力して、テストメールを送信
  6. テストメールでBloggerが更新されているはずなので、更新内容の4桁の数字を確認
  7. ↑の4桁の数字をtwtr2srcに入力して認証完了
  8. フォーマットを設定して保存すれば完了
とりあえず実験のため、今日開設したモバイル端末用ブログ
自動更新しようと思います。

tumblrとbloggerでカスタマイズ機能について比較

どちらの方が拡張性/発展性があるか、現状の機能調査

tumblr
  • Javascriptを入力できない(エスケープされたり、ファイルリンクを消されたり)
  • HTMLは投稿できる
  • CSSはカスタマイズできる
  • followしている人の投稿内容が自分のdashboadに表示される
  • followしている人の投稿内容は自分のFrontページには表示されない
  • APIがある が、投稿内容の編集が出来るだけで、デザインまで変更できない
  • Frontでは検索機能がついていない。dashboadには検索機能がある
blogger
  • Javascriptを入力できる。外部読み込みも可能
  • HTMLを投稿できる
  • CSSもカスタマイズできる。外部読み込みも可能
  • 読者になっている人のアイコンをFrontページに出すモジュールがある(friend connect)。表示されるのは人物アイコンだけ
  • 友達ブログリンクはある。RSSから情報を取得している。表示内容はテキストのみ。
  • APIがある が、投稿内容の編集が出来るだけで、デザインまで変更できない
  • タグ付け機能、検索機能(期間指定など)が標準装備
色々調べてみたが、少なくても現段階ではbloggerの方が
拡張性が高くなんでもできそうな感じがする。

特に個人的には、tumblrでJavascriptをかけないのは致命的な感じ。
書ける方法があれば誰か教えてください。

bloggerのテンプレートをカスタマイズしてみる(favicon編)

テストエンジニアのfaviconを変えてみた。
参考サイト:
Blogger に favicon を付けた
Favicon Japan!! -ファビコンの設置方法-
<link href="http://www.geocities.jp/tanarky/blogger/tanarky5/img/cup.ico" rel="shortcut icon"/>
をテンプレートのhead内に書くだけ。
Firefoxはアニメーションgifのfaviconに対応しているが
IEは対応していないので、出し分けたい人は2行書くみたいだが、
必要ないので、1行追加しただけ。

なんとも簡単。

Blogger Data APIについて調査 その1 できること/できないこと


Blogger Data APIについて
というページを発見。

どんなことができるのかなとドキュメントを読もうとしたら
http://code.google.com/intl/ja/apis/blogger/docs/gadgets/gadgets_for_blogger.html
まあ、あっさり英語なわけですが、そんなことにへこむわけもいかないので
調査をすすめてみる。

2010年1/2現在API versionは2.0のです。
APIは、
  • ブログの新規投稿(下書き含む)
  • ブログの投稿検索
  • ブログの投稿更新
  • ブログの投稿削除
  • ブログのコメント追加、削除、更新
  • ブログのエクスポート(データDump)
といった処理を、HTTP経由で可能にする。
# HTTPなので言語依存なし

ドキュメントを読んで始めて知りましたが、
Bloggerにブログを開設すると、一意なブログID(半角数字)が発行されるようです。
自分のブログIDを確認するには、Googleアカウントでログイン後、
Bloggerのダッシュボードにいって、
投稿ボタンなどのリンク先を確認してみるとわかる。
http://www.blogger.com/posts.g?blogID=****************
↑の**********の部分がブログIDとなる。

ブログのデータを操作するための認証処理としては、
AuthSubというAPIで認証します。
http://code.google.com/intl/ja/apis/blogger/docs/2.0/developers_guide_protocol.html#AuthSub
http://code.google.com/intl/ja/apis/accounts/docs/AuthForWebApps.html

ちょっと残念だったのは、ブログのデザインも
APIで変更したかったのだが、そのようなAPIは今のところ用意されていなかった。

2010年の目標

あけましておめでとうございます。今年もよろしくおねがいします。

今年の目標を考えてみました
  • 今まで作ったサイト分や新規で作るサイトも全部合わせて、月1万ユニークユーザ
    • 2009年は月1500ユニークユーザくらいでした
  • 毎月1万円の利益(レンタルサーバ代やドメイン代は引く。自分の人件費は考慮しない)
    •  2009年は、、、内緒です
  • 新規サイトを最低3つ作る
こんなところです。

今年もよろしくおねがいします。