Ruby MongoDB イン・アクション のTweetArchiverを作成する
概要
MongoDBについてはマニュアルを読むのが一番いいと思いますが、日本語で読めるMongoDB イン・アクションを進めています。
- 作者: Kyle Banker,Sky株式会社玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/12/14
- メディア: 大型本
- 購入: 5人 クリック: 55回
- この商品を含むブログ (8件) を見る
ただ、さすがに情報が古くなっていますね。Rubyでツイートを検索しMongoDBに登録・ブラウザに表示するサンプルアプリケーションが載っているのですが、ライブラリのAPIが変わっていたりとそのままでは動きませんでした。ということで動くように少し内容を更新してみます。
セットアップ
ライブラリのインストール
以下の3つ。ここは変わりませんね。
$ gem install mongo $ gem install twitter $ gem install sinatra
バージョンは以下。
設定ファイル
MongoDBのRubyドライバに変更が。書籍ではデータベース名を設定してましたが、接続文字列に変更。
Twitter APIでも4つのキーが必要になっているため設定ファイルに指定できるようにしておきました。キーの取得は以前Twitter Botを作成したときと同じでOKでした。
■ config.rb
CONNECTION_STRING = "mongodb://localhost/twitter-archive" COLLECTION_NAME = "tweets" TAGS = ["mongodb","ruby"] CONSUMER_KEY = "your_consumer_key" CONSUMER_SECRET = "your_consumer_secret" ACCESS_TOKEN = "your_access_token" ACCESS_TOKEN_SECRET = "your_access_token_secret"
ツイートの保存
MongoDBへの接続やインデックスの作成を変更しました。Twitter APIもconfigからキーを指定して呼び出すように変更。サンプルコードを見ていると、当時はキー指定とかなくてただAPI呼んでるだけ。シンプルで手軽だったんですね。
■ archiver.rb
require 'rubygems' require 'mongo' require 'twitter' require './config' class TweetArchiver def initialize(tag) db = Mongo::Client.new(CONNECTION_STRING) @tweet = db[COLLECTION_NAME] @tweet.indexes.create_many([ {:key => {id: 1}, unique: true}, {:key => {tags: 1,id: -1}} ]) @tag = tag @tweet_found = 0 end def update puts "Starting Twitter search for '#{@tag}'..." save_tweets_for(@tag) print "#{@tweet_found} tweets saved.\n\n" end def save_tweets_for(term) twitter_client = Twitter::REST::Client.new do |config| config.consumer_key = CONSUMER_KEY config.consumer_secret = CONSUMER_SECRET config.access_token = ACCESS_TOKEN config.access_token_secret = ACCESS_TOKEN_SECRET end twitter_client.search(term).each do |tweet| @tweet_found += 1 tweet_with_tag = tweet.to_hash.merge!({"tags" => [term]}) @tweet.insert_one(tweet_with_tag) end end end
TweetArchiverクラスの実行スクリプトには変更なし。
■ update.rb
require './config' require './archiver' TAGS.each do |tag| archiver = TweetArchiver.new(tag) archiver.update end
こいつを実行すればタグに指定した内容で検索して結果をMongoDBに登録してくれます。ツイートだけでなくユーザ名やプロフィールの内容にも引っかかるみたいですけど、今回その辺の細かいことは気にしないようにします。
$ ruby update.rb
ブラウザに表示
Sinatra?知らない子ですねぇ。RubyのWebアプリケーションフレームワークといえばRails一択だろ。その程度の認識しかありませんでした。
小規模なWebアプリであればSinatraの方が簡単、お手軽に作成できるらしい。初めて触ってみたんですがいいですねSinatra!
ここもMongoDBの接続とソートクエリを少し変更。
■ viewer.rb
require 'rubygems' require 'mongo' require 'sinatra' require './config' configure do db = Mongo::Client.new(CONNECTION_STRING) TWEETS = db[COLLECTION_NAME] end get '/' do if params['tag'] selector = {:tags => params['tag']} else selector = {} end @tweets = TWEETS.find(selector).sort({"id" => -1}) erb :tweets end
viewsサブディレクトリにerbファイルを作成します。DOCTYPE宣言をHTML5に。それから一部のtweetプロパティも変わっていたので変更しました。
■ views/tweets.erb
<!DOCTYPE> <html> <head> <style> body{ width:1000px; margin: 50px auto; } h2{ margin-top:2em; } </style> <title>Tweet Archive</title> </head> <body> <h1>Tweet Archive</h1> <% TAGS.each do |tag| %> <a href="/?tag=<%= tag %>"><%= tag %></a> <% end %> <% @tweets.each do |tweet| %> <h2><%= tweet['text'] %></h2> <p> <a href="http://twitter.com/<%= tweet['user']['screen_name'] %>"> <%= tweet['user']['name'] %> </a> on <%= tweet['created_at'] %> </p> <img src="<%= tweet['user']['profile_image_url'] %>" width="48" /> <% end %> </body> </html>
これでたぶんOKなはず。
あとはアプリケーションを実行してブラウザでhttp://localhost:4567へアクセス!
$ ruby viewer.rb