sinatra/unicorn/nginxでTwitterハッシュタグの画像一覧を表示する


Twitterの特定ハッシュタグの画像ツイートを抜き出したくて、GemにあるTwitterが便利そうだったのでRubyでやってみることにしました。表示するだけなので、サクッと作れるsinatraをチョイス。

Webサーバは、なんとなくnginx+unicornの組み合わせ。Rubyの王道パターンがまだ良くわからないので、とりあえず。

## 下準備

```
$ cd proj_dir
$ bundle init
$ vi Gemfile
```

```Gemfile
# A sample Gemfile
source "https://rubygems.org"

gem 'sinatra'
gem 'twitter'
gem 'unicorn'
```

```
$ bundle install --path vendor/bundler
```

## Twitterのハッシュタグ画像一覧を取得

```ruby:twitter.rb
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`などに書き出すようにしてみます。

```crontab
0 * * * * /hoge/twitter.rb > /hoge/result.txt
```

## sinatraを使ってみる

データはtwitter.rbを使って取得出来ました。次はsinatraを使ってページを作ってみます。ロジックのmain.rbとビューのindex.erbを用意します。

```main.rb
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
```

```views/index.erb
<!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
```

```unicorn.rb
# プロジェクトディレクトリのパス
@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
```

```config.ru
require './main.rb'
run MainApp
```

### main.rbをunicorn用に書き換える

```main.rb
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の設定

なんかちょっと強引で荒っぽい設定だけど、とりあえず。

```nginx.conf
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を使ったりするのがいいのかな。