Skip to content

Instantly share code, notes, and snippets.

@masuidrive
Created January 3, 2009 07:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masuidrive/42812 to your computer and use it in GitHub Desktop.
Save masuidrive/42812 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'rubygems'
require 'eventmachine'
module Log2IRC
include EventMachine::Protocols::LineText2
attr_reader :channels
class Message
attr_reader :line, :pattern, :match
def initialize(line, pattern=nil, match=nil)
@line, @pattern, @match = line, pattern, match
end
def [](index)
@cols ||= @line.split(' ')
@cols[index]
end
end
class Channel
attr_accessor :name, :topic, :session
def initialize(session, name)
@session, @name = session, name
@queue, @be_active = [], false
end
def active?
@be_active
end
def active
@be_active = true
flush
end
def deactive
@be_active = false
end
def tell(msg)
if @be_active
@session.send_data "PRIVMSG #{@name} :#{msg}\r\n"
else
@queue << msg
end
end
def flush
return unless active?
while msg = @queue.shift
tell(msg)
end
end
end
def initialize(options={})
define_handlers
@channels, @pending_join = { }, []
options.each do |opt, val|
instance_variable_set("@opt_#{opt}", val)
end
@opt_user ||= 'logbot'
if @opt_channels
@opt_channels = [@opt_channels] unless @opt_channels.is_a?(Array)
@opt_channels.each do |name|
join name
end
end
end
def self.connect(options)
EM.connect options[:server], (options[:port] || 6667), self, options
end
def post_init
command "USER", [@opt_user]*4
command "NICK", @opt_user
command("NickServ IDENTIFY",@opt_password) if @opt_password
end
def active?
@be_active
end
def active
@be_active = true
while name = @pending_join.shift
join name
end
end
def deactive
@be_active = false
channels.values.each do |channel|
channel.deactive
end
@pending_join += channels.keys
end
def join(name)
channel = (channels[name] ||= Channel.new(self, name))
if active?
command "JOIN", name
else
@pending_join << name
end
unless respond_to?(name[1..-1])
instance_eval <<-__EVAL__
def #{name[1..-1]}(msg)
@channels["#{name}"].tell(msg)
end
__EVAL__
end
end
def receive_line(line)
puts line
@handlers.each do |block, pattern|
match = pattern.match(line)
next if match.nil?
block.call Message.new(line, pattern, match)
end
end
def command(*cmd)
send_data "#{cmd.flatten.join(' ')}\r\n"
end
def unbind
deactive
EM.add_timer(3) do
reconnect @opt_server, (@opt_port || 6667)
post_init
end
end
private
def define_handlers
message_on /^PING/ do |message|
command 'PONG', message[1]
end
message_on(/^:\S+ JOIN \:(#.+)/) do |message|
channel = @channels[message[2][1..-1]]
channel.active if channel
end
message_on(/^:\S+ 001/) do |message|
active
end
end
private
def message_on(expression = nil, &block)
@handlers ||= { }
unless expression
@handlers[block] = /./
else
if expression.is_a?(Regexp)
@handlers[block] = expression
else
pattern = %r{^\:(\S+) (#{expression.to_s}) (\S+) \:(.+)}
@handlers[block] = pattern
end
end
end
end
if $0==__FILE__
EventMachine::run do
# irc = EventMachine::connect('10.0.1.32', 6667, Log2IRC, :user => 'bot23', :channels => ['#debug', '#warn', '#error', '#fatal', '#info'])
irc = Log2IRC.connect(:server => '10.0.1.32', :user => 'bot23', :channels => ['#debug', '#warn', '#error', '#fatal', '#info'])
Thread.start {
# sleep 6
begin
irc.debug 'message to #debug'
irc.warn 'message to #warn'
irc.error 'message to #error'
irc.fatal 'message to #fatal'
irc.info 'message to #info'
rescue => e
puts e,e.backtrace
end
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment