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.
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