RubyonRailsでOAuth経由でTwitterのタイムラインを取得する

2010-06-18
このエントリーをはてなブックマークに追加

OAuthを使えるようになっておけば今後いろいろなマッシュアップに便利だろうと思い、試してみました。RoRで書いたのは、最近ご無沙汰過ぎてあまりに覚えてなかったのでリハビリを兼ねたわけです。

class TwitterAuth
require ‘oauth’

def self.consumer

OAuth::Consumer.new(
[Consumer key],
[Consumer secret],
:site => “http://api.twitter.com”
)

end

def self.request_token(_token, _secret)

OAuth::RequestToken.new(
consumer,
_token,
_secret
)

end

def self.access_token(_token, _secret)

OAuth::AccessToken.new(
consumer,
_token,
_secret
)

end

end

まずは上記のクラスを作成。OAuth関連の処理はこっちにやらせます。で、次がコントローラー。

require ‘rubytter’

class AuthController < ApplicationController

def index

request_token = TwitterAuth.consumer.get_request_token(:oauth_callback => “http://#{request.host_with_port}/auth/callback”)
session[:request_token] = request_token
redirect_to request_token.authorize_url

end

def callback

_token = session[:request_token]
request_token = TwitterAuth.request_token(_token.token, _token.secret)
access_token = request_token.get_access_token(
{},
:oauth_token => params[:oauth_token],
:oauth_verifier => params[:oauth_verifier]
)
session[:request_token]=nil
_account = {
:user_id => access_token.params[:user_id],
:token => access_token.token,
:secret => access_token.secret
}
session[:account] = _account
redirect_to :action => “timeline”

end

def timeline

_account = session[:account]
token = TwitterAuth.access_token(_account[:token] , _account[:secret])
_twitter = OAuthRubytter.new(token)
@user_timeline = _twitter.user_timeline(_account[:user_id],:count => 100)

end

end

def timelineが自分のタイムラインを取ってくるところで、「:count=>100」と指定しているのは「新着100件取ってきて」っていうことです。ここを指定しないでおくと規定値では20件取得してくれます。def callbackでセッションに入れたuser_id、token、secretをデータベース等に保存しておけば次回以降はこれらだけで認証とツイートの取得ができます(というか認証自体はtokenとsecretだけでOK)。

Twitterのアプリケーション登録申請で登録する際、コールバックURLを指定しないとWebアプリケーションとして登録されません。「開発中だからURLなんて決まってないよ」っていうケースでも、適当なURLを登録しておいてください。どうせ実際のコールバックURLはRubyのスクリプトで指定しなおしています。ハセテツはここに気が付かず、そこそこの時間を浪費しました。

で、タイムラインを表示するviewは

<ul>
<% for item in @user_timeline do -%>
<li><%= item.text %></li>
<% end -%>
</ul>

こんな感じです。

RubyとPythonについて考えてみました

2010-04-27
このエントリーをはてなブックマークに追加

ハセテツは複数の言語を状況に応じて使い分けてきましたが、最近のWeb系開発はPython(+Django)がメインになってきています。

ちょっと前までRuby(+Rails)だったのですが、いろいろと考えるところもあり、乗り換えました。その乗り換えた理由をまとめてみようと思います。

まとめてみたら「やっぱりRailsじゃね?」となるかもしれません。w

Ruby(+Rails)

  • Rails便利すぎる。
  • コントローラとモデルが別々のファイルになってくれるのはソースが追いやすい。
  • Railsを通さない画像やCSSはpublicフォルダに置けばよいのはわかりやすい。
  • urlディスパッチャーがいまいち使いにくい。(知らないだけかも)
  • APサーバはmongrel一択?
  • VirtualHost使おうとするとApache+Passenger(mod_rails)だが、これが重い。(チューニングで速くなるのかも)
  • というか、Railsがそもそも重い。
  • ちゅーか、Rubyが重い、遅い。
  • PassengerはWindowsじゃ動かない。
  • mongrelもPassengerより激速軽快かというと、そうでもない。
  • gem便利すぎ。
  • ワンライナで書く人が多くて、Perlとおなじ匂いがする。

ハセテツが使っていたRubyは1.8で、速くなったといわれる1.9には触れていないのでもしかすると古いのかもしれません。でも、Railsって1.9には対応してないですよね?(本日現在)

Python(+Django)

  • Django便利すぎる。
  • 日本語の書籍、情報が少なすぎる。(ハマるとキツい)
  • modelが一枚のファイルなので、大量のmodelがあると可読性が激しくダウン。
  • viewファイルをフォルダで分けたくても、アプリケーションフォルダ直下以外にviewファイル置くなら「sys.path.append」しないといけない。(違う?)
  • urlディスパッチャーのカスタマイズが超便利。
  • mod_pythonが使えるので、Windows環境だろうがLinux環境だろうが気にせずVirtualHostが使える。
  • 速い。
  • 日本語大変。Shift_JIS怖い。
  • easy_installでパッケージのインストールは楽だが、管理が悪夢。

メリットとデメリットが入り乱れました。見難くてすいません。

結局フルスタックのフレームワークということで、DjangoとRailsに関しては一長一短だと思います。個人的にはRailsの方が良くできてたかなぁと。

最終的に、「RubyonRailsは重い」というオチになってしまうのです。Rubyも、Railsも、です。ただ、これはRuby1.9が実は劇的に速くなっていて、1.9に対応したRailsがリリースされたらすべて解決されるのかもしれません。

それでも、いまのところPythonの軽快さ、シンプルさに満足しています。あと、GAEでPythonが動くのもいいですよね。

「Googleが導入した言語」というのがハセテツ的に琴線に触れたのかもしれません。

ミーハーですいません。w

RubyonRailsでページングする方法

2009-09-28
このエントリーをはてなブックマークに追加

will_paginateを利用します。とってもらくちんです。

require ‘will_paginate’

def hoge
  @items = Item.pagenate(
                  :conditions => [“hoge= ?”, hoge],
                  :page => params[:page],
                  :per_page => 30)
end

コントローラ側は以上。30レコードでページングします。find_by_sqlみたいな使い方も可能です。

  @items = Item.paginate_by_sql(
                  [“select * from hoge where hoge = ?”, hoge],
                  :page => params[:page],
                  :per_page => 30)

たいして変わりません。View側も通常のActiveRecordとの違いは

<%= will_paginate @items, :prev_label => ‘< 前’, :next_label => ‘次 >’ %>

こういうタグを記述しておけば勝手にページングアンカーが表示されるようになるくらいです。

:prev_labelは指定しなくてもOKです。デフォルトの文字列が表示されます。

 

RubyonRailsでform_tagのselect_tagを使う

2009-08-25
このエントリーをはてなブックマークに追加

#コントローラ側
@target_year_options = [2007, 2008, 2009]

#ビュー側
<%= select_tag(“target_year”, options_for_select(@target_year_options, Time.now.year)) %>

引数は「名前、option(要素配列、selectedの値)」ですね。selectedの値は省略可能です。

ビュー側に

<%= select_tag(“target_month”, options_for_select([’01’,’02’,’03’,’04’,’05’,’06’,’07’,’08’,’09’,’10’,’11’,’12’], Time.now.month )) %>

って感じで直接配列を書き込むことも可能。

<%= select_tag(“target_month”, options_for_select([[‘一月’,1],[‘二月’,2],[‘三月’,3],[‘四月’,4]], Time.now.month )) %>

これで表示は漢字、valueが数字、っていうやり方もできます。

こういうことも書き溜めておかないと、必要なときになってググるはめになるんですよね。

RubyonRailsでLike演算子を使ったあいまい検索をする方法

2009-07-07
このエントリーをはてなブックマークに追加

:conditionsにクエリ文字列ごりごり書くなら別に気にしなくてもいいのですが、まぁたいていはインジェクション対策も兼ねてプレースホルダーを使うか、シンボルを使うかのどちらかでは無いでしょうか。

ハセテツは前者です。PHPでもPEARを使っていたので、プレースホルダーを使っていました。

で、Rails(ActiveRecord)でプレースホルダーを利用している状況でLike演算子を使ったあいまい検索はどうしたらよいものか、と意外にシンプルな部分で躓いたりします。キーワード検索機能を実装しない限り、Like演算子って使わないですよね。

:conditions => [“hoge like ?”, “%#{hogeParam}%”]

上記の書き方であいまい検索ができました。手抜きではあるのですが、これでhogeParamが空白文字列であっても検索はできます。nilだったらどうしようもないですけどね。

RubyonRailsでクッキーの処理をモジュールで共通化する方法

2009-06-18
このエントリーをはてなブックマークに追加

猛烈にはまったので、これは書き残しておかないと後々後悔すると思った次第であります。もしかするとハセテツがやり方を知らないだけで意外と簡単なのかもしれません。もし「いやいや、あんたが知らないだけでこうやるとラクチンだよ」という情報お持ちの方がいたら教えていただけると非常にありがたいです。

Railsでクッキーを扱う際、コントローラに書けば特に問題はありません。ただ、メソッドをモデルやモジュール側に書いて置くと、コールしたときに怒られます。これはApplicationControllerを継承していないからのようです。といって、他のコントローラの中にメソッドを書いておいてそれをコールしても怒られます。クッキーは「自分のトコで処理しろや」ということなのでしょうか。

かといって、クッキーのチェックなどなどをすべてのコントローラに書くのはDRYに反しているのでは、と悩んでおったのです。

module HogeModule
 
  def self.included(base)
  base.class_eval{

    def set_cookies

      cookies[:key] = {:value => “hogehoge”, :path => “/”, :expires => Time.now + 45 }
      end

    }
  end

end

上記のようなモジュールを用意します。これは、このモジュールがコントローラからインクルードされるとset_cookiesというメソッドがインクルードした方のコントローラ側に展開され、selfとして扱えるということです。つまり、コントローラ自身のメソッドになる、という感じです(多分)。

あとはコントローラからset_cookiesをコールするだけです。エラーはでず、クッキーも書き込まれます。

base.class_evalの中に:before_filterを書いておけば、インクルードされるたびにフィルターも実行されます。ハセテツはbefore_filterでクッキーのチェックを行い、メソッドで書き込みを行うように書きました。

RubyでPOST送信して結果を受け取る

2009-06-17
このエントリーをはてなブックマークに追加

RubyでHTTP経由でのXMLの受信と解析でGETする方法は書きましたが、POSTまでは書いていませんでした。今回はRubyでPOSTする方法です。GETで猛烈に長いクエリをつければPOSTできなくても同じことが実現できますが、まぁそこは気にせず。

require ‘net/http’
Net::HTTP.version_1_2
http = Net::HTTP.new(ホスト名, 80)
response = http.post( ‘/hoge.php’, ‘a=hoge&b=hogehoge’ )
p response.body

これだけ。ホスト名にはhttpは付けません。ポート番号は省略しても大丈夫です。Content-Type等は必要に応じて。newするときの第三引数です。「application/x-www-form-urlencoded」でいいのかな?ハセテツはつけてませんが、きちんとPOSTできてます。あー、相手がUTF8じゃない場合とかは文字コードの指定が必要かも。

responseの中身を見ればHTTPステータスコードとかも入っていると思います。その辺は割愛。

次はファイルのアップロードのやり方なんかも調べてみましょう。使うかどうかは微妙な気もしますが。

RubyonRailsでクエリを直接実行したいときの方法

2009-06-16
このエントリーをはてなブックマークに追加

ActiveRecord::Base.connection.execute(実行したいクエリ)

インデックス張りなおしたいときや更新クエリをごそっと投げたいときなんかは意外と重宝します。

これにコールバック関数とか組み合わせることができると便利なんですよね。あ、BackgrounDRb使えばいいのか。

RubyonRailsでメールを送信するサンプルをもうちょっと詳しく

2009-05-29
このエントリーをはてなブックマークに追加

RubyOnRailsで日本語メールを送信するでActionMailerの使い方を簡単に説明しましたが、これだけだと自分の備忘録にすらなっていないので追記。

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  :address => ‘SMTPサーバ’,
  :port => 25,
  :authentication => :login,
  :user_name => ‘アカウント’,
  :password => ‘パスワード’
}

上記をconfig/environment.rbに追記。

送信するときには「RubyOnRailsで日本語メールを送信する」の例であれば、コントローラ等から

Hoge.deliver_sendmail

とすればOK。「Hoge」はクラスですね。「deliver_」はお約束です。アンダースコアの後ろがメソッド名になります。~というメソッドに紐付くメールを送信しなさい、っていうイメージですかね。

RubyでHTTP経由でのXMLの受信と解析

2009-05-27
このエントリーをはてなブックマークに追加

まぁ簡単にいうとRSSリーダーみたいなことをしたいときに使います。相手がRSSじゃなくてもOKです。Web上のコンテンツを読み込みたいときに使います。ただ、今回のサンプルだとgetしかできないので、制限はあります。

require ‘open-uri’

open(“http://www.tt-house.com/atom.xml”){|f|
  data = f.read
  xmldoc = REXML::Document.new data
  xmldoc.elements.each(“feed/entry/title”){|element|
    p element.text
  }
}

文字コードのことは気にしてません。

これでハセテツラボRSSのタイトル一覧が取得できます。他のサービスとのマッシュアップ等にも使えますが、やっぱりデータのpostもできないと使い勝手は悪いですよね。

postをするサンプルは次回にしましょう。