module Irc
+module Plugins
require 'rbot/messagemapper'
# base class for all rbot plugins
#
# map(template, options)::
# map is the new, cleaner way to respond to specific message formats
- # without littering your plugin code with regexps
- # examples:
+ # without littering your plugin code with regexps. examples:
+ #
# plugin.map 'karmastats', :action => 'karma_stats'
#
# # while in the plugin...
# topic(TopicMessage)::
# Called when a user (or the bot) changes a channel
# topic
+ #
+ # connect():: Called when a server is joined successfully, but
+ # before autojoin channels are joined (no params)
#
# save:: Called when you are required to save your plugin's
# state, if you maintain data between sessions
# default usage method provided as a utility for simple plugins. The
# MessageMapper uses 'usage' as its default fallback method.
- def usage(m, params)
+ def usage(m, params = {})
m.reply "incorrect usage, ask for help using '#{@bot.nick}: help #{m.plugin}'"
end
# load plugins from pre-assigned list of directories
def scan
dirs = Array.new
- dirs << @bot.datadir + "/plugins"
+ dirs << Config::datadir + "/plugins"
dirs += @dirs
dirs.each {|dir|
if(FileTest.directory?(dir))
d = Dir.new(dir)
- d.each {|file|
+ d.sort.each {|file|
next if(file =~ /^\./)
next unless(file =~ /\.rb$/)
- @tmpfilename = "#{dir}/#{file}"
+ tmpfilename = "#{dir}/#{file}"
# create a new, anonymous module to "house" the plugin
+ # the idea here is to prevent namespace pollution. perhaps there
+ # is another way?
plugin_module = Module.new
begin
- plugin_string = IO.readlines(@tmpfilename).join("")
- puts "loading module: #{@tmpfilename}"
+ plugin_string = IO.readlines(tmpfilename).join("")
+ debug "loading plugin #{tmpfilename}"
plugin_module.module_eval(plugin_string)
- rescue StandardError, NameError, LoadError, SyntaxError => err
- puts "plugin #{@tmpfilename} load failed: " + err
+ rescue TimeoutError, StandardError, NameError, LoadError, SyntaxError => err
+ puts "warning: plugin #{tmpfilename} load failed: " + err
puts err.backtrace.join("\n")
end
}
# call the save method for each active plugin
def save
- @@plugins.values.uniq.each {|p|
- next unless(p.respond_to?("save"))
- begin
- p.save
- rescue StandardError, NameError, SyntaxError => err
- puts "plugin #{p.name} save() failed: " + err
- puts err.backtrace.join("\n")
- end
- }
+ delegate 'save'
end
# call the cleanup method for each active plugin
def cleanup
- @@plugins.values.uniq.each {|p|
- next unless(p.respond_to?("cleanup"))
- begin
- p.cleanup
- rescue StandardError, NameError, SyntaxError => err
- puts "plugin #{p.name} cleanup() failed: " + err
- puts err.backtrace.join("\n")
- end
- }
+ delegate 'cleanup'
end
# drop all plugins and rescan plugins on disk
if(@@plugins.has_key?(key))
begin
return @@plugins[key].help(key, params)
- rescue StandardError, NameError, SyntaxError => err
+ rescue TimeoutError, StandardError, NameError, SyntaxError => err
puts "plugin #{@@plugins[key].name} help() failed: " + err
puts err.backtrace.join("\n")
end
# see if each plugin handles +method+, and if so, call it, passing
# +message+ as a parameter
- def delegate(method, message)
+ def delegate(method, *args)
@@plugins.values.uniq.each {|p|
if(p.respond_to? method)
begin
- p.send method, message
- rescue StandardError, NameError, SyntaxError => err
+ p.send method, *args
+ rescue TimeoutError, StandardError, NameError, SyntaxError => err
puts "plugin #{p.name} #{method}() failed: " + err
puts err.backtrace.join("\n")
end
@@bot.auth.allow?(m.plugin, m.source, m.replyto))
begin
@@plugins[m.plugin].privmsg(m)
- rescue StandardError, NameError, SyntaxError => err
+ rescue TimeoutError, StandardError, NameError, SyntaxError => err
puts "plugin #{@@plugins[m.plugin].name} privmsg() failed: " + err
puts err.backtrace.join("\n")
end
end
end
+end