net-yail 1.4.0 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  require 'rubygems'
4
- require 'net/yail/IRCBot'
4
+ require 'net/yail/irc_bot'
5
5
  require 'date'
6
6
 
7
7
  class LoggerBot < IRCBot
data/lib/net/yail.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'socket'
2
2
  require 'thread'
3
3
  require 'yaml'
4
+ require 'logger'
4
5
 
5
6
  # To make this library seem smaller, a lot of code has been split up and put
6
7
  # into semi-logical files. I don't really like this hacky solution, but I
@@ -242,11 +243,28 @@ class YAIL
242
243
  :socket # TCPSocket instance
243
244
  )
244
245
  attr_accessor(
245
- :silent,
246
- :loud,
247
- :throttle_seconds
246
+ :throttle_seconds,
247
+ :log
248
248
  )
249
249
 
250
+ def silent
251
+ @log.warn '[DEPRECATED] - Net::YAIL#silent is deprecated as of 1.4.1'
252
+ return @log_silent
253
+ end
254
+ def silent=(val)
255
+ @log.warn '[DEPRECATED] - Net::YAIL#silent= is deprecated as of 1.4.1'
256
+ @log_silent = val
257
+ end
258
+
259
+ def loud
260
+ @log.warn '[DEPRECATED] - Net::YAIL#loud is deprecated as of 1.4.1'
261
+ return @log_loud
262
+ end
263
+ def loud=(val)
264
+ @log.warn '[DEPRECATED] - Net::YAIL#loud= is deprecated as of 1.4.1'
265
+ @log_loud = val
266
+ end
267
+
250
268
  # Makes a new instance, obviously.
251
269
  #
252
270
  # Note: I haven't done this everywhere, but for the constructor, I felt
@@ -259,15 +277,19 @@ class YAIL
259
277
  # * <tt>:username</tt>: Username reported to server
260
278
  # * <tt>:realname</tt>: Real name reported to server
261
279
  # * <tt>:nicknames</tt>: Array of nicknames to cycle through
262
- # * <tt>:silent</tt>: Don't report output messages from this object,
263
- # defaults to false
264
- # * <tt>:loud</tt>: Report a whole lot of stuff that's normally silenced and
265
- # is generally very annoying. Defaults to false, thankfully.
280
+ # * <tt>:silent</tt>: DEPRECATED - Sets Logger level to FATAL and silences most non-Logger
281
+ # messages.
282
+ # * <tt>:loud</tt>: DEPRECATED - Sets Logger level to DEBUG. Spits out too many messages for your own good,
283
+ # and really is only useful when debugging YAIL. Defaults to false, thankfully.
266
284
  # * <tt>:throttle_seconds</tt>: Seconds between a cycle of privmsg sends.
267
285
  # Defaults to 1. One "cycle" is defined as sending one line of output to
268
286
  # *all* targets that have output buffered.
269
287
  # * <tt>:server_password</tt>: Very optional. If set, this is the password
270
288
  # sent out to the server before USER and NICK messages.
289
+ # * <tt>:log</tt>: Optional, if set uses this logger instead of the default (Ruby's Logger).
290
+ # If set, :loud and :silent options are ignored.
291
+ # * <tt>:log_io</tt>: Optional, ignored if you specify your own :log - sends given object to
292
+ # Logger's constructor. Must be filename or IO object.
271
293
  def initialize(options = {})
272
294
  @me = ''
273
295
  @nicknames = options[:nicknames]
@@ -276,11 +298,27 @@ class YAIL
276
298
  @realname = options[:realname]
277
299
  @address = options[:address]
278
300
  @port = options[:port] || 6667
279
- @silent = options[:silent] || false
280
- @loud = options[:loud] || false
301
+ @log_silent = options[:silent] || false
302
+ @log_loud = options[:loud] || false
281
303
  @throttle_seconds = options[:throttle_seconds] || 1
282
304
  @password = options[:server_password]
283
305
 
306
+ # Special handling to avoid mucking with Logger constants if we're using a different logger
307
+ if options[:log]
308
+ @log = options[:log]
309
+ else
310
+ @log = Logger.new(options[:log_io] || STDERR)
311
+ @log.level = Logger::WARN
312
+
313
+ # Convert old-school options into logger stuff
314
+ @log.level = Logger::DEBUG if @log_loud
315
+ @log.level = Logger::FATAL if @log_silent
316
+ end
317
+
318
+ if (options[:silent] || options[:loud])
319
+ @log.warn '[DEPRECATED] - passing :silent and :loud options to constructor are deprecated as of 1.4.1'
320
+ end
321
+
284
322
  # Read in map of event numbers and names. Yes, I stole this event map
