butler 1.8.1 → 1.8.2

Sign up to get free protection for your applications and to get access to all the features.
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: