ツイートを検索して、その結果をニコニコ動画のコメント風に端末に流すスクリプトを書きました。
以下は「#桐間紗路生誕祭2016」を検索した際の動画です。
#桐間紗路生誕祭2016 pic.twitter.com/4H3QF4RZBP
— せーのすけ (@seinosuke_i) 2016年7月15日
動作環境
- Ubuntu 14.04
- Ruby 2.2.0
- ncursesw (gem) 1.4.9
- twitter (gem) 5.16.0
必要なもののインストールは以下のコマンドで
$ sudo apt-get install libncursesw5-dev
$ gem install ncursesw
$ gem install twitter
ソースコード
ncurses周りについては以前投稿した【Ruby】 ncurseswでゲームをつくる のコードをわりとそのまま使っているので、もしよろしければそちらを参照してください。
twitterのアクセストークンなどはご自分のもので置き換えてください。
main.rb
require 'thread'
require 'nkf'
require 'twitter'
require 'ncursesw'
class RTStream
BLANK = " "
def initialize
Ncurses.initscr
Ncurses.curs_set(0)
Ncurses.cbreak
Ncurses.noecho
Ncurses.use_default_colors
@client = Twitter::Streaming::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
@height = Ncurses.LINES
@width = Ncurses.COLS
@width -= 1 if @width.odd?
@rows = Array.new(@height) { Array.new(@width/2) { BLANK } }
@row_queues = Array.new(@height) { Queue.new }
@tweet_queue = Queue.new
end
def run(track_word = nil)
@threads = []
@threads << drawing_thread
@threads << stream_thread(track_word)
@threads << enqueue_thread
@threads.each(&:join)
close_scr
rescue Interrupt
@threads.each(&:kill)
close_scr
end
private
# 描画するスレッド
def drawing_thread
Thread.new do
loop do
@row_queues.each_with_index do |queue, i|
@rows[i].shift
@rows[i].push( queue.empty? ? BLANK : queue.deq )
Ncurses.mvaddstr(i, 0, @rows[i].join)
end
sleep 0.1
Ncurses.refresh
end
end
end
# ツイートを取得し enqueue 待ちツイートを enqueue していくスレッド
def stream_thread(track_word)
Thread.new do
if track_word
@client.filter(track: track_word) do |object|
if object.is_a? Twitter::Tweet
@tweet_queue.enq filter(object.text)
end
end
else
@client.user do |object|
# @client.sample do |object|
if object.is_a? Twitter::Tweet
@tweet_queue.enq filter(object.text)
end
end
end
end
end
# 表示待ちツイートを enqueue していくスレッド
def enqueue_thread
Thread.new do
loop do
i = @row_queues.find_index { |queue| queue.empty? }
sleep 0.1
redo unless i
tweet = @tweet_queue.deq
tweet.each_char { |ch| @row_queues[i].enq ch }
end
end
end
# 半角を全角にするフィルター(適当)
def filter(text)
NKF.nkf('-w -X', text) # 半角カタカナを全角に
.gsub(URI.regexp(["http", "https"]), "") # URLは削除
.tr('0-9a-zA-Z', '0-9a-zA-Z') # 半角英数字を全角に
.gsub(/[\R\s]/, " ") # 改行とかスペースは全角スペースに
.gsub(/[!-~]/, "") # 他の半角記号とかは削除
end
# ncursesの後処理
def close_scr
Ncurses::curs_set(1)
Ncurses.nocbreak
Ncurses.echo
Ncurses.endwin
end
end
rtstream = RTStream.new
track_word = "#桐間紗路生誕祭2016"
rtstream.run(track_word)
track_word
で検索したい文字列を与えます。
track_word
を与えない場合は自分のタイムラインが流れてきます。
おわりに
今回は日本語のツイートを想定していたので、処理の都合上ツイートを全て全角に揃える必要がありました。そのためフィルタをいろいろ頑張ってみたのですが、文字力、正規表現力が足りず結局なんだかよくわからん感じになりました(特殊文字とかのことは何も考えてない)。まあとりあえず動作したのでよかったということに。
これで端末上でいい感じにタイムラインを眺めることができます。
参考サイト
http://easyramble.com/convert-half-full-width-with-ruby.html
http://docs.ruby-lang.org/ja/2.2.0/class/URI.html#S_REGEXP