Esempio n. 1
0
    def setBehaviour(self, list_of_pmd):
        """
        Set the functionalities handled by the plugin manager by
        giving a list of ``PluginManager`` decorators.
        
        This function shouldn't be called several time in a same
        process, but if it is only the first call will have an effect.

        It also has an effect only if called before the initialisation
        of the singleton.

        In cases where the function is indeed going to change anything
        the ``True`` value is return, in all other cases, the ``False``
        value is returned.
        """
        if self.__decoration_chain is None and self.__instance is None:
            log.debug(
                "Setting up a specific behaviour for the PluginManagerSingleton"
            )
            self.__decoration_chain = list_of_pmd
            return True
        else:
            log.debug(
                "Useless call to setBehaviour: the singleton is already instanciated of already has a behaviour."
            )
            return False
Esempio n. 2
0
	def __init__(self, decorated_object=None,
         		 # The following args will only be used if we need to
         		 # create a default PluginManager
                  categories_filter={"Default":IPlugin},
                  directories_list=[os.path.dirname(__file__)],
                  plugin_info_ext="yapsy-plugin"):
         """
         Mimics the PluginManager's __init__ method and wraps an
         instance of this class into this decorator class.

           - *If the decorated_object is not specified*, then we use the
             PluginManager class to create the 'base' manager, and to do
             so we will use the arguments: ``categories_filter``,
             ``directories_list``, and ``plugin_info_ext`` or their
             default value if they are not given.

           - *If the decorated object is given*, these last arguments are
             simply **ignored** !

         All classes (and especially subclasses of this one) that want
         to be a decorator must accept the decorated manager as an
         object passed to the init function under the exact keyword
         ``decorated_object``.
         """
         if decorated_object is None:
             log.debug("Creating a default PluginManager instance to be decorated.")
             decorated_object = PluginManager(categories_filter,
         									 directories_list,
         									 plugin_info_ext)
         self._component = decorated_object
Esempio n. 3
0
 def activatePluginByName(self, name, category="Default"):
     """
     Activate a plugin corresponding to a given category + name.
     """
     pta_item = self.getPluginByName(name, category)
     if pta_item is not None:
         plugin_to_activate = pta_item.plugin_object
         if plugin_to_activate is not None:
             log.debug("Activating plugin: %s.%s" % (category, name))
             plugin_to_activate.activate()
             return plugin_to_activate
     return None
Esempio n. 4
0
 def activatePluginByName(self, name, category="Default"):
     """
     Activate a plugin corresponding to a given category + name.
     """
     pta_item = self.getPluginByName(name, category)
     if pta_item is not None:
         plugin_to_activate = pta_item.plugin_object
         if plugin_to_activate is not None:
             log.debug("Activating plugin: %s.%s" % (category, name))
             plugin_to_activate.activate()
             return plugin_to_activate
     return None
Esempio n. 5
0
	def removeAnalyzers(self, name):
		"""
		Removes analyzers of a given name.
		"""
		analyzersListCopy = self._analyzers[:]
		foundAndRemoved = False
		for obj in analyzersListCopy:
			if obj.name == name:
				self._analyzers.remove(obj)
				foundAndRemoved = True
		if not foundAndRemoved:
			log.debug("'%s' is not a known strategy name: can't remove it." % name)
Esempio n. 6
0
    def removeAnalyzers(self, name):
        """
		Removes analyzers of a given name.
		"""
        analyzersListCopy = self._analyzers[:]
        foundAndRemoved = False
        for obj in analyzersListCopy:
            if obj.name == name:
                self._analyzers.remove(obj)
                foundAndRemoved = True
        if not foundAndRemoved:
            log.debug("'%s' is not a known strategy name: can't remove it." %
                      name)
Esempio n. 7
0
 def deactivatePluginByName(self, name, category="Default"):
     """
     Desactivate a plugin corresponding to a given category + name.
     """
     if category in self.category_mapping:
         plugin_to_deactivate = None
         for item in self.category_mapping[category]:
             if item.name == name:
                 plugin_to_deactivate = item.plugin_object
                 break
         if plugin_to_deactivate is not None:
             log.debug("Deactivating plugin: %s.%s" % (category, name))
             plugin_to_deactivate.deactivate()
             return plugin_to_deactivate
     return None
Esempio n. 8
0
 def deactivatePluginByName(self, name, category="Default"):
     """
     Desactivate a plugin corresponding to a given category + name.
     """
     if category in self.category_mapping:
         plugin_to_deactivate = None
         for item in self.category_mapping[category]:
             if item.name == name:
                 plugin_to_deactivate = item.plugin_object
                 break
         if plugin_to_deactivate is not None:
             log.debug("Deactivating plugin: %s.%s" % (category, name))
             plugin_to_deactivate.deactivate()
             return plugin_to_deactivate
     return None
Esempio n. 9
0
    def getPluginNameAndModuleFromStream(self,
                                         infoFileObject,
                                         candidate_infofile=None):
        """
		Extract the name and module of a plugin from the
		content of the info file that describes it and which
		is stored in ``infoFileObject``.
		
		.. note:: Prefer using ``_extractCorePluginInfo``
		          instead, whenever possible...
		
		.. warning:: ``infoFileObject`` must be a file-like object:
		             either an opened file for instance or a string
		             buffer wrapped in a StringIO instance as another
		             example.
		      
		.. note:: ``candidate_infofile`` must be provided
		          whenever possible to get better error messages.
		
		Return a 3-uple with the name of the plugin, its
		module and the config_parser used to gather the core
		data *in a tuple*, if the required info could be
		localised, else return ``(None,None,None)``.
		
		.. note:: This is supposed to be used internally by subclasses
			      and decorators.
		"""
        # parse the information buffer to get info about the plugin
        config_parser = configparser.ConfigParser()
        try:
            config_parser.read_file(infoFileObject)
        except Exception as e:
            log.debug(
                "Could not parse the plugin file '%s' (exception raised was '%s')"
                % (candidate_infofile, e))
            return (None, None, None)
        # check if the basic info is available
        if not config_parser.has_section("Core"):
            log.debug("Plugin info file has no 'Core' section (in '%s')" %
                      candidate_infofile)
            return (None, None, None)
        if not config_parser.has_option(
                "Core", "Name") or not config_parser.has_option(
                    "Core", "Module"):
            log.debug(
                "Plugin info file has no 'Name' or 'Module' section (in '%s')"
                % candidate_infofile)
            return (None, None, None)
        # check that the given name is valid
        name = config_parser.get("Core", "Name")
        name = name.strip()
        if PLUGIN_NAME_FORBIDEN_STRING in name:
            log.debug("Plugin name contains forbiden character: %s (in '%s')" %
                      (PLUGIN_NAME_FORBIDEN_STRING, candidate_infofile))
            return (None, None, None)
        return (name, config_parser.get("Core", "Module"), config_parser)
Esempio n. 10
0
 def get(self):
     """
     Actually create an instance
     """
     if self.__instance is None:
         if self.__decoration_chain is not None:
             # Get the object to be decorated
             # print self.__decoration_chain
             pm = self.__decoration_chain[0]()
             for cls_item in self.__decoration_chain[1:]:
                 # print cls_item
                 pm = cls_item(decorated_manager=pm)
             # Decorate the whole object
             self.__instance = pm
         else:
             # initialise the 'inner' PluginManagerDecorator
             self.__instance = PluginManager()
         log.debug("PluginManagerSingleton initialised")
     return self.__instance
Esempio n. 11
0
 def get(self):
     """
     Actually create an instance
     """
     if self.__instance is None:
         if self.__decoration_chain is not None:
             # Get the object to be decorated
             # print self.__decoration_chain
             pm = self.__decoration_chain[0]()
             for cls_item in self.__decoration_chain[1:]:
                 # print cls_item
                 pm = cls_item(decorated_manager=pm)
             # Decorate the whole object
             self.__instance = pm
         else:
             # initialise the 'inner' PluginManagerDecorator
             self.__instance = PluginManager()
         log.debug("PluginManagerSingleton initialised")
     return self.__instance
Esempio n. 12
0
    def setBehaviour(self, list_of_pmd):
        """
        Set the functionalities handled by the plugin manager by
        giving a list of ``PluginManager`` decorators.
        
        This function shouldn't be called several time in a same
        process, but if it is only the first call will have an effect.

        It also has an effect only if called before the initialisation
        of the singleton.

        In cases where the function is indeed going to change anything
        the ``True`` value is return, in all other cases, the ``False``
        value is returned.
        """
        if self.__decoration_chain is None and self.__instance is None:
            log.debug("Setting up a specific behaviour for the PluginManagerSingleton")
            self.__decoration_chain = list_of_pmd
            return True
        else:
            log.debug("Useless call to setBehaviour: the singleton is already instanciated of already has a behaviour.")
            return False
Esempio n. 13
0
	def getPluginNameAndModuleFromStream(self, infoFileObject, candidate_infofile=None):
		"""
		Extract the name and module of a plugin from the
		content of the info file that describes it and which
		is stored in ``infoFileObject``.
		
		.. note:: Prefer using ``_extractCorePluginInfo``
		          instead, whenever possible...
		
		.. warning:: ``infoFileObject`` must be a file-like object:
		             either an opened file for instance or a string
		             buffer wrapped in a StringIO instance as another
		             example.
		      
		.. note:: ``candidate_infofile`` must be provided
		          whenever possible to get better error messages.
		
		Return a 3-uple with the name of the plugin, its
		module and the config_parser used to gather the core
		data *in a tuple*, if the required info could be
		localised, else return ``(None,None,None)``.
		
		.. note:: This is supposed to be used internally by subclasses
			      and decorators.
		"""
		# parse the information buffer to get info about the plugin
		config_parser = configparser.ConfigParser()
		try:
			config_parser.read_file(infoFileObject)
		except Exception as e:
			log.debug("Could not parse the plugin file '%s' (exception raised was '%s')" % (candidate_infofile,e))
			return (None, None, None)
		# check if the basic info is available
		if not config_parser.has_section("Core"):
			log.debug("Plugin info file has no 'Core' section (in '%s')" % candidate_infofile)
			return (None, None, None)
		if not config_parser.has_option("Core","Name") or not config_parser.has_option("Core","Module"):
			log.debug("Plugin info file has no 'Name' or 'Module' section (in '%s')" % candidate_infofile)
			return (None, None, None)
		# check that the given name is valid
		name = config_parser.get("Core", "Name")
		name = name.strip()
		if PLUGIN_NAME_FORBIDEN_STRING in name:
			log.debug("Plugin name contains forbiden character: %s (in '%s')" % (PLUGIN_NAME_FORBIDEN_STRING,
																					candidate_infofile))
			return (None, None, None)
		return (name, config_parser.get("Core", "Module"), config_parser)
Esempio n. 14
0
	def locatePlugins(self):
		"""
		Walk through the plugins' places and look for plugins.

		Return the candidates and number of plugins found.
		"""
# 		print "%s.locatePlugins" % self.__class__
		_candidates = []
		_discovered = {}
		for directory in map(os.path.abspath, self.plugins_places):
			# first of all, is it a directory :)
			if not os.path.isdir(directory):
				log.debug("%s skips %s (not a directory)" % (self.__class__.__name__, directory))
				continue
			if self.recursive:
				debug_txt_mode = "recursively"
				walk_iter = os.walk(directory, followlinks=True)
			else:
				debug_txt_mode = "non-recursively"
				walk_iter = [(directory,[],os.listdir(directory))]
			# iteratively walks through the directory
			log.debug("%s walks (%s) into directory: %s" % (self.__class__.__name__, debug_txt_mode, directory))
			for item in walk_iter:
				dirpath = item[0]
				for filename in item[2]:
					# print("testing candidate file %s" % filename)
					for analyzer in self._analyzers:
						# print("... with analyzer %s" % analyzer.name)
						# eliminate the obvious non plugin files
						if not analyzer.isValidPlugin(filename):
							log.debug("%s is not a valid plugin for strategy %s" % (filename, analyzer.name))
							continue
						candidate_infofile = os.path.join(dirpath, filename)
						if candidate_infofile in _discovered:
							log.debug("%s (with strategy %s) rejected because already discovered" % (candidate_infofile, analyzer.name))
							continue
						log.debug("%s found a candidate:\n    %s" % (self.__class__.__name__, candidate_infofile))
#						print candidate_infofile
						plugin_info = self._getInfoForPluginFromAnalyzer(analyzer, dirpath, filename)
						if plugin_info is None:
							log.warning("Plugin candidate '%s'  rejected by strategy '%s'" % (candidate_infofile, analyzer.name))
							break # we consider this was the good strategy to use for: it failed -> not a plugin -> don't try another strategy
						# now determine the path of the file to execute,
						# depending on wether the path indicated is a
						# directory or a file
#					print plugin_info.path
						# Remember all the files belonging to a discovered
						# plugin, so that strategies (if several in use) won't
						# collide
						if os.path.isdir(plugin_info.path):
							candidate_filepath = os.path.join(plugin_info.path, "__init__")
							# it is a package, adds all the files concerned
							for _file in os.listdir(plugin_info.path):
								if _file.endswith(".py"):
									self._discovered_plugins[os.path.join(plugin_info.path, _file)] = candidate_filepath
									_discovered[os.path.join(plugin_info.path, _file)] = candidate_filepath
						elif (plugin_info.path.endswith(".py") and os.path.isfile(plugin_info.path)) or os.path.isfile(plugin_info.path+".py"):
							candidate_filepath = plugin_info.path
							if candidate_filepath.endswith(".py"):
								candidate_filepath = candidate_filepath[:-3]
							# it is a file, adds it
							self._discovered_plugins[".".join((plugin_info.path, "py"))] = candidate_filepath
							_discovered[".".join((plugin_info.path, "py"))] = candidate_filepath
						else:
							log.error("Plugin candidate rejected: cannot find the file or directory module for '%s'" % (candidate_infofile))
							break
