読者です 読者をやめる 読者になる 読者になる

IRCでTwitterをごにょごにょできるのを作った

Ruby IRC

それtigで(ry、という話なんですが、Growlでアイコンと一緒に表示させるのがtigでやろうとして挫折したので、自分でごにょごにょしました。といってもIRC botを自分で作っていたら卒業できなくなるので、nadokaさんを使うことにしました。

nadokaさんは前少し触ってたりもする。

なんかそういうわけで、適当にコピペを繰り返して作りましたw。

  • IRCで、Twitterのtimelineを追える
    • 複数立ち上げれば、マルチアカウントでいける
    • チャネルに対応させればいい
  • 特定ユーザーのlogを取得できる
  • 発言をgrowlで表示させる

などができます。なんかきたなくてよくないプログラミングという感じですが、欲しいものができたのでよいとするw。

#!/opt/local/bin/ruby
# -*- coding: utf-8 -*-

require 'rubygems'
require "date"
require 'twitter'
require 'open-uri'
require 'yaml'
require 'cgi'
require 'pp'

$KCODE = 'UTF8'

class TwitterGrowlBot < Nadoka::NDK_Bot
  def bot_initialize
    @ch = @bot_config[:ch]
    id = @bot_config[:id]
    pass = @bot_config[:pass]
    @twitter = TwitterTail.new(id, pass)
    @twittersearch = TwitterSearch.new(@bot_config[:file_dir])
  end
  def on_privmsg prefix, ch, msg
    msg = msg.chomp
    if msg == "\001VERSION\001"
      puts "do nothing..."
    elsif msg =~ /^\/(.*)/
      send_privmsg(@ch,"send query #{$1}")
      @twittersearch.user_log($1).each{|log|
        send_privmsg(@ch,log)
        sleep 1      
      }
    else
      @twitter.update(msg)
    end
  end
  def on_timer t
    tls = @twitter.read_timeline
    pp tls
    tls.each{|tl|
      pp tl
      send_privmsg(@ch,"("+tl[0]+") "+tl[1])
      sleep 1
    }
  end
end

class TwitterTail
  def initialize(id, pass)
    @twitter = Twitter::Base.new(id, pass)
  end  
  def update(text)
    @twitter.update(text)
  end
  def read_timeline
    @list ||= []
    cache_size = 100
    timeline = @twitter.timeline(:friends).reverse
    timeline_array = []
    timeline.each do |status|
      next if @list.include?(status.id)
      @list << status.id
      user = status.user
      screen_name = user.screen_name
      text = CGI.unescapeHTML(status.text)
      
      icon = get_usericon(screen_name, user.profile_image_url)
      timeline_array.push(notify(screen_name, text, icon))
    end
    @list = @list.last(cache_size)
    return timeline_array
  end
  def notify(title, msg, img = nil)
    cmd = "growlnotify -n twittertail -m #{msg.inspect} #{title} -H localhost"
    cmd << " --image #{img}" if img
    system cmd
    return [title, msg]
  end
  def get_usericon(screen_name, icon_url)
    cache_dir_path = File.dirname(__FILE__) + '/icons/'
    Dir.mkdir(cache_dir_path) unless File.exist?(cache_dir_path)    
    icon_path = cache_dir_path + screen_name + '.ico'
    cache_lifetime = 60 * 60 * 24
    if(!File.exist?(icon_path) || (File.mtime(icon_path) + cache_lifetime < Time.now))
      File.open(icon_path, 'w') do |f|
        open(icon_url){|data| f.write(data.read(1024 * 10))}
      end      
    end
    icon_path
  end
end
class TwitterSearch
  def initialize(file_dir)
    @file_dir = file_dir
    @timelines = []
  end
  def user_log(users)
    users = users.split
    pp users
    logs = []
    day = Time.now
    Dir::glob(@file_dir + "*.txt.mule-utf-8").each {|f|
      f = open(f)
      f.each {|line|
        users.each{|user|
          if line =~ /\d\d:\d\d <(.*?)> (\(#{user}\)) (.*)/
            logs.push $2 + $3
          end
        }
      }
      f.close
    }
    return logs.uniq.reverse[0..9].reverse
  end
end