285
323
  # file from RubyIRC and made very minor changes.... They stole it from
286
324
  # somewhere else anyway, so it's okay.
@@ -294,7 +332,7 @@ class YAIL
294
332
  begin
295
333
  @socket = TCPSocket.new(@address, @port)
296
334
  rescue StandardError => boom
297
- report "+++ERROR: Unable to open socket connection in Net::YAIL.initialize: #{boom.inspect}"
335
+ @log.fatal "+++ERROR: Unable to open socket connection in Net::YAIL.initialize: #{boom.inspect}"
298
336
  @dead_socket = true
299
337
  raise
300
338
  end
@@ -387,7 +425,7 @@ class YAIL
387
425
  line = @socket.gets
388
426
  rescue StandardError => boom
389
427
  @dead_socket = true
390
- report "+++ERROR in read_incoming_data -> @socket.gets: #{boom.inspect}" if @loud
428
+ @log.fatal "+++ERROR in read_incoming_data -> @socket.gets: #{boom.inspect}"
391
429
  raise
392
430
  end
393
431
 
@@ -399,7 +437,7 @@ class YAIL
399
437
 
400
438
  line.chomp!
401
439
 
402
- report "+++INCOMING: #{line}" if @loud
440
+ @log.debug "+++INCOMING: #{line}"
403
441
 
404
442
  # Only synchronize long enough to push our incoming string onto the
405
443
  # input buffer
@@ -562,10 +600,13 @@ class YAIL
562
600
  when :incoming_nick
563
601
  handle(event.type, event.fullname, event.nick, event.text)
564
602
 
603
+ when :incoming_error
604
+ handle(event.type, event.text)
605
+
565
606
  # Unknown line!
566
607
  else
567
- # This should really never happen, so reporting is forced here for now
568
- report('Unknown line: %s!' % line.inspect)
608
+ # This should really never happen, but isn't technically an error per se
609
+ @log.warn 'Unknown line: %s!' % line.inspect
569
610
  handle(:incoming_miscellany, line)
570
611
  end
571
612
  end
@@ -608,7 +649,7 @@ class YAIL
608
649
  # Don't bother with anything if there are no handlers registered.
609
650
  return unless Array === @handlers[event]
610
651
 
611
- report "+++EVENT HANDLER: Handling event #{event} via #{@handlers[event].inspect}:" if @loud
652
+ @log.debug "+++EVENT HANDLER: Handling event #{event} via #{@handlers[event].inspect}:"
612
653
 
613
654
  # Call all hooks in order until one breaks the chain. For incoming
614
655
  # events, we want something to break the chain or else it'll likely
@@ -633,7 +674,7 @@ class YAIL
633
674
  handle(base_event, text, args)
634
675
  else
635
676
  # No handler = report and don't worry about it
636
- report "Unknown raw #{number.to_s} from #{fullactor}: #{text}"
677
+ @log.info "Unknown raw #{number.to_s} from #{fullactor}: #{text}"
637
678
  end
638
679
  end
639
680
 
@@ -1,154 +1,7 @@
1
+ # This is a deprecated file!
2
+ warn '[DEPRECATED] Requiring "net/yail/IRCBot" is deprecated! Use "net/yail/irc_bot" instead.'
3
+
4
+ # Wrapper for irc_bot for backward-compatibility
1
5
  require 'rubygems'
2
6
  require 'net/yail'
