Skip to content

Commit

Permalink
Misc: Add --unloaded option.
Browse files Browse the repository at this point in the history
  • Loading branch information
progval committed Sep 1, 2011
1 parent 6be6c91 commit 2f6acdf
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 16 deletions.
5 changes: 5 additions & 0 deletions plugins/Misc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ def configure(advanced):
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
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',
registry.String('[%H:%M:%S]', _("""Determines the format string for
timestamps in the Misc.last command. Refer to the Python documentation
Expand Down
72 changes: 57 additions & 15 deletions plugins/Misc/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import re
import os
import imp
import sys
import time

Expand All @@ -49,6 +50,23 @@
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = 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):
pass

Expand Down Expand Up @@ -121,34 +139,57 @@ def invalidCommand(self, irc, msg, tokens):

@internationalizeDocstring
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
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
unloaded = False
for (option, argument) in optlist:
if option == 'private':
private = True
if not self.registryValue('listPrivatePlugins') and \
not ircdb.checkCapability(msg.prefix, '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:
def isPublic(cb):
name = cb.name()
return conf.supybot.plugins.get(name).public()
names = [cb.name() for cb in irc.callbacks
if (private and not isPublic(cb)) or
(not private and isPublic(cb))]
names.sort()
if names:
irc.reply(format('%L', names))
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:
if private:
irc.reply(_('There are no private plugins.'))
def isPublic(cb):
name = cb.name()
return conf.supybot.plugins.get(name).public()
names = [cb.name() for cb in irc.callbacks
if (private and not isPublic(cb)) or
(not private and isPublic(cb))]
names.sort()
if names:
irc.reply(format('%L', names))
else:
irc.reply(_('There are no public plugins.'))
if private:
irc.reply(_('There are no private plugins.'))
else:
irc.reply(_('There are no public plugins.'))
else:
commands = cb.listCommands()
if commands:
Expand All @@ -162,7 +203,8 @@ def isPublic(cb):
'Try "config list supybot.plugins.%s" to see '
'what configuration variables it has.'),
cb.name()))
list = wrap(list, [getopts({'private':''}), additional('plugin')])
list = wrap(list, [getopts({'private':'', 'unloaded':''}),
additional('plugin')])

@internationalizeDocstring
def apropos(self, irc, msg, args, s):
Expand Down
6 changes: 6 additions & 0 deletions plugins/Misc/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ def testListPrivate(self):
self.assertRegexp('list', 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):
self.assertNotRegexp('list Owner', '_exec')

Expand Down
2 changes: 1 addition & 1 deletion src/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""stick the various versioning attributes in here, so we only have to change
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)'

0 comments on commit 2f6acdf

Please sign in to comment.