butler 1.8.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.
- data/CHANGELOG +4 -0
- data/GPL.txt +340 -0
- data/LICENSE.txt +52 -0
- data/README +37 -0
- data/Rakefile +334 -0
- data/bin/botcontrol +230 -0
- data/data/butler/config_template.yaml +4 -0
- data/data/butler/dialogs/backup.rb +19 -0
- data/data/butler/dialogs/botcontrol.rb +4 -0
- data/data/butler/dialogs/config.rb +1 -0
- data/data/butler/dialogs/create.rb +53 -0
- data/data/butler/dialogs/delete.rb +3 -0
- data/data/butler/dialogs/en/backup.yaml +6 -0
- data/data/butler/dialogs/en/botcontrol.yaml +5 -0
- data/data/butler/dialogs/en/create.yaml +11 -0
- data/data/butler/dialogs/en/delete.yaml +2 -0
- data/data/butler/dialogs/en/help.yaml +17 -0
- data/data/butler/dialogs/en/info.yaml +13 -0
- data/data/butler/dialogs/en/list.yaml +4 -0
- data/data/butler/dialogs/en/notyetimplemented.yaml +2 -0
- data/data/butler/dialogs/en/rename.yaml +3 -0
- data/data/butler/dialogs/en/start.yaml +3 -0
- data/data/butler/dialogs/en/sync_plugins.yaml +3 -0
- data/data/butler/dialogs/en/uninstall.yaml +5 -0
- data/data/butler/dialogs/en/unknown_command.yaml +2 -0
- data/data/butler/dialogs/help.rb +11 -0
- data/data/butler/dialogs/info.rb +27 -0
- data/data/butler/dialogs/interactive.rb +1 -0
- data/data/butler/dialogs/list.rb +10 -0
- data/data/butler/dialogs/notyetimplemented.rb +1 -0
- data/data/butler/dialogs/rename.rb +4 -0
- data/data/butler/dialogs/selectbot.rb +2 -0
- data/data/butler/dialogs/start.rb +5 -0
- data/data/butler/dialogs/sync_plugins.rb +30 -0
- data/data/butler/dialogs/uninstall.rb +17 -0
- data/data/butler/dialogs/unknown_command.rb +1 -0
- data/data/butler/plugins/core/logout.rb +41 -0
- data/data/butler/plugins/core/plugins.rb +134 -0
- data/data/butler/plugins/core/privilege.rb +103 -0
- data/data/butler/plugins/core/user.rb +166 -0
- data/data/butler/plugins/dev/eval.rb +64 -0
- data/data/butler/plugins/dev/nometa.rb +14 -0
- data/data/butler/plugins/dev/onhandlers.rb +93 -0
- data/data/butler/plugins/dev/raw.rb +36 -0
- data/data/butler/plugins/dev/rawlog.rb +77 -0
- data/data/butler/plugins/games/eightball.rb +54 -0
- data/data/butler/plugins/games/mastermind.rb +174 -0
- data/data/butler/plugins/irc/action.rb +36 -0
- data/data/butler/plugins/irc/join.rb +38 -0
- data/data/butler/plugins/irc/notice.rb +36 -0
- data/data/butler/plugins/irc/part.rb +38 -0
- data/data/butler/plugins/irc/privmsg.rb +36 -0
- data/data/butler/plugins/irc/quit.rb +36 -0
- data/data/butler/plugins/operator/deop.rb +41 -0
- data/data/butler/plugins/operator/devoice.rb +41 -0
- data/data/butler/plugins/operator/limit.rb +47 -0
- data/data/butler/plugins/operator/op.rb +41 -0
- data/data/butler/plugins/operator/voice.rb +41 -0
- data/data/butler/plugins/public/help.rb +69 -0
- data/data/butler/plugins/public/login.rb +72 -0
- data/data/butler/plugins/public/usage.rb +49 -0
- data/data/butler/plugins/service/clones.rb +56 -0
- data/data/butler/plugins/service/define.rb +47 -0
- data/data/butler/plugins/service/log.rb +183 -0
- data/data/butler/plugins/service/svn.rb +91 -0
- data/data/butler/plugins/util/cycle.rb +98 -0
- data/data/butler/plugins/util/load.rb +41 -0
- data/data/butler/plugins/util/pong.rb +29 -0
- data/data/butler/strings/random/acknowledge.en.yaml +5 -0
- data/data/butler/strings/random/gratitude.en.yaml +3 -0
- data/data/butler/strings/random/hello.en.yaml +4 -0
- data/data/butler/strings/random/ignorance.en.yaml +7 -0
- data/data/butler/strings/random/ignorance_about.en.yaml +3 -0
- data/data/butler/strings/random/insult.en.yaml +3 -0
- data/data/butler/strings/random/rejection.en.yaml +12 -0
- data/data/man/botcontrol.1 +17 -0
- data/lib/access.rb +187 -0
- data/lib/access/admin.rb +16 -0
- data/lib/access/privilege.rb +122 -0
- data/lib/access/role.rb +102 -0
- data/lib/access/savable.rb +18 -0
- data/lib/access/user.rb +180 -0
- data/lib/access/yamlbase.rb +126 -0
- data/lib/butler.rb +188 -0
- data/lib/butler/bot.rb +247 -0
- data/lib/butler/control.rb +93 -0
- data/lib/butler/dialog.rb +64 -0
- data/lib/butler/initialvalues.rb +40 -0
- data/lib/butler/irc/channel.rb +135 -0
- data/lib/butler/irc/channels.rb +96 -0
- data/lib/butler/irc/client.rb +351 -0
- data/lib/butler/irc/hostmask.rb +53 -0
- data/lib/butler/irc/message.rb +184 -0
- data/lib/butler/irc/parser.rb +125 -0
- data/lib/butler/irc/parser/commands.rb +83 -0
- data/lib/butler/irc/parser/generic.rb +343 -0
- data/lib/butler/irc/socket.rb +378 -0
- data/lib/butler/irc/string.rb +186 -0
- data/lib/butler/irc/topic.rb +15 -0
- data/lib/butler/irc/user.rb +265 -0
- data/lib/butler/irc/users.rb +112 -0
- data/lib/butler/plugin.rb +249 -0
- data/lib/butler/plugin/configproxy.rb +35 -0
- data/lib/butler/plugin/mapper.rb +85 -0
- data/lib/butler/plugin/matcher.rb +55 -0
- data/lib/butler/plugin/onhandlers.rb +70 -0
- data/lib/butler/plugin/trigger.rb +58 -0
- data/lib/butler/plugins.rb +147 -0
- data/lib/butler/version.rb +17 -0
- data/lib/cloptions.rb +217 -0
- data/lib/cloptions/adapters.rb +24 -0
- data/lib/cloptions/switch.rb +132 -0
- data/lib/configuration.rb +223 -0
- data/lib/dialogline.rb +296 -0
- data/lib/dialogline/localizations.rb +24 -0
- data/lib/durations.rb +57 -0
- data/lib/event.rb +295 -0
- data/lib/event/at.rb +64 -0
- data/lib/event/every.rb +56 -0
- data/lib/event/timed.rb +112 -0
- data/lib/installer.rb +75 -0
- data/lib/iterator.rb +34 -0
- data/lib/log.rb +68 -0
- data/lib/log/comfort.rb +85 -0
- data/lib/log/converter.rb +23 -0
- data/lib/log/entry.rb +152 -0
- data/lib/log/fakeio.rb +55 -0
- data/lib/log/file.rb +54 -0
- data/lib/log/filereader.rb +81 -0
- data/lib/log/forward.rb +49 -0
- data/lib/log/methods.rb +39 -0
- data/lib/log/nolog.rb +18 -0
- data/lib/log/splitter.rb +26 -0
- data/lib/ostructfixed.rb +26 -0
- data/lib/ruby/array/columnize.rb +38 -0
- data/lib/ruby/dir/mktree.rb +28 -0
- data/lib/ruby/enumerable/join.rb +13 -0
- data/lib/ruby/exception/detailed.rb +24 -0
- data/lib/ruby/file/append.rb +11 -0
- data/lib/ruby/file/write.rb +11 -0
- data/lib/ruby/hash/zip.rb +15 -0
- data/lib/ruby/kernel/bench.rb +15 -0
- data/lib/ruby/kernel/daemonize.rb +42 -0
- data/lib/ruby/kernel/non_verbose.rb +17 -0
- data/lib/ruby/kernel/safe_fork.rb +18 -0
- data/lib/ruby/range/stepped.rb +11 -0
- data/lib/ruby/string/arguments.rb +72 -0
- data/lib/ruby/string/chunks.rb +15 -0
- data/lib/ruby/string/post_arguments.rb +44 -0
- data/lib/ruby/string/unescaped.rb +17 -0
- data/lib/scheduler.rb +164 -0
- data/lib/scriptfile.rb +101 -0
- data/lib/templater.rb +86 -0
- data/test/cloptions.rb +134 -0
- data/test/cv.rb +28 -0
- data/test/irc/client.rb +85 -0
- data/test/irc/client_login.txt +53 -0
- data/test/irc/client_subscribe.txt +8 -0
- data/test/irc/message.rb +30 -0
- data/test/irc/messages.txt +64 -0
- data/test/irc/parser.rb +13 -0
- data/test/irc/profile_parser.rb +12 -0
- data/test/irc/users.rb +28 -0
- metadata +256 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
module Log
|
|
10
|
+
module Converter
|
|
11
|
+
def default_type
|
|
12
|
+
:info
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def convert(obj)
|
|
16
|
+
case obj
|
|
17
|
+
when Entry: obj
|
|
18
|
+
when Exception: Entry.new(obj.message.chomp, :error, obj.backtrace)
|
|
19
|
+
else Entry.new(obj.to_str.chomp, default_type)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/log/entry.rb
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require 'enumerator'
|
|
10
|
+
require 'log'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
module Log
|
|
15
|
+
# currently unused
|
|
16
|
+
Printable = "%d#{RecordSeparator}%s#{RecordSeparator}%s#{RecordSeparator}%s"
|
|
17
|
+
# currently *only* used by Entry#serialize, but not by Entry::deserialize
|
|
18
|
+
Serialized =
|
|
19
|
+
"%d#{RecordSeparator}" \
|
|
20
|
+
"%s#{RecordSeparator}" \
|
|
21
|
+
"%s#{RecordSeparator}" \
|
|
22
|
+
"%s#{RecordSeparator}" \
|
|
23
|
+
"%s"
|
|
24
|
+
|
|
25
|
+
class Entry
|
|
26
|
+
class <<self
|
|
27
|
+
attr_accessor :time_format
|
|
28
|
+
|
|
29
|
+
def deserialize(line)
|
|
30
|
+
time, severity, text, flagstr, data = line.chomp(RecordTerminator).split(RecordSeparator)
|
|
31
|
+
flags = {}
|
|
32
|
+
flagstr.split(UnitSeparator).each_cons(2) { |key, value|
|
|
33
|
+
flagstr[key] = value
|
|
34
|
+
}
|
|
35
|
+
severity = Integer(severity) rescue severity
|
|
36
|
+
new(text, InvSeverity[severity], Marshal.load(Log.unescape(data)), Time.at(time.to_i), flags)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def formatter_for(entity, &formatter)
|
|
40
|
+
@formatter[entity] = formatter
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def format(entity, value, *args)
|
|
44
|
+
@formatter[entity].call(value, *args)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def format_time(entry, time, format=nil)
|
|
48
|
+
entry.time.strftime(format || @time_format)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def format_severity(entry)
|
|
52
|
+
entry.severity.to_s
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def format_flags(entry, flags)
|
|
56
|
+
entry.flags.map{ |k,v| "#{k}: #{v}"}.join(", ")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def format_text(entry)
|
|
60
|
+
entry.text.chomp.gsub(/[\r\n]+/, '; ').gsub(/[\x00-\x1f\x7f]/, '.')
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
Severity = Hash.new{|h,k|k}.merge({
|
|
65
|
+
:debug => 1,
|
|
66
|
+
:info => 2,
|
|
67
|
+
:warn => 4,
|
|
68
|
+
:error => 8,
|
|
69
|
+
:fail => 16,
|
|
70
|
+
})
|
|
71
|
+
InvSeverity = Severity.invert
|
|
72
|
+
@formatter = {
|
|
73
|
+
"time" => method(:format_time),
|
|
74
|
+
"severity" => method(:format_severity),
|
|
75
|
+
"flags" => method(:format_flags),
|
|
76
|
+
"text" => method(:format_text), #Log.method(:escape),
|
|
77
|
+
}
|
|
78
|
+
@time_format = "%FT%T"
|
|
79
|
+
|
|
80
|
+
attr_reader :time
|
|
81
|
+
attr_reader :severity
|
|
82
|
+
attr_reader :text
|
|
83
|
+
attr_reader :flags
|
|
84
|
+
attr_reader :data
|
|
85
|
+
def initialize(text, severity=:info, data=nil, *flags)
|
|
86
|
+
@time = flags.first.kind_of?(Time) ? flags.shift : Time.now
|
|
87
|
+
@severity = severity
|
|
88
|
+
@text = text
|
|
89
|
+
@data = data
|
|
90
|
+
@flags = flags.last.kind_of?(Hash) ? flags.pop : {}
|
|
91
|
+
@flags.each_key { |k,v| @flags[k.to_s] = @flags.delete(k) }
|
|
92
|
+
flags.each { |flag| @flags[flag.to_s] = true }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def [](key)
|
|
96
|
+
@flags[key]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def debug?
|
|
100
|
+
@severity == Severity[:debug]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def info?
|
|
104
|
+
@severity == Severity[:info]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def warn?
|
|
108
|
+
@severity == Severity[:warn]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def error?
|
|
112
|
+
@severity == Severity[:error]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def fail?
|
|
116
|
+
@severity == Severity[:fail]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def serialize
|
|
120
|
+
Serialized % [
|
|
121
|
+
@time,
|
|
122
|
+
Severity[@severity],
|
|
123
|
+
Log.escape(@text),
|
|
124
|
+
@flags.map.join(UnitSeparator),
|
|
125
|
+
Log.escape(Marshal.dump(@data))
|
|
126
|
+
]
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def to_s(format=nil)
|
|
130
|
+
format ||= "%{time:%FT%T} [%{severity}]: %{text}"
|
|
131
|
+
format.gsub(/%(%|\{[^}]+\})/) { |match|
|
|
132
|
+
if match == "%%" then
|
|
133
|
+
"%"
|
|
134
|
+
else
|
|
135
|
+
entity, *args = match[2..-2].split(/:/)
|
|
136
|
+
Entry.format(entity, self, *args)
|
|
137
|
+
end
|
|
138
|
+
}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def inspect
|
|
142
|
+
"#<%s %s %s %s flags=%s data=%s>" % [
|
|
143
|
+
self.class,
|
|
144
|
+
@time.strftime("%FT%T"),
|
|
145
|
+
@severity,
|
|
146
|
+
@text.inspect,
|
|
147
|
+
@flags.inspect,
|
|
148
|
+
@data.inspect
|
|
149
|
+
]
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
data/lib/log/fakeio.rb
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
module Log
|
|
10
|
+
# == Description
|
|
11
|
+
# Fakes most IO methods and forwards the converted data to #process
|
|
12
|
+
#
|
|
13
|
+
# == Requisites
|
|
14
|
+
# * @buffer initialized to ""
|
|
15
|
+
# * #process method present (this should write to the storage)
|
|
16
|
+
# * #convert method present (see Log::Converter)
|
|
17
|
+
#
|
|
18
|
+
# == Notes
|
|
19
|
+
# Following methods might be useful to be implemented:
|
|
20
|
+
# binmode, fcntl, fileno, flush, fsync, isatty, lineno, lineno=, pid, pos,
|
|
21
|
+
# pos=, , scanf, seek, soak_up_spaces, stat, sync, sync=, sysread, tell, to_i,
|
|
22
|
+
# to_io, tty?
|
|
23
|
+
#
|
|
24
|
+
# Following write methods are NOT implemented:
|
|
25
|
+
# puts, syswrite, write_nonblock
|
|
26
|
+
#
|
|
27
|
+
# All read methods must be implemented by the including class
|
|
28
|
+
#
|
|
29
|
+
module FakeIO
|
|
30
|
+
def process_buffer
|
|
31
|
+
while line = @buffer.slice!(/.*?\n/)
|
|
32
|
+
process(convert(line))
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def <<(obj)
|
|
37
|
+
process(convert(obj))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def puts(*objs)
|
|
41
|
+
objs.each { |obj| process(convert(obj)) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def write(*objs)
|
|
45
|
+
@buffer << objs.join("")
|
|
46
|
+
process_buffer
|
|
47
|
+
end
|
|
48
|
+
alias print write
|
|
49
|
+
|
|
50
|
+
def printf(*args)
|
|
51
|
+
@buffer << sprintf(*args)
|
|
52
|
+
process_buffer
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/log/file.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require 'log/converter'
|
|
10
|
+
require 'log/fakeio'
|
|
11
|
+
require 'log/methods'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
module Log
|
|
16
|
+
# Log.file is equivalent to Log::File.new
|
|
17
|
+
def self.file(*args)
|
|
18
|
+
Log::File.new(*args)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class File
|
|
22
|
+
include Converter
|
|
23
|
+
include FakeIO
|
|
24
|
+
include Methods
|
|
25
|
+
|
|
26
|
+
def initialize(out)
|
|
27
|
+
@out = nil
|
|
28
|
+
@default_type = :error
|
|
29
|
+
@buffer = ""
|
|
30
|
+
reopen(out)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def process(obj)
|
|
34
|
+
@out.puts(obj.serialize)
|
|
35
|
+
@out.flush
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def reopen(out)
|
|
39
|
+
close
|
|
40
|
+
@out = out.respond_to?(:to_str) ? ::File.open(out, "a") : out
|
|
41
|
+
raise TypeError, "out #{@out} does not respond to 'puts'." unless @out.respond_to?(:puts)
|
|
42
|
+
self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def close
|
|
46
|
+
@out.close if @out.respond_to?(:close)
|
|
47
|
+
self
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def closed?
|
|
51
|
+
@out.respond_to?(:close) ? @out.closed? : true
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
module Log
|
|
2
|
+
class FileReader
|
|
3
|
+
include Enumerable
|
|
4
|
+
class Filter
|
|
5
|
+
module Grep; def =~(entry); entry.text =~ @arg1; end; end
|
|
6
|
+
module NoGrep; def =~(entry); entry.text !~ @arg1; end; end
|
|
7
|
+
module Find; def =~(entry); entry.text.include?(@arg1); end; end
|
|
8
|
+
module NoFind; def =~(entry); !entry.text.include?(@arg1); end; end
|
|
9
|
+
module StartDate; def =~(entry); entry.time > @arg1; end; end
|
|
10
|
+
module EndDate; def =~(entry); entry.time < @arg1; end; end
|
|
11
|
+
module OneOfLevels; def =~(entry); @arg1.include?(entry.severity); end; end
|
|
12
|
+
module NoneOfLevels; def =~(entry); !@arg1.include?(entry.severity); end; end
|
|
13
|
+
|
|
14
|
+
Types = {
|
|
15
|
+
:grep => Grep,
|
|
16
|
+
:no_grep => NoGrep,
|
|
17
|
+
:find => Find,
|
|
18
|
+
:no_find => NoFind,
|
|
19
|
+
:start_date => StartDate,
|
|
20
|
+
:end_date => EndDate,
|
|
21
|
+
:one_of_levels => OneOfLevels,
|
|
22
|
+
:none_of_levels => NoneOfLevels,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
def initialize(type, *args)
|
|
26
|
+
extend Types[type]
|
|
27
|
+
@arg1 = args.first
|
|
28
|
+
@args = args
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def initialize(file)
|
|
33
|
+
@file = ::File.open(file, "r")
|
|
34
|
+
@pos = 0
|
|
35
|
+
@cache = {}
|
|
36
|
+
@filters = []
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def add_filter(type, *args)
|
|
40
|
+
@filters << Filter.new(type, *args)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def matches(entry)
|
|
44
|
+
@filters.all? { |filter| filter =~ entry }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def head(n)
|
|
48
|
+
i = 0
|
|
49
|
+
while line = @file.gets and i < n
|
|
50
|
+
entry = Log::Entry.deserialize(line)
|
|
51
|
+
if matches(entry) then
|
|
52
|
+
yield(entry)
|
|
53
|
+
i+=1
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
entries
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def tail(n, &block)
|
|
60
|
+
entries = []
|
|
61
|
+
while line = @file.gets and entries.length < n
|
|
62
|
+
entry = Log::Entry.deserialize(line)
|
|
63
|
+
entries.push entry if matches(entry)
|
|
64
|
+
end
|
|
65
|
+
while line = @file.gets
|
|
66
|
+
entry = Log::Entry.deserialize(line)
|
|
67
|
+
entries.push entry if matches(entry)
|
|
68
|
+
entries.shift
|
|
69
|
+
end
|
|
70
|
+
entries.compact
|
|
71
|
+
entries.each(&block)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def each
|
|
75
|
+
while line = @file.gets
|
|
76
|
+
entry = Log::Entry.deserialize(line)
|
|
77
|
+
yield(entry) if matches(entry)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
data/lib/log/forward.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require 'log/fakeio'
|
|
10
|
+
require 'log/converter'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
module Log
|
|
15
|
+
# Log.forward is equivalent to Log::Forward.new
|
|
16
|
+
def self.forward(*args)
|
|
17
|
+
Forward.new(*args)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Forward an IO to an object (object must respond to #puts)
|
|
21
|
+
# Will convert all puts/prints etc. to Log::Entry's using
|
|
22
|
+
# Log::Converter#convert
|
|
23
|
+
# Example:
|
|
24
|
+
# $stderr = Log.forward(your_logfile)
|
|
25
|
+
class Forward
|
|
26
|
+
include FakeIO
|
|
27
|
+
include Converter
|
|
28
|
+
|
|
29
|
+
def initialize(to, type=:info)
|
|
30
|
+
raise ArgumentError, "Target must respond to 'puts'" unless to.respond_to?(:puts)
|
|
31
|
+
@to = to
|
|
32
|
+
@default_type = type
|
|
33
|
+
@buffer = ""
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def process(obj)
|
|
37
|
+
@to.puts(obj)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def inspect
|
|
41
|
+
"#<%s:%08x %s %s>" % [
|
|
42
|
+
self.class,
|
|
43
|
+
object_id,
|
|
44
|
+
@default_type,
|
|
45
|
+
@to.inspect
|
|
46
|
+
]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/lib/log/methods.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
module Log
|
|
10
|
+
# Provides convenience mappings to #process
|
|
11
|
+
# Map debug, info, warn, error, fail to log, log itself uses process with
|
|
12
|
+
# Entry.new
|
|
13
|
+
# See Log::File for an example.
|
|
14
|
+
module Methods
|
|
15
|
+
def log(*args)
|
|
16
|
+
process(Entry.new(*args))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def debug(text, *args)
|
|
20
|
+
log(text, :debug, *args)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def info(text, *args)
|
|
24
|
+
log(text, :info, *args)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def warn(text, *args)
|
|
28
|
+
log(text, :warn, *args)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def error(text, *args)
|
|
32
|
+
log(text, :error, *args)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def fail(text, *args)
|
|
36
|
+
log(text, :fail, *args)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|