Now allow multiple plugin directories, RFE #802614.

This commit is contained in:
Jeremy Fincher 2003-09-10 06:05:58 +00:00
parent 73986cb03c
commit e0fae30f46
7 changed files with 34 additions and 30 deletions

View File

@ -45,14 +45,12 @@ from fix import *
import conf import conf
import callbacks import callbacks
if conf.pluginDir not in sys.path:
sys.path.insert(0, conf.pluginDir)
def makePluginDocumentation(filename): def makePluginDocumentation(filename):
trClasses = { 'lightyellow':'lightgreen', 'lightgreen':'lightyellow' } trClasses = { 'lightyellow':'lightgreen', 'lightgreen':'lightyellow' }
trClass = 'lightyellow' trClass = 'lightyellow'
pluginName = filename.split('.')[0] pluginName = filename.split('.')[0]
moduleInfo = imp.find_module(pluginName) moduleInfo = imp.find_module(pluginName, conf.pluginDirs)
module = imp.load_module(pluginName, *moduleInfo) module = imp.load_module(pluginName, *moduleInfo)
directory = os.path.join('docs', 'plugins') directory = os.path.join('docs', 'plugins')
if not os.path.exists(directory): if not os.path.exists(directory):
@ -62,17 +60,18 @@ def makePluginDocumentation(filename):
isinstance(plugin, callbacks.PrivmsgRegexp): isinstance(plugin, callbacks.PrivmsgRegexp):
fd = file(os.path.join(directory,'%s.html' % pluginName), 'w') fd = file(os.path.join(directory,'%s.html' % pluginName), 'w')
fd.write(textwrap.dedent(""" fd.write(textwrap.dedent("""
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en-us"> <html lang="en-us">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Documentation for the %s plugin for Supybot</title> <title>Documentation for the %s plugin for Supybot</title>
<link rel="stylesheet" type="text/css" href="supybot.css"> <link rel="stylesheet" type="text/css" href="supybot.css">
<body><div> <body><div>
%s<br><br><table> <h1>%s</h1><br><br><table>
<tr id="headers"><td>Command</td><td>Args</td><td> <tr id="headers"><td>Command</td><td>Args</td><td>
Detailed Help</td></tr> Detailed Help</td></tr>
""") % (pluginName, cgi.escape(module.__doc__))) """) % (pluginName, cgi.escape(module.__doc__ or "")))
for attr in dir(plugin): for attr in dir(plugin):
trClass = trClasses[trClass] trClass = trClasses[trClass]
if plugin.isCommand(attr): if plugin.isCommand(attr):
@ -97,7 +96,7 @@ def makePluginDocumentation(filename):
s = s.replace('\\n', '\n') s = s.replace('\\n', '\n')
s = s.replace("\\'", "'") s = s.replace("\\'", "'")
fd.write(textwrap.dedent(""" fd.write(textwrap.dedent("""
<p>Here's an example session with this plugin:</p> <h2><p>Here's an example session with this plugin:</p></h2>
<pre> <pre>
%s %s
</pre> </pre>
@ -110,9 +109,10 @@ def makePluginDocumentation(filename):
fd.close() fd.close()
if __name__ == '__main__': if __name__ == '__main__':
for filename in os.listdir(conf.pluginDir): for directory in conf.pluginDirs:
if filename.endswith('.py') and filename.lower() != filename: for filename in os.listdir(directory):
makePluginDocumentation(filename) if filename.endswith('.py') and filename.lower() != filename:
makePluginDocumentation(filename)

View File

@ -53,9 +53,6 @@ import conf
import ircdb import ircdb
import ircutils import ircutils
if conf.pluginDir not in sys.path:
sys.path.insert(0, conf.pluginDir)
if __name__ == '__main__': if __name__ == '__main__':
fd = file('src/template.py') fd = file('src/template.py')
template = fd.read() template = fd.read()
@ -128,7 +125,9 @@ if __name__ == '__main__':
### ###
# Modules. # Modules.
### ###
filenames = os.listdir(conf.pluginDir) filenames = []
for dir in conf.pluginDirs:
filenames.extend(os.listdir(dir))
plugins = [] plugins = []
for filename in filenames: for filename in filenames:
if filename.endswith('.py') and \ if filename.endswith('.py') and \
@ -139,7 +138,7 @@ if __name__ == '__main__':
print 'The available plugins are:\n %s' % '\n '.join(plugins) print 'The available plugins are:\n %s' % '\n '.join(plugins)
while yn('Would you like to add a plugin?') == 'y': while yn('Would you like to add a plugin?') == 'y':
plugin = expect('What plugin?', plugins) plugin = expect('What plugin?', plugins)
moduleInfo = imp.find_module(plugin) moduleInfo = imp.find_module(plugin, conf.pluginDirs)
try: try:
module = imp.load_module(plugin, *moduleInfo) module = imp.load_module(plugin, *moduleInfo)
except ImportError, e: except ImportError, e:

View File

@ -205,7 +205,7 @@ class OwnerCommands(privmsgs.CapabilityCheckingPrivmsg):
irc.error(msg, 'That module is already loaded.') irc.error(msg, 'That module is already loaded.')
return return
try: try:
moduleInfo = imp.find_module(name) moduleInfo = imp.find_module(name, conf.pluginDirs)
except ImportError: except ImportError:
irc.error(msg, 'No plugin %s exists.' % name) irc.error(msg, 'No plugin %s exists.' % name)
return return
@ -240,7 +240,7 @@ class OwnerCommands(privmsgs.CapabilityCheckingPrivmsg):
if callbacks: if callbacks:
try: try:
moduleInfo = imp.find_module(name) moduleInfo = imp.find_module(name, conf.pluginDirs)
module = imp.load_module(name, *moduleInfo) module = imp.load_module(name, *moduleInfo)
linecache.checkcache() linecache.checkcache()
for callback in callbacks: for callback in callbacks:

View File

@ -46,7 +46,7 @@ import os.path
logDir = 'logs' logDir = 'logs'
confDir = 'conf' confDir = 'conf'
dataDir = 'data' dataDir = 'data'
pluginDir = 'plugins' pluginDirs = ['src', 'plugins']
### ###
# Files. # Files.
@ -197,7 +197,7 @@ driverModule = 'socketDrivers'
############################### ###############################
############################### ###############################
############################### ###############################
version ='0.70.0' version ='0.72.0'
commandsOnStart = [] commandsOnStart = []

View File

@ -151,8 +151,6 @@ if __name__ == '__main__':
valueString) valueString)
sys.exit(-1) sys.exit(-1)
sys.path.append(conf.pluginDir)
nick = options.nick nick = options.nick
user = options.user user = options.user
ident = options.ident ident = options.ident

