Skip to content

Instantly share code, notes, and snippets.

@kkosuge
Created November 19, 2011 14:46
Show Gist options
  • Save kkosuge/1378905 to your computer and use it in GitHub Desktop.
Save kkosuge/1378905 to your computer and use it in GitHub Desktop.
最近のタイムライン保存事情

最近のタイムライン保存事情

TwitterのタイムラインはJSONで流れてくるので、JSONぽい形式でデータを突っ込むMongoDBと相性が良い。
今まではtimeline.logとして書き出してたけど、GB単位に膨らんだテキストファイル重すぎて扱いづらいし最近は専らMongoDBに流し込んでます。
全部保存しとくと、誰がいつどのtweetを消したとか分かって異常に便利。こわい。
全文検索したいときがあるので、ツイイトはわかち書きでsplitして配列としても入れといてます。
MongoDBは配列で保存出来て、配列内にインデックスを貼れるので、簡単にいい感じの検索機能が作れて楽しいですね。
TLの全保存やってる人自体はそこら中に居るだろうし目新しいことは特にないでした。

# coding:utf-8
require 'time'
require 'rubygems'
require 'userstream'
require 'json'
require 'mongo'
require 'MeCab'
require 'pp'

class Userstream
  def process(http, request, &block)
    raise unless block_given?
    http.request(request) do |response|
      response.read_body do |chunk|
        yield JSON.parse(chunk) rescue next
      end
    end
  end
end

db = Mongo::Connection.new.db('twitter')
# db.collection('status').remove
# db.collection('friends').remove
# db.collection('event').remove

consumer = OAuth::Consumer.new(
  'CONSUMER_KEY',
  'CONSUMER_SECRET',
  {site: 'https://userstream.twitter.com/'}
)
access_token = OAuth::AccessToken.new(
  consumer,
  'OAUTH_TOKEN',
  'OAUTH_TOKEN_SECRET'
)

# デーモン化
Process.daemon

userstream = Userstream.new(consumer, access_token)
userstream.user do |data|

  coll_key = data['friends'] ? 'friends'
           : data['event']   ? 'event'
           : data['delete']  ? 'delete'
           : 'status'

  [data, data['source'], data['target'], data['target_object']].each do |h|
    h['created_at'] = Time.parse(h['created_at']) if h && h['created_at']
  end

  if data['text']
    m = MeCab::Tagger.new("-Owakati")
    data['keywords'] = m.parse(data['text']).split(' ').map{|w| w.force_encoding("utf-8")}
  end

  db.collection(coll_key).insert(data)

  #puts "#{data['user']['screen_name']}: #{data['text']}" if data['text']
  #puts "☆ #{data['source']['screen_name']}: #{data['target_object']['text']}" if data['event'] == 'favorite'
end

全検

db = Mongo::Connection.new.db('twitter')
keywords = MeCab::Tagger.new("-Owakati").parse(ARGV.join).split(' ')
db['status'].find({'keywords'=>{'$all'=>keywords}},{:sort=>['id', 'ascending']}).each do |s|
  puts "#{s['user']['screen_name']}: #{s['text']}"
end

# ruby zenken.rb 二郎 国王
# ...
# 9m: ブータンの国王と二郎食ってる
# NStyles: 照英が泣きながらブータン国王が残した二郎ヤサイマシマシニンニクカラメアブラを完食する画像ください。
# hatebu: ブータン国王がラーメン二郎を食してみたいと要望し、ラーメン二郎目黒店がお休みに:ハムスター速報 (59 users) http://t.co/LfkiOy2K
# ...

ruby 1.9.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment