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
@@ -8,7 +8,7 @@
8
8
 
9
9
  require 'ruby/array/columnize'
10
10
 
11
- #trigger "plugins"
11
+
12
12
 
13
13
  def on_load_plugin(param)
14
14
  if plugin_name = @butler.plugins.identify(param.plugin_name) then
@@ -39,55 +39,33 @@ def on_unload_plugin(param)
39
39
  end
40
40
 
41
41
  def on_list_plugins(param)
42
- return answer(usage) unless %w(active inactive all).include?(param.which)
43
- plugins = @butler.plugins.send(param.which).sort.columnize(5)
44
- answer(param.which.to_sym, :plugins => plugins)
45
- end
46
-
47
- # 37
48
- def on_trigger
49
- case @message.arguments[1]
50
- when nil
51
- answer(usage)
52
-
53
- when "groups"
54
- return answer(unknown(2)) if @message.arguments[2]
55
- groups = @butler.plugins.groups.sort.columnize(5)
56
- answer(:groups, :groups => groups)
57
-
58
- when "names"
59
- return answer(unknown(2)) if @message.arguments[2]
60
- names = @butler.plugins.all.sort.columnize(5)
61
- answer(:names, :names => names)
62
-
63
- when "active"
64
-
65
-
66
- else
67
- unknown(1)
42
+ param.which ||= "all"
43
+ plugins = @butler.plugins.send(param.which.downcase).sort.columnize(5)
44
+ if plugins.empty? then
45
+ answer("none_in_#{param.which}".to_sym)
46
+ else
47
+ answer(param.which.to_sym, :plugins => plugins)
68
48
  end
69
49
  end
70
50
 
71
51
  __END__
72
52
  ---
73
- :revision:
74
- :plugin: 2
75
- :summary:
76
- en: Plugin management
77
53
  :about:
78
54
  :mail: "apeiros@gmx.net"
79
55
  :version: "1.0.0"
80
56
  :author: "Stefan Rusterholz"
57
+ :help:
58
+ en:
59
+ "": "Plugins is responsible for loading, unloading and listing available plugins."
81
60
  :map:
82
61
  :on_load_plugin:
83
- en:
84
- load plugin :plugin_name
62
+ en: load plugin :plugin_name
85
63
  :on_unload_plugin:
86
- en:
87
- unload plugin :plugin_name
64
+ en: unload plugin :plugin_name
88
65
  :on_list_plugins:
89
- en:
90
- list :which plugins
66
+ en: list [:which{all,active,inactive}] plugins
67
+ :revision:
68
+ :plugin: 2
91
69
  :strings:
92
70
  :groups:
93
71
  en: |
@@ -109,6 +87,12 @@ __END__
109
87
  en: |
110
88
  All plugins:
111
89
  <%= plugins %>
90
+ :none_in_active:
91
+ en: No active plugins.
92
+ :none_in_inactive:
93
+ en: No inactive plugins.
94
+ :none_in_all:
95
+ en: No plugins.
112
96
  :load:
113
97
  en: Loaded '<%= plugin_name %>'.
114
98
  :unload:
@@ -123,12 +107,10 @@ __END__
123
107
  en: |
124
108
  An exception occured while unloading '<%= plugin_name %>':
125
109
  <%= exception %> in <%= exception.backtrace.first.sub(/.*?(lib|butler)/, '\1') %>
126
-
110
+ :summary:
111
+ en: Plugin management
127
112
  :usage:
128
113
  en: |
129
114
  'load plugin' ![c(blue)]name![o]
130
115
  'unload plugin' ![c(blue)]name![o]
131
116
  'list' [![c(blue)]type![o]] 'plugins'
