rhuidean 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@
8
8
  module Rhuidean
9
9
  # Version number
10
10
  V_MAJOR = 1
11
- V_MINOR = 0
11
+ V_MINOR = 1
12
12
  V_PATCH = 0
13
13
 
14
14
  VERSION = "#{V_MAJOR}.#{V_MINOR}.#{V_PATCH}"
@@ -8,15 +8,19 @@
8
8
  # Import required Ruby modules
9
9
  %w(logger socket).each { |m| require m }
10
10
 
11
+ # Import required application modules
12
+ %w(loggable).each { |m| require 'rhuidean/' + m }
13
+
11
14
  module IRC
12
15
 
13
16
  # The IRC::Client class acts as an abstract interface to the IRC protocol.
14
17
  class Client
15
18
  include Rhuidean # Version info and such
19
+ include Loggable # Magic logging stuff
16
20
 
17
21
  ##
18
22
  # instance attributes
19
- attr_accessor :server, :port, :password, :debug, :thread,
23
+ attr_accessor :server, :port, :password, :thread,
20
24
  :nickname, :username, :realname, :bind_to
21
25
 
22
26
  # Our TCPSocket.
@@ -40,7 +44,7 @@ class Client
40
44
  # c.bind_to = '10.0.1.20'
41
45
  #
42
46
  # c.logger = Logger.new($stderr)
43
- # c.debug = false
47
+ # c.log_level = :debug
44
48
  # end
45
49
  #
46
50
  # client.thread = Thread.new { client.io_loop }
@@ -65,9 +69,15 @@ class Client
65
69
  # Our event queue.
66
70
  @eventq = EventQueue.new
67
71
 
72
+ # Local IP to bind to
73
+ @bind_to = nil
74
+
75
+ # Password to login to the server
76
+ @password = nil
77
+
68
78
  # Our Logger object.
69
- @logger = Logger.new($stderr)
70
- @debug = false
79
+ @logger = Logger.new($stderr)
80
+ self.log_level = :info
71
81
 
72
82
  # If we have a block let it set up our instance attributes.
73
83
  yield(self) if block_given?
@@ -80,7 +90,7 @@ class Client
80
90
  on(:dead) { self.dead = true }
81
91
 
82
92
  on(:exit) do |from|
83
- log("exiting via #{from}...")
93
+ log(:fatal, "exiting via #{from}...")
84
94
  Thread.exit
85
95
  end
86
96
 
@@ -108,8 +118,14 @@ class Client
108
118
  # returns:: +self+
109
119
  #
110
120
  def set_default_handlers
121
+ # Append random numbers if our nick is in use
122
+ on(Numeric::ERR_NICKNAMEINUSE) do |m|
123
+ @nickname = m.params[0] + rand(100).to_s
124
+ nick(@nickname)
125
+ end
126
+
111
127
  # Consider ourselves connected on 001
112
- on(Numeric::RPL_WELCOME) { log("connected to #@server:#@port") }
128
+ on(Numeric::RPL_WELCOME) { log(:info, "connected to #@server:#@port") }
113
129
 
114
130
  # Track our nickname...
115
131
  on(:NICK) { |m| @nickname = m.target if m.origin_nick == @nickname }
@@ -162,7 +178,7 @@ class Client
162
178
  #
163
179
  def dead=(bool)
164
180
  if bool == true
165
- log("lost connection to #@server:#@port")
181
+ log(:info, "lost connection to #@server:#@port")
166
182
  @dead = Time.now.to_i
167
183
  @socket = nil
168
184
  @connected = false
@@ -217,7 +233,7 @@ class Client
217
233
  # Use shift because we need it to fall off immediately.
218
234
  while line = @sendq.shift
219
235
  line += "\r\n"
220
- debug(line)
236
+ log(:debug, line)
221
237
  @socket.write(line)
222
238
  end
223
239
  rescue Errno::EAGAIN
@@ -265,7 +281,7 @@ class Client
265
281
  @recvq.each do |line|
266
282
  line.chomp!
267
283
 
268
- debug(line)
284
+ log(:debug, line)
269
285
 
270
286
  m = IRC_RE.match(line)
271
287
 
@@ -291,53 +307,10 @@ class Client
291
307
  self
