Misc: Add --unloaded option.

This commit is contained in:
Valentin Lorentz 2011-09-01 17:48:09 +00:00
parent 6be6c91657
commit 2f6acdf42f
4 changed files with 69 additions and 16 deletions

View File

@ -46,6 +46,11 @@ conf.registerGlobalValue(Misc, 'listPrivatePlugins',
plugins with the list command if given the --private switch. If this is plugins with the list command if given the --private switch. If this is
disabled, non-owner users should be unable to see what private plugins disabled, non-owner users should be unable to see what private plugins
are loaded."""))) are loaded.""")))
conf.registerGlobalValue(Misc, 'listUnloadedPlugins',
registry.Boolean(True, _("""Determines whether the bot will list unloaded
plugins with the list command if given the --unloaded switch. If this is
disabled, non-owner users should be unable to see what unloaded plugins
are available.""")))
conf.registerGlobalValue(Misc, 'timestampFormat', conf.registerGlobalValue(Misc, 'timestampFormat',
registry.String('[%H:%M:%S]', _("""Determines the format string for registry.String('[%H:%M:%S]', _("""Determines the format string for
timestamps in the Misc.last command. Refer to the Python documentation timestamps in the Misc.last command. Refer to the Python documentation

View File

@ -30,6 +30,7 @@
import re import re
import os import os
import imp
import sys import sys
import time import time
@ -49,6 +50,23 @@ from supybot.utils.iter import ifilter
from supybot.i18n import PluginInternationalization, internationalizeDocstring from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Misc') _ = PluginInternationalization('Misc')
def get_suffix(file):
for suffix in imp.get_suffixes():
if file[-len(suffix[0]):] == suffix[0]:
return suffix
return None
def getPluginsInDirectory(directory):
# get modules in a given directory
plugins = []
for filename in os.listdir(directory):
pluginPath = os.path.join(directory, filename)
if os.path.isdir(pluginPath):
if all(os.path.isfile(os.path.join(pluginPath, x))
for x in ['__init__.py', 'config.py', 'plugin.py']):
plugins.append(filename)
return plugins
class RegexpTimeout(Exception): class RegexpTimeout(Exception):
pass pass
@ -121,20 +139,43 @@ class Misc(callbacks.Plugin):
@internationalizeDocstring @internationalizeDocstring
def list(self, irc, msg, args, optlist, cb): def list(self, irc, msg, args, optlist, cb):
"""[--private] [<plugin>] """[--private] [--unloaded] [<plugin>]
Lists the commands available in the given plugin. If no plugin is Lists the commands available in the given plugin. If no plugin is
given, lists the public plugins available. If --private is given, given, lists the public plugins available. If --private is given,
lists the private plugins. lists the private plugins. If --unloaded is given, it will list
available plugins that are not loaded.
""" """
private = False private = False
unloaded = False
for (option, argument) in optlist: for (option, argument) in optlist:
if option == 'private': if option == 'private':
private = True private = True
if not self.registryValue('listPrivatePlugins') and \ if not self.registryValue('listPrivatePlugins') and \
not ircdb.checkCapability(msg.prefix, 'owner'): not ircdb.checkCapability(msg.prefix, 'owner'):
irc.errorNoCapability('owner') irc.errorNoCapability('owner')
elif option == 'unloaded':
unloaded = True
if not self.registryValue('listUnloadedPlugins') and \
not ircdb.checkCapability(msg.prefix, 'owner'):
irc.errorNoCapability('owner')
if unloaded and private:
irc.error(_('--private and --unloaded are uncompatible options.'))
return
if not cb: if not cb:
if unloaded:
installedPluginsDirectory = os.path.join(
os.path.dirname(__file__), '..')
plugins = getPluginsInDirectory(installedPluginsDirectory)
for directory in conf.supybot.directories.plugins()[:]:
plugins.extend(getPluginsInDirectory(directory))
# Remove loaded plugins:
loadedPlugins = [x.name() for x in irc.callbacks]
plugins = [x for x in plugins if x not in loadedPlugins]
plugins.sort()
irc.reply(format('%L', plugins))
else:
def isPublic(cb): def isPublic(cb):
name = cb.name() name = cb.name()
return conf.supybot.plugins.get(name).public() return conf.supybot.plugins.get(name).public()
@ -162,7 +203,8 @@ class Misc(callbacks.Plugin):
'Try "config list supybot.plugins.%s" to see ' 'Try "config list supybot.plugins.%s" to see '
'what configuration variables it has.'), 'what configuration variables it has.'),
cb.name())) cb.name()))
list = wrap(list, [getopts({'private':''}), additional('plugin')]) list = wrap(list, [getopts({'private':'', 'unloaded':''}),
additional('plugin')])
@internationalizeDocstring @internationalizeDocstring
def apropos(self, irc, msg, args, s): def apropos(self, irc, msg, args, s):

View File

@ -114,6 +114,12 @@ class MiscTestCase(ChannelPluginTestCase):
self.assertRegexp('list', name) self.assertRegexp('list', name)
self.assertNotRegexp('list --private', name) self.assertNotRegexp('list --private', name)
def testListUnloaded(self):
unloadedPlugin = 'Alias'
loadedPlugin = 'Anonymous'
self.assertRegexp('list --unloaded', 'Alias')
self.assertNotRegexp('list --unloaded', 'Anonymous')
def testListDoesNotIncludeNonCanonicalName(self): def testListDoesNotIncludeNonCanonicalName(self):
self.assertNotRegexp('list Owner', '_exec') self.assertNotRegexp('list Owner', '_exec')

View File

@ -1,3 +1,3 @@
"""stick the various versioning attributes in here, so we only have to change """stick the various versioning attributes in here, so we only have to change
them once.""" them once."""
version = '0.83.4.1+limnoria (2011-08-30T17:21:39+0000)' version = '0.83.4.1+limnoria (2011-09-01T17:48:08+0000)'