zmb 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.markdown +39 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/bin/zmb +188 -0
- data/lib/zmb.rb +296 -0
- data/lib/zmb/commands.rb +63 -0
- data/lib/zmb/event.rb +15 -0
- data/lib/zmb/plugin.rb +110 -0
- data/lib/zmb/settings.rb +48 -0
- data/lib/zmb/timer.rb +28 -0
- data/plugins/bank.rb +101 -0
- data/plugins/commands.rb +119 -0
- data/plugins/irc.rb +230 -0
- data/plugins/quote.rb +100 -0
- data/plugins/relay.rb +70 -0
- data/plugins/users.rb +280 -0
- data/test/helper.rb +10 -0
- data/test/test_zmb.rb +7 -0
- data/zmb.gemspec +71 -0
- metadata +97 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 kylef
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
## zmb messenger bot
|
2
|
+
|
3
|
+
zmb is a complete messenger bot supporting irc, and command line interface.
|
4
|
+
|
5
|
+
### Install
|
6
|
+
gem install zmb
|
7
|
+
|
8
|
+
### Uninstall
|
9
|
+
gem uninstall zmb
|
10
|
+
rm -rf ~/.zmb # If you used the default settings location
|
11
|
+
|
12
|
+
### Creating a bot
|
13
|
+
|
14
|
+
This command will use the default settings location of ~/.zmb, you can pass `-s <PATH>` to change this.
|
15
|
+
|
16
|
+
zmb --create
|
17
|
+
|
18
|
+
### Launching the bot
|
19
|
+
zmb --daemon
|
20
|
+
|
21
|
+
### Using the bot in command shell mode
|
22
|
+
|
23
|
+
You can run zmb in a shell mode to test plugins without even connecting to any irc servers. It will create a shell where you can enter commands.
|
24
|
+
|
25
|
+
zmb --shell
|
26
|
+
|
27
|
+
### Included plugins
|
28
|
+
|
29
|
+
- IRC
|
30
|
+
- Quote
|
31
|
+
- Relay - Relay between servers and/or channels
|
32
|
+
- Users - User management
|
33
|
+
- Bank - Points system
|
34
|
+
|
35
|
+
### Support
|
36
|
+
|
37
|
+
You can find support at #zmb @ efnet.
|
38
|
+
|
39
|
+
For complete documentation please visit [Documentation](http://kylefuller.co.uk/projects/zmb/)
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "zmb"
|
8
|
+
gem.summary = %Q{ZMB, messenger bot}
|
9
|
+
gem.description = %Q{ZMB, messenger bot}
|
10
|
+
gem.email = "inbox@kylefuller.co.uk"
|
11
|
+
gem.homepage = "http://github.com/kylef/zmb"
|
12
|
+
gem.authors = ["kylef"]
|
13
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
14
|
+
gem.add_dependency "json", ">= 1.0.0"
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
24
|
+
test.libs << 'lib' << 'test'
|
25
|
+
test.pattern = 'test/**/test_*.rb'
|
26
|
+
test.verbose = true
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'rcov/rcovtask'
|
31
|
+
Rcov::RcovTask.new do |test|
|
32
|
+
test.libs << 'test'
|
33
|
+
test.pattern = 'test/**/test_*.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
rescue LoadError
|
37
|
+
task :rcov do
|
38
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
task :test => :check_dependencies
|
43
|
+
|
44
|
+
task :default => :test
|
45
|
+
|
46
|
+
require 'rake/rdoctask'
|
47
|
+
Rake::RDocTask.new do |rdoc|
|
48
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
|
+
|
50
|
+
rdoc.rdoc_dir = 'rdoc'
|
51
|
+
rdoc.title = "zmb #{version}"
|
52
|
+
rdoc.rdoc_files.include('README*')
|
53
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
data/bin/zmb
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
$:.unshift File.dirname(__FILE__) + "/../lib"
|
4
|
+
|
5
|
+
require 'zmb'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
class AdminUser
|
9
|
+
attr_accessor :username, :userhosts
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@username = 'admin'
|
13
|
+
@userhosts = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def admin?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def permission?(perm)
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def authenticated?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Event
|
30
|
+
attr_accessor :message
|
31
|
+
|
32
|
+
def initialize(message)
|
33
|
+
@message = message
|
34
|
+
end
|
35
|
+
|
36
|
+
def message?
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def private?
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
def user
|
45
|
+
AdminUser.new
|
46
|
+
end
|
47
|
+
|
48
|
+
def reply(msg)
|
49
|
+
puts "> #{msg}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def ask(question)
|
54
|
+
puts "#{question} (yes/no)"
|
55
|
+
answer = gets.chomp
|
56
|
+
answer == 'yes' or answer == 'y'
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_value(question)
|
60
|
+
puts question
|
61
|
+
answer = gets.chomp
|
62
|
+
|
63
|
+
return nil if answer == ''
|
64
|
+
answer
|
65
|
+
end
|
66
|
+
|
67
|
+
def wizard(zmb, plugin)
|
68
|
+
STDOUT.flush
|
69
|
+
|
70
|
+
if ask("Would you like to add the #{plugin.name} plugin? #{plugin.description}") then
|
71
|
+
if plugin.multi_instances? then
|
72
|
+
instance = get_value("What would you like to name this instance of #{plugin.name}?")
|
73
|
+
else
|
74
|
+
instance = plugin.name
|
75
|
+
end
|
76
|
+
|
77
|
+
if not instance then
|
78
|
+
puts "Must supply instance name, if this plugin should only be loaded once such as commands or users then you can call it that."
|
79
|
+
return wizard zmb, plugin
|
80
|
+
end
|
81
|
+
|
82
|
+
zmb.setup(plugin.name, instance)
|
83
|
+
obj = zmb.plugin_manager.plugin plugin.name
|
84
|
+
if obj.respond_to?('wizard') then
|
85
|
+
settings = zmb.settings.setting(instance)
|
86
|
+
settings['plugin'] = plugin.name
|
87
|
+
|
88
|
+
obj.wizard.each do |key, value|
|
89
|
+
if value.has_key?('help') then
|
90
|
+
set = get_value("#{value['help']} (default=#{value['default']})")
|
91
|
+
settings[key] = set if set
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
zmb.settings.save(instance, settings)
|
96
|
+
end
|
97
|
+
zmb.load instance
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
options = {}
|
102
|
+
|
103
|
+
optparse = OptionParser.new do |opts|
|
104
|
+
opts.banner = "Usage: zmb [options]"
|
105
|
+
|
106
|
+
options[:settings] = nil
|
107
|
+
opts.on('-s', '--settings SETTING', 'Use a settings folder') do |settings|
|
108
|
+
options[:settings] = settings
|
109
|
+
end
|
110
|
+
|
111
|
+
options[:daemon] = false
|
112
|
+
opts.on('-d', '--daemon', 'Run ZMB') do
|
113
|
+
options[:daemon] = true
|
114
|
+
end
|
115
|
+
|
116
|
+
options[:create] = false
|
117
|
+
opts.on('-c', '--create', 'Create a new ZMB settings file') do
|
118
|
+
options[:create] = true
|
119
|
+
end
|
120
|
+
|
121
|
+
options[:shell] = false
|
122
|
+
opts.on('-b', '--shell', 'Create a commands shell') do
|
123
|
+
options[:shell] = true
|
124
|
+
end
|
125
|
+
|
126
|
+
options[:command] = false
|
127
|
+
opts.on('-l', '--line LINE', 'Execute a command') do |line|
|
128
|
+
options[:command] = line
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
optparse.parse!
|
133
|
+
|
134
|
+
if not options[:settings] then
|
135
|
+
options[:settings] = File.expand_path('~/.zmb')
|
136
|
+
puts "No settings file specified, will use #{options[:settings]}"
|
137
|
+
end
|
138
|
+
|
139
|
+
zmb = Zmb.new(options[:settings])
|
140
|
+
|
141
|
+
if options[:create] then
|
142
|
+
STDOUT.flush
|
143
|
+
|
144
|
+
zmb.save
|
145
|
+
|
146
|
+
while ask('Would you like to add additional plugin sources?')
|
147
|
+
source = get_value('Which path?')
|
148
|
+
if source and File.exists?(source) then
|
149
|
+
zmb.plugin_manager.add_plugin_source source
|
150
|
+
puts 'Source added'
|
151
|
+
zmb.save
|
152
|
+
else
|
153
|
+
puts 'Invalid source'
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
zmb.plugin_manager.plugins.reject{ |plugin| zmb.instances.has_key? plugin.name }.each{ |plugin| wizard(zmb, plugin) }
|
158
|
+
|
159
|
+
if zmb.instances.has_key?('users') and ask('Would you like to add a admin user?') then
|
160
|
+
username = get_value('Username:')
|
161
|
+
password = get_value('Password:')
|
162
|
+
userhost = get_value('Userhost: (Leave blank for none)')
|
163
|
+
zmb.instances['users'].create_user(username, password, userhost).permit('admin')
|
164
|
+
end
|
165
|
+
|
166
|
+
zmb.save
|
167
|
+
end
|
168
|
+
|
169
|
+
if options[:command] then
|
170
|
+
zmb.event(nil, Event.new(options[:command]))
|
171
|
+
zmb.save
|
172
|
+
end
|
173
|
+
|
174
|
+
if options[:shell] then
|
175
|
+
STDOUT.flush
|
176
|
+
|
177
|
+
begin
|
178
|
+
while 1
|
179
|
+
zmb.event(nil, Event.new(gets.chomp))
|
180
|
+
end
|
181
|
+
rescue Interrupt
|
182
|
+
zmb.save
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
if options[:daemon] then
|
187
|
+
zmb.run
|
188
|
+
end
|
data/lib/zmb.rb
ADDED
@@ -0,0 +1,296 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'json'
|
5
|
+
rescue LoadError
|
6
|
+
require 'rubygems'
|
7
|
+
gem 'json'
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'zmb/plugin'
|
11
|
+
require 'zmb/settings'
|
12
|
+
require 'zmb/event'
|
13
|
+
require 'zmb/commands'
|
14
|
+
require 'zmb/timer'
|
15
|
+
|
16
|
+
class Zmb
|
17
|
+
attr_accessor :instances, :plugin_manager, :settings
|
18
|
+
|
19
|
+
def initialize(config_dir)
|
20
|
+
@plugin_manager = PluginManager.new
|
21
|
+
@settings = Settings.new(config_dir)
|
22
|
+
|
23
|
+
@instances = {'core/zmb' => self}
|
24
|
+
@sockets = Hash.new
|
25
|
+
|
26
|
+
@minimum_timeout = 0.5 # Half a second
|
27
|
+
@maximum_timeout = 60.0 # Sixty seconds
|
28
|
+
@timers = Array.new
|
29
|
+
timer_add(Timer.new(self, :save, 120.0, true)) # Save every 2 minutes
|
30
|
+
|
31
|
+
@settings.get('core/zmb', 'plugin_sources', []).each{|source| @plugin_manager.add_plugin_source source}
|
32
|
+
|
33
|
+
if @plugin_manager.plugin_sources.empty? then
|
34
|
+
@plugin_manager.add_plugin_source File.join(File.expand_path(File.dirname(File.dirname(__FILE__))), 'plugins')
|
35
|
+
end
|
36
|
+
|
37
|
+
@settings.get('core/zmb', 'plugin_instances', []).each{|instance| load instance}
|
38
|
+
|
39
|
+
@running = false
|
40
|
+
end
|
41
|
+
|
42
|
+
def running?
|
43
|
+
@running
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_json(*a)
|
47
|
+
{
|
48
|
+
'plugin_sources' => @plugin_manager.plugin_sources,
|
49
|
+
'plugin_instances' => @instances.keys,
|
50
|
+
}.to_json(*a)
|
51
|
+
end
|
52
|
+
|
53
|
+
def save
|
54
|
+
@instances.each{ |k,v| @settings.save(k, v) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def load(key)
|
58
|
+
return true if @instances.has_key?(key)
|
59
|
+
|
60
|
+
if p = @settings.get(key, 'plugin') then
|
61
|
+
object = @plugin_manager.plugin(p)
|
62
|
+
return false if not object
|
63
|
+
@instances[key] = object.new(self, @settings.setting(key))
|
64
|
+
post! :plugin_loaded, key, @instances[key]
|
65
|
+
true
|
66
|
+
else
|
67
|
+
false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def unload(key, tell=true)
|
72
|
+
return false if not @instances.has_key?(key)
|
73
|
+
instance = @instances.delete(key)
|
74
|
+
@settings.save key, instance
|
75
|
+
socket_delete instance
|
76
|
+
timer_delete instance
|
77
|
+
instance.unloaded if instance.respond_to?('unloaded') and tell
|
78
|
+
post! :plugin_unloaded, key, instance
|
79
|
+
end
|
80
|
+
|
81
|
+
def run
|
82
|
+
post! :running, self
|
83
|
+
|
84
|
+
@running = true
|
85
|
+
begin
|
86
|
+
while @running
|
87
|
+
socket_run(timeout)
|
88
|
+
timer_run
|
89
|
+
end
|
90
|
+
rescue Interrupt
|
91
|
+
save
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def timeout
|
96
|
+
if timer_timeout > @maximum_timeout
|
97
|
+
if @sockets.count < 1 then
|
98
|
+
5
|
99
|
+
else
|
100
|
+
@maximum_timeout
|
101
|
+
end
|
102
|
+
elsif timer_timeout > @minimum_timeout
|
103
|
+
timer_timeout
|
104
|
+
else
|
105
|
+
@minimum_timeout
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def socket_add(delegate, socket)
|
110
|
+
@sockets[socket] = delegate
|
111
|
+
end
|
112
|
+
|
113
|
+
def socket_delete(item)
|
114
|
+
if @sockets.has_value?(item) then
|
115
|
+
@sockets.select{ |sock, delegate| delegate == item }.each{ |sock, delegate| @sockets.delete(sock) }
|
116
|
+
end
|
117
|
+
|
118
|
+
if @sockets.has_key?(item) then
|
119
|
+
@sockets.delete(item)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def socket_run(timeout)
|
124
|
+
result = select(@sockets.keys, nil, nil, timeout)
|
125
|
+
|
126
|
+
if result != nil then
|
127
|
+
result[0].select{|sock| @sockets.has_key?(sock)}.each do |sock|
|
128
|
+
if sock.eof? then
|
129
|
+
@sockets[sock].disconnected(self, sock) if @sockets[sock].respond_to?('disconnected')
|
130
|
+
socket_delete sock
|
131
|
+
else
|
132
|
+
@sockets[sock].received(self, sock, sock.gets()) if @sockets[sock].respond_to?('received')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def timer_add(timer)
|
139
|
+
@timers << timer
|
140
|
+
end
|
141
|
+
|
142
|
+
def timer_delete(search)
|
143
|
+
@timers.each{ |timer| @timers.delete(timer) if timer.delegate == search }
|
144
|
+
@timers.delete(search)
|
145
|
+
end
|
146
|
+
|
147
|
+
def timer_timeout # When will the next timer run?
|
148
|
+
@timers.map{|timer| timer.timeout}.sort.fetch(0, @maximum_timeout)
|
149
|
+
end
|
150
|
+
|
151
|
+
def timer_run
|
152
|
+
@timers.select{|timer| timer.timeout <= 0.0 and timer.respond_to?("fire") }.each{|timer| timer.fire(self)}
|
153
|
+
end
|
154
|
+
|
155
|
+
def post(signal, *args)
|
156
|
+
results = Array.new
|
157
|
+
|
158
|
+
@instances.select{|name, instance| instance.respond_to?(signal)}.each do |name, instance|
|
159
|
+
results << instance.send(signal, *args) rescue nil
|
160
|
+
end
|
161
|
+
|
162
|
+
results
|
163
|
+
end
|
164
|
+
|
165
|
+
def post!(signal, *args) # This will exclude the plugin manager
|
166
|
+
@instances.select{|name, instance| instance.respond_to?(signal) and instance != self}.each do |name, instance|
|
167
|
+
instance.send(signal, *args) rescue nil
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def setup(plugin, instance)
|
172
|
+
object = @plugin_manager.plugin plugin
|
173
|
+
return false if not object
|
174
|
+
|
175
|
+
settings = Hash.new
|
176
|
+
settings['plugin'] = plugin
|
177
|
+
|
178
|
+
if object.respond_to? 'wizard' then
|
179
|
+
d = object.wizard
|
180
|
+
d.each{ |k,v| settings[k] = v['default'] if v.has_key?('default') and v['default'] }
|
181
|
+
end
|
182
|
+
|
183
|
+
@settings.save instance, settings
|
184
|
+
|
185
|
+
true
|
186
|
+
end
|
187
|
+
|
188
|
+
def event(sender, e)
|
189
|
+
post! :pre_event, sender, e
|
190
|
+
post! :event, sender, e
|
191
|
+
end
|
192
|
+
|
193
|
+
def commands
|
194
|
+
{
|
195
|
+
'reload' => PermCommand.new('admin', self, :reload_command),
|
196
|
+
'unload' => PermCommand.new('admin', self, :unload_command),
|
197
|
+
'load' => PermCommand.new('admin', self, :load_command),
|
198
|
+
'save' => PermCommand.new('admin', self, :save_command, 0),
|
199
|
+
'loaded' => PermCommand.new('admin', self, :loaded_command, 0),
|
200
|
+
'setup' => PermCommand.new('admin', self, :setup_command, 2),
|
201
|
+
'set' => PermCommand.new('admin', self, :set_command, 3),
|
202
|
+
'get' => PermCommand.new('admin', self, :get_command, 2),
|
203
|
+
'clone' => PermCommand.new('admin', self, :clone_command, 2),
|
204
|
+
'reset' => PermCommand.new('admin', self, :reset_command),
|
205
|
+
'addsource' => PermCommand.new('admin', self, :addsource_command),
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
def reload_command(e, instance)
|
210
|
+
if @instances.has_key?(instance) then
|
211
|
+
sockets = Array.new
|
212
|
+
@sockets.each{ |sock,delegate| sockets << sock if delegate == @instances[instance] }
|
213
|
+
unload(instance, false)
|
214
|
+
reloaded = @plugin_manager.reload_plugin(@settings.get(instance, 'plugin'))
|
215
|
+
load(instance)
|
216
|
+
|
217
|
+
sockets.each{ |socket| @sockets[socket] = @instances[instance] }
|
218
|
+
@instances[instance].socket = sockets[0] if sockets.size == 1 and @instances[instance].respond_to?('socket=')
|
219
|
+
|
220
|
+
reloaded ? "#{instance} reloaded" : "#{instance} refreshed"
|
221
|
+
else
|
222
|
+
"No such instance #{instance}"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def unload_command(e, instance)
|
227
|
+
if @instances.has_key?(instance) then
|
228
|
+
unload(instance)
|
229
|
+
"#{instance} unloaded"
|
230
|
+
else
|
231
|
+
"No such instance #{instance}"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def load_command(e, instance)
|
236
|
+
if not @instances.has_key?(instance) then
|
237
|
+
load(instance) ? "#{instance} loaded" : "#{instance} did not load correctly"
|
238
|
+
else
|
239
|
+
"Instance already #{instance}"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def save_command(e)
|
244
|
+
save
|
245
|
+
'settings saved'
|
246
|
+
end
|
247
|
+
|
248
|
+
def loaded_command(e)
|
249
|
+
@instances.keys.join(', ')
|
250
|
+
end
|
251
|
+
|
252
|
+
def setup_command(e, plugin, instance)
|
253
|
+
if setup(plugin, instance) then
|
254
|
+
object = @plugin_manager.plugin plugin
|
255
|
+
result = ["Instance saved, please use the set command to override the default configuration for this instance."]
|
256
|
+
result += d.map{ |k,v| "#{k} - #{v['help']} (default=#{v['default']})" } if object.respond_to? 'wizard'
|
257
|
+
result.join("\n")
|
258
|
+
else
|
259
|
+
"plugin not found"
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def set_command(e, instance, key, value)
|
264
|
+
settings = @settings.setting(instance)
|
265
|
+
settings[key] = value
|
266
|
+
@settings.save(instance, settings)
|
267
|
+
"#{key} set to #{value} for #{instance}"
|
268
|
+
end
|
269
|
+
|
270
|
+
def get_command(e, instance, key)
|
271
|
+
if value = @settings.get(instance, key) then
|
272
|
+
"#{key} is #{value} for #{instance}"
|
273
|
+
else
|
274
|
+
"#{instance} or #{instance}/#{key} not found."
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def clone_command(e, instance, new_instance)
|
279
|
+
if (settings = @settings.setting(instance)) != {} then
|
280
|
+
@settings.save(new_instance, settings)
|
281
|
+
"The settings for #{instance} were copied to #{new_instance}"
|
282
|
+
else
|
283
|
+
"No settings for #{instance}"
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def reset_command(e, instance)
|
288
|
+
@settings.save(instance, {})
|
289
|
+
"Settings for #{instance} have been deleted."
|
290
|
+
end
|
291
|
+
|
292
|
+
def addsource_command(e, source)
|
293
|
+
@plugin_manager.add_plugin_source source
|
294
|
+
"#{source} added to plugin manager"
|
295
|
+
end
|
296
|
+
end
|