butler 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. data/CHANGELOG +4 -0
  2. data/GPL.txt +340 -0
  3. data/LICENSE.txt +52 -0
  4. data/README +37 -0
  5. data/Rakefile +334 -0
  6. data/bin/botcontrol +230 -0
  7. data/data/butler/config_template.yaml +4 -0
  8. data/data/butler/dialogs/backup.rb +19 -0
  9. data/data/butler/dialogs/botcontrol.rb +4 -0
  10. data/data/butler/dialogs/config.rb +1 -0
  11. data/data/butler/dialogs/create.rb +53 -0
  12. data/data/butler/dialogs/delete.rb +3 -0
  13. data/data/butler/dialogs/en/backup.yaml +6 -0
  14. data/data/butler/dialogs/en/botcontrol.yaml +5 -0
  15. data/data/butler/dialogs/en/create.yaml +11 -0
  16. data/data/butler/dialogs/en/delete.yaml +2 -0
  17. data/data/butler/dialogs/en/help.yaml +17 -0
  18. data/data/butler/dialogs/en/info.yaml +13 -0
  19. data/data/butler/dialogs/en/list.yaml +4 -0
  20. data/data/butler/dialogs/en/notyetimplemented.yaml +2 -0
  21. data/data/butler/dialogs/en/rename.yaml +3 -0
  22. data/data/butler/dialogs/en/start.yaml +3 -0
  23. data/data/butler/dialogs/en/sync_plugins.yaml +3 -0
  24. data/data/butler/dialogs/en/uninstall.yaml +5 -0
  25. data/data/butler/dialogs/en/unknown_command.yaml +2 -0
  26. data/data/butler/dialogs/help.rb +11 -0
  27. data/data/butler/dialogs/info.rb +27 -0
  28. data/data/butler/dialogs/interactive.rb +1 -0
  29. data/data/butler/dialogs/list.rb +10 -0
  30. data/data/butler/dialogs/notyetimplemented.rb +1 -0
  31. data/data/butler/dialogs/rename.rb +4 -0
  32. data/data/butler/dialogs/selectbot.rb +2 -0
  33. data/data/butler/dialogs/start.rb +5 -0
  34. data/data/butler/dialogs/sync_plugins.rb +30 -0
  35. data/data/butler/dialogs/uninstall.rb +17 -0
  36. data/data/butler/dialogs/unknown_command.rb +1 -0
  37. data/data/butler/plugins/core/logout.rb +41 -0
  38. data/data/butler/plugins/core/plugins.rb +134 -0
  39. data/data/butler/plugins/core/privilege.rb +103 -0
  40. data/data/butler/plugins/core/user.rb +166 -0
  41. data/data/butler/plugins/dev/eval.rb +64 -0
  42. data/data/butler/plugins/dev/nometa.rb +14 -0
  43. data/data/butler/plugins/dev/onhandlers.rb +93 -0
  44. data/data/butler/plugins/dev/raw.rb +36 -0
  45. data/data/butler/plugins/dev/rawlog.rb +77 -0
  46. data/data/butler/plugins/games/eightball.rb +54 -0
  47. data/data/butler/plugins/games/mastermind.rb +174 -0
  48. data/data/butler/plugins/irc/action.rb +36 -0
  49. data/data/butler/plugins/irc/join.rb +38 -0
  50. data/data/butler/plugins/irc/notice.rb +36 -0
  51. data/data/butler/plugins/irc/part.rb +38 -0
  52. data/data/butler/plugins/irc/privmsg.rb +36 -0
  53. data/data/butler/plugins/irc/quit.rb +36 -0
  54. data/data/butler/plugins/operator/deop.rb +41 -0
  55. data/data/butler/plugins/operator/devoice.rb +41 -0
  56. data/data/butler/plugins/operator/limit.rb +47 -0
  57. data/data/butler/plugins/operator/op.rb +41 -0
  58. data/data/butler/plugins/operator/voice.rb +41 -0
  59. data/data/butler/plugins/public/help.rb +69 -0
  60. data/data/butler/plugins/public/login.rb +72 -0
  61. data/data/butler/plugins/public/usage.rb +49 -0
  62. data/data/butler/plugins/service/clones.rb +56 -0
  63. data/data/butler/plugins/service/define.rb +47 -0
  64. data/data/butler/plugins/service/log.rb +183 -0
  65. data/data/butler/plugins/service/svn.rb +91 -0
  66. data/data/butler/plugins/util/cycle.rb +98 -0
  67. data/data/butler/plugins/util/load.rb +41 -0
  68. data/data/butler/plugins/util/pong.rb +29 -0
  69. data/data/butler/strings/random/acknowledge.en.yaml +5 -0
  70. data/data/butler/strings/random/gratitude.en.yaml +3 -0
  71. data/data/butler/strings/random/hello.en.yaml +4 -0
  72. data/data/butler/strings/random/ignorance.en.yaml +7 -0
  73. data/data/butler/strings/random/ignorance_about.en.yaml +3 -0
  74. data/data/butler/strings/random/insult.en.yaml +3 -0
  75. data/data/butler/strings/random/rejection.en.yaml +12 -0
  76. data/data/man/botcontrol.1 +17 -0
  77. data/lib/access.rb +187 -0
  78. data/lib/access/admin.rb +16 -0
  79. data/lib/access/privilege.rb +122 -0
  80. data/lib/access/role.rb +102 -0
  81. data/lib/access/savable.rb +18 -0
  82. data/lib/access/user.rb +180 -0
  83. data/lib/access/yamlbase.rb +126 -0
  84. data/lib/butler.rb +188 -0
  85. data/lib/butler/bot.rb +247 -0
  86. data/lib/butler/control.rb +93 -0
  87. data/lib/butler/dialog.rb +64 -0
  88. data/lib/butler/initialvalues.rb +40 -0
  89. data/lib/butler/irc/channel.rb +135 -0
  90. data/lib/butler/irc/channels.rb +96 -0
  91. data/lib/butler/irc/client.rb +351 -0
  92. data/lib/butler/irc/hostmask.rb +53 -0
  93. data/lib/butler/irc/message.rb +184 -0
  94. data/lib/butler/irc/parser.rb +125 -0
  95. data/lib/butler/irc/parser/commands.rb +83 -0
  96. data/lib/butler/irc/parser/generic.rb +343 -0
  97. data/lib/butler/irc/socket.rb +378 -0
  98. data/lib/butler/irc/string.rb +186 -0
  99. data/lib/butler/irc/topic.rb +15 -0
  100. data/lib/butler/irc/user.rb +265 -0
  101. data/lib/butler/irc/users.rb +112 -0
  102. data/lib/butler/plugin.rb +249 -0
  103. data/lib/butler/plugin/configproxy.rb +35 -0
  104. data/lib/butler/plugin/mapper.rb +85 -0
  105. data/lib/butler/plugin/matcher.rb +55 -0
  106. data/lib/butler/plugin/onhandlers.rb +70 -0
  107. data/lib/butler/plugin/trigger.rb +58 -0
  108. data/lib/butler/plugins.rb +147 -0
  109. data/lib/butler/version.rb +17 -0
  110. data/lib/cloptions.rb +217 -0
  111. data/lib/cloptions/adapters.rb +24 -0
  112. data/lib/cloptions/switch.rb +132 -0
  113. data/lib/configuration.rb +223 -0
  114. data/lib/dialogline.rb +296 -0
  115. data/lib/dialogline/localizations.rb +24 -0
  116. data/lib/durations.rb +57 -0
  117. data/lib/event.rb +295 -0
  118. data/lib/event/at.rb +64 -0
  119. data/lib/event/every.rb +56 -0
  120. data/lib/event/timed.rb +112 -0
  121. data/lib/installer.rb +75 -0
  122. data/lib/iterator.rb +34 -0
  123. data/lib/log.rb +68 -0
  124. data/lib/log/comfort.rb +85 -0
  125. data/lib/log/converter.rb +23 -0
  126. data/lib/log/entry.rb +152 -0
  127. data/lib/log/fakeio.rb +55 -0
  128. data/lib/log/file.rb +54 -0
  129. data/lib/log/filereader.rb +81 -0
  130. data/lib/log/forward.rb +49 -0
  131. data/lib/log/methods.rb +39 -0
  132. data/lib/log/nolog.rb +18 -0
  133. data/lib/log/splitter.rb +26 -0
  134. data/lib/ostructfixed.rb +26 -0
  135. data/lib/ruby/array/columnize.rb +38 -0
  136. data/lib/ruby/dir/mktree.rb +28 -0
  137. data/lib/ruby/enumerable/join.rb +13 -0
  138. data/lib/ruby/exception/detailed.rb +24 -0
  139. data/lib/ruby/file/append.rb +11 -0
  140. data/lib/ruby/file/write.rb +11 -0
  141. data/lib/ruby/hash/zip.rb +15 -0
  142. data/lib/ruby/kernel/bench.rb +15 -0
  143. data/lib/ruby/kernel/daemonize.rb +42 -0
  144. data/lib/ruby/kernel/non_verbose.rb +17 -0
  145. data/lib/ruby/kernel/safe_fork.rb +18 -0
  146. data/lib/ruby/range/stepped.rb +11 -0
  147. data/lib/ruby/string/arguments.rb +72 -0
  148. data/lib/ruby/string/chunks.rb +15 -0
  149. data/lib/ruby/string/post_arguments.rb +44 -0
  150. data/lib/ruby/string/unescaped.rb +17 -0
  151. data/lib/scheduler.rb +164 -0
  152. data/lib/scriptfile.rb +101 -0
  153. data/lib/templater.rb +86 -0
  154. data/test/cloptions.rb +134 -0
  155. data/test/cv.rb +28 -0
  156. data/test/irc/client.rb +85 -0
  157. data/test/irc/client_login.txt +53 -0
  158. data/test/irc/client_subscribe.txt +8 -0
  159. data/test/irc/message.rb +30 -0
  160. data/test/irc/messages.txt +64 -0
  161. data/test/irc/parser.rb +13 -0
  162. data/test/irc/profile_parser.rb +12 -0
  163. data/test/irc/users.rb +28 -0
  164. metadata +256 -0
