Skip to content

Instantly share code, notes, and snippets.

@trapezoid
Created November 7, 2010 17:04
Show Gist options
  • Save trapezoid/666244 to your computer and use it in GitHub Desktop.
Save trapezoid/666244 to your computer and use it in GitHub Desktop.
IrcJabberGateway
require 'rubygems'
require 'xmpp4r'
require "iconv"
require "nkf"
require "kconv"
require "uri"
/*
# in nadokarc (NADOKA_Config)
BotFiles = [
'irchat'
]
BotConfig = [
{
:name => :irchat,
:user => "server_account@example.com",
:pass => "please-write-your-password",
:patterns => ["Trapezoid", "とらぺ", "トラペ" ,"おおたけ", "はると", "悠人", "ハルト"],
:channels => ["#reply@tig", "trapezoid"],
:target => "target_device_account@example.com",
},
]
*/
class IRChatMessage
attr_reader :prefix, :ch, :body
def initialize(prefix, ch, body)
@prefix = prefix
@ch = ch
@body = body
end
end
class IRCLog
attr_reader :data
def initialize(max_line)
@max_line = max_line
@data = []
end
def add(message)
@data.push message
@data.shift if @data.size > @max_line
end
def [](i)
@data[i]
end
end
class TypeableMap
DEFAULT_POINTER = "a"
def initialize(size = 3)
super()
@size = size
@hash = {}
@pointer = DEFAULT_POINTER
end
def insert(value)
if @pointer.succ.length > @size then
@pointer = DEFAULT_POINTER
else
@pointer.succ!
end
@hash[@pointer] = value
puts "TypableMap: " + @pointer.to_s + " => " + @hash[@pointer].ch.tosjis + " , " + @hash[@pointer].body.tosjis
end
def <<(value)
insert(value)
return @pointer
end
def [](key)
@hash[key]
end
def last
[@pointer, @hash[@pointer]]
end
def reset
@hash = {}
@pointer = DEFAULT_POINTER
end
end
class IRChat < Nadoka::NDK_Bot
def connect_jabber(user, password)
begin
connection = Jabber::Client.new(Jabber::JID.new(user))
connection.connect('talk.google.com', 5222)
connection.auth(password)
connection.send(Jabber::Presence.new.set_show(:chat))
connection.add_message_callback do |message|
params = message.body.split(" ")
cmd = params.shift
case cmd
when "say"
command_say(params.shift, params.join(" "))
when "get"
command_get(params.shift)
when "join"
command_join(params.shift)
when "leave"
command_leave(params.shift)
else
command_default(message.body)
end
end
puts "connected to google talk"
return connection
rescue => e
puts "ExceptionError: in connect_jabber"
p e
puts e.backtrace
return nil
end
end
def jabber
if (@jabber == nil) || @jabber.is_disconnected?
puts "reconnecting..."
@jabber = connect_jabber @user, @password
end
@jabber
end
def bot_initialize
@typeable_map = TypeableMap.new
@pickers = []
@post_queue = []
@jabber_queue = []
@last_msg = nil
@irclog = Hash.new do |hash, key|
hash[key] = IRCLog.new(10)
end
@jabber_mutex = Mutex.new
@ch_patterns = []
@default_ch_patterns = @bot_config[:channels] || []
@default_patterns = @bot_config[:patterns] || []
add_picker_callback do |m|
result = false
@default_patterns.each do |s|
pattern = Regexp.new(s, Regexp::IGNORECASE, "s")
if pattern =~ m.body.tosjis then
result = true
end
end
result
end
add_picker_callback do |m|
result = false
@default_ch_patterns.each do |s|
pattern = Regexp.new(s, Regexp::IGNORECASE, "s")
if pattern =~ m.ch.tosjis then
result = true
end
end
result
end
add_picker_callback do |m|
result = false
@ch_patterns.each do |s|
pattern = Regexp.new(s, Regexp::IGNORECASE, "s")
if pattern =~ m.ch.tosjis then
result = true
end
end
result
end
@user, @password = @bot_config[:user], @bot_config[:pass]
@target = @bot_config[:target] || "target_device_account@example.com"
@jabber = connect_jabber @user, @password
puts "irchat loaded"
end
def command_leave(ch)
unless ch
@ch_patterns = []
post_jabber(@target, "leave all channels")
return
end
@ch_patterns.delete(ch.tosjis)
post_jabber(@target, "#{ch.toutf8} leaved.")
end
def command_join(ch)
@ch_patterns.push ch.tosjis unless @ch_patterns.include? ch.tosjis
post_jabber(@target, "#{ch.toutf8} joined.")
end
def command_get(ch)
log = if @typeable_map[ch] then
@irclog[@typeable_map[ch].ch]
else
@irclog[ch.tosjis]
end
if log.data.size == 0 then
post_jabber(@target, "#{ch.toutf8} channel not found.")
return
end
log.data.each do |message|
puts message.body.tosjis
post_jabber(@target, "[#{message.ch.toutf8}]#{message.prefix.nick}: #{message.body.toutf8}")
sleep(1)
end
end
def command_say(map, body)
target = if @typeable_map[map] then
@typeable_map[map].ch.tosjis
elsif @irclog[map.tosjis].data.size > 0
map.tosjis
else
nil
end
if target then
@post_queue.push IRChatMessage.new("", target, body)
post_jabber(@target, "send to #{target.toutf8}")
else
post_jabber(@target, "invalid typable map.")
end
end
def command_default(body)
puts "PrePost: #{@last_msg ? @last_msg.ch : "dummy(#twitter@tig)"} / #{body}"
@post_queue.push IRChatMessage.new("", @last_msg ? @last_msg.ch : "#twitter@tig", body)
end
def on_topic(prefix, ch, topic)
ch = NKF.nkf "-s", ch
topic = NKF.nkf "-s", topic
end
def on_timer(time)
if @post_queue.size == 0 then
@post_queue = []
else
message = @post_queue.shift
puts "Post: #{message.ch} / #{message.body}"
send_privmsg(message.ch, message.body) unless message.body.index(/^\[#/)
end
@jabber_mutex.synchronize do
jabber.send(Jabber::Presence.new.set_show(:chat)) if jabber
end
end
def on_privmsg(prefix, ch, msg)
ch = NKF.nkf "-s", ch
msg = NKF.nkf "-s", msg
message = IRChatMessage.new(prefix, ch, msg)
if @pickers.any?{|picker| picker.call(message) == true} then
pointer = (@typeable_map << message)
unless @last_msg && (@last_msg.body == message.body) && (@last_msg.prefix.nick == message.prefix.nick)
post_jabber(@target, "[#{message.ch.toutf8}(#{pointer})]\n#{message.prefix.nick}: #{message.body.toutf8}")
end
@last_msg = message
end
@irclog[ch].add(message)
on_timer(nil)
false
end
def send_notice(ch, msg)
super(NKF.nkf("-j",ch), NKF.nkf("-j",msg))
end
def send_privmsg(ch, msg)
super(NKF.nkf("-j",ch), NKF.nkf("-j",msg))
end
def post_jabber(to, message)
jabber_message = Jabber::Message.new(to, message)
jabber_message.type = :chat
@jabber_mutex.synchronize do
puts "post to jabber"
jabber.send(jabber_message) if jabber
end
end
def add_picker_callback(&picker)
@pickers << picker
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment