Exemplo n.º 1
0
    def install(self, directory, plugin_info_filename):
        """
		Giving the plugin's info file (e.g. ``myplugin.yapsy-plugin``),
		and the directory where it is located, get all the files that
		define the plugin and copy them into the correct directory.
		
		Return ``True`` if the installation is a success, ``False`` if
		it is a failure.
		"""
        # start collecting essential info about the new plugin
        plugin_info, config_parser = self._gatherCorePluginInfo(
            directory, plugin_info_filename)
        # now determine the path of the file to execute,
        # depending on wether the path indicated is a
        # directory or a file
        if not (os.path.exists(plugin_info.path)
                or os.path.exists(plugin_info.path + ".py")):
            log.warning("Could not find the plugin's implementation for %s." %
                        plugin_info.name)
            return False
        if os.path.isdir(plugin_info.path):
            try:
                shutil.copytree(
                    plugin_info.path,
                    os.path.join(self.install_dir,
                                 os.path.basename(plugin_info.path)))
                shutil.copy(os.path.join(directory, plugin_info_filename),
                            self.install_dir)
            except:
                log.error("Could not install plugin: %s." % plugin_info.name)
                return False
            else:
                return True
        elif os.path.isfile(plugin_info.path + ".py"):
            try:
                shutil.copy(plugin_info.path + ".py", self.install_dir)
                shutil.copy(os.path.join(directory, plugin_info_filename),
                            self.install_dir)
            except:
                log.error("Could not install plugin: %s." % plugin_info.name)
                return False
            else:
                return True
        else:
            return False
Exemplo n.º 2
0
	def install(self, directory, plugin_info_filename):
		"""
		Giving the plugin's info file (e.g. ``myplugin.yapsy-plugin``),
		and the directory where it is located, get all the files that
		define the plugin and copy them into the correct directory.
		
		Return ``True`` if the installation is a success, ``False`` if
		it is a failure.
		"""
		# start collecting essential info about the new plugin
		plugin_info, config_parser = self._gatherCorePluginInfo(directory, plugin_info_filename)
		# now determine the path of the file to execute,
		# depending on wether the path indicated is a
		# directory or a file
		if not (os.path.exists(plugin_info.path) or os.path.exists(plugin_info.path+".py") ):
			log.warning("Could not find the plugin's implementation for %s." % plugin_info.name)
			return False
		if os.path.isdir(plugin_info.path):
			try:
				shutil.copytree(plugin_info.path,
								os.path.join(self.install_dir,os.path.basename(plugin_info.path)))
				shutil.copy(os.path.join(directory, plugin_info_filename),
							self.install_dir)
			except:
				log.error("Could not install plugin: %s." % plugin_info.name)
				return False
			else:
				return True
		elif os.path.isfile(plugin_info.path+".py"):
			try:
				shutil.copy(plugin_info.path+".py",
							self.install_dir)
				shutil.copy(os.path.join(directory, plugin_info_filename),
						   self.install_dir)
			except:
				log.error("Could not install plugin: %s." % plugin_info.name)
				return False
			else:
				return True
		else:
			return False
Exemplo n.º 3
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)
Exemplo n.º 4
0
    def installFromZIP(self, plugin_ZIP_filename):
        """
		Giving the plugin's zip file (e.g. ``myplugin.zip``), check
		that their is a valid info file in it and correct all the
		plugin files into the correct directory.
		
		.. warning:: Only available for python 2.6 and later.
		
		Return ``True`` if the installation is a success, ``False`` if
		it is a failure.
		"""
        if not os.path.isfile(plugin_ZIP_filename):
            log.warning("Could not find the plugin's zip file at '%s'." %
                        plugin_ZIP_filename)
            return False
        try:
            candidateZipFile = zipfile.ZipFile(plugin_ZIP_filename)
            first_bad_file = candidateZipFile.testzip()
            if first_bad_file:
                raise Exception("Corrupted ZIP with first bad file '%s'" %
                                first_bad_file)
        except Exception as e:
            log.warning("Invalid zip file '%s' (error: %s)." %
                        (plugin_ZIP_filename, e))
            return False
        zipContent = candidateZipFile.namelist()
        log.info("Investigating the content of a zip file containing: '%s'" %
                 zipContent)
        log.info(
            "Sanity checks on zip's contained files (looking for hazardous path symbols)."
        )
        # check absence of root path and ".." shortcut that would
        # send the file oustide the desired directory
        for containedFileName in zipContent:
            # WARNING: the sanity checks below are certainly not
            # exhaustive (maybe we could do something a bit smarter by
            # using os.path.expanduser, os.path.expandvars and
            # os.path.normpath)
            if containedFileName.startswith("/"):
                log.warning(
                    "Unsecure zip file, rejected because one of its file paths ('%s') starts with '/'"
                    % containedFileName)
                return False
            if containedFileName.startswith(
                    r"\\") or containedFileName.startswith("//"):
                log.warning(
                    r"Unsecure zip file, rejected because one of its file paths ('%s') starts with '\\'"
                    % containedFileName)
                return False
            if os.path.splitdrive(containedFileName)[0]:
                log.warning(
                    "Unsecure zip file, rejected because one of its file paths ('%s') starts with a drive letter"
                    % containedFileName)
                return False
            if os.path.isabs(containedFileName):
                log.warning(
                    "Unsecure zip file, rejected because one of its file paths ('%s') is absolute"
                    % containedFileName)
                return False
            pathComponent = os.path.split(containedFileName)
            if ".." in pathComponent:
                log.warning(
                    "Unsecure zip file, rejected because one of its file paths ('%s') contains '..'"
                    % containedFileName)
                return False
            if "~" in pathComponent:
                log.warning(
                    "Unsecure zip file, rejected because one of its file paths ('%s') contains '~'"
                    % containedFileName)
                return False
        infoFileCandidates = [
            filename for filename in zipContent
            if os.path.dirname(filename) == ""
        ]
        if not infoFileCandidates:
            log.warning(
                "Zip file structure seems wrong in '%s', no info file found." %
                plugin_ZIP_filename)
            return False
        isValid = False
        log.info("Looking for the zipped plugin's info file among '%s'" %
                 infoFileCandidates)
        for infoFileName in infoFileCandidates:
            infoFile = candidateZipFile.read(infoFileName)
            log.info("Assuming the zipped plugin info file to be '%s'" %
                     infoFileName)
            pluginName, moduleName, _ = self._getPluginNameAndModuleFromStream(
                io.StringIO(str(infoFile, encoding="utf-8")))
            if moduleName is None:
                continue
            log.info(
                "Checking existence of the expected module '%s' in the zip file"
                % moduleName)
            if moduleName in zipContent or os.path.join(
                    moduleName, "__init__.py") in zipContent:
                isValid = True
                break
        if not isValid:
            log.warning(
                "Zip file structure seems wrong in '%s', "
                "could not match info file with the implementation of plugin '%s'."
                % (plugin_ZIP_filename, pluginName))
            return False
        else:
            try:
                candidateZipFile.extractall(self.install_dir)
                return True
            except Exception as e:
                log.error(
                    "Could not install plugin '%s' from zip file '%s' (exception: '%s')."
                    % (pluginName, plugin_ZIP_filename, e))
                return False
