RubyでOAuth
最近、Rubyを弄ってなくすっかり忘れてしまったのでtoRuby勉強会に向けてのリハビリを兼ねて、昔書いたTwitterライブラリをOAuthに対応させてみた。
OAuthは既存のライブラリを使うのではなく id:yoshiori さんのブログ
やる夫と Python で学ぶ Twitter の OAuth - 宇宙行きたい
が分かり易くてとても参考になったのでコードをパクらせて頂いたw
# -*- coding: utf-8 -*- # # oauth.rb # Twitter用OAuthライブラリ # require "openssl" require "base64" require "uri" require "net/http" class OAuth URL = "http://twitter.com" REQUEST_TOKEN_PATH = "/oauth/request_token" ACCESS_TOKEN_PATH = "/oauth/access_token" OAUTH_VERIFIER_PATH = "/oauth/authorize" # OAuth spec escape def escape(str) URI.escape(str, /[^a-zA-Z0-9\-\.\_\~]/) end private :escape # パラメータをエンコードした key=value の形にして separator で繋げる def encode_params(hash, separator) array = [] hash.each do |key, value| array.push escape(key) + "=" + escape(value) end array.join(separator) end private :encode_params # キーを元に message で hmac-digest を作成し base64 でエンコード def signature(key, message) Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, key, message)).strip end private :signature # nonce word def nonce OpenSSL::Digest::Digest.hexdigest("MD5", "#{Time.now.to_f}#{rand}") end private :nonce # timestamp def timestamp Time.now.tv_sec.to_s end private :timestamp # parse def parse_body(body) hash = {} body.split("&").each do |param| key, value = param.split("=", 2) hash[key] = value end hash end private :parse_body def request_get(path, header = nil) http = Net::HTTP.new(URI.parse(URL).host) http.request_get(path, header) end private :request_get def initialize(consumer_key, consumer_secret, oauth_token = nil, oauth_token_secret = nil) @consumer_key = consumer_key @consumer_secret = consumer_secret # 必須パラメータ @params = { "oauth_consumer_key" => consumer_key, "oauth_signature_method" => "HMAC-SHA1", "oauth_version" => "1.0", } if oauth_token != nil && oauth_token_secret != nil @params["oauth_token"] = oauth_token @oauth_token = oauth_token @oauth_token_secret = oauth_token_secret end end # Request Token取得 def request_token params = @params.dup params["oauth_timestamp"] = timestamp params["oauth_nonce"] = nonce # パラメータをソートし,エンコードした key=value の形にして & で繋げる params_str = encode_params(params.sort, "&") # メソッド, エンコードした URL, 上で作ったパラメータ文字列を & で繋げる message = "GET&" + escape(URL + REQUEST_TOKEN_PATH) + "&" + escape(params_str) # consumer_secret を元にキーを作成 key = @consumer_secret + "&" # キーを元に message で hmac-digest を作成 sig = signature(key, message) # 作成したダイジェストをパラメータに追加 params["oauth_signature"] = sig # 作成したパラメータを GET のパラメータとして追加 path = REQUEST_TOKEN_PATH + "?" + encode_params(params, "&") res = request_get(path) parse_body(res.body) end # Access Token取得 def access_token(oauth_token, oauth_token_secret, oauth_verifier) params = @params.dup params["oauth_token"] = oauth_token params["oauth_token_secert"] = oauth_token_secret params["oauth_verifier"] = oauth_verifier params["oauth_timestamp"] = timestamp params["oauth_nonce"] = nonce # パラメータをソートし,エンコードした key=value の形にして & で繋げる params_str = encode_params(params.sort, "&") # メソッド, エンコードした URL, 上で作ったパラメータ文字列を & で繋げる message = "GET&" + escape(URL + ACCESS_TOKEN_PATH) + "&" + escape(params_str) # consumer_secret を元にキーを作成 key = @consumer_secret + "&" + oauth_token_secret # キーを元に message で hmac-digest を作成 sig = signature(key, message) # 作成したダイジェストをパラメータに追加 params["oauth_signature"] = sig # 作成したパラメータを GET のパラメータとして追加 path = ACCESS_TOKEN_PATH + "?" + encode_params(params, "&") # ヘッダに Authorization:OAuth を追加 header = {"Authorization" => "OAuth"} res = request_get(path, header) parse_body(res.body) end # OAuth Verifier URL def oauth_verifier_url(token) URL + OAUTH_VERIFIER_PATH + "?oauth_token=" + token["oauth_token"] end # Authorization Header def auth_header(method, url, option = nil) params = @params.dup params["oauth_timestamp"] = timestamp params["oauth_nonce"] = nonce # option をパラメータに追加 opt_key = nil if option != nil opt_key, value = option.split("=", 2) params[opt_key] = value end # パラメータをソートし,エンコードした key=value の形にして & で繋げる params_str = encode_params(params.sort, "&") # メソッド, エンコードした URL, 上で作ったパラメータ文字列を & で繋げる message = method.to_s.upcase + "&" + escape(url) + "&" + escape(params_str) # consumer_secret を元にキーを作成 key = @consumer_secret + "&" + @oauth_token_secret # キーを元に message で hmac-digest を作成 sig = signature(key, message) # 作成したダイジェストをパラメータに追加 params["oauth_signature"] = sig # header に不要なパラメータを削除 if option != nil params.delete(opt_key) end header = {"Authorization" => "OAuth " + encode_params(params, ",")} end end
OAuthコア以外のソースはこちら
GitHub - m92o/twitter-ruby: Twitter library for Ruby
アクセストークンはこんな風にして取得します。
1. Twitter Application Management でアプリ登録してConsumer Key / Consumer Secretを得る
2. Consumer Key / Consumer Secretを元にOAuth Token / OAuth Token Secret (リクエストトークン)及びOAuth Verifier URLを得る
$ ruby requesttoken.rb consumer_key consumer_secret
3. OAuth Verifier URL にブラウザでアクセスしてアプリ使用許可しOAuth Verifierを得る
4. 今まで取得した情報を元にOAuth Token / OAuth Token Secret (アクセストークン)を得る
$ ruby requesttoken.rb consumer_key consumer_secret oauth_token oauth_token_secret oauth_verifier
つぶやくのはこんな感じです。
# -*- coding: utf-8 -*- require 'twitter' # 発言内容 text = 'おっぱい' consumer_key = '最初に使ったやつ' consumer_secret = '最初に使ったやつ' oauth_token = 'アクセストークン取得の時に取得した OAuth Token' oauth_token_secret = 'アクセストークン取得の時に取得した OAuth Token Secret' ssl = false tw = Twitter.new(consumer_key, consumer_secret, oauth_token, oauth_token_secret, ssl) tw.update(text)
ちょっとバグってて発言内容にイコール「=」が入ってると認証エラーになっちゃいます。何故だろう?
ScalaでO'ReillyのiPhoneアプリ版の本からepubを引っこ抜く
404 Blog Not Found:perl - O'ReillyのiPhoneアプリ本からepubをぶっこぬく
これを真似をしてScalaでipa2epubスクリプトを書いてみた。
Rubyで書こうと思ったけど
O'ReillyのiPhone AppからEPUBファイルを抽出するRubyスクリプト - いたさんの日記
すでに書いている人がいたので
Scalaにした
弾さんのと違いはiBooksに自動登録しないのと、zip処理を自前で書いたのでちょっと長い
初Scalaコードなので、なんかJavaっぽくなってしまった...
使い方はこんな感じでepubを作ってくれる
$ scala ipa2epub.scala xxx.ipa
Viliv N5でUbuntu
Viliv N5にLubuntu 10.04をインストールしたので設定をメモ
インストール直後は内蔵のOptical Joystick, 無線LANが使えないのでUSB-Mouse, USB-Ethernetを使って設定した。
Optical Joystick
/etc/default/grubのGRUB_CMDLINE_LINUXを変更
GRUB_CMDLINE_LINUX="i8042.nomux=1 i8042.noloop=1"
設定を反映
$ sudo update-grub
Video
Intel GMA500(Poulsbo)は標準状態だと使えないのでPPAから入れる。
$ sudo add-apt-repository ppa:gma500/ppa $ sudo apt-get update $ sudo apt-get install poulsbo-driver-2d poulsbo-driver-3d poulsbo-config
無線LAN
SD-8686用ファームを以下からダウンロード
http://extranet.marvell.com/drivers/driverDisplay.do?driverId=203
アーカイブを解いて所定の場所にコピー
$ unzip SD-8686-LINUX26-SYSKT-9.70.3.p24-26409.P45-GPL.zip $ tar xvf SD-8686-FEDORA26FC6-SYSKT-9.70.3.p24-26409.P45.tar $ sudo cp FwImage/sd8686.bin /lib/firmware $ sudo cp FwImage/helper_sd.bin /lib/firmware/sd8686_helper.bin
GUIのNetworkManagerアプレットを使うと固まるのでCUIで使う設定をする。
/etc/wpa_supplicant/wpa_supplicant.conf (WPA2-PSKの場合)
network={ ssid="SSIDを記入" psk="キーを記入" key_mgmt=WPA-PSK proto=WPA WPA2 pairwise=CCMP TKIP group=CCMP TKIP }
/etc/network/interfacesに以下を追加
iface wlan0 inet dhcp wpa-driver wext wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
無線LANを使う
$ sudo ifup wlan0
無線LANを切る
$ sudo ifdown wlan0
追記 (2010.08.18)
無線LAN使用時にNetworkManagerが動いているとDHCPでアドレスを取得出来ないので事前に次のコマンドで停止させておく。またはパネル上のアイコンを右クリックし「無線を有効にする」を外しても可
$ sudo stop network-manager
Sound
ヘッドフォンだと鳴るが、内蔵スピーカだと音が出ない。
/etc/modprobe.d/alsa-base.conf を弄ってみたが直らない。誰か教えて
ブックスタンド買ったよ
プログラミングの本を読みながら例題コードを実際に入力するのって、本を押さえながらキーを打たないといけないし、視線移動も大きいのでかなりやり辛い。そこで、このブックスタンドを買ってみた。
- 出版社/メーカー: 株式会社エジソン
- メディア:
- 購入: 1人 クリック: 122回
- この商品を含むブログ (3件) を見る
こんな感じで設置
固定部分
本を置いた時
iPadも置いてみたけど、強度的にはあまり置かない方が良いかも
これでかなりコード入力しやすくなったよ
Dreamweaver CS5でHTML5とiPhone
Adobe Dreamweaver CS5用のHTML5/CSS3エクステンションとCS4/5用iPhoneサイト向けエクステンションが公開されているのでメモ
Adobe - Dreamweaver Support Center : Updaters
http://h2o-space.com/web/product/iphone_dw/