@@ -0,0 +1,64 @@
1
+ #--
2
+ # Copyright 2007 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ require 'event'
10
+
11
+
12
+
13
+ class Event
14
+ class At < Event
15
+ class <<self
16
+ public :new
17
+ end
18
+
19
+ attr_reader :index
20
+
21
+ # A string representation. Just nice for printing.
22
+ def inspect
23
+ string = if off? then
24
+ "Off"
25
+ elsif finished? then
26
+ "Finished"
27
+ elsif left = seconds_left then
28
+ "Due: %s (%.2fs)" % [@next.strftime("%H:%M:%S"), left]
29
+ else
30
+ "Error"
31
+ end
32
+
33
+ datetimes = (@previous ? @datetimes.select { |dt| dt > @previous } : @datetimes)
34
+ "#<%s %s, %s done, due at %s%s>" % [
35
+ self.class,
36
+ string,
37
+ @times ? "#{@count}/#{@times}" : @count,
38
+ datetimes.first(5).join(', '),
39
+ datetimes.length > 5 ? "..." : ""
40
+ ]
41
+ end
42
+
43
+ def initialize(*datetimes, &block)
44
+ super(datetimes.last.kind_of?(Hash) ? datetimes.pop : {}, &block)
45
+ @datetimes = datetimes.sort
46
+ #@start = @datetimes.first
47
+ #@stop = @datetimes.last
48
+ @index = nil
49
+ @next = calculate_first(@start)
50
+ end
51
+
52
+ protected
53
+ def calculate_first(with_start)
54
+ found = @datetimes.find { |compare| compare >= with_start }
55
+ @index = found && @datetimes.index(found)
56
+ return found
57
+ end
58
+
59
+ def calculate_next(withLast)
60
+ @index += 1
61
+ @datetimes[@index]
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,56 @@
1
+ #--
2
+ # Copyright 2007 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ require 'event'
10
+
11
+
12
+
13
+ class Event
14
+ class Every < Event
15
+ class <<self
16
+ public :new
17
+ end
18
+
19
+ attr_reader :interval
20
+
21
+ # A string representation. Just nice for printing.
22
+ def inspect
23
+ string = if off? then
24
+ "Off"
25
+ elsif finished? then
26
+ "Finished"
27
+ elsif left = seconds_left then
28
+ "Due: %s (%.2fs)" % [@next.strftime("%H:%M:%S"), left]
29
+ else
30
+ "Error"
31
+ end
32
+
33
+ "#<%s %s, %s done, scheduled every %.1fs>" % [
34
+ self.class,
35
+ string,
36
+ @times ? "#{@count}/#{@times}" : @count,
37
+ @interval
38
+ ]
39
+ end
40
+
41
+ protected
42
+ def initialize(seconds, options={}, &block)
43
+ super(options, &block)
44
+ @interval = seconds
45
+ @next = calculate_first(@start)
46
+ end
47
+
48
+ def calculate_first(with_start)
49
+ with_start+@interval
50
+ end
51
+
52
+ def calculate_next(with_last)
53
+ with_last+@interval
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,112 @@
1
+ #--
2
+ # Copyright 2007 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ require 'event'
10
+
11
+
12
+
13
+ class Event
14
+ class Timed < Event
15
+ class <<self
16
+ public :new
17
+ end
18
+
19
+ attr_reader :original
20
+
21
+ # A string representation. Just nice for printing.
22
+ def inspect
23
+ string = if off? then
24
+ "Off"
25
+ elsif finished? then
26
+ "Finished"
27
+ elsif left = seconds_left then
28
+ "Due: %s (%.2fs)" % [@next.strftime("%H:%M:%S"), left]
29
+ else
30
+ "Error"
31
+ end
32
+
33
+ "#<%s %s, %s done, timed for %s, %s, %s>" % [
34
+ self.class,
35
+ string,
36
+ @times ? "#{@count}/#{@times}" : @count,
37
+ *@original
38
+ ]
39
+ end
40
+
41
+ def initialize(hours=[0], minutes=[0], seconds=[0], options={}, &block)
42
+ super(options, &block)
43
+ @original = [hours.inspect, minutes.inspect, seconds.inspect]
44
+ @indices = [0,0,0]
45
+ @hours = extract_time_range(hours, 23, HOUR_DIVISORS).sort
46
+ @minutes = extract_time_range(minutes, 59, MINUTE_DIVISORS).sort
47
+ @seconds = extract_time_range(seconds, 59, SECOND_DIVISORS).sort
48
+ @next = calculate_first(@start)
49
+ end
50
+
51
+ def hours
52
+ @hours.dup
53
+ end
54
+
55
+ def minutes
56
+ @minutes.dup
57
+ end
58
+
59
+ def seconds
60
+ @seconds.dup
61
+ end
62
+
63
+ protected
64
+ def calculate_first(with_start)
65
+ start_sec = with_start.sec
66
+ start_min = with_start.min
67
+ start_hour = with_start.hour
68
+
69
+ sec = @seconds.find { |s| s > start_sec } || @seconds.first
70
+
71
+ # if second is smaller than start time's second, it can't be in the same minute
72
+ min = if (sec <= start_sec) then
73
+ @minutes.find { |m| m > start_min } || @minutes.first
74
+ else
75
+ @minutes.find { |m| m >= start_min } || @minutes.first
76
+ end
77
+
78
+ # if minute is smaller than start time's minute, it can't be in the same hour
79
+ hour = if (min < start_min) then
80
+ @hours.find { |h| h > start_hour } || @hours.first
81
+ else
82
+ @hours.find { |h| h >= start_hour } || @hours.first
83
+ end
84
+
85
+ @indices = [@hours.index(hour), @minutes.index(min), @seconds.index(sec)]
86
+ first = Time.mktime(with_start.year, with_start.month, with_start.day, hour, min, sec)
87
+ first += 86400 if first < with_start # happens if hour was nil (e.g. it's 23.00 and next timer is 01.00)
88
+
89
+ first
90
+ end
91
+
92
+ def calculate_next(with_last)
93
+ overflow = 0
94
+ 2.downto(0) { |i|
95
+ @indices[i] += 1
96
+ @indices[i], overflow = *@indices[i].divmod(@seconds.length)
97
+ }
98
+ hour = @hours[@indices[0]]
99
+ minute = @minutes[@indices[1]]
100
+ second = @seconds[@indices[2]]
101
+
102
+ Time.mktime(
103
+ with_last.year,
104
+ with_last.month,
105
+ with_last.day,
106
+ hour,
107
+ minute,
108
+ second
109
+ )+overflow*86400
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,75 @@
1
+ require 'rbconfig'
2
+
3
+ class Installer
4
+ def initialize(app_name)
5
+ @app_name = app_name
6
+ end
7
+
8
+ def os_class
9
+ @os_class ||= case Config::CONFIG["target_os"]
10
+ when /^darwin/: :osx
11
+ when /^win/: :windows
12
+ else :nix
13
+ end
14
+ end
15
+
16
+ def user_data_suggestions
17
+ {
18
+ :osx => ["#{ENV['HOME']}/Library/Application Support/#{@app_name}", "#{ENV['HOME']}/.#{@app_name}"],
19
+ :windows => ["#{ENV['HOME']}/.#{@app_name}"],
20
+ :nix => ["#{ENV['HOME']}/.#{@app_name}"],
21
+ }[os_class]
22
+ end
23
+
24
+ def user_config_suggestions
25
+ {
26
+ :osx => ["#{ENV['HOME']}/Library/Preferences/#{@app_name}", "#{ENV['HOME']}/.#{@app_name}/etc"],
27
+ :windows => ["#{ENV['HOME']}/.#{@app_name}/etc"],
28
+ :nix => ["#{ENV['HOME']}/.#{@app_name}/etc"],
29
+ }[os_class]
30
+ end
31
+
32
+ def user_documents_suggestions
33
+ {
34
+ :osx => ["#{ENV['HOME']}/Documents"],
35
+ :windows => [
36
+ "#{ENV['HOME']}/My Documents",
37
+ "#{ENV['HOME']}/#{ENV['USER']}'s Documents",
38
+ "#{ENV['HOME']}/#{ENV['USER'].downcase}'s documents"
39
+ ].select { |path| File.directory?(path) },
40
+ :nix => ["#{ENV['HOME']}/"],
41
+ }[os_class]
42
+ end
43
+
44
+ def user_pid_suggestions
45
+ {
46
+ :osx => ["#{ENV['HOME']}/Library/Application Support/#{@app_name}/run", "#{ENV['HOME']}/.#{@app_name}/run"],
47
+ :windows => ["#{ENV['HOME']}/.#{@app_name}/run"],
48
+ :nix => ["#{ENV['HOME']}/.#{@app_name}/run"],
49
+ }[os_class]
50
+ end
51
+
52
+ def shared_data_suggestions
53
+ {
54
+ :osx => ["/Library/Application Support/#{@app_name}", "#{Config::CONFIG['datadir']}/#{@app_name}"],
55
+ :windows => ["#{Config::CONFIG['datadir']}/#{@app_name}"],
56
+ :nix => ["#{Config::CONFIG['datadir']}/#{@app_name}"],
57
+ }[os_class]
58
+ end
59
+
60
+ def cli_binary_suggestions
61
+ {
62
+ :osx => [Config::CONFIG['bindir']],
63
+ :windows => [Config::CONFIG['bindir']],
64
+ :nix => [Config::CONFIG['bindir'], "#{ENV['HOME']}/bin"],
65
+ }[os_class]
66
+ end
67
+
68
+ def gui_binary_suggestions
69
+ {
70
+ :osx => ["/Applications", ENV['HOME']+"/Applications"],
71
+ :windows => [Config::CONFIG['bindir']],
72
+ :nix => [Config::CONFIG['bindir'], "#{ENV['HOME']}/bin"],
73
+ }[os_class]
74
+ end
75
+ end
@@ -0,0 +1,34 @@
1
+ #--
2
+ # Copyright 2007 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ class Iterator
10
+ include Enumerable
11
+
12
+ class Iteration
13
+ def initialize(&block)
14
+ @block = block
15
+ end
16
+ def yield(*args)
17
+ @block.call(*args)
18
+ end
19
+ end
20
+
21
+ def initialize(&iterator)
22
+ @iterator = iterator
23
+ end
24
+
25
+ def each(&block)
26
+ @iterator.call(Iteration.new(&block))
27
+ end
28
+ end
29
+
30
+ if __FILE__ == $0 then
31
+ #Iterator.new { |iter| File.open(path) { |fh| while buf = fh.read(8192); iter.yield(buf); end } }
32
+ x = Iterator.new { |iter| [1,2,3].each { |e| iter.yield(e) } }
33
+ p x.map { |e| e*2 }
34
+ end
@@ -0,0 +1,68 @@
1
+ #--
2
+ # Copyright 2007 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ # == Synopsis
10
+ # Logfile = Log::File.new("foo.log")
11
+ # $stderr = Log::Forward(Logfile, :warn) # capture everything that prints to $stderr and treat it as :warn level message
12
+ # $stdout = Log::Forward(Logfile, :info)
13
+ # $stderr.puts "foo" # same as Log::File#log("foo", :warn)
14
+ # $stdout.puts "bar" # same as Log::File#log("bar", :info)
15
+ # begin
16
+ # raise "baz"
17
+ # rescue => exception
18
+ # $stdout.puts(exception) # same as Log::File#log(exception)
19
+ # end
20
+ #
21
+ # == Notes
22
+ # require 'log/kernel' to get convenience methods in Kernel
23
+ # it isn't required via 'log' alone to avoid accidental method name clashes.
24
+ # notice that log/kernel will override Kernel#warn
25
+ #
26
+ module Log
27
+ GroupSeparator = "\x1d"
28
+ RecordSeparator = "\x1e"
29
+ UnitSeparator = "\x1f"
30
+ RecordTerminator = "\n"
31
+
32
+ # escape binary data, the data will contain no \n, \r or \t's after escaping, but
33
+ # still contain binary characters, but all of them preceeded by \e
34
+ def self.escape(data)
35
+ data.
36
+ gsub(/\e/, "\e\e").
37
+ gsub(/\n/, "\en").
38
+ gsub(/\r/, "\er").
39
+ gsub(/\t/, "\et").
40
+ gsub(/[\x00-\x1a\x1c-\x1f]/, "\e\\0")
41
+ end
42
+
43
+ # unescapes data escaped by Log.escape
44
+ def self.unescape(data)
45
+ data.
46
+ gsub(/\en/, "\n").
47
+ gsub(/\er/, "\r").
48
+ gsub(/\et/, "\t").
49
+ gsub(/\e(.)/, '\1')
50
+ end
51
+ end
52
+
53
+ require 'log/comfort'
54
+ require 'log/converter'
55
+ require 'log/entry'
56
+ require 'log/forward'
57
+ require 'log/fakeio'
58
+ require 'log/file'
59
+ require 'log/nolog'
60
+
61
+
62
+ if __FILE__ == $0 then
63
+ lf = StringIO.new
64
+ log = Log::File.new(lf)
65
+ $stderr = Log::Forward.new(log, :warn)
66
+ warn "foo"
67
+ Log::Entry.deserialize(lf.string.split("\n").first)
68
+ end
@@ -0,0 +1,85 @@
1
+ #--
2
+ # Copyright 2007 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ require 'log/entry'
10
+
11
+
12
+
13
+ # == Description
14
+ # log/entry.rb provides some convenience methods in Log.
15
+ #
16
+ # == Synopsis
17
+ # log("Some info")
18
+ # log("Danger!", :warn)
19
+ # warn("Danger!")
20
+ # debug("mecode was here")
21
+ #
22
+ module Log
23
+ module Comfort
24
+ # where data is logged to
25
+ attr_accessor :log_device
26
+
27
+ # See Log::Message.new
28
+ # Module::log(*args) is simply: $stderr.puts(Log::Message.new(*args))
29
+ def log(text, severity=:info, *args)
30
+ (@log_device || $stderr).puts(Log::Entry.new(text.to_str, severity, *args))
31
+ end
32
+
33
+ # See Log::Entry.new to see what arguments are valid.
34
+ # Module::debug(text, *args) is the same as:
35
+ # $stderr.puts(Log::Message.new(text, :debug, *args))
36
+ def debug(text, *args)
37
+ (@log_device || $stderr).puts(Log::Entry.new(text.to_str, :debug, *args))
38
+ end
39
+
40
+ # See Log::Entry.new to see what arguments are valid.
41
+ # Module::info(text, *args) is the same as:
42
+ # $stderr.puts(Log::Message.new(text, :info, *args))
43
+ def info(text, *args)
44
+ (@log_device || $stderr).puts(Log::Entry.new(text.to_str, :info, *args))
45
+ end
46
+
47
+ # See Log::Entry.new to see what arguments are valid.
48
+ # Module::warn(text, *args) is the same as:
49
+ # $stderr.puts(Log::Message.new(text, :warn, *args))
50
+ def warn(text, *args)
51
+ (@log_device || $stderr).puts(Log::Entry.new(text.to_str, :warn, *args))
52
+ end
53
+
54
+ # See Log::Entry.new to see what arguments are valid.
55
+ # Module::error(text, *args) is the same as:
56
+ # $stderr.puts(Log::Message.new(text, :error, *args))
57
+ def error(text, *args)
58
+ (@log_device || $stderr).puts(Log::Entry.new(text.to_str, :error, *args))
59
+ end
60
+
61
+ # See Log::Entry.new to see what arguments are valid.
62
+ # Module::fail(text, *args) is the same as:
63
+ # $stderr.puts(Log::Message.new(text, :fail, *args))
64
+ def fail(text, *args)
65
+ (@log_device || $stderr).puts(Log::Entry.new(text.to_str, :fail, *args))
66
+ end
67
+
68
+ #
69
+ def exception(e)
70
+ log = @log_device || $stderr
71
+ if log.respond_to?(:exception) then
72
+ log.exception(e)
73
+ else
74
+ log.puts("#{Time.now.strftime('%FT%T')} [exception]: #{e} (#{e.class})")
75
+ if $VERBOSE then
76
+ prefix = "--> "
77
+ log.puts(*e.backtrace.map { |l| prefix+l })
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ # enable Log.log etc.
84
+ extend Comfort
85
+ end