292
308
  end
293
309
 
294
- #
295
- # Logs a regular message.
296
- # ---
297
- # message:: the string to log
298
- # returns:: +self+
299
- #
300
- def log(message)
301
- @logger.info(caller[0].split('/')[-1]) { message } if @logger
302
- end
303
-
304
- #
305
- # Logs a debug message.
306
- # ---
307
- # message:: the string to log
308
- # returns:: +self+
309
- #
310
- def debug(message)
311
- return unless @logger
312
-
313
- @logger.debug(caller[0].split('/')[-1]) { message } if @debug
314
- end
315
-
316
310
  ######
317
311
  public
318
312
  ######
319
313
 
320
- #
321
- # Sets the logging object to use.
322
- # If it quacks like a Logger object, it should work.
323
- # ---
324
- # logger:: the Logger to use
325
- # returns:: +self+
326
- #
327
- def logger=(logger)
328
- @logger = logger
329
-
330
- # Set to false/nil to disable logging...
331
- return unless @logger
332
-
333
- @logger.progname = 'irc'
334
- @logger.datetime_format = '%b %d %H:%M:%S '
335
-
336
- # We only have 'logging' and 'debugging', so just set the
337
- # object to show all levels. I might change this someday.
338
- @logger.level = Logger::DEBUG
339
- end
340
-
341
314
  #
342
315
  # Registers Event handlers with our EventQueue.
343
316
  # ---
@@ -424,7 +397,7 @@ class Client
424
397
  def connect
425
398
  verify_attributes
426
399
 
427
- log("connecting to #@server:#@port")
400
+ log(:info, "connecting to #@server:#@port")
428
401
 
429
402
  begin
430
403
  @socket = TCPSocket.new(@server, @port, @bind_to)
@@ -0,0 +1,59 @@
1
+ #
2
+ # rhuidean: a small, lightweight IRC client library
3
+ # lib/rhuidean/loggable.rb: a mixin for easy logging
4
+ #
5
+ # Copyright (c) 2003-2010 Eric Will <rakaur@malkier.net>
6
+ #
7
+ # encoding: utf-8
8
+
9
+ module Loggable
10
+ ##
11
+ # Logs a regular message.
12
+ # ---
13
+ # message:: the string to log
14
+ # returns:: +self+
15
+ #
16
+ def log(level, message)
17
+ return unless level.to_s =~ /(fatal|error|warning|info|debug)/
18
+
19
+ @logger.send(level, caller[0].split('/')[-1]) { message } if @logger
20
+ end
21
+
22
+ ##
23
+ # Sets the logging object to use.
24
+ # If it quacks like a Logger object, it should work.
25
+ # ---
26
+ # logger:: the Logger to use
27
+ # returns:: +self+
28
+ #
29
+ def logger=(logger)
30
+ logger.level = @logger.level if @logger and logger
31
+
32
+ @logger = logger
33
+
34
+ # Set to false/nil to disable logging...
35
+ return unless @logger
36
+
37
+ @logger.datetime_format = '%m/%d %H:%M:%S '
38
+ end
39
+
40
+ def log_level=(level)
41
+ case level
42
+ when :none
43
+ @logger = nil
44
+ when :fatal
45
+ @logger.level = Logger::FATAL
46
+ when :error
47
+ @logger.level = Logger::ERROR
48
+ when :warning
49
+ @logger.level = Logger::WARN
50
+ when :info
51
+ @logger.level = Logger::INFO
52
+ when :debug
53
+ @logger.level = Logger::DEBUG
54
+ else
55
+ @logger.level = Logger::WARN
56
+ end
57
+ end
58
+ end # module Loggable
59
+
@@ -43,11 +43,25 @@ class Client
43
43
  @sendq << "PRIVMSG #{to} :#{message}"
44
44
  end
45
45
 
46
+ # Sends a CTCP
47
+ def ctcp(to, type, params = nil)
48
+ if params
49
+ @sendq << "PRIVMSG #{to} :\1#{type} #{params}\1"
50
+ else
51
+ @sendq << "PRIVMSG #{to} :\1#{type}\1"
52
+ end
53
+ end
54
+
46
55
  # Sends an IRC NOTICE command.
