butler 1.8.1 → 1.8.2

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 (71) hide show
  1. data/CHANGELOG.txt +212 -0
  2. data/{README → README.txt} +0 -0
  3. data/Rakefile +16 -11
  4. data/bin/botcontrol +35 -14
  5. data/data/butler/dialogs/create.rb +29 -40
  6. data/data/butler/dialogs/create_config.rb +1 -1
  7. data/data/butler/dialogs/dir.rb +13 -0
  8. data/data/butler/dialogs/en/create.yaml +24 -10
  9. data/data/butler/dialogs/en/dir.yaml +5 -0
  10. data/data/butler/dialogs/en/help.yaml +28 -11
  11. data/data/butler/dialogs/en/quickcreate.yaml +14 -0
  12. data/data/butler/dialogs/help.rb +16 -4
  13. data/data/butler/dialogs/quickcreate.rb +49 -0
  14. data/data/butler/plugins/core/access.rb +211 -0
  15. data/data/butler/plugins/core/logout.rb +11 -11
  16. data/data/butler/plugins/core/plugins.rb +23 -41
  17. data/data/butler/plugins/dev/bleakhouse.rb +46 -0
  18. data/data/butler/plugins/games/roll.rb +1 -1
  19. data/data/butler/plugins/operator/deop.rb +15 -20
  20. data/data/butler/plugins/operator/devoice.rb +14 -20
  21. data/data/butler/plugins/operator/limit.rb +56 -21
  22. data/data/butler/plugins/operator/op.rb +15 -20
  23. data/data/butler/plugins/operator/voice.rb +15 -20
  24. data/data/butler/plugins/service/define.rb +3 -3
  25. data/data/butler/plugins/service/more.rb +40 -0
  26. data/data/butler/plugins/util/cycle.rb +1 -1
  27. data/data/butler/plugins/util/load.rb +5 -5
  28. data/data/butler/plugins/util/pong.rb +3 -2
  29. data/lib/access/privilege.rb +17 -0
  30. data/lib/access/role.rb +33 -2
  31. data/lib/access/savable.rb +6 -0
  32. data/lib/access/yamlbase.rb +1 -2
  33. data/lib/butler/bot.rb +40 -7
  34. data/lib/butler/debuglog.rb +17 -0
  35. data/lib/butler/dialog.rb +1 -1
  36. data/lib/butler/irc/{channels.rb → channellist.rb} +2 -2
  37. data/lib/butler/irc/client.rb +60 -79
  38. data/lib/butler/irc/client/filter.rb +12 -0
  39. data/lib/butler/irc/client/listener.rb +55 -0
  40. data/lib/butler/irc/client/listenerlist.rb +69 -0
  41. data/lib/butler/irc/hostmask.rb +31 -16
  42. data/lib/butler/irc/message.rb +3 -3
  43. data/lib/butler/irc/parser.rb +2 -2
  44. data/lib/butler/irc/parser/rfc2812.rb +2 -6
  45. data/lib/butler/irc/socket.rb +12 -6
  46. data/lib/butler/irc/string.rb +4 -0
  47. data/lib/butler/irc/user.rb +0 -6
  48. data/lib/butler/irc/{users.rb → userlist.rb} +2 -2
  49. data/lib/butler/irc/whois.rb +6 -0
  50. data/lib/butler/plugin.rb +48 -14
  51. data/lib/butler/plugin/configproxy.rb +20 -0
  52. data/lib/butler/plugin/mapper.rb +308 -24
  53. data/lib/butler/plugin/matcher.rb +3 -1
  54. data/lib/butler/plugin/more.rb +65 -0
  55. data/lib/butler/plugin/onhandlers.rb +4 -4
  56. data/lib/butler/plugin/trigger.rb +4 -2
  57. data/lib/butler/plugins.rb +1 -1
  58. data/lib/butler/session.rb +11 -0
  59. data/lib/butler/version.rb +1 -1
  60. data/lib/cloptions.rb +1 -1
  61. data/lib/diagnostics.rb +20 -0
  62. data/lib/dialogline.rb +1 -1
  63. data/lib/durations.rb +19 -6
  64. data/lib/event.rb +8 -5
  65. data/lib/installer.rb +10 -3
  66. data/lib/ostructfixed.rb +11 -0
  67. data/lib/ruby/kernel/daemonize.rb +1 -2
  68. data/test/butler/plugin/mapper.rb +46 -0
  69. metadata +28 -11
  70. data/CHANGELOG +0 -44
  71. data/data/butler/plugins/core/privilege.rb +0 -103
@@ -20,11 +20,11 @@ class Butler
20
20
  when :on_notice: subscribe(:NOTICE, priority) { |listener, message| new(message).on_notice(listener, message.from, message.text) }
21
21
  when :on_nick: subscribe(:NICK, priority) { |listener, message| new(message).on_nick(listener, message.from, message.old_nick) }
22
22
  when :on_topic: subscribe(:TOPIC, priority) { |listener, message| new(message).on_topic(listener, message.from, message.channel, message.text) }
23
- when :on_part: subscribe(:PART, priority) { |listener, message| new(message).on_part(listener, message.from, message.channel) }
23
+ when :on_part: subscribe(:PART, priority) { |listener, message| new(message).on_part(listener, message.from, message.channel, message.text) }
24
24
  when :on_quit: subscribe(:QUIT, priority) { |listener, message| new(message).on_quit(listener, message.from, message.text) }
25
- when :on_kick: subscribe(:KICK, priority) { |listener, message| new(message).on_kick(listener) }
26
- when :on_kill: subscribe(:KILL, priority) { |listener, message| new(message).on_kill(listener) }
27
- when :on_kline: subscribe(:KLINE, priority) { |listener, message| new(message).on_kline(listener) }
25
+ when :on_kick: subscribe(:KICK, priority) { |listener, message| new(message).on_kick(listener, message.from, message.for, message.channel, message.text) }
26
+ when :on_kill: subscribe(:KILL, priority) { |listener, message| new(message).on_kill(listener, message.from, message.for, message.text) }
27
+ when :on_kline: subscribe(:KLINE, priority) { |listener, message| new(message).on_kline(listener, message.from, message.for, message.text) }
28
28
  when :on_invocation
29
29
  subscribe(:PRIVMSG, priority) { |listener, message|
30
30
  new(message).on_invocation(listener) if message.invocation
@@ -13,6 +13,8 @@ require 'butler/plugin'
13
13
  class Butler
14
14
  class Plugin
15
15
  class Trigger
16
+ Priority = 0
17
+
16
18
  attr_reader :authorization
17
19
  attr_reader :hash
18
20
  attr_reader :language
@@ -39,11 +41,11 @@ class Butler
39
41
  end
40
42
 
41
43
  def priority
42
- 0
44
+ Priority
43
45
  end
44
46
 
45
47
  def <=>(other)
46
- 0 <=> other.priority
48
+ other.priority <=> Priority
47
49
  end
48
50
 
49
51
  def abort_invocations?
@@ -80,7 +80,7 @@ class Butler
80
80
  end
81
81
 
82
82
  def identify(name)
83
- plugin = Dir["#{@dir}/**/*#{name}#{Suffix}"].first
83
+ plugin = Dir["#{@dir}/**/#{name}#{Suffix}"].first
84
84
  plugin && plugin[@dir.length+1..-(Suffix.length+1)]
85
85
  end
86
86
 
@@ -0,0 +1,11 @@
1
+ class Butler
2
+ class Session < Hash
3
+ def []=(key, value)
4
+ if value.nil? then
5
+ delete(key)
6
+ else
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -10,7 +10,7 @@ class Butler #:nodoc:
10
10
  module VERSION #:nodoc:
11
11
  MAJOR = 1
12
12
  MINOR = 8
13
- TINY = 1
13
+ TINY = 2
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY].join('.')
16
16
  end
