2009年10月8日木曜日

PythonのEvernote APIをプロキシに対応させようとして挫折した

Evernote APIで使用されているThriftのTHttpClientクラスには、プロキシの設定を行うためのインターフェースが用意されていません。そのため、プロキシ越しにEvernote APIの呼び出しを行うことが出来ないみたいです。
(ひょっとしたら出来るのかもしれませんが、調べた範囲ではわからず)

そこでThriftのTHttpClientクラスのPython実装をプロキシに対応させるべくチャレンジしてみました。

http://gist.github.com/204501

基本的には元々httplib.HTTPで実装されていたところをhttplib.HTTPConnectionに変えただけなのですが、ところがこれがうまくいかない。このクライアントで/edam/user/にCheckVersionリクエストを投げると500エラーが返却されてしまいます。で、500エラーを拾うと再度試行するようになっているのか、あえなく無限ループに突入><
プロキシの設定が間違っているのかと思い、試しにプロキシを外してデバッグログをはかせた結果がこちら。
send: 'POST /edam/user HTTP/1.1\r\nHost: sandbox.evernote.com:443\r\nAccept-Encoding: identity\r\nHost: sandbox.evernote.com\r\nContent-Type: application/x-thrift\r\nContent-Length: 82\r\n\r\n'
send: '\x80\x01\x00\x01\x00\x00\x00\x0ccheckVersion\x00\x00\x00\x00\x0b\x00\x01\x00\x00\x00(Python URL to Evernote/0.1; Python/2.5.2\x06\x00\x02\x00\x01\x06\x00\x03\x00\r\x00'
debug: HTTPConnection
Request-sent None
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: Apache-Coyote/1.1
header: Content-Type: application/x-thrift
header: Content-Length: 29
header: Date: Wed, 07 Oct 2009 09:04:29 GMT
read start
read POST request
send: 'POST /edam/user HTTP/1.1\r\nHost: sandbox.evernote.com:443\r\nAccept-Encoding: identity\r\n\r\n'
read getresponse
debug: HTTPConnection
Request-sent None
reply: 'HTTP/1.1 500 \r\n'
header: Server: Apache-Coyote/1.1
header: ETag: W/"3401-1254794526000"
header: Last-Modified: Tue, 06 Oct 2009 02:02:06 GMT
header: Content-Type: text/html
header: Content-Length: 3401
header: Date: Wed, 07 Oct 2009 09:04:29 GMT
header: Connection: close
read start
read POST request
うーん、HTTPSの実装が間違っているのか、リクエストパラメータが間違っているのか。1回目のリクエストはうまくいくけど2回目のリクエストが失敗しがちみたいです。もう少し調査してみます。


あ!今気づいた!!
2回目のリクエスト時(readメソッド実行時)のHTTPヘッダがめちゃくちゃだ!!ここを直せば動くかも。

2009年10月5日月曜日

Evernote APIためしてみた


API Keyくださいとお願いしたらすぐに発行してもらえたので、試しにEvernote APIを触ってみました。


■準備
http://blog.lilyx.net/2008/11/03/evernote-api/を見ると発行するときに手間がかかったとの記述がありましたが、私の場合は半日で発行されました。まぁ1年たってますし、状況が良くなったのかもしれませんね。申請時にアプリの詳細を事細かに書いたのが良かったのかもしれません。


■Hello Worldを動かす
まず最初にsandbox環境に自分用のアカウントを作成します。http://sandbox.evernote.com/login.jspにアクセスして、いつも通りアカウントを作成。忘れがちなので注意です。
アカウントが出来たら、ダウンロードしてきたSDKに最初っからサンプルスクリプトがついてきているので、こちらを実行するだけです。今回はPythonのサンプルスクリプトを試してみました。
cd sample/python
cp * ../../lib/python
cd ../../lib/python
python EDAMTest.py username password


■ENMLを試してみる
今回の最終目的は「はてブみたいにURLだけ渡したら勝手にEvernoteに取り込んでくれる」ことなので、まずはどのぐらい気軽にHTMLを取り込めるかを調べてみました。Evernoteの本文はENMLというHTMLに似たマークアップ言語で記述されています。
http://www.evernote.com/about/developer/api/evernote-api.htm#_Toc200272588
こちらの記載を読んでみたところ、かなーーーーーり面倒くさいということが判明。htmlタグやbodyタグが含められないのはまだいいとして、id属性もclass属性も許可されません。さらに困ったことに・・・

pタグ閉じてないからダメー。


brタグ閉じてないからダメー。

さすがXML、厳しい。どうやらHTMLとは全く互換性がないと考えた方が良さそうです。
HTMLをENMLに変換するライブラリとかないかなー?

ENMLは死ぬほど面倒ですが、それ以外のところは今のところ簡単です。

2009年10月4日日曜日

cocos2dでParticleSystemを使うときのメモ

懲りずにcocos2dで遊んでます。今回はParticleSystemを触ったときに気づいたことなどをメモしてみます。


■ParticleSystemが放出するParticleを回転させたい
http://www.cocos2d-iphone.org/api-ref/latest-stable/interface_particle_system.html
こちらの公式リファレンスには2009/10/02現在記載されていませんが、startSpin, startSpinVar, endSpin, endSpinVarというプロパティが用意されており、こちらの値を調整することで放出される個々のParticleに回転を与えることが出来ます。
        // angle of particles
startSpin = 90;
startSpinVar = 0;
endSpin = 1800;
endSpinVar = 3600;
注意点として、PointParticleSystemを継承したParticleSystemでは、spin系のプロパティは利用できないみたいです。パフォーマンスで劣るそうですが、QuadParticleSystemを継承するようにしましょう。

結果はこんな感じ。青いミミズみたいなのがParticleSystemから放出しているParticleです。
回転の中心軸の位置がおかしいのかな?


■Particleの大きさを変化させたくない
endSizeにkParticleStartSizeEqualToEndSizeを指定すると、放出されたParticleの大きさが変化しなくなります。
        // size, in pixels
startSize = 90.0f;
startSizeVar = 30.0f;
endSize = kParticleStartSizeEqualToEndSize;
endSizeVar = 30.0f;


■応用:Particleの回転を変化させたくない
現在のcocos2dではまだサポートされていませんので、適当にParticleSystem.mのコードを書き換えます。具体的には180行目のあたりを以下のようにします。
 // angle
float startA = startSpin + startSpinVar * CCRANDOM_MINUS1_1();
particle->angle = startA;
if (endSpin == kParticleStartSpinEqualToEndSpin )
particle->deltaAngle = 0;
else {
float endA = endSpin + endSpinVar * CCRANDOM_MINUS1_1();
particle->deltaAngle = (endA - startA) / particle->life;
}
これで放出されたParticleがくるくる回転するのを防げます。でもこのマジックナンバーを使った実装、正直イマイチです。
 // angle
float startA = startSpin + startSpinVar * CCRANDOM_MINUS1_1();
particle->angle = startA;
if (spinFixed)
particle->deltaAngle = 0;
else {
float endA = endSpin + endSpinVar * CCRANDOM_MINUS1_1();
particle->deltaAngle = (endA - startA) / particle->life;
}
個人的にはこの方に実装するほうが好きです。パフォーマンスは悪いかも。