percy 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +7 -0
- data/README.rdoc +80 -0
- data/lib/percy.rb +450 -0
- data/lib/percylogger.rb +67 -0
- metadata +58 -0
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2009 Tobias Bühlmann
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
= Percy 0.0.3
|
2
|
+
|
3
|
+
== Configuring the bot
|
4
|
+
|
5
|
+
=== mybot.rb
|
6
|
+
$:.unshift "#{File.expand_path(File.dirname(__FILE__))}/lib"
|
7
|
+
PERCY_ROOT = File.expand_path(File.dirname(__FILE__))
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'percy'
|
11
|
+
|
12
|
+
bot = Percy.new
|
13
|
+
|
14
|
+
bot.configure do |c|
|
15
|
+
c.server = 'chat.eu.freenode.net'
|
16
|
+
c.port = 6667
|
17
|
+
c.nick = 'Percyguy'
|
18
|
+
c.verbose = true
|
19
|
+
c.logging = true
|
20
|
+
end
|
21
|
+
|
22
|
+
Start it with <tt>ruby mybot.rb</tt>.
|
23
|
+
|
24
|
+
== Events
|
25
|
+
Handle events with:
|
26
|
+
bot.on :connect do
|
27
|
+
# join channels
|
28
|
+
# do things
|
29
|
+
end
|
30
|
+
|
31
|
+
bot.on :channel, /^foo!/ do |env|
|
32
|
+
# available variables: env[:nick], env[:user], env[:host], env[:channel], env[:message]
|
33
|
+
end
|
34
|
+
|
35
|
+
bot.on :query, /^bar!/ do |env|
|
36
|
+
# available variables: env[:nick], env[:user], env[:host], env[:message]
|
37
|
+
end
|
38
|
+
|
39
|
+
bot.on :join do |env|
|
40
|
+
# available variables: env[:nick], env[:user], env[:host], env[:channel]
|
41
|
+
end
|
42
|
+
|
43
|
+
bot.on :part do |env|
|
44
|
+
# available variables: env[:nick], env[:user], env[:host], env[:channel], env[:message]
|
45
|
+
end
|
46
|
+
|
47
|
+
bot.on :quit do |env|
|
48
|
+
# available variables: env[:nick], env[:user], env[:host], env[:message]
|
49
|
+
end
|
50
|
+
|
51
|
+
bot.on :nickchange do |env|
|
52
|
+
# available variables: env[:nick], env[:user], env[:host], env[:new_nick]
|
53
|
+
end
|
54
|
+
|
55
|
+
bot.on :kick do |env|
|
56
|
+
# available variables: env[:nick], env[:user], env[:host], env[:new_nick], env[:channel], env[:victim]
|
57
|
+
end
|
58
|
+
|
59
|
+
== Methods availabe
|
60
|
+
* message(recipient, msg)
|
61
|
+
* notice(recipient, msg)
|
62
|
+
* action(recipient, msg)
|
63
|
+
* mode(recipient, option)
|
64
|
+
* channellimit(channel)
|
65
|
+
* kick(channel, user, reason)
|
66
|
+
* topic(channel, topic)
|
67
|
+
* join(channel, password = nil)
|
68
|
+
* part(channel, msg)
|
69
|
+
* quit(msg = nil)
|
70
|
+
* users_on(channel)
|
71
|
+
* is_online(nick)
|
72
|
+
|
73
|
+
== License
|
74
|
+
Copyright (c) 2009 Tobias Bühlmann
|
75
|
+
|
76
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
77
|
+
|
78
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
79
|
+
|
80
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/percy.rb
ADDED
@@ -0,0 +1,450 @@
|
|
1
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'percylogger'
|
4
|
+
require 'socket'
|
5
|
+
require 'timeout'
|
6
|
+
require 'thread'
|
7
|
+
|
8
|
+
Thread.abort_on_exception = true
|
9
|
+
|
10
|
+
class Percy
|
11
|
+
VERSION = 'Percy 0.0.3 (http://github.com/tbuehlmann/percy)'
|
12
|
+
|
13
|
+
Config = Struct.new(:server, :port, :password, :nick, :username, :verbose, :logging)
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@config = Config.new("localhost", 6667, nil, 'Percy', 'Percy', true, false)
|
17
|
+
|
18
|
+
# helper variables for getting server return values
|
19
|
+
@observers = 0
|
20
|
+
@temp_socket = []
|
21
|
+
|
22
|
+
# user methods
|
23
|
+
@on_channel = []
|
24
|
+
@on_query = []
|
25
|
+
@on_connect = []
|
26
|
+
@on_join = []
|
27
|
+
@on_part = []
|
28
|
+
@on_quit = []
|
29
|
+
@on_nickchange = []
|
30
|
+
@on_kick = []
|
31
|
+
|
32
|
+
# observer synchronizer
|
33
|
+
@mutex = Mutex.new
|
34
|
+
|
35
|
+
# running variable (provisional solution for rejoining at netsplit)
|
36
|
+
@running = true
|
37
|
+
end
|
38
|
+
|
39
|
+
# configure block
|
40
|
+
def configure(&block)
|
41
|
+
block.call(@config)
|
42
|
+
|
43
|
+
# logger
|
44
|
+
@traffic_logger = PercyLogger.new("#{PERCY_ROOT}/logs/traffic.log") if @config.logging
|
45
|
+
@error_logger = PercyLogger.new("#{PERCY_ROOT}/logs/error.log") if @config.logging
|
46
|
+
end
|
47
|
+
|
48
|
+
# raw irc messages
|
49
|
+
def raw(msg)
|
50
|
+
@socket.puts "#{msg}\r\n"
|
51
|
+
@traffic_logger.info(">> #{msg}") if @traffic_logger
|
52
|
+
puts "#{Time.now.strftime('%d.%m.%Y %H:%M:%S')} >> #{msg}" if @config.verbose
|
53
|
+
end
|
54
|
+
|
55
|
+
# send a message
|
56
|
+
def message(recipient, msg)
|
57
|
+
raw "PRIVMSG #{recipient} :#{msg}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# send a notice
|
61
|
+
def notice(recipient, msg)
|
62
|
+
raw "NOTICE #{recipient} :#{msg}"
|
63
|
+
end
|
64
|
+
|
65
|
+
# set a mode
|
66
|
+
def mode(recipient, option)
|
67
|
+
raw "MODE #{recipient} #{option}"
|
68
|
+
end
|
69
|
+
|
70
|
+
# get the channellimit of a channel
|
71
|
+
def channellimit(channel)
|
72
|
+
add_observer
|
73
|
+
raw "MODE #{channel}"
|
74
|
+
|
75
|
+
begin
|
76
|
+
Timeout::timeout(10) do # try 10 seconds to retrieve l mode of <channel>
|
77
|
+
loop do
|
78
|
+
@temp_socket.each do |line|
|
79
|
+
if line =~ /^:(\S+) 324 (\S+) #{channel} .*l.* (\d+)/
|
80
|
+
return $3.to_i
|
81
|
+
end
|
82
|
+
end
|
83
|
+
sleep 0.5
|
84
|
+
end
|
85
|
+
end
|
86
|
+
rescue Timeout::Error
|
87
|
+
return false
|
88
|
+
ensure
|
89
|
+
remove_observer
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# check whether an user is online
|
94
|
+
def is_online(nick)
|
95
|
+
add_observer
|
96
|
+
raw "WHOIS #{nick}"
|
97
|
+
|
98
|
+
begin
|
99
|
+
Timeout::timeout(10) do
|
100
|
+
loop do
|
101
|
+
@temp_socket.each do |line|
|
102
|
+
if line =~ /^:(\S+) 311 (\S+) (#{nick}) /i
|
103
|
+
return $3
|
104
|
+
elsif line =~ /^:\S+ 401 \S+ #{nick} /i
|
105
|
+
return false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
sleep 0.5
|
109
|
+
end
|
110
|
+
end
|
111
|
+
rescue Timeout::Error
|
112
|
+
return false
|
113
|
+
ensure
|
114
|
+
remove_observer
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# kick a user
|
119
|
+
def kick(channel, user, reason)
|
120
|
+
if reason
|
121
|
+
raw "KICK #{channel} #{user} :#{reason}"
|
122
|
+
else
|
123
|
+
raw "KICK #{channel} #{user}"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# perform an action
|
128
|
+
def action(recipient, msg)
|
129
|
+
raw "PRIVMSG #{recipient} :\001ACTION #{msg}\001"
|
130
|
+
end
|
131
|
+
|
132
|
+
# set a topic
|
133
|
+
def topic(channel, topic)
|
134
|
+
raw "TOPIC #{channel} :#{topic}"
|
135
|
+
end
|
136
|
+
|
137
|
+
# joining a channel
|
138
|
+
def join(channel, password = nil)
|
139
|
+
if password
|
140
|
+
raw "JOIN #{channel} #{password}"
|
141
|
+
else
|
142
|
+
raw "JOIN #{channel}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# parting a channel
|
147
|
+
def part(channel, msg)
|
148
|
+
if msg
|
149
|
+
raw "PART #{channel} :#{msg}"
|
150
|
+
else
|
151
|
+
raw 'PART'
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# quitting
|
156
|
+
def quit(msg = nil)
|
157
|
+
if msg
|
158
|
+
raw "QUIT :#{msg}"
|
159
|
+
else
|
160
|
+
raw 'QUIT'
|
161
|
+
end
|
162
|
+
|
163
|
+
@running = false # so Percy does not reconnect after the socket has been closed
|
164
|
+
end
|
165
|
+
|
166
|
+
# on method
|
167
|
+
def on(type = :channel, match = //, &block)
|
168
|
+
case type
|
169
|
+
when :channel
|
170
|
+
@on_channel << {:match => match, :proc => block}
|
171
|
+
when :connect
|
172
|
+
@on_connect << block
|
173
|
+
when :query
|
174
|
+
@on_query << {:match => match, :proc => block}
|
175
|
+
when :join
|
176
|
+
@on_join << block
|
177
|
+
when :part
|
178
|
+
@on_part << block
|
179
|
+
when :quit
|
180
|
+
@on_quit << block
|
181
|
+
when :nickchange
|
182
|
+
@on_nickchange << block
|
183
|
+
when :kick
|
184
|
+
@on_kick << block
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# add observer
|
189
|
+
def add_observer
|
190
|
+
@mutex.synchronize do
|
191
|
+
@observers += 1
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# remove observer
|
196
|
+
def remove_observer
|
197
|
+
@mutex.synchronize do
|
198
|
+
@observers -= 1 # remove observer
|
199
|
+
@temp_socket = [] if @observers == 0 # clear @temp_socket if no observers are active
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# returns all users on a specific channel
|
204
|
+
def users_on(channel)
|
205
|
+
add_observer
|
206
|
+
raw "NAMES #{channel}"
|
207
|
+
|
208
|
+
begin
|
209
|
+
Timeout::timeout(10) do # try 10 seconds to retrieve the users of <channel>
|
210
|
+
loop do
|
211
|
+
@temp_socket.each do |line|
|
212
|
+
if line =~ /^:(\S+) 353 (\S+) = #{channel} :/
|
213
|
+
return $'.split(' ')
|
214
|
+
end
|
215
|
+
end
|
216
|
+
sleep 0.5
|
217
|
+
end
|
218
|
+
end
|
219
|
+
rescue Timeout::Error
|
220
|
+
return false
|
221
|
+
ensure
|
222
|
+
remove_observer
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# parses incoming traffic
|
227
|
+
def parse(type, env = nil)
|
228
|
+
case type
|
229
|
+
when :connect
|
230
|
+
@on_connect.each do |block|
|
231
|
+
Thread.new do
|
232
|
+
begin
|
233
|
+
unless @connected
|
234
|
+
@connected = true
|
235
|
+
block.call
|
236
|
+
end
|
237
|
+
rescue => e
|
238
|
+
if @error_logger
|
239
|
+
@error_logger.error(e.message)
|
240
|
+
e.backtrace.each do |line|
|
241
|
+
@error_logger.error(line)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
when :channel
|
249
|
+
@on_channel.each do |method|
|
250
|
+
if env[:message] =~ method[:match]
|
251
|
+
Thread.new do
|
252
|
+
begin
|
253
|
+
method[:proc].call(env)
|
254
|
+
rescue => e
|
255
|
+
if @error_logger
|
256
|
+
@error_logger.error(e.message)
|
257
|
+
e.backtrace.each do |line|
|
258
|
+
@error_logger.error(line)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
when :query
|
267
|
+
# version respones
|
268
|
+
if env[:message] == "\001VERSION\001"
|
269
|
+
notice env[:nick], "\001VERSION #{VERSION}\001"
|
270
|
+
end
|
271
|
+
|
272
|
+
# time response
|
273
|
+
if env[:message] == "\001TIME\001"
|
274
|
+
notice env[:nick], "\001TIME #{Time.now.strftime('%a %b %d %H:%M:%S %Y')}\001"
|
275
|
+
end
|
276
|
+
|
277
|
+
# ping response
|
278
|
+
if env[:message] =~ /\001PING (\d+)\001/
|
279
|
+
notice env[:nick], "\001PING #{$1}\001"
|
280
|
+
end
|
281
|
+
|
282
|
+
@on_query.each do |method|
|
283
|
+
if env[:message] =~ method[:match]
|
284
|
+
Thread.new do
|
285
|
+
begin
|
286
|
+
method[:proc].call(env)
|
287
|
+
rescue => e
|
288
|
+
if @error_logger
|
289
|
+
@error_logger.error(e.message)
|
290
|
+
e.backtrace.each do |line|
|
291
|
+
@error_logger.error(line)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
when :join
|
300
|
+
@on_join.each do |block|
|
301
|
+
Thread.new do
|
302
|
+
begin
|
303
|
+
block.call(env)
|
304
|
+
rescue => e
|
305
|
+
if @error_logger
|
306
|
+
@error_logger.error(e.message)
|
307
|
+
e.backtrace.each do |line|
|
308
|
+
@error_logger.error(line)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
when :part
|
316
|
+
@on_part.each do |block|
|
317
|
+
Thread.new do
|
318
|
+
begin
|
319
|
+
block.call(env)
|
320
|
+
rescue => e
|
321
|
+
if @error_logger
|
322
|
+
@error_logger.error(e.message)
|
323
|
+
e.backtrace.each do |line|
|
324
|
+
@error_logger.error(line)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
when :quit
|
332
|
+
@on_quit.each do |block|
|
333
|
+
Thread.new do
|
334
|
+
begin
|
335
|
+
block.call(env)
|
336
|
+
rescue => e
|
337
|
+
if @error_logger
|
338
|
+
@error_logger.error(e.message)
|
339
|
+
e.backtrace.each do |line|
|
340
|
+
@error_logger.error(line)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
when :nickchange
|
348
|
+
@on_nickchange.each do |block|
|
349
|
+
Thread.new do
|
350
|
+
begin
|
351
|
+
block.call(env)
|
352
|
+
rescue => e
|
353
|
+
if @error_logger
|
354
|
+
@error_logger.error(e.message)
|
355
|
+
e.backtrace.each do |line|
|
356
|
+
@error_logger.error(line)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
when :kick
|
364
|
+
@on_kick.each do |block|
|
365
|
+
Thread.new do
|
366
|
+
begin
|
367
|
+
block.call(env)
|
368
|
+
rescue => e
|
369
|
+
if @error_logger
|
370
|
+
@error_logger.error(e.message)
|
371
|
+
e.backtrace.each do |line|
|
372
|
+
@error_logger.error(line)
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
# connect!
|
382
|
+
def connect
|
383
|
+
begin
|
384
|
+
while @running
|
385
|
+
@traffic_logger.info('-- Starting Percy') if @traffic_logger
|
386
|
+
puts "#{Time.now.strftime('%d.%m.%Y %H:%M:%S')} -- Starting Percy"
|
387
|
+
|
388
|
+
|
389
|
+
@socket = TCPSocket.open(@config.server, @config.port)
|
390
|
+
raw "PASS #{@config.password}" if @config.password
|
391
|
+
raw "NICK #{@config.nick}"
|
392
|
+
raw "USER #{@config.nick} 0 * :#{@config.username}"
|
393
|
+
|
394
|
+
while line = @socket.gets
|
395
|
+
@traffic_logger.info("<< #{line.chomp}") if @traffic_logger
|
396
|
+
puts "#{Time.now.strftime('%d.%m.%Y %H:%M:%S')} << #{line.chomp}" if @config.verbose
|
397
|
+
|
398
|
+
case line.chomp
|
399
|
+
when /^PING \S+$/
|
400
|
+
raw line.chomp.gsub('PING', 'PONG')
|
401
|
+
|
402
|
+
when /^:(\S+) (376|422)/
|
403
|
+
parse(:connect)
|
404
|
+
|
405
|
+
when /^:(\S+)!(\S+)@(\S+) PRIVMSG #(\S+) :/
|
406
|
+
parse(:channel, :nick => $1, :user => $2, :host => $3, :channel => "##{$4}", :message => $')
|
407
|
+
|
408
|
+
when /^:(\S+)!(\S+)@(\S+) PRIVMSG (\S+) :/
|
409
|
+
parse(:query, :nick => $1, :user => $2, :host => $3, :message => $')
|
410
|
+
|
411
|
+
when /^:(\S+)!(\S+)@(\S+) JOIN :*(\S+)$/
|
412
|
+
parse(:join, :nick => $1, :user => $2, :host => $3, :channel => $4)
|
413
|
+
|
414
|
+
when /^:(\S+)!(\S+)@(\S+) PART (\S+)/
|
415
|
+
parse(:part, :nick => $1, :user => $2, :host => $3, :channel => $4, :message => $'.sub(' :', ''))
|
416
|
+
|
417
|
+
when /^:(\S+)!(\S+)@(\S+) QUIT/
|
418
|
+
parse(:quit, :nick => $1, :user => $2, :host => $3, :message => $'.sub(' :', ''))
|
419
|
+
|
420
|
+
when /^:(\S+)!(\S+)@(\S+) NICK :/
|
421
|
+
parse(:nickchange, :nick => $1, :user => $2, :host => $3, :new_nick => $')
|
422
|
+
|
423
|
+
when /^:(\S+)!(\S+)@(\S+) KICK (\S+) (\S+) :/
|
424
|
+
parse(:kick, :nick => $1, :user => $2, :host => $3, :channel => $4, :victim => $5, :reason => $')
|
425
|
+
end
|
426
|
+
|
427
|
+
if @observers > 0
|
428
|
+
@temp_socket << line.chomp
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
@traffic_logger.info('-- Percy disconnected') if @traffic_logger
|
433
|
+
puts "#{Time.now.strftime('%d.%m.%Y %H:%M:%S')} -- Percy disconnected"
|
434
|
+
@connected = false
|
435
|
+
end
|
436
|
+
rescue => e
|
437
|
+
@error_logger.error(e.message)
|
438
|
+
e.backtrace.each do |line|
|
439
|
+
@error_logger.error(line)
|
440
|
+
end
|
441
|
+
|
442
|
+
@traffic_logger.info('-- Percy disconnected') if @traffic_logger
|
443
|
+
puts "#{Time.now.strftime('%d.%m.%Y %H:%M:%S')} -- Percy disconnected"
|
444
|
+
@connected = false
|
445
|
+
ensure
|
446
|
+
@traffic_logger.file.close if @traffic_logger
|
447
|
+
@error_logger.file.close if @error_logger
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|
data/lib/percylogger.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
class PercyLogger
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
DEBUG = 0
|
5
|
+
INFO = 1
|
6
|
+
WARN = 2
|
7
|
+
ERROR = 3
|
8
|
+
FATAL = 4
|
9
|
+
UNKNOWN = 5
|
10
|
+
LEVEL = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL', 'UNKNOWN']
|
11
|
+
|
12
|
+
attr_accessor :level, :time_format, :file
|
13
|
+
|
14
|
+
def initialize(filename = 'log.log', level = DEBUG, time_format = '%d.%m.%Y %H:%M:%S')
|
15
|
+
@filename = filename
|
16
|
+
@level = level
|
17
|
+
@time_format = time_format
|
18
|
+
@mutex = Mutex.new
|
19
|
+
|
20
|
+
unless File.exist?(@filename)
|
21
|
+
unless File.directory?(File.dirname(@filename))
|
22
|
+
Dir.mkdir(File.dirname(@filename))
|
23
|
+
end
|
24
|
+
File.new(@filename, 'w+')
|
25
|
+
end
|
26
|
+
|
27
|
+
@file = File.open(@filename, 'w+')
|
28
|
+
@file.sync = true
|
29
|
+
end
|
30
|
+
|
31
|
+
def write(severity, message)
|
32
|
+
begin
|
33
|
+
if severity >= @level
|
34
|
+
@mutex.synchronize do
|
35
|
+
@file.puts "#{LEVEL[severity]} #{Time.now.strftime(@time_format)} #{message}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
rescue => e
|
39
|
+
puts e.message
|
40
|
+
puts e.backtrace.join('\n')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def debug(message)
|
45
|
+
write DEBUG, message
|
46
|
+
end
|
47
|
+
|
48
|
+
def info(message)
|
49
|
+
write INFO, message
|
50
|
+
end
|
51
|
+
|
52
|
+
def warn(message)
|
53
|
+
write WARN, message
|
54
|
+
end
|
55
|
+
|
56
|
+
def error(message)
|
57
|
+
write ERROR, message
|
58
|
+
end
|
59
|
+
|
60
|
+
def fatal(message)
|
61
|
+
write FATAL, message
|
62
|
+
end
|
63
|
+
|
64
|
+
def unknown(message)
|
65
|
+
write UNKNOWN, message
|
66
|
+
end
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: percy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Tobias B\xC3\xBChlmann"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-01 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Percy is an IRC bot framework inspired by isaac with various changes.
|
17
|
+
email: tobias.buehlmann@gmx.de
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/percy.rb
|
26
|
+
- lib/percylogger.rb
|
27
|
+
- README.rdoc
|
28
|
+
- LICENSE
|
29
|
+
has_rdoc: true
|
30
|
+
homepage: http://github.com/tbuehlmann/percy
|
31
|
+
licenses: []
|
32
|
+
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: "0"
|
43
|
+
version:
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
requirements: []
|
51
|
+
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.3.5
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: IRC bot framework (inspired by isaac)
|
57
|
+
test_files: []
|
58
|
+
|