hagino3000's blog

平成アーカイブス (更新停止)

Twitterのフレンドタイムラインを取得してDBに突っこむRubyスクリプト

タイムラインを取得してMySQLに重複を除いた形で保管する。数十秒毎にcronか何かでぶんまわして使う。MySQLにつっこんだ後は特定のユーザのみの抽出タイムラインを携帯から見れるようにしたり、いろいろな事に使う。

コード本体

require 'rubygems'
require 'twitter'
require 'twitter/console'
require 'json'
require 'time'
require 'yaml'
require 'active_record'

gem('twitter4r','0.3.0')

def log(msg)
  puts Time.new.to_s + ' ' + msg
end

def getClient(mode)
  begin
    config_file = File.join(File.dirname(__FILE__), 'config', 'twitter.yml')
    client = Twitter::Client.from_config(config_file, mode)
  rescue Exception => ex
    puts ex.message
    puts 'Cannot get twitter client.'
    raise
  end
  return client
end

def getConnection()
  config = nil
  File.open( 'config/database.yml') do |io|
    YAML.load_documents(io){|y|
      config = y
    }
  end
  
  ActiveRecord::Base.establish_connection(
    :adapter  => config["adapter"],
    :host     => config["host"],
    :username => config["username"],
    :password => config["password"],
    :database => config["database"],
    :socket   => config["socket"]
  )
end

class TwitterPost < ActiveRecord::Base
end

######################################################
# main
######################################################

log "start()"

system = nil

## Open control file
File.open( 'log/result.yml' ) do |io|
  YAML.load_documents(io){|y|
    system = y
  }
end

begin  
  client = getClient(system["mode"])
  
  statuses = Array.new
  friend_timeline = client.timeline_for(:friends) do |status|
    statuses << status
  end
  
  if statuses.size > 0
    system["last_status_get_time"] = Time.new.to_s
    system["last_exec_result"] = "success"
  else
    system["last_exec_result"] = "no data"
  end
  
  getConnection()
  
  statuses.each { |s|  
    exists = TwitterPost.find(:first, :conditions => [ "post_id = ?", s.id.to_s])

    # 新規postのみ登録
    unless exists
      TwitterPost.create(
        :user_id          => s.user.id.to_s,
        :user_name        => s.user.name,
        :user_screen_name => s.user.screen_name,
        :post_id          => s.id.to_s,
        :status_text      => s.text,
        :post_time        => s.created_at
      )
    end
  }
  
rescue Exception => exp
  log "Abnormaly ended"
  log exp.to_s
  system["last_exec_result"] = "error"
ensure
  system["last_exec_time"] = Time.new.to_s
  YAML.dump(system, File.open('log/result.yml', 'w'))
end

log "end()"

設定ファイル

Twitterアカウント(config/twitter.yml)
test:
    login: XXXXXXXXX
    password: XXXXXXXXXX
prod:
    login: XXXXXXXXX
    password: XXXXXXXXXX
Database接続(config/database.yml)
adapter: mysql
host: localhost
username: root
password: password
database: database_name
socket: /private/tmp/mysql.sock
結果出力用(log/result.yml)
mode: test
last_status_get_time:
last_exec_result:
last_exec_time:

DDL

create table twitter_posts (
	id int(11) unsigned not null auto_increment primary key,
	post_id int(11),
	user_id int(11),
	user_name varchar(200),
	user_screen_name varchar(200),
	status_text text,
	post_time varchar(200),
	created_at datetime,
	unique index idx_post_id (post_id)
)