132
- :help:
133
- en:
134
- "": "Plugins is responsible for loading, unloading and listing available plugins."
@@ -0,0 +1,46 @@
1
+ #--
2
+ # Copyright 2007 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+ def self.logfile
8
+ @logfile
9
+ end
10
+
11
+ def self.on_load
12
+ @logfile = @butler.path.log+'/bleakhouse.log'
13
+ @bl_logger = BleakHouse::Logger.new
14
+ File.delete(@logfile) if File.exist?(@logfile)
15
+ end
16
+
17
+ def self.snapshot(*args)
18
+ @bl_logger.snapshot(@logfile, *args)
19
+ end
20
+
21
+ def on_trigger
22
+ plugin.snapshot('plugin', false)
23
+ answer(:done, :file => plugin.logfile)
24
+ end
25
+
26
+ __END__
27
+ ---
28
+ :about:
29
+ :mail: "apeiros@gmx.net"
30
+ :version: "1.0.0"
31
+ :author: "Stefan Rusterholz"
32
+ :help:
33
+ en:
34
+ "": Inspect butlers memory usage, requires butler to run via ruby-bleak-house.
35
+ :revision:
36
+ :plugin: 1
37
+ :strings:
38
+ :done:
39
+ en: "Snapshot taken. The file is in <%= file %>."
40
+ :summary:
41
+ en: Inspect butlers memory usage.
42
+ :trigger:
43
+ en: bleakhouse
44
+ :usage:
45
+ en: |
46
+ ![b]bleakhouse![o]
@@ -15,7 +15,7 @@ end
15
15
  def dices(dices, sides)
16
16
  dices = 1 if dices.zero?
17
17
  sides = 6 if sides.zero?
18
- (0..dices).inject { |sum,i| sum+rand(sides) }
18
+ (0..dices).inject { |sum,i| sum+rand(sides)+1 }
19
19
  end
20
20
 
21
21
  def chance(from, to)
@@ -6,36 +6,31 @@
6
6
 
7
7
 
8
8
 
9
- trigger "deop"
9
+ def on_deop(params)
10
+ channel = params.channel || message.channel
11
+ nicks = params.user || [message.from.nick]
10
12
 
11
- def on_trigger
12
- channels, nicks = [], message.arguments[1..-1]
13
- channames = @butler.channels.channel_names
14
-
15
- channels << nicks.pop while channames.include?(nicks.last.downcase)
16
- nicks << @message.from.nick if nicks.empty?
17
- channels << @message.channel.to_str if channels.empty?
18
-
19
- channels.each { |channel|
20
- @butler.irc.deop(channel, *nicks)
21
- }
13
+ @butler.irc.deop(channel, *nicks)
22
14
  end
23
15
 
16
+
24
17
  __END__
25
18
  ---
26
- :revision:
27
- :plugin: 1
28
- :summary:
29
- en: Revoke a users op via butler.
30
19
  :about:
31
20
  :mail: "apeiros@gmx.net"
32
21
  :version: "1.0.0"
33
22
  :author: "Stefan Rusterholz"
34
- :strings:
35
- :usage:
36
- en: |
37
- ![b]deop![o] [![c(green)]nick![o] ...] [![c(green)]channel![o] ...]
38
23
  :help:
39
24
  en:
40
25
  "": |
41
26
  Revoke a users op via butler.
27
+ :map:
28
+ :on_deop:
29
+ en: "deop [*user@Nick] [in :channel@Channel]"
30
+ :revision:
31
+ :plugin: 1
32
+ :summary:
33
+ en: Revoke a users op via butler.
34
+ :usage:
35
+ en: |
36
+ ![b]deop![o] [![c(green)]nick![o] ...] [in ![c(green)]channel![o]]
@@ -6,36 +6,30 @@
6
6
 
7
7
 
8
8
 
9
- trigger "devoice"
9
+ def on_voice(params)
10
+ channel = params.channel || message.channel
11
+ nicks = params.user || [message.from.nick]
10
12
 
11
- def on_trigger
12
- channels, nicks = [], message.arguments[1..-1]
13
- channames = @butler.channels.channel_names
14
-
15
- channels << nicks.pop while channames.include?(nicks.last.downcase)
16
- nicks << @message.from.nick if nicks.empty?
17
- channels << @message.channel.to_str if channels.empty?
18
-
19
- channels.each { |channel|
20
- @butler.irc.devoice(channel, *nicks)
21
- }
13
+ @butler.irc.devoice(channel, *nicks)
22
14
  end
23
15
 
24
16
  __END__
25
17
  ---
26
- :revision:
27
- :plugin: 1
28
- :summary:
29
- en: Revoke a users voice via butler.
30
18
  :about:
31
19
  :mail: "apeiros@gmx.net"
32
20
  :version: "1.0.0"
33
21
  :author: "Stefan Rusterholz"
34
- :strings:
35
- :usage:
36
- en: |
37
- ![b]devoice![o] [![c(green)]nick![o] ...] [![c(green)]channel![o] ...]
38
22
  :help:
39
23
  en:
40
24
  "": |
41
25
  Revoke a users voice via butler.
26
+ :map:
27
+ :on_devoice:
28
+ en: "devoice [*user@Nick] [in :channel@Channel]"
29
+ :revision:
30
+ :plugin: 1
31
+ :summary:
32
+ en: Revoke a users voice via butler.
33
+ :usage:
34
+ en: |
35
+ ![b]devoice![o] [![c(green)]nick![o] ...] [![c(green)]channel![o] ...]
@@ -6,42 +6,77 @@
6
6
 
7
7
 
8
8
 
9
- extend OnHandlers
10
-
11
- trigger "limit"
12
-
13
9
  configuration(
14
10
  "channels" => []
15
11
  )
12
+ @channels = {}
13
+
14
+ every minute do
15
+ @config["channels"].each { |channel|
16
+ next unless channel = @butler.channels[channel]
17
+ limit(channel)
18
+ }
19
+ end
20
+
21
+ def self.limit(channel)
22
+ new_limit = channel.users.length+4
23
+ unless new_limit == @channels[channel.to_str] then
24
+ @butler.irc.mode(channel, "+l #{new_limit}")
25
+ @channels[channel.to_str] = new_limit
26
+ end
27
+ end
16
28
 
17
- def on_mode(*args)
29
+ def self.unlimit(channel)
30
+ @butler.irc.mode(channel, "-l")
31
+ @channels.delete(channel.to_str)
18
32
  end
19
33
 
20
- def on_trigger
21
- limit = @message.arguments[1].downcase
22
- limit = limit == "off" ? nil : Integer(limit)
23
- rescue
24
- answer(:invalid_limit, :limit => limit)
34
+ def on_limit(param)
35
+ plugin.config.synchronize {
36
+ plugin.config["channels"] |= param.channels.map { |channel| channel.to_str }
37
+ }
38
+ param.channels.each { |channel|
39
+ next unless channel = @butler.channels[channel]
40
+ plugin.limit(channel)
41
+ }
42
+ answer(:limiting, :channels => param.channels)
43
+ end
44
+
45
+ def on_unlimit(param)
46
+ plugin.config.synchronize {
47
+ plugin.config["channels"] = plugin.config["channels"] - param.channels.map { |channel| channel.to_str }
48
+ }
49
+ param.channels.each { |channel|
50
+ next unless channel = @butler.channels[channel]
51
+ plugin.unlimit(channel)
52
+ }
53
+ answer(:unlimiting, :channels => param.channels)
25
54
  end
26
55
 
27
56
  __END__
28
57
  ---
29
- :revision:
30
- :plugin: 1
31
- :summary:
32
- en: A slowly shifting channel-limit to avoid join-floods.
33
58
  :about:
34
59
  :mail: "apeiros@gmx.net"
35
60
  :version: "1.0.0"
36
61
  :author: "Stefan Rusterholz"
37
- :strings:
38
- :invalid_limit:
39
- en: |
40
- <%= limit %> is not a valid limit, use either 'off' or a positive number.
41
- :usage:
42
- en: |
43
- ![b]limit![o] ('off' | ![c(green)]int![o]) *![c(green)]channel![o] ...
44
62
  :help:
45
63
  en:
46
64
  "": |
47
65
  A slowly shifting channel-limit to avoid join-floods.
