Created
November 7, 2010 17:04
-
-
Save trapezoid/666244 to your computer and use it in GitHub Desktop.
IrcJabberGateway
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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