예제 #1
0
 def setPluginPlaces(self, directories_list):
     """
     DEPRECATED(>1.9): kept for backward compatibility
     with existing PluginManager child classes.
     
     Set the list of directories where to look for plugin places.
     """
     log.warning(
         "setPluginPlaces was called but '%s' doesn't implement it." % self)
예제 #2
0
 def getPluginInfoClass(self):
     """
     DEPRECATED(>1.9): kept for backward compatibility
     with existing PluginManager child classes.
     
     Get the class that holds PluginInfo.
     """
     log.warning(
         "getPluginInfoClass was called but '%s' doesn't implement it." %
         self)
     return None
예제 #3
0
 def setPluginInfoClass(self, picls, names=None):
     """
     DEPRECATED(>1.9): kept for backward compatibility
     with existing PluginManager child classes.
     
     Set the class that holds PluginInfo. The class should inherit
     from ``PluginInfo``.
     """
     log.warning(
         "setPluginInfoClass was called but '%s' doesn't implement it." %
         self)
예제 #4
0
 def getPluginNameAndModuleFromStream(self, fileobj):
     """
     DEPRECATED(>1.9): kept for backward compatibility
     with existing PluginManager child classes.
     
     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)``.
     """
     log.warning(
         "setPluginInfoClass was called but '%s' doesn't implement it." %
         self)
     return None, None, None
예제 #5
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
예제 #6
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(
                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)
            candidate_module_paths = [
                moduleName,
                # Try path consistent with the platform specific one
                os.path.join(moduleName, "__init__.py"),
                # Try typical paths (unix and windows)
                "%s/__init__.py" % moduleName,
                "%s\\__init__.py" % moduleName
            ]
            for candidate in candidate_module_paths:
                if candidate in zipContent:
                    isValid = True
                    break
            if isValid:
                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