2011年12月31日土曜日

[toodledo][ruby] Toodledo API version 2.0 の使い方


== 概要

タスク管理サービス
Toodledo http://www.toodledo.com/
の API version 2.0 を使う方法のメモです.
基本的には Toodledo の

Developer's API Documentation : Version 2.0
http://api.toodledo.com/2/account/index.php

をもとにしていますので, 詳細を知りたい場合はそちらを参考にしてください.
これ以降に引用しているページは全てこのドキュメントの中のページです.

実行環境には Debian GNU/Linux 6.0 (squeeze),
サンプルコードには Ruby を使っています.

== 認証の流れ

最初に認証の流れを概説します.

* 新たにアプリケーションを作るときだけ行えばいいこと
  * Toodledo のサイトでアプリケーションの登録をし, app ID と app token を取得する
  * user ID と app token から signature を求める

* 4 時間に 1 回必要
  * user ID, app ID, signature を Toodledo のサーバに送信して session token を取得する
  * ユーザの password, app token, session token から key を求める

* Toodledo のサーバへの問い合わせのたびに必要
  * 問い合わせ内容に key を添付する

詳細は
Authentication http://api.toodledo.com/2/account/index.php
が参考になります.

== アプリケーションの登録

API を使うためには,  作るアプリケーションごとに登録が必要です,
バージョンアップだけなら登録しなおす必要はありません.

Toodledo にログインした状態でブラウザで
Register & Stats http://api.toodledo.com/2/account/doc_register.php
に行きます.
以下の項目を記入し, "Register" ボタンを選択.

* Desired AppID
* Product Name
* Website
* Email Address
* Category (プルダウンメニューから選択)
* Short Description
* Long Description
* Icon (設定は任意)
* State (とりあえずは In Development / Beta)

うまくいけば
app ID と app token が発行されます.
後から確認・編集するには再び
Register & Stats http://api.toodledo.com/2/account/doc_register.php
にアクセスして, ページの下のほうにある一覧表から行います.

== signature の計算

Authentication http://api.toodledo.com/2/account/index.php
より, signature の計算式は以下のとおりです.

  sig = md5( userid + appToken )

ここで userid は Toodledo の通常のタスク管理のページの "setting" に書かれている "Unique ID" のことです.
また, md5 は与えられた文字列の MD5 ダイジェストを返す関数を意味します.

自分のプログラムの結果が正しいかどうか調べたい場合は,
Authentication http://api.toodledo.com/2/account/index.php
のページの上から 2 割くらいの場所に "Testing" という名前で
テキストボックスが二つある場所で答え合わせができます.

もしくは md5("test") の結果が
"098f6bcd4621d373cade4e832627b4f6" になることを確認してもよいでしょう.

== session token の取得

session token を得るためにサーバに問い合わせます.

Sync & Rate Limiting http://api.toodledo.com/2/account/doc_sync.php
によると, session token の取得は 1 時間に 10 回までという制限があります.
ただしひとつの session token は 4 時間の間は使い回せます.
同一ユーザは 1 時間に最大 250 回まで問い合わせることができます.

方法の詳細は
Connecting & Encoding http://api.toodledo.com/2/account/doc_encode.php
が参考になります.
ここでは JSON 形式で記述して http の POST メソッドで問い合わせることにします.
SSL はプロアカウントでないと使えないようです.

Ruby の JSON ライブラリのインストールは以下でできます.

  $ sudo gem install json

Toodledo には以下のような文字列を送ることになります.
vers, device, os は省略可能です.

  http://api.toodledo.com/2/account/token.php?userid=abcdef1234556789&appid=myAppID&vers=21&device=iphone4&os=401&sig=a1s2d3f4a5s6d7f8a9s0d

サーバが返した結果を JSON 形式のまま表示させると

  {"token":"1a2b3c4d5e6f7"}

のような形になっています.

== key の作成

毎回の問い合わせの際に用いる key の計算式は
Authentication http://api.toodledo.com/2/account/index.php
より, 以下のとおりです.

  key = md5( md5(userPassword) + appToken + sessionToken )

これも
Authentication http://api.toodledo.com/2/account/index.php
のページの上から半分くらいの場所の,
テキストボックスが三つある場所で答え合わせができます
(生 password 入れさせられるのでおすすめしませんが).

これで準備が整いました.

== サンプルコード

