Twitterの特定ハッシュタグの画像ツイートを抜き出したくて、GemにあるTwitterが便利そうだったのでRubyでやってみることにしました。表示するだけなので、サクッと作れるsinatraをチョイス。
Webサーバは、なんとなくnginx+unicornの組み合わせ。Rubyの王道パターンがまだ良くわからないので、とりあえず。
下準備
$ cd proj_dir
$ bundle init
$ vi Gemfile
# A sample Gemfile
source "https://rubygems.org"
gem 'sinatra'
gem 'twitter'
gem 'unicorn'
$ bundle install --path vendor/bundler
Twitterのハッシュタグ画像一覧を取得
require "twitter"
# TwitterDeveloperでアプリ登録&トークンを発行
client = Twitter::REST::Client.new do |config|
config.consumer_key = ""
config.consumer_secret = ""
config.access_token = ""
config.access_token_secret = ""
end
begin
client.search("#猫画像 -rt", :locale => "ja", :result_type => "recent", :include_entities => true).take(50).map do |tweet|
output = ''
if tweet.media? then
output = tweet.user.screen_name + "\t" + tweet.user.profile_image_url
tweet.media.each do |value|
output += "\t" + value.media_uri
end
puts output
end
end
rescue Twitter::Error::ClientError
puts "Error"
end
$ ruby twitter.rb
これで、指定ハッシュタグ(今回だと猫画像)のツイートを取得して、その中から画像が付いているものだけを抜き出せます。あくまで指定ハッシュタグを50件取得してから、画像付きだけ抜き出すので、50件の画像ツイートが抜き出せるわけではないです。
ここらへん、もっとうまくやるやり方あるのかな?
リアルタイムでツイートを取得する必要はないので、crondなどで定期的にツイート一覧をresult.txt
などに書き出すようにしてみます。
0 * * * * /hoge/twitter.rb > /hoge/result.txt
sinatraを使ってみる
データはtwitter.rbを使って取得出来ました。次はsinatraを使ってページを作ってみます。ロジックのmain.rbとビューのindex.erbを用意します。
require 'sinatra'
get '/' do
tweets = []
open("./result.txt") { |file|
while line = file.gets
name, icon, url = line.split("\t")
tweets.push({"name" => name, "url" => url, "icon" => icon})
end
}
@tweets = tweets
erb :index
end
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
</head>
<body>
<ul>
<% @tweets.each do |tweet| %>
<li>
<img src="<%="#{tweet["url"]}"%>" class="shot"><br>
<img src="<%="#{tweet["icon"]}"%>" class="icon"> @<%="#{tweet["name"]}"%>
</li>
<% end%>
</ul>
</body>
</html>
$ ruby main.rb
これで、sinatra単体でWebサーバが立ち上がります。http://localhost:4567/ にアクセスをすると、猫画像の一覧が表示されると思います。
nginx + unicornでWebサーバを立ち上げる
unicornの設定
unicornの起動スクリプトや設定ファイルを作ります。
$ mkdir -p tmp/pids
$ mkdir logs
$ mkdir public
# プロジェクトディレクトリのパス
@path = "/hoge/"
worker_processes 1
working_directory @path
timeout 300
listen '/tmp/app1.sock'
pid "#{@path}tmp/pids/unicorn.pid"
stderr_path "#{@path}logs/unicorn.stderr.log"
stdout_path "#{@path}logs/unicorn.stdout.log"
preload_app true
require './main.rb'
run MainApp
main.rbをunicorn用に書き換える
require 'sinatra/base'
class MainApp < Sinatra::Base
get '/' do
tweets = []
open("./result.txt") { |file|
while line = file.gets
name, icon, url = line.split("\t")
tweets.push({"name" => name, "url" => url, "icon" => icon})
end
}
@tweets = tweets
erb :index
end
end
$ bundle exec unicorn -c unicorn.rb -D
これでデーモンとしてunicornの立ち上げが完了です。
nginxの設定
なんかちょっと強引で荒っぽい設定だけど、とりあえず。
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
gzip on;
index index.html index.htm;
upstream unicorn_server {
server unix:/tmp/app1.sock;
}
server {
listen 80;
server_name example.com;
root /hoge/public;
location / {
if (!-f $request_filename) {
proxy_pass http://unicorn_server;
break;
}
}
}
}
/hoge/public以下のファイルはnginxで処理(画像とかCSSなスタティック系)、それ以外はunicornで処理するようにしてます。
$ sudo service nginx start
これでとりあえずnginx + unicornな構成でWebサーバが完成。ただこれだけだとunicornの死活監視ができていなかったりする…。Supervisordを使ったりするのがいいのかな。