예제 #1
0
    def remove_slot(self, name, slot=None):
        """
        Remove a slot from the plugin manager and disconnect it from any
        plugins currently connected to it.

        If no ``slot`` is provided, *all* slots with the given name will be
        disconnected and removed from the plugin manager.
        """
        log.debug("remove_slot(%r, %r)" % (name, slot))

        if (not name in self._slots or
            (slot and not slot in self._slots[name])):
            return

        if isinstance(slot, (tuple,list)):
            slots = slot
        else:
            slots = [slot] if slot else self._slots[name].itervalues()

        for slot in slots:
            self._slots[name].remove(slot)
            for info in addons.find('plugin', lambda info: info.is_active):
                signal = getattr(info.plugin, name, None)
                if not isinstance(signal, Signal):
                    continue
                signal.disconnect(slot)
예제 #2
0
    def add_slot(self, name, slot):
        """
        Register a new slot with the plugin manager. All active plugins with
        signals matching the given name will be automatically connected to
        the slot.

        Additionally, this function returns a method that, when called, will
        remove the slot from the system.
        """
        if not name in self._slots:
            self._slots[name] = []

        # Build the remover.
        remover = functools.partial(self.remove_slot, name, slot)

        if slot in self._slots[name]:
            return remover
        self._slots[name].append(slot)

        # Now, iterate through our plugins and connect the slot to every
        # plugin that's currently active.
        for info in addons.find('plugin', lambda info: info.is_active):
            signal = getattr(info.plugin, name, None)
            if not isinstance(signal, Signal):
                continue
            signal.connect(slot)

        return remover
예제 #3
0
    def add_signal(self, name, signal):
        """
        Register a new signal with the plugin manager. All active plugins with
        slots matching the given name will be automatically connected to the
        signal.

        Additionally, this function returns a method that, when called, will
        remove the signal from the system.
        """
        if not name in self._signals:
            self._signals[name] = []

        # Build the remover.
        remover = functools.partial(self.remove_signal, name, signal)

        # If we already have it, just return now.
        if signal in self._signals[name]:
            return remover

        # Store the signal in the list.
        self._signals[name].append(signal)

        # Now, iterate through our plugins and connect the signal to every
        # plugin that's currently active.
        for info in addons.find('plugin', lambda info: info.is_active):
            slot = getattr(info.plugin, name, None)
            if not hasattr(slot, '_slots'):
                continue
            signal.connect(slot)

        return remover
예제 #4
0
 def run_signal(self, name, *args):
     """
     Process a signal immediately with all active plugins with slots
     matching the given name. Any provided arguments will be sent along
     to those slots.
     """
     for info in addons.find('plugin', lambda info: info.is_active):
         slot = getattr(info.plugin, name, None)
         if not hasattr(slot, '_slots'):
             continue
         try:
             slot(*args)
         except Exception:
             log.exception('Error running signal through plugin %r.' %
                           info.data['name'])
예제 #5
0
    def remove_signal(self, name, signal=None):
        """
        Remove a signal from the plugin manager and disconnect it from any
        plugins currently connected to it.

        If no ``signal`` is provided, *all* signals with the given name will be
        disconnected and removed from the plugin manager.
        """
        if (not name in self._signals or
            (signal and not signal in self._signals[name])):
            return

        if isinstance(signal, (list, tuple)):
            signals = signal
        else:
            signals = [signal] if signal else self._signals[name].itervalues()

        for signal in signals:
            self._signals[name].remove(signal)
            for info in addons.find('plugin', lambda info: info.is_active):
                slot = getattr(info.plugin, name, None)
                if not hasattr(slot, '_slots'):
                    continue
                signal.disconnect(slot)
예제 #6
0
def initialize(args=None, **kwargs):
    """
    Initialize the plugin system. You may use the following arguments to
    configure the plugin system:

    ==============  ==============  ============
    Argument        Default         Description
    ==============  ==============  ============
    discover        ``True``        If this is True, we'll search for plugins immediately.
    load            ``True``        If this is True, plugins will be loaded automatically after discovery.
    activate        ``True``        If this is True, plugins will be activated automatically after loading.
    paths           ``[]``          A list of paths to search for plugins.
    ==============  ==============  ============

    In addition, you can provide a list of command line arguments to have
    siding load them automatically. Example::

        siding.plugins.initialize(sys.argv[1:])

    The following command line arguments are supported:

    ==================  ============
    Argument            Description
    ==================  ============
    ``--safe-mode``     When safe mode is enabled, add-ons, including styles, won't be loaded automatically.
    ``--plugin-path``   Add the given path to the plugin search paths. This may be used more than once.
    ==================  ============
    """

    # First, get the paths in case we need it.
    paths = addons.manager._types['plugin'][2]

    if kwargs.has_key('paths'):
        # Clear out paths. But don't delete it, because we'd just lose our
        # reference.
        del paths[:]
        paths.extend(kwargs.get('paths'))

    # Now, parse our options.
    if args:
        if args is True:
            args = sys.argv[1:]

        parser = argparse.ArgumentParser(add_help=False)
        parser.add_argument('--safe-mode', action='store_true')
        parser.add_argument('--plugin-path', action='append')

        options = parser.parse_known_args(args)[0]

        # Do stuff.
        if options.safe_mode:
            addons.safe_mode = True

        if options.plugin_path:
            for path in reversed(options.plugin_path):
                paths.insert(0, path)

    # Now, for the discovery.
    if kwargs.get('discover', True):
        addons.discover('plugin')

    # And loading...
    if addons.safe_mode:
        log.info('Not loading plugins due to safe-mode.')
        return

    if kwargs.get('load', True):
        for info in addons.find('plugin', lambda info: not info.is_loaded):
            try:
                info.load()
            except (addons.DependencyError, ImportError), err:
                log.error('Error loading plugin %r: %s' %
                          (info.data['name'], err))
예제 #7
0
            for path in reversed(options.plugin_path):
                paths.insert(0, path)

    # Now, for the discovery.
    if kwargs.get('discover', True):
        addons.discover('plugin')

    # And loading...
    if addons.safe_mode:
        log.info('Not loading plugins due to safe-mode.')
        return

    if kwargs.get('load', True):
        for info in addons.find('plugin', lambda info: not info.is_loaded):
            try:
                info.load()
            except (addons.DependencyError, ImportError), err:
                log.error('Error loading plugin %r: %s' %
                          (info.data['name'], err))

    # And activation...
    if kwargs.get('activate', True):
        for info in addons.find('plugin', lambda info: info.is_loaded):
            if info.is_active:
                continue
            try:
                info.plugin.activate()
            except Exception:
                log.exception('Error activating plugin %r.' %
                              info.data['name'])