参考までに, key を得るまでの Ruby のコードを示します.
以下では簡単のため session token の使い回しは行っておらず,
スクリプトが実行されるたびに取得し直されます.
また, ログインパスワードは早い段階で md5 を通しているので
key を計算する行の内容はさきほど挙げたものとは少し違います.

  require 'rubygems'
  require 'digest/md5'
  require 'json'
  require 'uri'
  require 'net/http'
  Net::HTTP.version_1_2
 
  # MD5 digest を返す
  def md5(str)
    Digest::MD5.hexdigest(str)
  end
 
  # url に JSON 形式の body を http で post し,                                
  # 受け取ったデータの body (JSON 形式) を hash に parse して返す
  def post_server(url, body)
    response_hash = nil
    uri = URI.parse(url)
    Net::HTTP.start(uri.host, uri.port){|http|
      response = http.post(uri.path, body)
      response_hash = JSON.parse(response.body)
    }
    response_hash
  end
 
  # session token の取得に必要な signature の生成
  def gen_signature(userid, apptoken)
    sig = md5( userid + apptoken )
  end
 
  # session token の取得
  def get_session_token(url, appid, apptoken, userid)
    sig = gen_signature(userid, apptoken)
    body = "userid=#{userid}&appid=#{appid}&sig=#{sig}"
    token = post_server(url, body)["token"]
  end
 
  # 通常の問い合わせに必要な key の生成
  def gen_key(md5_password, apptoken, session_token)
    key = md5( md5_password + apptoken + session_token )
  end
 
  SESSION_TOKEN_URL = "http://api.toodledo.com/2/account/token.php"
  APPID = YOUR_APPID    # ブラウザでアプリを登録する際に取得
  APPTOKEN = YOUR_APPTOKEN    # ブラウザでアプリを登録する際に取得
  USERID = YOUR_USERID    # setting の Unique ID
  PASSWORD = YOUR_PASSWORD    # ログインパスワード
  MD5_PASSWORD = md5(PASSWORD)

  session_token = get_session_token(SESSION_TOKEN_URL, \
                                      APPID, APPTOKEN, USERID)
 
  p key = gen_key(MD5_PASSWORD, APPTOKEN, session_token)



== 実行例: タスクの取得

実行例として,
Tasks http://api.toodledo.com/2/tasks/index.php
の "Retrieving Tasks" を例にタスク取得について解説します.
他の操作も同じ要領です.

session token の取得の要領で, たとえば以下をサーバに送信します.
以下は unix time で 1234567890 以降に更新されたタスクのみを
folder,star,priority も含めて要求する命令になります.
id, title, modified, completed は常に返ってくる仕様です.

  http://api.toodledo.com/2/tasks/get.php?key=YourKey&modafter=1234567890&fields=folder,star,priority

注意: session token を取得したときと POST する先が違います!

以下のようなデータが返ってきます.
最初に num (取得できたレコード数), total (サーバでヒットしたレコード数) で構成されたレコードがあり,
後は要求した内容のレコードが並んでいます.

  [{"num":"2","total":"2"}, {"id":"1234","title":"Buy Milk","modified":1281990824, "completed":0,"folder":"5409195","star":"1","priority":"-1"},{"id":"1235", "title":"Fix flat tire","modified":1280877483,"completed":1280808000, "folder":"0","star":"0","priority":"0"}]

データの読み方は
Tasks http://api.toodledo.com/2/tasks/index.php
の "Task Datatypes" などを参照してください.

2011年12月23日金曜日

意義なんか気にせずにやっていたら意義が見つかる?


最近自分の目にちょくちょく飛び込んできている主張に

  多くの人がブログなどで自分の意見を公開するのをためらう理由のひとつとして、
  自分の考えがありふれたものであって公開するに値しない、と思ってしまうことがあるけど、
  じつは自分が普通だと思っていても他人から見たら全然普通ではないんだよ。
  だから気にすることなく発信したらいいよ。

というのがある。
ぱっと探せたものだと以下のような記事。

【「普通」を武器にする!自分レベルアップ術】「普通」を発信することを恐れない
http://www.ashi-tano.jp/?p=586

あなたにとって当たり前のことが他人にとっては驚くべき事である - GIGAZINE
http://gigazine.net/news/20111213-obvious-to-you-amazing-to-others

自分が普通だと思っていても他人から見たら普通じゃないことがある、というのは
たとえばテレビでケンミンショーを見れば感じることができる。
自分の出身地域の「普通のこと」に
東京のスタジオが「えーーーーっ!?」と言っているのを見て、逆に驚くはず。

で、ここで立ち止まって、
自分で普通だと思っていても発信できている人ってどういう人だろうと考えてみた。
考えついたのは二種類。

