Preliminary RSS plug-in
[six.git] / lib / plugin.rb
blob86bb9c0aee25c93343a88870af6b077c5e83d497
2 # Plugin manager plugin.
5 class Plugin < PluginBase
7   def initialize
8     @brief_help = 'Manages plugins.'
9     super
10     $config.merge(
11       'plugins' => {
12         :dir => true,
13         'path' => {
14           :type => Array
15         },
16         'autoload' => {
17           :type => Array
18         }
19       }
20     )
21   end
23   # Special initializer method for core plugins. We feel special :-).
24   def on_startup
25     $log.puts 'Autoloading plugins...'
26     autoload = $config['plugins/autoload', []]
27     autoload.each do |plugin|
28       if $plugins[pn = plugin.downcase]
29         $log.puts "Plugin '#{pn.capitalize}' was already loaded; skipping."
30       else
31         begin
32           if !load_plugin(pn)
33             irc.reply "Error loading plugin '#{pn.capitalize}': File not found in plugin path."
34           elsif (klass = self.class.const_get(pn.capitalize))
35             ins = klass.instance
36             $plugins[ins.name] = ins
37           else
38             $log.puts "Error loading plugin '#{pn.capitalize}': Couldn't locate plugin class."
39           end
40         rescue Exception => e
41           $log.puts "Error loading plugin '#{pn.capitalize}':"
42           $log.puts e.message
43           $log.puts e.backtrace.join("\n")
44         end
45       end
46     end
47   end
49   # Tries to load a plugin. Returns true if successful, false or exception otherwise.
50   def load_plugin(name)
51     path = ['lib', 'plugins'] + $config['plugins/path', []]
52     path.each do |dir|
53       begin
54         Plugins.module_eval { load("#{dir}/#{name}.rb") }
55         $log.puts "Loaded plugin '#{name.capitalize}' [#{dir}/#{name}.rb]"
56         return true
57       rescue LoadError
58         # Just try the next directory...
59       end
60     end
61     false
62   end
64   # Reloads a plugin. Note that support is currently SHAKY!
65   def cmd_reload(irc, plugin)
67     # Caps and usage.
68     if !$user.caps(irc, 'admin', 'owner').any?
69       irc.reply "You're not a bot administrator, so don't even start!"
70       return
71     end
72     if !plugin or plugin.empty?
73       irc.reply "USAGE: reload [-f] <plugin name>, where <plugin name> is as it appears in the list given by 'plugin list'. The -f option can be used to force a reload if the plugin doesn't want to."
74       return
75     end
77     # Check arguments.
78     op, pl = plugin.split(' ', 2)
79     if op and op == '-f'
80       forcing = true
81       plugin = pl
82     else
83       forcing = false
84     end
86     # Look for plugin.
87     if !(p = $plugins[pn = plugin.downcase])
88       irc.reply "Plugin '#{plugin}' not found. Try '?' for a list of currently loaded plugins."
89       return
90     end
92     # Before reload business.
93     if (r = p.before_reload(forcing)) and r.kind_of?(String)
94       if forcing
95         irc.reply "WARNING: Forcing reload of plugin, even though it refuses with reason: #{r}"
96       else
97         irc.reply "Plugin refuses to reload with reason: #{r}"
98         return
99       end
100     end
101     p.unregister
103     # Reload!
104     begin
105       unless load_plugin(pn)
106         irc.reply "Error reloading plugin: File not found in plugin path."
107         return
108       end
109     rescue Exception => e
110       $log.puts "Error loading plugin '#{pn.capitalize}':"
111       $log.puts e.message
112       $log.puts e.backtrace.join("\n")
113       msg = p.reload_failed(e) || e.message
114       irc.reply "Error reloading plugin: #{msg}"
115       return
116     end
118     # After reload business.
119     if p.after_reload(forcing)
120       $plugins[pn] = p.class.instance
121     else
122       p.register_commands
123     end
124     irc.reply 'Plugin reloaded successfully!'
126   end
127   help :reload, "Reloads the given plugin. Note that support for this is currently somewhat prelimenary. Use at your own risk. If a plugin refuses to reload, you can pass option -f to make it do so anyway."
129   # Unloads a plugin.
130   def cmd_unload(irc, plugin)
131     if !$user.caps(irc, 'admin', 'owner').any?
132       irc.reply "You're not a bot administrator, so don't even start!"
133     elsif !plugin or plugin.empty?
134       irc.reply "USAGE: unload <plugin name>. Use 'plugin list' to get a list."
135     elsif !(p = $plugins[pn = plugin.downcase])
136       irc.reply "Plugin not found. Make sure it's in the list given by 'plugin list'."
137     else
138       p.unregister
139       $plugins.delete(pn)
140       irc.reply 'Plugin unloaded successfully!'
141     end
142   end
143         help :unload, "Unloads a loaded plugin."
145   # Loads a new plugin.
146   def cmd_load(irc, plugin)
147     if !$user.caps(irc, 'admin', 'owner').any?
148       irc.reply "You're not a bot administrator, so don't even start!"
149     elsif !plugin or plugin.empty?
150       irc.reply "USAGE: load <plugin name>. This command will not reload an already loaded plugin. Use 'reload' for that."
151     elsif $plugins[pn = plugin.downcase]
152       irc.reply "That plugin is already loaded!  (To reload it, use the 'reload' command)."
153     else
154       begin
155         if !load_plugin(pn)
156           irc.reply "Error loading plugin: File not found in plugin path."
157         elsif (klass = self.class.const_get(pn.capitalize))
158           ins = klass.instance
159           $plugins[ins.name] = ins
160           irc.reply 'Plugin loaded successfully!'
161         else
162           $log.puts "Error loading plugin '#{pn.capitalize}':"
163           $log.puts "Couldn't locate plugin class."
164           irc.reply "Error loading plugin: Couldn't locate the plugin class."
165         end
166       rescue Exception => e
167         $log.puts "Error loading plugin '#{pn.capitalize}':"
168         $log.puts e.message
169         $log.puts e.backtrace.join("\n")
170         irc.reply "Error loading plugin: #{e.message}"
171       end
172     end
173   end
174         help :load, "Loads a plugin in the plugin path."
176   def cmd_list(irc, line)
177     irc.reply "The following plugins are loaded: \x02#{$plugins.keys.sort.join(', ')}.\x0f"
178   end
179         help :list, "Lists all loaded plugins."