View File

@ -38,13 +38,11 @@ if 'test' not in sys.path:
import conf import conf
conf.dataDir = 'test-data' conf.dataDir = 'test-data'
if conf.pluginDir not in sys.path:
sys.path.insert(0, conf.pluginDir)
from fix import * from fix import *
import gc import gc
import re import re
import imp
import glob import glob
import time import time
import os.path import os.path
@ -99,9 +97,10 @@ nicks = ['fatjim','scn','moshez','LordVan','MetaCosm','pythong','fishfart',
nicks += [msg.nick for msg in msgs if msg.nick] nicks += [msg.nick for msg in msgs if msg.nick]
def getMsgs(command): def loadPlugin(name):
return [msg for msg in msgs if msg.command == command] moduleInfo = imp.find_module(name, conf.pluginDirs)
module = imp.load_module(name, *moduleInfo)
return module
class PluginTestCase(unittest.TestCase): class PluginTestCase(unittest.TestCase):
"""Subclass this to write a test case for a plugin. See test_FunCommands """Subclass this to write a test case for a plugin. See test_FunCommands
@ -120,12 +119,13 @@ class PluginTestCase(unittest.TestCase):
while self.irc.takeMsg(): while self.irc.takeMsg():
pass pass
if isinstance(self.plugins, str): if isinstance(self.plugins, str):
module = __import__(name) moduleInfo = imp.find_module(name, conf.pluginDirs)
module = imp.load_module(name, *moduleInfo)
plugin = module.Class() plugin = module.Class()
self.irc.addCallback(plugin) self.irc.addCallback(plugin)
else: else:
for name in self.plugins: for name in self.plugins:
module = __import__(name) module = loadPlugin(name)
plugin = module.Class() plugin = module.Class()
self.irc.addCallback(plugin) self.irc.addCallback(plugin)
@ -259,6 +259,13 @@ class PluginDocumentation:
self.failUnless(helps and len(helps.splitlines()) >= 3, self.failUnless(helps and len(helps.splitlines()) >= 3,
'%s has no morehelp' % attr) '%s has no morehelp' % attr)
def testPluginHasDocumentation(self):
for cb in self.irc.callbacks:
m = sys.modules[cb.__class__.__module__]
self.failIf(m.__doc__ is None,
'%s has no module documentation'%cb.__class__.__name__)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -31,7 +31,7 @@
from test import * from test import *
import Alias Alias = loadPlugin('Alias')
class FunctionsTest(unittest.TestCase): class FunctionsTest(unittest.TestCase):