3
-
4
- # My abstraction from adapter to a real bot.
5
- class IRCBot
6
- attr_reader :irc
7
-
8
- public
9
-
10
- # Creates a new bot yay. Note that due to my laziness, the options here
11
- # are almost exactly the same as those in Net::YAIL. But at least there
12
- # are more defaults here.
13
- #
14
- # Options:
15
- # * <tt>:irc_network</tt>: Name/IP of the IRC server
16
- # * <tt>:channels</tt>: Channels to automatically join on connect
17
- # * <tt>:port</tt>: Port number, defaults to 6667
18
- # * <tt>:username</tt>: Username reported to server
19
- # * <tt>:realname</tt>: Real name reported to server
20
- # * <tt>:nicknames</tt>: Array of nicknames to cycle through
21
- # * <tt>:silent</tt>: Silence a lot of reports
22
- # * <tt>:loud</tt>: Lots more verbose reports
23
- def initialize(options = {})
24
- @start_time = Time.now
25
-
26
- @channels = options[:channels] || []
27
- @irc_network = options[:irc_network]
28
- @port = options[:port] || 6667
29
- @username = options[:username] || 'IRCBot'
30
- @realname = options[:realname] || 'IRCBot'
31
- @nicknames = options[:nicknames] || ['IRCBot1', 'IRCBot2', 'IRCBot3']
32
- @silent = options[:silent] || false
33
- @loud = options[:loud] || false
34
- end
35
-
36
- # Returns a string representing uptime
37
- def get_uptime_string
38
- uptime = (Time.now - @start_time).to_i
39
- seconds = uptime % 60
40
- minutes = (uptime / 60) % 60
41
- hours = (uptime / 3600) % 24
42
- days = (uptime / 86400)
43
-
44
- str = []
45
- str.push("#{days} day(s)") if days > 0
46
- str.push("#{hours} hour(s)") if hours > 0
47
- str.push("#{minutes} minute(s)") if minutes > 0
48
- str.push("#{seconds} second(s)") if seconds > 0
49
-
50
- return str.join(', ')
51
- end
52
-
53
- # Creates the socket connection and registers the (very simple) default
54
- # welcome handler. Subclasses should build their hooks in
55
- # add_custom_handlers to allow auto-creation in case of a restart.
56
- def connect_socket
57
- @irc = Net::YAIL.new(
58
- :address => @irc_network,
59
- :port => @port,
60
- :username => @username,
61
- :realname => @realname,
62
- :nicknames => @nicknames,
63
- :silent => @silent,
64
- :loud => @loud
65
- )
66
-
67
- # Simple hook for welcome to allow auto-joining of the channel
68
- @irc.prepend_handler :incoming_welcome, self.method(:welcome)
69
-
70
- add_custom_handlers
71
- end
72
-
73
- # To be subclassed - this method is a nice central location to allow the
74
- # bot to register its handlers before this class takes control and hits
75
- # the IRC network.
76
- def add_custom_handlers
77
- raise "You must define your handlers in add_custom_handlers, or else " +
78
- "explicitly override with an empty method."
79
- end
80
-
81
- # Enters the socket's listening loop(s)
82
- def start_listening
83
- # If socket's already dead (probably couldn't connect to server), don't
84
- # try to listen!
85
- if @irc.dead_socket
86
- $stderr.puts "Dead socket, can't start listening!"
87
- end
88
-
89
- @irc.start_listening
90
- end
91
-
92
- # Tells us the main app wants to just wait until we're done with all
93
- # thread processing, or get a kill signal, or whatever. For now this is
94
- # basically an endless loop that lets the threads do their thing until
95
- # the socket dies. If a bot wants, it can handle :irc_loop to do regular
96
- # processing.
97
- def irc_loop
98
- while true
99
- until @irc.dead_socket
100
- sleep 15
101
- @irc.handle(:irc_loop)
102
- Thread.pass
103
- end
104
-
105
- # Disconnected? Wait a little while and start up again.
106
- sleep 30
107
- @irc.stop_listening
108
- self.connect_socket
109
- start_listening
110
- end
111
- end
112
-
113
- private
114
- # Basic handler for joining our channels upon successful registration
115
- def welcome(text, args)
116
- @channels.each {|channel| @irc.join(channel) }
117
- # Let the default welcome stuff still happen
118
- return false
119
- end
120
-
121
- ################
122
- # Helpful wrappers
123
- ################
124
-
125
- # Wraps Net::YAIL.me
126
- def bot_name
127
- @irc.me
128
- end
129
-
130
- # Wraps Net::YAIL.msg
131
- def msg(*args)
132
- @irc.msg(*args)
133
- end
134
-
135
- # Wraps Net::YAIL.act
136
- def act(*args)
137
- @irc.act(*args)
138
- end
139
-
140
- # Wraps Net::YAIL.join
141
- def join(*args)
142
- @irc.join(*args)
143
- end
144
-
145
- # Wraps Net::YAIL.report
146
- def report(*args)
147
- @irc.report(*args)
148
- end
149
-
150
- # Wraps Net::YAIL.nick
151
- def nick(*args)
152
- @irc.nick(*args)
153
- end
154
- end
7
+ require 'net/yail/irc_bot'
@@ -0,0 +1,155 @@
1
+ require 'rubygems'
2
+ require 'net/yail'
3
+
4
+ # My abstraction from adapter to a real bot.
5
+ class IRCBot
6
+ attr_reader :irc
7
+
8
+ public
9
+
10
+ # Creates a new bot. Options are anything you can pass to the Net::YAIL constructor:
11
+ # * <tt>:irc_network</tt>: Name/IP of the IRC server - backward-compatibility hack, and is
12
+ # ignored if :address is passed in
13
+ # * <tt>:address</tt>: Name/IP of the IRC server
14
+ # * <tt>:port</tt>: Port number, defaults to 6667
15
+ # * <tt>:username</tt>: Username reported to server
16
+ # * <tt>:realname</tt>: Real name reported to server
17
+ # * <tt>:nicknames</tt>: Array of nicknames to cycle through
18
+ # * <tt>:throttle_seconds</tt>: Seconds between a cycle of privmsg sends.
19
+ # Defaults to 1. One "cycle" is defined as sending one line of output to
20
+ # *all* targets that have output buffered.
21
+ # * <tt>:server_password</tt>: Very optional. If set, this is the password
22
+ # sent out to the server before USER and NICK messages.
23
+ # * <tt>:log</tt>: Optional, if set uses this logger instead of the default (Ruby's Logger).
24
+ # If set, :loud and :silent options are ignored.
25
+ # * <tt>:log_io</tt>: Optional, ignored if you specify your own :log - sends given object to
26
+ # Logger's constructor. Must be filename or IO object.
27
+ def initialize(options = {})
28
+ @start_time = Time.now
29
+ @options = options
30
+
31
+ # Set up some friendly defaults
32
+ @options[:address] ||= @options.delete(:irc_network)
33
+ @options[:channels] ||= []
34
+ @options[:port] ||= 6667
35
+ @options[:username] ||= 'IRCBot'
36
+ @options[:realname] ||= 'IRCBot'
37
+ @options[:nicknames] ||= ['IRCBot1', 'IRCBot2', 'IRCBot3']
38
+ end
39
+
40
+ # Returns a string representing uptime
41
+ def get_uptime_string
42
+ uptime = (Time.now - @start_time).to_i
43
+ seconds = uptime % 60
44
+ minutes = (uptime / 60) % 60
45
+ hours = (uptime / 3600) % 24
46
+ days = (uptime / 86400)
47
+
48
+ str = []
49
+ str.push("#{days} day(s)") if days > 0
50
+ str.push("#{hours} hour(s)") if hours > 0
51
+ str.push("#{minutes} minute(s)") if minutes > 0
52
+ str.push("#{seconds} second(s)") if seconds > 0
53
+
54
+ return str.join(', ')
55
+ end
56
+
57
+ # Creates the socket connection and registers the (very simple) default
58
+ # welcome handler. Subclasses should build their hooks in
59
+ # add_custom_handlers to allow auto-creation in case of a restart.
60
+ def connect_socket
61
+ @irc = Net::YAIL.new(@options)
62
+
63
+ # Simple hook for welcome to allow auto-joining of the channel
64
+ @irc.prepend_handler :incoming_welcome, self.method(:welcome)
65
+
66
+ add_custom_handlers
67
+ end
68
+
69
+ # To be subclassed - this method is a nice central location to allow the
70
+ # bot to register its handlers before this class takes control and hits
71
+ # the IRC network.
72
+ def add_custom_handlers
73
+ raise "You must define your handlers in add_custom_handlers, or else " +
74
+ "explicitly override with an empty method."
75
+ end
76
+
77
+ # Enters the socket's listening loop(s)
78
+ def start_listening
79
+ # If socket's already dead (probably couldn't connect to server), don't
80
+ # try to listen!
81
+ if @irc.dead_socket
82
+ $stderr.puts "Dead socket, can't start listening!"
83
+ end
84
+
85
+ @irc.start_listening
86
+ end
87
+
88
+ # Tells us the main app wants to just wait until we're done with all
89
+ # thread processing, or get a kill signal, or whatever. For now this is
90
+ # basically an endless loop that lets the threads do their thing until
91
+ # the socket dies. If a bot wants, it can handle :irc_loop to do regular
92
+ # processing.
93
+ def irc_loop
94
+ while true
95
+ until @irc.dead_socket
96
+ sleep 15
97
+ @irc.handle(:irc_loop)
98
+ Thread.pass
99
+ end
100
+
101
+ # Disconnected? Wait a little while and start up again.
102
+ sleep 30
103
+ @irc.stop_listening
104
+ self.connect_socket
105
+ start_listening
106
+ end
107
+ end
108
+
109
+ private
110
+ # Basic handler for joining our channels upon successful registration
111
+ def welcome(text, args)
112
+ @options[:channels].each {|channel| @irc.join(channel) }
113
+ # Let the default welcome stuff still happen
114
+ return false
115
+ end
116
+
117
+ ################
118
+ # Helpful wrappers
119
+ ################
120
+
121
+ # Wraps Net::YAIL.log
122
+ def log
123
+ @irc.log
124
+ end
125
+
126
+ # Wraps Net::YAIL.me
127
+ def bot_name
128
+ @irc.me
129
+ end
130
+
131
+ # Wraps Net::YAIL.msg
132
+ def msg(*args)
133
+ @irc.msg(*args)
134
+ end
135
+
136
+ # Wraps Net::YAIL.act
137
+ def act(*args)
138
+ @irc.act(*args)
139
+ end
140
+
141
+ # Wraps Net::YAIL.join
142
+ def join(*args)
143
+ @irc.join(*args)
144
+ end
145
+
146
+ # Wraps Net::YAIL.report
147
+ def report(*args)
148
+ @irc.report(*args)
149
+ end
150
+
151
+ # Wraps Net::YAIL.nick
152
+ def nick(*args)
153
+ @irc.nick(*args)
154
+ end
155
+ end
@@ -69,7 +69,7 @@ module IRCOutputAPI
69
69
 