冒頭の記事のように、
自分の考えが普通じゃないこともあるかもしれない、と自覚して
発信している人もいるだろう。

あともうひとつ。
普通であろうがなかろうが発信というか、表現そのもののが好きな人がいるだろう。
後者は巧拙はさておき、表現自体が好きなのだろう。

で、さらに考えてみると、
「自分の意見は意外と普通じゃない」と気づいた人は
後者の「表現そのものが好きな人」が多いのではないかと勝手に思った。
普通だと思ったことも発信すれば、自分が普通だと思ったことに
他人がすごいと思った、というフィードバックをもらいやすいからだ。

まとめると
「発信の意義を気にせず、好きでたくさん発信していたら発信の意義に気づいた」
ということか。

2011年12月20日火曜日

[memo]技術メモを一挙公開


これまで書きためていた技術メモを一挙公開しました.

http://epa.scitec.kobe-u.ac.jp/~noda/memo/

書きためていたメモの中に公開不可能なものが混ざっていたため,
公開可能な部分を取り出すのが面倒で放置していたのだが,
思い立って分別, 公開した.

あくまでも自分用メモが外から見えるだけ, というスタンス.
気が向いたら整理します.

非公開ものも含めたらテキストで 55KB あった.
継続はなんとかかんとか.

2011年12月14日水曜日

学生時代の「余命」


後輩たちの行動に学んだ。

年度末がどんどん近づき、卒論・修論の締め切りはどんどん近づいてくる。
当然研究が忙しくなってくるわけだが、彼らは遊ぶのをやめない。
というよりむしろ睡眠時間を削ってでも普段よりたくさん遊んでいるように見える (のは気のせい?)。
そこには「社会人になったら遊べなくなるから今のうちに遊び倒しておく」というようなセリフがちらほら。

ああそうか、これは「余命」の過ごし方と一緒だ。と気づいた。

自己啓発本には
「もし自分の余命があと半年しかなかったらどうするか?」
といった質問がよく登場する。
この質問は読者が本当にやりたいことを洗い出すためのトリガーなのだけど、
彼らはこれの回答を地で実践しているように見える。
学生時代の「命」が尽きるのに向かって全力で走っているよう。

この勢いならば、彼らは人生の終わりの際も悔いを残すことはないだろう、とすら思えた。

自分も見習いたい。

2011年12月11日日曜日

[ruby][twitter] 任意の公開ユーザのツイートを取得する


過去のツイートを加工したくなったので、
任意の公開ユーザのツイートを取得する ruby スクリプトを作ってみた。
予め

The Twitter Ruby Gem
http://twitter.rubyforge.org/

をインストールする必要がある。

 require 'rubygems'
 require 'twitter'
 require 'time'

 ID = USERID   # ツイートを取得したいユーザの ID
 COUNT = 20    # 一度に取得するツイート数. 最大値は 200.

 tweets = Twitter.user_timeline(ID, {:count=>COUNT, :page=>1})
 tweets.each do |t|
   puts "#{t.created_at.strftime("%Y/%m/%d %H:%M")} #{t.text}"
 end

公開されているものを読み込むだけなので結構短く書けた。

200 より大きい数のツイートを取得したい場合は
user_timeline の :page の数字を変えていけばよい.

== 参考ページ

tweet のバックアップ
http://kurano.net/text/id/12717045263.html

2011年12月7日水曜日

[lifehacks]ウェブサービスと非常勤の秘書


ウェブサービスにタスクやスケジュールを預けるのに
抵抗を抱いていた時期がある。
たとえば、そのサービスがずっと続く保証はないし、
もしかすると突然使えなくなるかもしれない。
果たしてそんなものにタスクやスケジュールを預けてよいものか、と。

今は、そういうサービスは秘書と同じような存在だと考えている。
たとえば秘書を雇うとすると、
秘書にはそんなに抵抗なくタスクやスケジュールを任せるだろう。
いつまで勤めているか保証されないのに、である。
真面目な人であっても、急病や事故で突然仕事ができなくなることだってある。

そんな万が一の場合に備えて、
いつでも次の人あるいは自分に引き継げるようにしておくことになる。

サービスにも同様に接していて、
急に止まっても泣かないようにバックアップを取っているし、
そもそもバックアップの取りづらいサービスは使わないようにしている。

また、万人単位でユーザのいるサービスが突然休止して二度と動かないことは滅多になく、
たいていは休止するとしても何ヶ月か前に予告があるので
その間に対策を考えればいいと楽観的に考えている。