2008/10/03

@dabesaと@AngraMainyuに返事をさせる

前回作った彼らですが、ただ投稿するだけだと面白くないので、Replyに反応するようにしてみました。Reply文の中の最初に出てくる名詞・動詞・形容詞・感動詞に反応して、形態素テーブルから文章を作って返事をします。名詞・動詞・形容詞・感動詞が含まれていない場合には無視します(笑)
ただ時々、文字化けした形態素をWhere条件にしてクエリを実行したときにエラーで落ちます。文字コードとか記号の扱いがダメなんだと思うけど、今日は断念。よし、祝杯あげるか。


#! /usr/bin/ruby -Ku

require 'rubygems'
gem 'twitter4r'
require 'time'
require 'twitter'
require 'pit'

require 'MeCab'
require 'mysql'
require 'net/http'
require 'rexml/document'
require 'kconv'

begin
mysql = Mysql::new('localhost','USERNAME','PASSWORD','DATABASENAME')
c = MeCab::Tagger.new(ARGV.join(" "))

config = Pit.get("dabesa")
cl = Twitter::Client.new(config)

flg = 0
sid = nil
idfile = open("repid.txt",'r')
idfile.each do |id| sid = id.chop end
idfile.close

req = Net::HTTP::Get.new("/statuses/replies.xml")
req.basic_auth("dabesa","PASSWORD")
xml = Net::HTTP.start('twitter.com',80) {|http|
http.request(req).body
}

doc=nil
doc=REXML::Document.new xml
doc.elements.each('/statuses/status') do |elm|
scname = elm.elements['user/screen_name'].text.to_s

if flg == 0 and elm.elements['id'].text.to_i >= sid.to_i then
idfile = open("repid.txt",'w')
idfile.puts elm.elements['id'].text.to_i
idfile.close
flg = 1
end
if elm.elements['id'].text.to_i <= sid.to_i then
mysql.close
exit
end
post = elm.elements['text'].text
post.chop!
post.gsub!(/@dabesa/i,'')
post.gsub!(/@/,'')
n = c.parseToNode(post)
n = n.next
nword = nil

while n do
feature = n.feature.split(/,/)
case feature[0].to_s
when Kconv.kconv("名詞",Kconv::UTF8),Kconv.kconv("動詞",Kconv::UTF8),Kconv.kconv("形容詞",Kconv::UTF8),Kconv.kconv("感動詞",Kconv::UTF8)
nword = n.surface
break
end
n = n.next
end

if nword != nil then
postline = nword
res = mysql.prepare("select surface,nextword from DATABASENAME where surface='#{Mysql::quote nword}'")
res.execute

while res.num_rows != 0 and nword != "EOL" do
nextwords = res.fetch[1].to_s.split(/<>/)
i = nextwords.size
nword = nextwords[rand(i)]
if nword == nil then nword = "EOL" end
postline = postline.to_s + nword.to_s
res = mysql.prepare("select surface,nextword from DATABASENAME where surface='#{Mysql::quote nword}'")
res.execute
end
postline.gsub!(/@/,'.@')
mess = "@" + scname + " " + postline.gsub(/EOL/,'')
cl.status(:post,mess)

end
end
mysql.close

rescue
print "RuntimeError: ", $!, "\n";
end