47
56
  def notice(to, message)
48
57
  @sendq << "NOTICE #{to} :#{message}"
49
58
  end
50
59
 
60
+ # Sends a CTCP reply
61
+ def ctcp_reply(to, type, params = '')
62
+ @sendq << "NOTICE #{to} :\1#{type} #{params}\1"
63
+ end
64
+
51
65
  # Sends an IRC JOIN command.
52
66
  def join(channel, key = '')
53
67
  @sendq << "JOIN #{channel} #{key}"
@@ -179,7 +179,7 @@ class StatefulClient < Client
179
179
  @users[user.nickname] ||= user
180
180
 
181
181
  @channels[m.target].add_user(user)
182
- debug("join: #{user} -> #{m.target}")
182
+ log(:info, "join: #{user} -> #{m.target}")
183
183
  end
184
184
  end
185
185
 
@@ -196,12 +196,12 @@ class StatefulClient < Client
196
196
 
197
197
  @channels.delete(chan.name)
198
198
 
199
- debug("parted: #{chan.name}")
199
+ log(:info, "parted: #{chan.name}")
200
200
  else
201
201
  user = @users[m.origin_nick]
202
202
 
203
203
  @channels[m.target].delete_user(user)
204
- debug("part: #{user.nickname} -> #{m.origin_nick}")
204
+ log(:info, "part: #{user.nickname} -> #{m.origin_nick}")
205
205
 
206
206
  delete_user(user) if user.channels.empty?
207
207
  end
@@ -222,7 +222,7 @@ class StatefulClient < Client
222
222
  channel.users.delete(m.origin_nick)
223
223
  end
224
224
 
225
- debug("nick: #{m.origin_nick} -> #{m.target}")
225
+ log(:info, "nick: #{m.origin_nick} -> #{m.target}")
226
226
  end
227
227
 
228
228
  def do_kick(m)
@@ -238,12 +238,12 @@ class StatefulClient < Client
238
238
 
239
239
  @channels.delete(chan.name)
240
240
 
241
- debug("kicked: #{chan.name}")
241
+ log(:info, "kicked: #{chan.name}")
242
242
  else
243
243
  user = @users[m.params[0]]
244
244
 
245
245
  @channels[m.target].delete_user(user)
246
- debug("kick: #{user.nickname} -> #{m.origin_nick}")
246
+ log(:info, "kick: #{user.nickname} -> #{m.origin_nick}")
247
247
 
248
248
  delete_user(user) if user.channels.empty?
249
249
  end
@@ -258,7 +258,7 @@ class StatefulClient < Client
258
258
  user.channels.each { |name, chan| chan.delete_user(user) }
259
259
 
260
260
  delete_user(user)
261
- debug("quit: #{user.nickname}")
261
+ log(:info, "quit: #{user.nickname}")
262
262
  end
263
263
  end
264
264
 
@@ -273,7 +273,7 @@ class StatefulClient < Client
273
273
  names[0] = names[0][1..-1] # Get rid of leading ':'
274
274
  modes = @status_modes.keys
275
275
  prefixes = @status_modes.values
276
- name_re = /^([#{prefixes}])*(.+)/
276
+ name_re = /^([#{prefixes.join('')}])*(.+)/
277
277
 
278
278
  names.each do |name|
279
279
  m = name_re.match(name)
@@ -294,7 +294,7 @@ class StatefulClient < Client
294
294
  end
295
295
 
296
296
  chan.add_user(user)
297
- debug("names: #{user} -> #{chan}")
297
+ log(:debug, "names: #{user} -> #{chan}")
298
298
  end
299
299
  end
300
300
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
+ - 1
7
8
  - 0
8
- - 0
9
- version: 1.0.0
9
+ version: 1.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Eric Will
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-10 00:00:00 -05:00
17
+ date: 2010-11-11 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -38,6 +38,7 @@ files:
38
38
  - lib/rhuidean/stateful_channel.rb
39
39
  - lib/rhuidean/stateful_client.rb
40
40
  - lib/rhuidean/stateful_user.rb
41
+ - lib/rhuidean/loggable.rb
41
42
  - test/tc_client.rb
42
43
  - test/ts_rhuidean.rb
43
44
  has_rdoc: true