66
+ :map:
67
+ :on_limit:
68
+ en: limit *channels@Channel
69
+ :on_unlimit:
70
+ en: unlimit *channels@Channel
71
+ :revision:
72
+ :plugin: 1
73
+ :strings:
74
+ :limiting:
75
+ en: Limiting channels <%= channels.join(', ') %>.
76
+ :unlimiting:
77
+ en: No longer limiting channels <%= channels.join(', ') %>.
78
+ :summary:
79
+ en: A slowly shifting channel-limit to avoid join-floods.
80
+ :usage:
81
+ en: |
82
+ (![b]limit![o]|![b]unlimit![o]) ![c(green)]channel![o] ...
@@ -6,36 +6,31 @@
6
6
 
7
7
 
8
8
 
9
- trigger "op"
9
+ def on_op(params)
10
+ channel = params.channel || message.channel
11
+ nicks = params.user || [message.from.nick]
10
12
 
11
- def on_trigger
12
- channels, nicks = [], message.arguments[1..-1]
13
- channames = @butler.channels.channel_names
14
-
15
- channels << nicks.pop while channames.include?(nicks.last.downcase)
16
- nicks << @message.from.nick if nicks.empty?
17
- channels << @message.channel.to_str if channels.empty?
18
-
19
- channels.each { |channel|
20
- @butler.irc.op(channel, *nicks)
21
- }
13
+ @butler.irc.op(channel, *nicks)
22
14
  end
23
15
 
24
16
  __END__
25
17
  ---
26
- :revision:
27
- :plugin: 1
28
- :summary:
29
- en: Grant a user op via butler.
30
18
  :about:
31
19
  :mail: "apeiros@gmx.net"
32
20
  :version: "1.0.0"
33
21
  :author: "Stefan Rusterholz"
34
- :strings:
35
- :usage:
36
- en: |
37
- ![b]op![o] [![c(green)]nick![o] ...] [![c(green)]channel![o] ...]
38
22
  :help:
39
23
  en:
40
24
  "": |
41
25
  Grant a user op via butler.
26
+ :map:
27
+ :on_op:
28
+ en: "op [*user@Nick] [in :channel@Channel]"
29
+ :revision:
30
+ :plugin: 1
31
+ :strings:
32
+ :summary:
33
+ en: Grant users op via butler.
34
+ :usage:
35
+ en: |
36
+ ![b]op![o] [![c(green)]nick![o] ...] [in ![c(green)]channel![o]]
@@ -6,36 +6,31 @@
6
6
 
7
7
 
8
8
 
9
- trigger "voice"
9
+ def on_voice(params)
10
+ channel = params.channel || message.channel
11
+ nicks = params.user || [message.from.nick]
10
12
 
11
- def on_trigger
12
- channels, nicks = [], message.arguments[1..-1]
13
- channames = @butler.channels.channel_names
14
-
15
- channels << nicks.pop while channames.include?(nicks.last.downcase)
16
- nicks << @message.from.nick if nicks.empty?
17
- channels << @message.channel.to_str if channels.empty?
18
-
19
- channels.each { |channel|
20
- @butler.irc.voice(channel, *nicks)
21
- }
13
+ @butler.irc.voice(channel, *nicks)
22
14
  end
23
15
 
24
16
  __END__
25
17
  ---
26
- :revision:
27
- :plugin: 1
28
- :summary:
29
- en: Grant a user voice via butler.
30
18
  :about:
31
19
  :mail: "apeiros@gmx.net"
32
20
  :version: "1.0.0"
33
21
  :author: "Stefan Rusterholz"
34
- :strings:
35
- :usage:
36
- en: |
37
- ![b]voice![o] [![c(green)]nick![o] ...] [![c(green)]channel![o] ...]
38
22
  :help:
39
23
  en:
40
24
  "": |
41
25
  Grant a user voice via butler.
26
+ :map:
27
+ :on_voice:
28
+ en:
29
+ "voice [*user@Nick] [in :channel@Channel]"
30
+ :revision:
31
+ :plugin: 1
32
+ :summary:
33
+ en: Grant a user voice via butler.
34
+ :usage:
35
+ en: |
36
+ ![b]voice![o] [![c(green)]nick![o] ...] [in ![c(green)]channel![o]]