registry.py
author Nicolas Chauvat <nicolas.chauvat@logilab.fr>
Mon, 23 Jun 2008 13:42:22 +0200
changeset 6 6aad8b499e86
parent 0 7710b138d4eb
permissions -rw-r--r--
fix reST markup

# Copyright (c) 2004 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# 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.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
"""plugins registry

a plugin is associated to a mime type
"""

__revision__ = '$Id: registry.py,v 1.8 2004-12-16 09:43:58 syt Exp $'

import sys

from logilab.common.modutils import load_module_from_name

__metaclass__ = type


class PlugInsRegistry:
    """the registry is responsible to handle loaded file/directory
    plugins
    """
    
    name = 'plugins'
    
    def __init__(self, appl):
        self.appl = appl
        # the registry has no options by itself
        self.cfg = None
        # loaded plugins
        self.plugins = []
        # plugins indexes
        self._plugins_idx = {}
        self._default_plugins = []

    def register_all(self, modnames):
        """load each python module in the modnames list and register it
        as a plugin.

        A Plugin module must have a "register" function taking this
        registry as only argument. The function should call the
        "register" method of this object to register handlers for some
        mime types.
        """
        for modname in modnames:
            try:
                module = load_module_from_name(modname)
            except:
                if __debug__:
                    import traceback
                    traceback.print_exc()
                log_traceback(LOG_ERR, sys.exc_info())
                continue
            try:
                register = module.register
            except AttributeError:
                log(LOG_ERR, 'plugin module %s has not the required function\
 "register(registry)"', modname)
                continue
            try:
                register(self)
            except:
                log_traceback(LOG_ERR, sys.exc_info())
            
    def register(self, plugin):
        """register a new plugin
        the plugin should have a mimetypes attribute indicating the
        mime types it is able to handle.

        wildcard are allowed in a mime type:
          - '*' will register plugin for any file
          - 'text/*' will register plugin for any text file
          - 'text/html' will register plugin for any html text file
          - '*/whatever' is not supported and won't work as espected
        """
        plugin.set_application(self.appl)
        self.plugins.append(plugin)
        for mimetype in plugin.mimetypes:
            mimetype = mimetype.strip()
            try:
                major, minor = mimetype.split('/')
            except:
                if mimetype == '*':
                    self._default_plugins.append(plugin)
                    continue
                raise
            idx = self._plugins_idx.setdefault(major, {})
            idx.setdefault(minor, []).append(plugin)

    def get_plugins(self, fileobj):
        """return a list of plugins able to handle the mime type of the
        given file
        """
        if fileobj.mimetype is None:
            if fileobj.is_directory():
                return [plug for plug in self.plugins
                        if plug.support_directory(fileobj)]
            return self._default_plugins
        major, minor = fileobj.mimetype.split('/')
        major_plugins = self._plugins_idx.get(major, {})
        return (self._default_plugins
                + major_plugins.get('*', [])
                + major_plugins.get(minor, []))

    def subconfiguration(self):
        """return a list of configuration nodes for subconfiguration
        (i.e. plugins for the registry)
        """
        return self.plugins
    
    
#REGISTRY = PlugInsRegistry()
#del PlugInsRegistry