@@ -70,7 +70,7 @@ class CLOptions
70
70
  private
71
71
  def add_flag(match, from)
72
72
  name, data = match.captures
73
- raise "Unknown switch -#{name}" unless switch = from[name]
73
+ raise "Unknown switch #{name}" unless switch = from[name]
74
74
  flag = switch.process(data, @argv_processing)
75
75
  switch.mappings.each { |mapping|
76
76
  @flags[mapping] = flag
@@ -0,0 +1,20 @@
1
+ #--
2
+ # Copyright 2007 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ # Used to provide better diagnostics
10
+ class Diagnostics
11
+ def initialize(owner, exceptions={})
12
+ @owner = owner
13
+ @exceptions = Hash.new { |h,k| [NoMethodError, "undefined method `#{k}' for #{@owner.inspect}"] }.merge(exceptions)
14
+ end
15
+
16
+ def method_missing(m, *args, &block)
17
+ ex, msg = *@exceptions[m]
18
+ raise ex, msg
19
+ end
20
+ end
@@ -244,7 +244,7 @@ class DialogLine
244
244
  Context.run(@dialog, file, @use_ostruct, variables)
245
245
  end
246
246
 
247
- def validate(response, default, klass, *args) # FIXME, use Validator class here
247
+ def validate(response, default, klass, *args)
248
248
  return [default, true] if !default.nil? and response.empty?
249
249
 
250
250
  case [klass]
@@ -6,6 +6,25 @@
6
6
 
7
7
 
8
8
 
9
+ module Kernel
10
+ private
11
+
12
+ # return 1 second
13
+ def second; 1.seconds; end
14
+
15
+ # return 1 minute
16
+ def minute; 1.minutes; end
17
+
18
+ # return 1 hour
19
+ def hour; 1.hours; end
20
+
21
+ # return 1 day
22
+ def day; 1.days; end
23
+
24
+ # return 1 week
25
+ def week; 1.weeks; end
26
+ end
27
+
9
28
  class Numeric
10
29
  # == Synopsis
11
30
  # 45.seconds # => 45
@@ -40,12 +59,6 @@ class Numeric
40
59
  def weeks(*args)
41
60
  args.inject(self*604800) { |s,a| s+a }
42
61
  end
43
-
44
- alias second seconds
45
- alias minute minutes
46
- alias hour hours
47
- alias day days
48
- alias week weeks
49
62
 
50
63
  def ago
51
64
  Time.now-self
@@ -7,10 +7,7 @@
7
7
 
8
8
 
9
9
  require 'ruby/range/stepped'
10
- require 'event/at'
11
- require 'event/every'
12
- require 'event/timed'
13
-
10
+ # more requires at bottom - privatizing Event.new makes that necessary
14
11
 
15
12
 
16
13
  # == Description
@@ -85,7 +82,7 @@ class Event
85
82
  attr_accessor :scheduler
86
83
 
87
84
  class <<self
88
- #private :new # FIXME I don't know what the fu* is going on but setting it public in descendants doesn't work here and I don't see why... :-S
85
+ private :new
89
86
 
90
87
  # Creates a Schedule which is invoked in an interval, every <seconds> seconds.
91
88
  # Postponing an every Schedule will set Schedule#next to Time.now+<seconds>.
@@ -296,3 +293,9 @@ class Event
296
293
  @scheduler.reschedule(self) if @scheduler
297
294
  end
298
295
  end
296
+
297
+
298
+
299
+ require 'event/at'
300
+ require 'event/every'
301
+ require 'event/timed'
@@ -7,6 +7,13 @@
7
7
 
8
8
 
9
9
  require 'rbconfig'
10
+ require 'etc'
11
+ begin
12
+ require 'win32/etc'
13
+ class Etc::Passwd
14
+ alias dir home_dir
15
+ end
16
+ rescue LoadError; end
10
17
 
11
18
 
12
19
 
@@ -21,8 +28,8 @@ require 'rbconfig'
21
28
  # where stuff might go.
22
29
  #
23
30
  # == Synopsis
24
- # x = Iterator.new { |iter| [1,2,3].each { |e| iter.yield(e) } }
25
- # p x.map { |e| e*2 }
31
+ # installer = Installer.new("appname")
32
+ # install_binary_in(installer.cli_binary_suggestions.first)
26
33
  #
27
34
  class Installer
28
35
  def initialize(app_name)
@@ -38,7 +45,7 @@ class Installer
38
45
  end
39
46
 
40
47
  def home(user=nil)
41
- File.expand_path("~#{user}")
48
+ Etc.getpwnam(user || Etc.getlogin).dir
42
49
  end
43
50
 
44
51
  def user_data_suggestions(user=nil)
@@ -11,6 +11,12 @@ require 'ostruct'
11
11
 
12
12
 
13
13
  class OpenStruct
14
+ def self.with(&block)
15
+ struct = new
16
+ struct.instance_eval(&block)
17
+ struct
18
+ end
19
+
14
20
  # Get the field by its name, faster than #send and with
15
21
  # dynamic field names more convenient.
16
22
  def [](field)
@@ -28,4 +34,9 @@ class OpenStruct
28
34
  def to_hash
29
35
  @table.dup
30
36
  end
37
+
38
+ # Get the internal hash-table.
39
+ def __hash__
40
+ @table
41
+ end
31
42
  end
@@ -14,7 +14,6 @@ require 'ruby/kernel/safe_fork'
14
14
  module Kernel
15
15
  # This method causes the current running process to become a daemon
16
16
  # All further printing is relied to the error.log
17
- # FIXME doesn't belong into Butler::Bot, rather into botcontrol
18
17
  def daemonize(chdir=nil, &on_sighup)
19
18
  srand # Split rand streams between spawning and daemonized process
20
19
  safe_fork and exit # Fork and exit from the parent
@@ -35,7 +34,7 @@ module Kernel
35
34
  STDERR.reopen(STDOUT)
36
35
 
37
36
  Dir.chdir(chdir) if chdir
38
- File.umask 0033 # FIXME ask somebody knowledgable about a sensible value
37
+ File.umask 0066
39
38
 
40
39
  sess_id
41
40
  end
@@ -0,0 +1,46 @@
1
+ require 'pp'
2
+ require 'test/unit'
3
+ require 'butler/plugin/mapper'
4
+
5
+ class TestMapper < Test::Unit::TestCase
6
+ class MockMessage < OpenStruct; def to_s; text; end; end
7
+ class MockPlugin < OpenStruct; end
8
+ class MockButler < OpenStruct; end
9
+
10
+ def setup
11
+ plugin = MockPlugin.new
12
+ butler = MockButler.new(
13
+ :users => { "apeiros" => "user:apeiros" },
14
+ :channels => { "#butler" => "channel:#butler" }
15
+ )
16
+ plugin.butler = butler
17
+ def plugin.typemap(name); Butler::Plugin::MappingTypes[name]; end
18
+ @messages_match = [
19
+ {:text => "op", :user => nil, :channel => nil},
20
+ {:text => "op apeiros", :user => nil, :channel => nil},
21
+ {:text => "op in #butler", :user => nil, :channel => nil},
22
+ {:text => "op apeiros in #butler", :user => nil, :channel => nil},
23
+ {:text => "op apeiros butler", :user => nil, :channel => nil},
24
+ {:text => "op apeiros,butler", :user => nil, :channel => nil},
25
+ {:text => "op apeiros, butler", :user => nil, :channel => nil},
26
+ {:text => "op apeiros butler in #butler", :user => nil, :channel => nil},
27
+ {:text => "op apeiros,butler in #butler", :user => nil, :channel => nil},
28
+ {:text => "op apeiros, butler in #butler", :user => nil, :channel => nil},
29
+ {:text => "op \"in\""},
30
+ {:text => "op \"in\" in #butler"},
31
+ ].map { |data| MockMessage.new(data) }
32
+ @mappings = [
33
+ Butler::Plugin::Mapper.new(plugin, nil, nil, "op [*user@Nick] [in :channel@Channel]")
34
+ ]
35
+ end
36
+
37
+ def test_match
38
+ mapper = @mappings.first
39
+ @messages_match.each { |m|
40
+ assert(mapper.invoked_by?(m), "failed mapping '#{m}' against #{mapper}")
41
+ }
42
+ end
43
+
44
+ def test_priority
45
+ end
46
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: butler
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.8.1
7
- date: 2007-10-27 00:00:00 +02:00
6
+ version: 1.8.2
7
+ date: 2007-11-28 00:00:00 +01:00
8
8
  summary: Butler - the IRC bot with class
9
9
  require_paths:
10
10
  - lib
@@ -29,10 +29,10 @@ post_install_message:
29
29
  authors:
30
30
  - Stefan Rusterholz
31
31
  files:
32
- - CHANGELOG
32
+ - CHANGELOG.txt
33
33
  - LICENSE.txt
34
34
  - GPL.txt
35
- - README
35
+ - README.txt
36
36
  - Rakefile
37
37
  - bin/botcontrol
38
38
  - data/butler
@@ -44,16 +44,19 @@ files:
44
44
  - data/butler/dialogs/create.rb
45
45
  - data/butler/dialogs/create_config.rb
46
46
  - data/butler/dialogs/delete.rb
47
+ - data/butler/dialogs/dir.rb
47
48
  - data/butler/dialogs/en
48
49
  - data/butler/dialogs/en/backup.yaml
49
50
  - data/butler/dialogs/en/botcontrol.yaml
50
51
  - data/butler/dialogs/en/create.yaml
51
52
  - data/butler/dialogs/en/create_config.yaml
52
53
  - data/butler/dialogs/en/delete.yaml
54
+ - data/butler/dialogs/en/dir.yaml
53
55
  - data/butler/dialogs/en/help.yaml
54
56
  - data/butler/dialogs/en/info.yaml
55
57
  - data/butler/dialogs/en/list.yaml
56
58
  - data/butler/dialogs/en/notyetimplemented.yaml
59
+ - data/butler/dialogs/en/quickcreate.yaml
57
60
  - data/butler/dialogs/en/rename.yaml
58
61
  - data/butler/dialogs/en/start.yaml
59
62
  - data/butler/dialogs/en/sync_plugins.yaml
@@ -64,20 +67,21 @@ files:
64
67
  - data/butler/dialogs/interactive.rb
65
68
  - data/butler/dialogs/list.rb
66
69
  - data/butler/dialogs/notyetimplemented.rb
70
+ - data/butler/dialogs/quickcreate.rb
67
71
  - data/butler/dialogs/rename.rb
68
72
  - data/butler/dialogs/selectbot.rb
69
73
  - data/butler/dialogs/start.rb
70
74
  - data/butler/dialogs/sync_plugins.rb
71
75
  - data/butler/dialogs/uninstall.rb
72
76
  - data/butler/dialogs/unknown_command.rb
73
- - data/butler/ircd_scripts
74
77
  - data/butler/plugins
75
78
  - data/butler/plugins/core
79
+ - data/butler/plugins/core/access.rb
76
80
  - data/butler/plugins/core/logout.rb
77
81
  - data/butler/plugins/core/plugins.rb
78
- - data/butler/plugins/core/privilege.rb
79
82
  - data/butler/plugins/core/user.rb
80
83
  - data/butler/plugins/dev
84
+ - data/butler/plugins/dev/bleakhouse.rb
81
85
  - data/butler/plugins/dev/eval.rb
82
86
  - data/butler/plugins/dev/nometa.rb
83
87
  - data/butler/plugins/dev/onhandlers.rb
@@ -109,6 +113,7 @@ files:
109
113
  - data/butler/plugins/service/clones.rb
110
114
  - data/butler/plugins/service/define.rb
111
115
  - data/butler/plugins/service/log.rb
116
+ - data/butler/plugins/service/more.rb
112
117
  - data/butler/plugins/service/svn.rb
113
118
  - data/butler/plugins/util
114
119
  - data/butler/plugins/util/cycle.rb
@@ -136,11 +141,16 @@ files:
136
141
  - lib/butler
137
142
  - lib/butler/bot.rb
138
143
  - lib/butler/control.rb
144
+ - lib/butler/debuglog.rb
139
145
  - lib/butler/dialog.rb
140
146
  - lib/butler/initialvalues.rb
141
147
  - lib/butler/irc
142
148
  - lib/butler/irc/channel.rb
143
- - lib/butler/irc/channels.rb
149
+ - lib/butler/irc/channellist.rb
150
+ - lib/butler/irc/client
151
+ - lib/butler/irc/client/filter.rb
152
+ - lib/butler/irc/client/listener.rb
153
+ - lib/butler/irc/client/listenerlist.rb
144
154
  - lib/butler/irc/client.rb
145
155
  - lib/butler/irc/hostmask.rb
146
156
  - lib/butler/irc/message.rb
@@ -153,15 +163,18 @@ files:
153
163
  - lib/butler/irc/string.rb
154
164
  - lib/butler/irc/topic.rb
155
165
  - lib/butler/irc/user.rb
156
- - lib/butler/irc/users.rb
166
+ - lib/butler/irc/userlist.rb
167
+ - lib/butler/irc/whois.rb
157
168
  - lib/butler/plugin
158
169
  - lib/butler/plugin/configproxy.rb
159
170
  - lib/butler/plugin/mapper.rb
160
171
  - lib/butler/plugin/matcher.rb
172
+ - lib/butler/plugin/more.rb
161
173
  - lib/butler/plugin/onhandlers.rb
162
174
  - lib/butler/plugin/trigger.rb
163
175
  - lib/butler/plugin.rb
164
176
  - lib/butler/plugins.rb
177
+ - lib/butler/session.rb
165
178
  - lib/butler/version.rb
166
179
  - lib/butler.rb
167
180
  - lib/cloptions
@@ -169,6 +182,7 @@ files:
169
182
  - lib/cloptions/switch.rb
170
183
  - lib/cloptions.rb
171
184
  - lib/configuration.rb
185
+ - lib/diagnostics.rb
172
186
  - lib/dialogline
173
187
  - lib/dialogline/localizations.rb
174
188
  - lib/dialogline.rb
@@ -229,6 +243,9 @@ files:
229
243
  - lib/string.rb
230
244
  - lib/templater.rb
231
245
  - lib/w3validator.rb
246
+ - test/butler
247
+ - test/butler/plugin
248
+ - test/butler/plugin/mapper.rb
232
249
  - test/cloptions.rb
233
250
  - test/cv.rb
234
251
  - test/irc
@@ -251,7 +268,7 @@ rdoc_options:
251
268
  - --title
252
269
  - Butler library API
253
270
  - --main
254
- - README
271
+ - README.txt
255
272
  - --charset
256
273
  - utf-8
257
274
  - --inline-source
@@ -259,8 +276,8 @@ rdoc_options:
259
276
  - "2"
260
277
  - --line-numbers
261
278
  extra_rdoc_files:
262
- - README
263
- - CHANGELOG
279
+ - README.txt
280
+ - CHANGELOG.txt
264
281
  - GPL.txt
265
282
  - LICENSE.txt
266
283
  executables: