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)
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
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
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'])
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)
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))
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'])