Ruby-IRC 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/lib/IRC.rb CHANGED
@@ -26,9 +26,7 @@ class IRC
26
26
 
27
27
  topic_proc = Proc.new { |event|
28
28
  self.channels.each { |chan|
29
- puts "Examine channel #{chan.name} for #{event.channel}"
30
29
  if chan == event.channel
31
- puts "Setting topic: #{event.message}"
32
30
  chan.topic = event.message
33
31
  end
34
32
  }
@@ -62,11 +60,19 @@ class IRC
62
60
  # method. Events yielded from the IRCConnection handler are
63
61
  # processed and then control is returned to IRCConnection
64
62
  def connect
63
+ quithandler = lambda { send_quit(); IRCConnection.quit }
64
+ trap("INT", quithandler)
65
+ trap("TERM", quithandler)
66
+
65
67
  IRCConnection.handle_connection(@server, @port, @nick, @realname) do
66
68
  # Log in information moved to IRCConnection
69
+ threads = []
67
70
  IRCConnection.main do |event|
68
- event.process
71
+ threads << Thread.new(event) {|localevent|
72
+ localevent.process
73
+ }
69
74
  end
75
+ threads.each {|thr| thr.join }
70
76
  end
71
77
  end
72
78
 
@@ -6,8 +6,22 @@ class IRCConnection
6
6
  @@events = Hash.new()
7
7
  # Creates a socket connection and then yields.
8
8
  def IRCConnection.handle_connection(server, port, nick='ChangeMe', realname='MeToo' )
9
+ @server = server;
10
+ @port = port
11
+ @nick = nick
12
+ @realname = realname
9
13
  socket = create_tcp_socket(server, port)
10
- add_IO_socket(socket) {|sock| IRCEvent.new(sock.readline.chomp) }
14
+ add_IO_socket(socket) {|sock|
15
+ begin
16
+ IRCEvent.new(sock.readline.chomp)
17
+ rescue Errno::ECONNRESET
18
+ # Catches connection reset by peer, attempts to reconnect
19
+ # after sleeping for 10 second.
20
+ remove_IO_socket(sock)
21
+ sleep 10
22
+ handle_connection(@server, @port, @nick, @realname)
23
+ end
24
+ }
11
25
  send_to_server "NICK #{nick}"
12
26
  send_to_server "USER #{nick} 8 * :#{realname}"
13
27
  if block_given?
@@ -46,8 +60,15 @@ class IRCConnection
46
60
  # and yields the data to the sockets event handler.
47
61
  def IRCConnection.do_one_loop
48
62
  read_sockets = select(@@readsockets, nil, nil, nil);
49
- read_sockets[0].each {|sock|
50
- yield @@events[sock.to_i].call(sock)
63
+ read_sockets[0].each {|sock|
64
+ if sock.eof? && sock == @@socket
65
+ p "Detected Socket Close"
66
+ remove_IO_socket(sock)
67
+ sleep 10
68
+ handle_connection(@server, @port, @nick, @realname)
69
+ else
70
+ yield @@events[sock.to_i].call(sock)
71
+ end
51
72
  }
52
73
  end
53
74
 
@@ -66,6 +87,11 @@ class IRCConnection
66
87
  @@readsockets.push(socket)
67
88
  @@events[socket.to_i] = event_generator
68
89
  end
90
+
91
+ def IRCConnection.remove_IO_socket(socket)
92
+ sock.close
93
+ @@readsockets.delete_if {|item| item == sock }
94
+ end
69
95
  end
70
96
 
71
97
 
@@ -82,7 +82,7 @@ class IRCEvent
82
82
  handled = 1
83
83
  end
84
84
  if !handled
85
- puts "No handler for event type #@event_type in #{self.class}"
85
+ # puts "No handler for event type #@event_type in #{self.class}"
86
86
  end
87
87
  end
88
88
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: Ruby-IRC
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.6
7
- date: 2006-12-08 00:00:00 -08:00
6
+ version: 1.0.7
7
+ date: 2006-12-14 00:00:00 -08:00
8
8
  summary: An IRC Client library
9
9
  require_paths:
10
10
  - lib
@@ -35,10 +35,6 @@ files:
35
35
  - lib/IRCUser.rb
36
36
  - lib/IRCUtil.rb
37
37
  - lib/eventmap.yml
38
- - lib/IRCEvent.rb.~1.5.~
39
- - lib/IRCConnection.rb.~1.2.~
40
- - lib/#IRCEvent.rb#
41
- - lib/IRC.rb.~1.4.~
42
38
  - README
43
39
  test_files: []
44
40
 
@@ -1,89 +0,0 @@
1
- require 'yaml'
2
-
3
- # This is a lookup class for IRC event name mapping
4
- class EventLookup
5
- @@lookup = YAML.load_file("#{File.dirname(__FILE__)}/eventmap.yml")
6
-
7
- # returns the event name, given a number
8
- def EventLookup::find_by_number(num)
9
- return @@lookup[num.to_i]
10
- end
11
- end
12
-
13
-
14
- # Handles an IRC generated event.
15
- # Handlers are for the IRC framework to use
16
- # Callbacks are for users to add.
17
- # Both handlers and callbacks can be called for the same event.
18
- class IRCEvent
19
- @@handlers = { 'ping' => lambda {|event| IRCConnection.send_to_server("PONG #{event.message}") } }
20
- @@callbacks = Hash.new()
21
- attr_reader :hostmask, :message, :event_type, :from, :channel, :target, :mode, :stats
22
- def initialize (line)
23
- line.sub!(/^:/, '')
24
- mess_parts = line.split(':', 2);
25
- # mess_parts[0] is server info
26
- # mess_parts[1] is the message that was sent
27
- @message = mess_parts[1]
28
- @stats = mess_parts[0].scan(/[-\w.\#\@]+/)
29
- puts "Event: #{line}"
30
- if @stats[0].match(/^PING/)
31
- @event_type = 'ping'
32
- elsif @stats[1] && @stats[1].match(/^\d+/)
33
- @event_type = EventLookup::find_by_number(@stats[1]);
34
- @channel = @stats[3]
35
- else
36
- @event_type = @stats[2].downcase if @stats[2]
37
- end
38
-
39
- if @event_type != 'ping'
40
- @from = @stats[0]
41
- @user = IRCUser.create_user(@from)
42
- end
43
- @hostmask = @stats[1] if %W(privmsg join).include? @event_type
44
- @channel = @stats[3] if @stats[3] && !@channel
45
- @target = @stats[5] if @stats[5]
46
- @mode = @stats[4] if @stats[4]
47
-
48
-
49
-
50
- # Unfortunatly, not all messages are created equal. This is our
51
- # special exceptions section
52
- if @event_type == 'join'
53
- @channel = @message
54
- end
55
-
56
- end
57
-
58
- # Adds a callback for the specified irc message.
59
- def IRCEvent.add_callback(message_id, &callback)
60
- @@callbacks[message_id] = callback
61
- end
62
-
63
- # Adds a handler to the handler function hash.
64
- def IRCEvent.add_handler(message_id, proc=nil, &handler)
65
- if block_given?
66
- @@handlers[message_id] = handler
67
- elsif proc
68
- @@handlers[message_id] = proc
69
- end
70
- end
71
-
72
- # Process this event, preforming which ever handler and callback is specified
73
- # for this event.
74
- def process
75
- handled = nil
76
- if @@handlers[@event_type]
77
- @@handlers[@event_type].call(self)
78
- handled = 1
79
- end
80
- if @@callbacks[@event_type]
81
- @@callbacks[@event_type].call(self)
82
- handled = 1
83
- end
84
- if !handled
85
- puts "No handler for event type #@event_type in #{self.class}"
86
- end
87
- end
88
- end
89
-
@@ -1,138 +0,0 @@
1
-
2
- require 'socket'
3
- require 'IRCConnection'
4
- require 'IRCEvent'
5
- require 'IRCChannel'
6
- require 'IRCUser'
7
- require 'IRCUtil'
8
-
9
-
10
-
11
- # Class IRC is a master class that handles connection to the irc
12
- # server and pasring of IRC events, through the IRCEvent class.
13
- class IRC
14
- @channels = nil
15
- # Create a new IRC Object instance
16
- def initialize( nick, server, port, realname='RBot')
17
- @nick = nick
18
- @server = server
19
- @port = port
20
- @realname = realname
21
- @channels = Array.new(0)
22
- # Some good default Event handlers. These can and will be overridden by users.
23
- # Thses make changes on the IRCbot object. So they need to be here.
24
-
25
- # Topic events can come on two tags, so we create on proc to handle them.
26
-
27
- topic_proc = Proc.new { |event|
28
- self.channels.each { |chan|
29
- puts "Examine channel #{chan.name} for #{event.channel}"
30
- if chan == event.channel
31
- puts "Setting topic: #{event.message}"
32
- chan.topic = event.message
33
- end
34
- }
35
- }
36
-
37
- IRCEvent.add_handler('332', topic_proc)
38
- IRCEvent.add_handler('topic', topic_proc)
39
-
40
-
41
- end
42
-
43
- attr_reader :nick, :server, :port
44
-
45
- # Join a channel, adding it to the list of joined channels
46
- def add_channel channel
47
- join(channel)
48
- self
49
- end
50
-
51
- # Returns a list of channels joined
52
- def channels
53
- @channels
54
- end
55
-
56
- # Alias for IRC.connect
57
- def start
58
- self.connect
59
- end
60
-
61
- # Open a connection to the server using the IRC Connect
62
- # method. Events yielded from the IRCConnection handler are
63
- # processed and then control is returned to IRCConnection
64
- def connect
65
- IRCConnection.handle_connection(@server, @port) do
66
- IRCConnection.send_to_server "NICK #{@nick}"
67
- IRCConnection.send_to_server "USER #{@nick} 8 * :#{@realname}"
68
- IRCConnection.main do |event|
69
- event.process
70
- end
71
- end
72
- end
73
-
74
- # Joins a channel on a server.
75
- def join(channel)
76
- if (IRCConnection.send_to_server("JOIN #{channel}"))
77
- @channels.push(IRCChannel.new(channel));
78
- end
79
- end
80
-
81
- # Leaves a channel on a server
82
- def part(channel)
83
- if (IRCConnection.send_to_server("PART #{channel}"))
84
- @channels.delete_if {|chan| chan.name == channel }
85
- end
86
- end
87
-
88
- # Sends a private message, or channel message
89
- def send_message(to, message)
90
- IRCConnection.send_to_server("privmsg #{to} :#{message}");
91
- end
92
-
93
- # Sends a notice
94
- def send_notice(to, message)
95
- IRCConnection.send_to_server("NOTICE #{to} :#{message}");
96
- end
97
-
98
- # performs an action
99
- def send_action(to, action)
100
- send_ctcp(to, 'ACTION', action);
101
- end
102
-
103
- # send CTCP
104
- def send_ctcp(to, type, message)
105
- IRCConnection.send_to_server("privmsg #{to} :\001#{type} #{message}");
106
- end
107
-
108
- # Quits the IRC Server
109
- def send_quit
110
- IRCConnection.send_to_server("QUIT : Quit ordered by user")
111
- end
112
-
113
- # Ops selected user.
114
- def op(channel, user)
115
- IRCConnection.send_to_server("MODE #{channel} +o #{user}")
116
- end
117
-
118
- # Changes the current nickname
119
- def ch_nick(nick)
120
- IRCConnection.send_to_server("NICK #{nick}")
121
- @nick = nick
122
- end
123
-
124
- # Removes operator status from a user
125
- def deop(channel, user)
126
- IRCConnection.send_to_server("MODE #{channel} -o #{user}")
127
- end
128
-
129
- # Changes target users mode
130
- def mode(channel, user, mode)
131
- IRCConnection.send_to_server("MODE #{channel} #{mode} #{user}")
132
- end
133
-
134
- # Retrievs user information from the server
135
- def get_user_info(user)
136
- IRCConnection.send_to_server("WHO #{user}")
137
- end
138
- end
@@ -1,59 +0,0 @@
1
-
2
- # Handles connection to IRC Server
3
- class IRCConnection
4
- @@quit = 0
5
- @@readsockets = Array.new(0)
6
- @@events = Hash.new()
7
- # Creates a socket connection and then yields.
8
- def IRCConnection.handle_connection(server, port)
9
- @@server = server
10
- @@port = port
11
- @@socket = TCPsocket.open(server, port)
12
- add_IO_socket(@@socket) {|sock| IRCEvent.new(sock.readline.chomp) }
13
- yield
14
- @@socket.close
15
- end
16
-
17
- # Sends a line of text to the server
18
- def IRCConnection.send_to_server(line)
19
- @@socket.write(line + "\n")
20
- end
21
-
22
- # This loop monitors all IO_Sockets IRCConnection controls
23
- # (including the IRC socket) and yields events to the IO_Sockets
24
- # event handler.
25
- def IRCConnection.main
26
- while(@@quit == 0)
27
- do_one_loop { |event|
28
- yield event
29
- }
30
- end
31
- end
32
-
33
- # Makes one single loop pass, checking all sockets for data to read,
34
- # and yields the data to the sockets event handler.
35
- def IRCConnection.do_one_loop
36
- read_sockets = select(@@readsockets, nil, nil, nil);
37
- read_sockets[0].each {|sock|
38
- yield @@events[sock.to_i].call(sock)
39
- }
40
- end
41
-
42
- # Ends connection to the irc server
43
- def IRCConnection.quit
44
- @@quit = 1
45
- end
46
-
47
- # Retrieves user info from the server
48
- def IRCConnection.get_user_info(user)
49
- IRCConnection.send_to_server("WHOIS #{user}")
50
- end
51
-
52
- # Adds a new socket to the list of sockets to monitor for new data.
53
- def IRCConnection.add_IO_socket(socket, &event_generator)
54
- @@readsockets.push(socket)
55
- @@events[socket.to_i] = event_generator
56
- end
57
- end
58
-
59
-
@@ -1,89 +0,0 @@
1
- require 'yaml'
2
-
3
- # This is a lookup class for IRC event name mapping
4
- class EventLookup
5
- @@lookup = YAML.load_file("#{File.dirname(__FILE__)}/eventmap.yml")
6
-
7
- # returns the event name, given a number
8
- def EventLookup::find_by_number(num)
9
- return @@lookup[num.to_i]
10
- end
11
- end
12
-
13
-
14
- # Handles an IRC generated event.
15
- # Handlers are for the IRC framework to use
16
- # Callbacks are for users to add.
17
- # Both handlers and callbacks can be called for the same event.
18
- class IRCEvent
19
- @@handlers = { 'ping' => lambda {|event| IRCConnection.send_to_server("PONG #{event.message}") } }
20
- @@callbacks = Hash.new()
21
- attr_reader :hostmask, :message, :event_type, :from, :channel, :target, :mode, :stats
22
- def initialize (line)
23
- line.sub!(/^:/, '')
24
- mess_parts = line.split(':', 2);
25
- # mess_parts[0] is server info
26
- # mess_parts[1] is the message that was sent
27
- @message = mess_parts[1]
28
- @stats = mess_parts[0].scan(/[-\w.\#\@]+/)
29
- puts "Event: #{line}"
30
- if @stats[0].match(/^PING/)
31
- @event_type = 'ping'
32
- elsif @stats[1] && @stats[1].match(/^\d+/)
33
- @event_type = EventLookup::find_by_number(@stats[1]);
34
- @channel = @stats[3]
35
- else
36
- @event_type = @stats[2].downcase if @stats[2]
37
- end
38
-
39
- if @event_type != 'ping'
40
- @from = @stats[0]
41
- @user = IRCUser.create_user(@from)
42
- end
43
- @hostmask = @stats[1] if %W(privmsg join).include? @event_type
44
- @channel = @stats[3] if @stats[3] && !@channel
45
- @target = @stats[5] if @stats[5]
46
- @mode = @stats[4] if @stats[4]
47
-
48
-
49
-
50
- # Unfortunatly, not all messages are created equal. This is our
51
- # special exceptions section
52
- if @event_type == 'join'
53
- @channel = @message
54
- end
55
-
56
- end
57
-
58
- # Adds a callback for the specified irc message.
59
- def IRCEvent.add_callback(message_id, &callback)
60
- @@callbacks[message_id] = callback
61
- end
62
-
63
- # Adds a handler to the handler function hash.
64
- def IRCEvent.add_handler(message_id, proc=nil, &handler)
65
- if block_given?
66
- @@handlers[message_id] = handler
67
- elsif proc
68
- @@handlers[message_id] = proc
69
- end
70
- end
71
-
72
- # Process this event, preforming which ever handler and callback is specified
73
- # for this event.
74
- def process
75
- handled = nil
76
- if @@handlers[@event_type]
77
- @@handlers[@event_type].call(self)
78
- handled = 1
79
- end
80
- if @@callbacks[@event_type]
81
- @@callbacks[@event_type].call(self)
82
- handled = 1
83
- end
84
- if !handled
85
- puts "No handler for event type #@event_type in #{self.class}"
86
- end
87
- end
88
- end
89
-