70
70
  handle(:outgoing_msg, target, text)
71
71
 
72
- report_string = @silent ? '' : "{#{target}} <#{@me}> #{text}"
72
+ report_string = @log_silent ? '' : "{#{target}} <#{@me}> #{text}"
73
73
  privmsg(target, text, report_string)
74
74
  end
75
75
 
@@ -81,7 +81,7 @@ module IRCOutputAPI
81
81
 
82
82
  handle(:outgoing_ctcp, target, text)
83
83
 
84
- report_string = @silent ? '' : "{#{target}} [#{@me} #{text}]"
84
+ report_string = @log_silent ? '' : "{#{target}} [#{@me} #{text}]"
85
85
  privmsg(target, "\001#{text}\001", report_string)
86
86
  end
87
87
 
@@ -105,7 +105,7 @@ module IRCOutputAPI
105
105
 
106
106
  handle(:outgoing_notice, target, text)
107
107
 
108
- report "{#{target}} -#{@me}- #{text}" unless @silent
108
+ report "{#{target}} -#{@me}- #{text}" unless @log_silent
109
109
  raw("NOTICE #{target} :#{text}", false)
110
110
  end
111
111
 
@@ -118,7 +118,7 @@ module IRCOutputAPI
118
118
 
119
119
  handle(:outgoing_ctcpreply, target, text)
