Yapsy:一个简单的黑客来摆脱插件信息文件

时间:2012-03-26 04:32:27

标签: python plugins

我想在我的代码中使用插件系统。我一直在寻找简单(但功能强大)的python模块,并找到了Yapsy(以及其他一些)。

这正是我所寻找的,但Yapsy发现插件的方式不是很灵活,需要一个插件信息文件。我想摆脱它,而不必分叉代码(如果我开始依赖Yapsy,我想确保我将从它获得所有更新,而不必每次都重新编译它。)

我推出了这个快速而肮脏的解决方案,它运行良好,但不会提高“发现”过程的灵活性:

#!/usr/bin/env python

import os
import logging
from cStringIO import StringIO

from yapsy.PluginManager import PluginManager
from yapsy.IPlugin import IPlugin
from yapsy.PluginInfo import PluginInfo


class MyPluginManager(PluginManager):
    """
    My attempt to get rid of the plugin info file...
    """
    def __init__(self, 
                 categories_filter={"Default":IPlugin}, 
                 directories_list=None, 
                 plugin_info_ext="plugin.py"):
        """
        Initialize the mapping of the categories and set the list of
        directories where plugins may be. This can also be set by
        direct call the methods: 

        - ``setCategoriesFilter`` for ``categories_filter``
        - ``setPluginPlaces`` for ``directories_list``
        - ``setPluginInfoExtension`` for ``plugin_info_ext``

        You may look at these function's documentation for the meaning
        of each corresponding arguments.
        """
        self.setPluginInfoClass(PluginInfo)
        self.setCategoriesFilter(categories_filter)     
        self.setPluginPlaces(directories_list)
        self.setPluginInfoExtension(plugin_info_ext)    

    def _gatherCorePluginInfo(self, directory, filename):
        """
        Gather the core information (name, and module to be loaded)
        about a plugin described by it's info file (found at
        'directory/filename').

        Return an instance of ``self.plugin_info_cls`` and the
        config_parser used to gather the core data *in a tuple*, if the
        required info could be localised, else return ``(None,None)``.

        .. note:: This is supposed to be used internally by subclasses
            and decorators.

        """
        # now we can consider the file as a serious candidate
        candidate_infofile = os.path.join(directory,filename)
        print candidate_infofile

        # My hack : just create a StringIO file with basic plugin info
        _fname = filename.rstrip(".py")
        _file = StringIO()
        _file.write("""[Core]
Name = %s
Module = %s
        """ % (_fname, _fname))
        _file.seek(0)

        # parse the information file to get info about the plugin
        name,moduleName,config_parser = self._getPluginNameAndModuleFromStream(_file, candidate_infofile)
        print name, moduleName, config_parser
        if (name,moduleName,config_parser)==(None,None,None):
                        return (None,None)
        # start collecting essential info
        plugin_info = self._plugin_info_cls(name,os.path.join(directory,moduleName))
        return (plugin_info,config_parser)

这个hack只是假设插件有一个扩展名“.plugin.py”(或“.plugin”用于目录,但我没有测试它)。然后我创建一个cSringIO文件来欺骗Yapsy并让它认为他找到了一个插件信息文件。 (通过设置适当的变量,仍然可以在插件中提供其他信息:author,description ...)。

我想知道是否有更好的方式,或者人们是否已经这样做了。这个hack显然太粗糙而不是非常有用,我希望有一些更灵活的东西:插件可以通过其插件信息文件(如原始代码中)或插件名称的模式(可能使用re,允许使用前缀,后缀......)。据我所知,实施这些想法需要比我已经完成的更复杂的黑客...

1 个答案:

答案 0 :(得分:0)

好的,我已经实现了Yapsy插件管理器的一个分支,并实际上与该软件包的作者保持联系。一旦文档和测试完成,我认为这可能会包含在Yapsy的下一个版本中。