grim/purple-plugin-pack
file isExecutable
Testing CIA again...
# plugin_pack.py - Helper script for obtaining info about the plugin pack # Copyright (C) 2008 Gary Kramlich <grim@reaperworld.com> # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA. """Usage: plugin_pack.py [OPTION...] command -i Load incomplate plugins webpage = 'http://plugins.guifications.org/' def __init__(self, directory, name, parser): self.directory = directory self.type = parser.get(name, 'type') self.depends = parser.get(name, 'depends').split() self.provides = parser.get(name, 'provides') self.summary = parser.get(name, 'summary') self.description = parser.get(name, 'description') self.authors = parser.get(name, 'authors').split(',') self.introduced = parser.get(name, 'introduced') if parser.has_option(name, 'notes'): self.notes = parser.get(name, 'notes') if self.type != 'default' and self.type != 'incomplete' and self.type != 'abusive': printerr('\'%s\' has an unknown type of \'%s\'!' % (self.name, self.type)) output = 'name: %s\n' % self.name output += 'authors: %s\n' % string.join(self.authors, ', ') output += 'type: %s\n' % self.type output += 'depends: %s\n' % string.join(self.depends, ' ') output += 'provides: %s\n' % self.provides output += 'directory: %s\n' % self.directory output += 'summary: %s\n' % self.summary output += 'description: %s\n' % self.description output += 'notes: %s\n' % self.notes def load_plugins(self, types, depends): for file in glob.glob('*/plugins.cfg'): parser = ConfigParser.ConfigParser() except ConfigParser.ParsingError, msg: printerr('Failed to parse \'%s\':\n%s' % (file, msg)) for plugin in parser.sections(): p = Plugin(os.path.dirname(file), plugin, parser) # this is kind of hacky, but if we have types, we check to see # if the type is in list of types to load. if types and not p.type in types: # now we check if the give plugins depends match the search if len(set(depends).intersection(set(p.depends))) == 0: self.plugins[p.provides] = p def list_type(self, type): for name in self.plugins.keys(): plugin = self.plugins[name] for name in self.plugins.keys(): plugin = self.plugins[name] if dep in plugin.depends: def print_names(self, list): names.append(plugin.name) print string.join(names, ',') def default_plugins(self): return self.list_type('default') def abusive_plugins(self): return self.list_type('abusive') def incomplete_plugins(self): return self.list_type('incomplete') def purple_plugins(self): return self.list_dep('purple') return self.list_dep('finch') def pidgin_plugins(self): return self.list_dep('pidgin') for name in self.plugins.keys(): dirs[self.plugins[name].directory] = 1 """Displays information about other commands""" cmd = self.commands[args[0]] print 'command \'%s\' was not found' % args[0] print '%s' % (self.help.__doc__) print 'Available commands:' cmds = self.commands.keys() print ' %s' % (string.join(cmds, ' ')) def dist_dirs(self, args): """Displays a list of all plugin directories to included in the distribution""" print string.join(self.unique_dirs(), ' ') commands['dist_dirs'] = dist_dirs def build_dirs(self, args): """Displays a list of the plugins that can be built""" printerr('build_dirs expects 2 arguments:') printerr('\ta comma separated list of dependencies') printerr('\ta comma separated list of plugins to build') # store the external depedencies externals = args[0].split(',') # run through the provided dependencies, setting their dependencies to # nothing since we know we already have them # now run through the plugins adding their deps to the dictionary for name in self.plugins.keys(): plugin = self.plugins[name] deps[plugin.provides] = plugin.depends # run through the requested plugins and store their plugin instance in check for provides in args[1].split(','): for p in self.default_plugins(): defaults.append(p.provides) plugin = self.plugins[provides] check.append(plugin.provides) # convert our list of plugins to check into a set to remove dupes # create our list of plugins to build # now define a function to check our deps # don't add anything to build more than once dep_list = deps[provides] # now check the dependencies # make sure the provides isn't an external if not provides in externals: # check all the plugins we were told to for their dependencies # now create a list of all directories to build plugin = self.plugins[provides] output.append(plugin.directory) print "%s" % (string.join(output, ',')) commands['build_dirs'] = build_dirs def list_plugins(self, args): """Displays a list similiar to 'dpkg -l' about the plugin pack""" # create an array for the widths, we initialize it to the lengths of # the title strings. We ignore summary, since that one shouldn't for p in self.plugins.keys(): if plugin.type == 'abusive': elif plugin.type == 'incomplete': if 'finch' in plugin.depends: elif 'pidgin' in plugin.depends: elif 'purple' in plugin.depends: widths[0] = max(widths[0], len(plugin.name)) widths[1] = max(widths[1], len(plugin.provides)) widths[2] = max(widths[2], len(plugin.summary)) data[plugin.provides] = [type, ui, plugin.name, plugin.provides, plugin.summary] print 'Type=Default/Incomplete/Abusive' print '| UI=Finch/Pidgin/puRple/Unknown' print '|/ Name%s Provides%s Summary' % (' ' * (widths[0] - 4), ' ' * (widths[1] - 8)) print '++-%s-%s-%s' % ('=' * (widths[0]), '=' * (widths[1]), '=' * (widths[2])) fmt = '%%s%%s %%-%ds %%-%ds %%s' % (widths[0], widths[1]) #, widths[2]) # now loop through the list again, with everything formatted print fmt % (d[0], d[1], d[2], d[3], d[4]) commands['list'] = list_plugins def config_file(self, args): """Outputs the contents for the file to be m4_include()'d from configure""" uniqdirs = self.unique_dirs() # add our --with-plugins option print 'AC_ARG_WITH(plugins,' print ' AC_HELP_STRING([--with-plugins], [what plugins to build]),' print ' ,with_plugins=all)' print 'if test -z $with_plugins ; then' print '\twith_plugins=all' # determine and add our output files print 'PP_DIST_DIRS="%s"' % (string.join(uniqdirs, ' ')) print 'AC_SUBST(PP_DIST_DIRS)' print 'AC_CONFIG_FILES([' print '\t%s/Makefile' % (dir) # setup a second call to determine the plugins to be built print 'PP_BUILD=`$PYTHON $srcdir/plugin_pack.py build_dirs $DEPENDENCIES $with_plugins`' print 'PP_BUILD_DIRS=`echo $PP_BUILD | sed \'s/,/\ /g\'`' print 'AC_SUBST(PP_BUILD_DIRS)' print 'PP_PURPLE_BUILD="$PYTHON $srcdir/plugin_pack.py -p show_names $PP_BUILD"' print 'PP_PIDGIN_BUILD="$PYTHON $srcdir/plugin_pack.py -P show_names $PP_BUILD"' print 'PP_FINCH_BUILD="$PYTHON $srcdir/plugin_pack.py -f show_names $PP_BUILD"' commands['config_file'] = config_file def dependency_graph(self, args): """Outputs a graphviz script showing plugin dependencies""" node = plugin.provides.replace('-', '_') node, label = node_label(plugin) print '\t%s[label="%s"];' % (node, label) print '\tlabel="Dependency Graph";' print '\tnode[fontname="sans", fontsize="8", style="filled"];' # run through the default plugins print '\t/* default plugins */' print '\tnode[fillcolor="palegreen",shape="tab"];' print_plugins(self.default_plugins()) # run through the incomplete plugins print '\t/* incomplete plugins */' print '\tnode[fillcolor="lightyellow1",shape="note"];' print_plugins(self.incomplete_plugins()) # run through the abusive plugins print '\t/* abusive plugins */' print '\tnode[fillcolor="lightpink",shape="octagon"];' print_plugins(self.abusive_plugins()) # run through again, this time showing the relations print '\t/* dependencies' print '\t * exteranl ones that don\'t have nodes get colored to the following' print '\tnode[fillcolor="powderblue", shape="egg"];' for name in self.plugins.keys(): plugin = self.plugins[name] node, label = node_label(plugin) for dep in plugin.depends: dep = dep.replace('-', '_') print '\t%s -> %s;' % (node, dep) commands['dependency_graph'] = dependency_graph def debian_description(self, args): """Outputs the description for the Debian packages""" print 'Description: %d useful plugins for Pidgin, Finch, and Purple' % len(self.plugins) print ' The Plugin Pack is a collection of many simple-yet-useful plugins for Pidgin,' print ' Finch, and Purple. You will find a summary of each plugin below. For more' print ' about an individual plugin, please see %s' % webpage print ' Note: not all %d of these plugins are currently usable' % len(self.plugins) list = self.plugins.keys() plugin = self.plugins[key] print ' %s: %s' % (plugin.name, plugin.summary) print ' Homepage: %s' % webpage commands['debian_description'] = debian_description def show_names(self, args): """Displays the names of the given comma separated list of provides""" if len(args) == 0 or len(args[0]) == 0: printerr('show_names expects a comma separated list of provides') provides = args[0].split(',') if not provide in self.plugins: name = self.plugins[provide].name if len(line) + len(name) + 2 > 75: commands['show_names'] = show_names """Displays all information about the given plugins""" print self.plugins[p].__str__().strip() print 'Failed to find a plugin that provides \'%s\'' % (p) """Displays stats about the plugin pack""" counts['total'] = len(self.plugins) counts['default'] = len(self.default_plugins()) counts['incomplete'] = len(self.incomplete_plugins()) counts['abusive'] = len(self.abusive_plugins()) counts['purple'] = len(self.purple_plugins()) counts['finch'] = len(self.finch_plugins()) counts['pidgin'] = len(self.pidgin_plugins()) return "%3d (%6.2f%%)" % (val, (float(val) / float(counts['total'])) * 100.0) print "Purple Plugin Pack Stats" print "%d plugins in total" % (counts['total']) print " complete: %s" % (value(counts['default'])) print " incomplete: %s" % (value(counts['incomplete'])) print " abusive: %s" % (value(counts['abusive'])) print " purple: %s" % (value(counts['purple'])) print " finch: %s" % (value(counts['finch'])) print " pidgin: %s" % (value(counts['pidgin'])) commands['stats'] = stats def show_usage(pp, exitcode): cmds = pp.commands.keys() print " %-20s %s" % (cmd, pp.commands[cmd].__doc__) # create our main instance opts, args = getopt.getopt(sys.argv[1:], shortopts) except getopt.error, msg: types.append('incomplete') # load the plugins that have been requested, if both lists are empty, all pp.load_plugins(types, depends) pp.commands[cmd](pp, args) printerr('\'%s\' command not found' % (cmd)) if __name__ == '__main__': # this is a work around when we're called for a directory that isn't the # directory that this file is in. This happens during distcheck, as well # as a few other cases that most people won't use ;) if os.path.dirname(__file__) != '': os.chdir(os.path.dirname(__file__))