120
120
 
121
- report "{#{target}} [Reply: #{@me} #{text}]" unless @silent
121
+ report "{#{target}} [Reply: #{@me} #{text}]" unless @log_silent
122
122
  notice(target, "\001#{text}\001")
123
123
  end
124
124
 
@@ -1,5 +1,5 @@
1
1
  module Net
2
2
  class YAIL
3
- VERSION = '1.4.0'
3
+ VERSION = '1.4.2'
4
4
  end
5
5
  end
data/tests/tc_event.rb CHANGED
@@ -224,4 +224,11 @@ class MessageParserEventTest < Test::Unit::TestCase
224
224
  assert_equal ['foo'], event.targets
225
225
  assert_equal '+k', event.text
226
226
  end
227
+
228
+ # Simple test of error event
229
+ def test_error
230
+ event = Net::YAIL::IncomingEvent.parse 'ERROR :Closing Link: nerdbucket.com (Quit: Terminated by user)'
231
+ assert_equal :incoming_error, event.type
232
+ assert_equal 'Closing Link: nerdbucket.com (Quit: Terminated by user)', event.text
233
+ end
227
234
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 4
8
- - 0
9
- version: 1.4.0
8
+ - 2
9
+ version: 1.4.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jeremy Echols
@@ -14,7 +14,7 @@ autorequire: net/yail
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-09-02 00:00:00 -04:00
17
+ date: 2010-09-08 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -40,6 +40,7 @@ files:
40
40
  - lib/net/yail/output_api.rb
41
41
  - lib/net/yail/event.rb
42
42
  - lib/net/yail/yail-version.rb
43
+ - lib/net/yail/irc_bot.rb
43
44
  - tests/net_yail.rb
44
45
  - tests/tc_message_parser.rb
45
46
  - tests/tc_event.rb