#					print candidate_filepath
						_candidates.append((candidate_infofile, candidate_filepath, plugin_info))
						# finally the candidate_infofile must not be discovered again
						_discovered[candidate_infofile] = candidate_filepath
						self._discovered_plugins[candidate_infofile] = candidate_filepath
#						print "%s found by strategy %s" % (candidate_filepath, analyzer.name)
		return _candidates, len(_candidates)
Esempio n. 15
0
    def locatePlugins(self):
        """
		Walk through the plugins' places and look for plugins.

		Return the candidates and number of plugins found.
		"""
        # 		print "%s.locatePlugins" % self.__class__
        _candidates = []
        _discovered = {}
        for directory in map(os.path.abspath, self.plugins_places):
            # first of all, is it a directory :)
            if not os.path.isdir(directory):
                log.debug("%s skips %s (not a directory)" %
                          (self.__class__.__name__, directory))
                continue
            if self.recursive:
                debug_txt_mode = "recursively"
                walk_iter = os.walk(directory, followlinks=True)
            else:
                debug_txt_mode = "non-recursively"
                walk_iter = [(directory, [], os.listdir(directory))]
            # iteratively walks through the directory
            log.debug("%s walks (%s) into directory: %s" %
                      (self.__class__.__name__, debug_txt_mode, directory))
            for item in walk_iter:
                dirpath = item[0]
                for filename in item[2]:
                    # print("testing candidate file %s" % filename)
                    for analyzer in self._analyzers:
                        # print("... with analyzer %s" % analyzer.name)
                        # eliminate the obvious non plugin files
                        if not analyzer.isValidPlugin(filename):
                            log.debug(
                                "%s is not a valid plugin for strategy %s" %
                                (filename, analyzer.name))
                            continue
                        candidate_infofile = os.path.join(dirpath, filename)
                        if candidate_infofile in _discovered:
                            log.debug(
                                "%s (with strategy %s) rejected because already discovered"
                                % (candidate_infofile, analyzer.name))
                            continue
                        log.debug(
                            "%s found a candidate:\n    %s" %
                            (self.__class__.__name__, candidate_infofile))
                        #						print candidate_infofile
                        plugin_info = self._getInfoForPluginFromAnalyzer(
                            analyzer, dirpath, filename)
                        if plugin_info is None:
                            log.warning(
                                "Plugin candidate '%s'  rejected by strategy '%s'"
                                % (candidate_infofile, analyzer.name))
                            break  # we consider this was the good strategy to use for: it failed -> not a plugin -> don't try another strategy
                        # now determine the path of the file to execute,
                        # depending on wether the path indicated is a
                        # directory or a file
#					print plugin_info.path
# Remember all the files belonging to a discovered
# plugin, so that strategies (if several in use) won't
# collide
                        if os.path.isdir(plugin_info.path):
                            candidate_filepath = os.path.join(
                                plugin_info.path, "__init__")
                            # it is a package, adds all the files concerned
                            for _file in os.listdir(plugin_info.path):
                                if _file.endswith(".py"):
                                    self._discovered_plugins[os.path.join(
                                        plugin_info.path,
                                        _file)] = candidate_filepath
                                    _discovered[os.path.join(
                                        plugin_info.path,
                                        _file)] = candidate_filepath
                        elif (plugin_info.path.endswith(".py")
                              and os.path.isfile(plugin_info.path)
                              ) or os.path.isfile(plugin_info.path + ".py"):
                            candidate_filepath = plugin_info.path
                            if candidate_filepath.endswith(".py"):
                                candidate_filepath = candidate_filepath[:-3]
                            # it is a file, adds it
                            self._discovered_plugins[".".join(
                                (plugin_info.path, "py"))] = candidate_filepath
                            _discovered[".".join(
                                (plugin_info.path, "py"))] = candidate_filepath
                        else:
                            log.error(
                                "Plugin candidate rejected: cannot find the file or directory module for '%s'"
                                % (candidate_infofile))
                            break
#					print candidate_filepath
                        _candidates.append((candidate_infofile,
                                            candidate_filepath, plugin_info))
                        # finally the candidate_infofile must not be discovered again
                        _discovered[candidate_infofile] = candidate_filepath
                        self._discovered_plugins[
                            candidate_infofile] = candidate_filepath
#						print "%s found by strategy %s" % (candidate_filepath, analyzer.name)
        return _candidates, len(_candidates)