Exemplo n.º 5
0
	def installFromZIP(self, plugin_ZIP_filename):
		"""
		Giving the plugin's zip file (e.g. ``myplugin.zip``), check
		that their is a valid info file in it and correct all the
		plugin files into the correct directory.
		
		.. warning:: Only available for python 2.6 and later.
		
		Return ``True`` if the installation is a success, ``False`` if
		it is a failure.
		"""
		if not os.path.isfile(plugin_ZIP_filename):
			log.warning("Could not find the plugin's zip file at '%s'." % plugin_ZIP_filename)
			return False
		try:
			candidateZipFile = zipfile.ZipFile(plugin_ZIP_filename)
			first_bad_file = candidateZipFile.testzip()
			if first_bad_file:
				raise Exception("Corrupted ZIP with first bad file '%s'" % first_bad_file)
		except Exception as e:
			log.warning("Invalid zip file '%s' (error: %s)." % (plugin_ZIP_filename,e))
			return False
		zipContent = candidateZipFile.namelist()
		log.info("Investigating the content of a zip file containing: '%s'" % zipContent)
		log.info("Sanity checks on zip's contained files (looking for hazardous path symbols).")	
		# check absence of root path and ".." shortcut that would
		# send the file oustide the desired directory
		for containedFileName in zipContent:
			# WARNING: the sanity checks below are certainly not
			# exhaustive (maybe we could do something a bit smarter by
			# using os.path.expanduser, os.path.expandvars and
			# os.path.normpath)
			if containedFileName.startswith("/"):
				log.warning("Unsecure zip file, rejected because one of its file paths ('%s') starts with '/'" % containedFileName)
				return False
			if containedFileName.startswith(r"\\") or containedFileName.startswith("//"):
				log.warning(r"Unsecure zip file, rejected because one of its file paths ('%s') starts with '\\'" % containedFileName)
				return False
			if os.path.splitdrive(containedFileName)[0]:
				log.warning("Unsecure zip file, rejected because one of its file paths ('%s') starts with a drive letter" % containedFileName)
				return False
			if os.path.isabs(containedFileName):
				log.warning("Unsecure zip file, rejected because one of its file paths ('%s') is absolute" % containedFileName)
				return False
			pathComponent = os.path.split(containedFileName)
			if ".." in pathComponent:
				log.warning("Unsecure zip file, rejected because one of its file paths ('%s') contains '..'" % containedFileName)	
				return False
			if "~" in pathComponent:
				log.warning("Unsecure zip file, rejected because one of its file paths ('%s') contains '~'" % containedFileName)	
				return False
		infoFileCandidates = [filename for filename in zipContent if os.path.dirname(filename)==""]
		if not infoFileCandidates:
			log.warning("Zip file structure seems wrong in '%s', no info file found." % plugin_ZIP_filename)
			return False
		isValid = False
		log.info("Looking for the zipped plugin's info file among '%s'" % infoFileCandidates)
		for infoFileName in infoFileCandidates:
			infoFile = candidateZipFile.read(infoFileName)
			log.info("Assuming the zipped plugin info file to be '%s'" % infoFileName)
			pluginName,moduleName,_ = self._getPluginNameAndModuleFromStream(io.StringIO(str(infoFile,encoding="utf-8")))
			if moduleName is None:
					continue
			log.info("Checking existence of the expected module '%s' in the zip file" % moduleName)
			if moduleName in zipContent or os.path.join(moduleName,"__init__.py") in zipContent:
				isValid = True
				break
		if not isValid:
			log.warning("Zip file structure seems wrong in '%s', "
							"could not match info file with the implementation of plugin '%s'." % (plugin_ZIP_filename,pluginName))
			return False
		else:
			try:
				candidateZipFile.extractall(self.install_dir)
				return True
			except Exception as e:
				log.error("Could not install plugin '%s' from zip file '%s' (exception: '%s')." % (pluginName,plugin_ZIP_filename,e))
				return False
Exemplo n.º 6
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)