Example #1
0
    def executeScript(self, fileName, autoDelete=True, optional=False, encoding="utf-8"):
        """
        Executes the given script for configuration proposes and deletes the file afterwards (by default).

        Returns True when the file was found and processed.

        """

        if not os.path.exists(fileName):
            if optional:
                return False
            else:
                raise UserError("Could not find configuration script: %s" % fileName)

        env = {
            "config" : self,
            "file" : File
        }

        code = open(fileName, "r", encoding=encoding).read()
        exec(compile(code, os.path.abspath(fileName), "exec"), globals(), env)

        if autoDelete:
            File.rm(fileName)

        return True
Example #2
0
    def executeScript(self,
                      fileName,
                      autoDelete=True,
                      optional=False,
                      encoding="utf-8"):
        """
        Executes the given script for configuration proposes and deletes the file afterwards (by default).

        Returns True when the file was found and processed.

        """

        if not os.path.exists(fileName):
            if optional:
                return False
            else:
                raise UserError("Could not find configuration script: %s" %
                                fileName)

        env = {"config": self, "file": File}

        code = open(fileName, "r", encoding=encoding).read()
        exec(compile(code, os.path.abspath(fileName), "exec"), globals(), env)

        if autoDelete:
            File.rm(fileName)

        return True
Example #3
0
    def readQuestions(self, fileName, force=False, autoDelete=True, optional=False, encoding="utf-8"):
        """
        Reads the given configuration file with questions and deletes the file afterwards (by default).
        Returns True when the file was found and processed.
        """

        configFile = findConfig(fileName)
        if configFile is None:
            if optional:
                return False
            else:
                raise UserError("Could not find configuration file (questions): %s" % configFile)

        data = loadConfig(configFile, encoding=encoding)
        for entry in data:
            question = entry["question"]
            name = entry["name"]

            accept = getKey(entry, "accept", None)
            required = getKey(entry, "required", True)
            default = getKey(entry, "default", None)
            force = getKey(entry, "force", False)

            self.ask(question, name, accept=accept, required=required, default=default, force=force)

        if autoDelete:
            File.rm(configFile)

        return True
Example #4
0
File: Project.py Project: E01T/jasy
    def __init__(self, path, config=None, version=None):
        """
        Constructor call of the project. 

        - First param is the path of the project relative to the current working directory.
        - Config can be read from jasyproject.json or using constructor parameter @config
        - Parent is used for structural debug messages (dependency trees)
        """

        if not os.path.isdir(path):
            raise UserError("Invalid project path: %s" % path)

        # Only store and work with full path
        self.__path = os.path.abspath(os.path.expanduser(path))

        # Store given params
        self.version = version

        # Intialize item registries
        self.classes = {}
        self.assets = {}
        self.docs = {}
        self.translations = {}

        # Load project configuration
        self.__config = Config.Config(config)
        self.__config.loadValues(os.path.join(self.__path, "jasyproject"), optional=True)

        # Initialize cache
        try:
            File.mkdir(os.path.join(self.__path, ".jasy"))
            self.__cache = jasy.core.Cache.Cache(self.__path, filename=".jasy/cache")
        except IOError as err:
            raise UserError(
                "Could not initialize project. Cache file in %s could not be initialized! %s" % (self.__path, err)
            )

        # Detect version changes
        if version is None:
            self.__modified = True
        else:
            cachedVersion = self.__cache.read("project[version]")
            self.__modified = cachedVersion != version
            self.__cache.store("project[version]", version)

        # Read name from manifest or use the basename of the project's path
        self.__name = self.__config.get("name", getProjectNameFromPath(self.__path))

        # Read requires
        self.__requires = self.__config.get("requires", {})

        # Defined whenever no package is defined and classes/assets are not stored in the toplevel structure.
        self.__package = self.__config.get("package", self.__name if self.__config.has("name") else None)

        # Read fields (for injecting data into the project and build permutations)
        self.__fields = self.__config.get("fields", {})

        # Read setup for running command pre-scan
        self.__setup = self.__config.get("setup")
Example #5
0
    def getPath(self):
        """Returns the exact position of the class file in the file system."""

        # Automatically write file (from eventually processed text content) when it does not exist
        if self.__text is not None and not File.exists(self.__path):
            File.write(self.__path, self.getText())

        return self.__path
Example #6
0
    def getPath(self):
        """Returns the exact position of the class file in the file system."""

        # Automatically write file (from eventually processed text content) when it does not exist
        if self.__text is not None and not File.exists(self.__path):
            File.write(self.__path, self.getText())

        return self.__path
Example #7
0
    def saveText(self, text, path, encoding="utf-8"):
        """
        Saves the given text under the given path and stores both for future access

        This is mainly useful for "virtual" files which are not edited by the developer
        but which are created dynamically during runtime.
        """

        self.__text = text
        self.__path = path

        if not File.exists(path) or File.read(path) != text:
            File.write(path, text)

        self.mtime = os.stat(path).st_mtime
Example #8
0
    def saveText(self, text, path, encoding="utf-8"):
        """
        Saves the given text under the given path and stores both for future access.

        This is mainly useful for "virtual" files which are not edited by the developer but which are created
        dynamically during runtime.

        """

        self.__text = text
        self.__path = path

        if not File.exists(path) or File.read(path) != text:
            File.write(path, text)

        self.mtime = os.stat(path).st_mtime
Example #9
0
    def readQuestions(self,
                      fileName,
                      force=False,
                      autoDelete=True,
                      optional=False,
                      encoding="utf-8"):
        """
        Reads the given configuration file with questions and deletes the file afterwards (by default).

        Returns True when the file was found and processed.

        """

        configFile = findConfig(fileName)
        if configFile is None:
            if optional:
                return False
            else:
                raise UserError(
                    "Could not find configuration file (questions): %s" %
                    configFile)

        data = loadConfig(configFile, encoding=encoding)
        for entry in data:
            question = entry["question"]
            name = entry["name"]

            accept = getKey(entry, "accept", None)
            required = getKey(entry, "required", True)
            default = getKey(entry, "default", None)
            force = getKey(entry, "force", False)

            self.ask(question,
                     name,
                     accept=accept,
                     required=required,
                     default=default,
                     force=force)

        if autoDelete:
            File.rm(configFile)

        return True
Example #10
0
    def copyAssets(self):
        """
        Copies assets from their source folder to the configured destination folder.

        Does apply file name transformations during copying when requested.

        """

        Console.info("Copying assets...")

        counter = 0
        for assetItem in self.__copylist:
            srcFile = assetItem.getPath()
            dstFile = self.__computeDestinationPath(assetItem)

            if File.syncfile(srcFile, dstFile):
                counter += 1

        Console.info("Copied %s assets.", counter)
Example #11
0
    def copyAssets(self):
        """
        Copies assets from their source folder to the configured destination folder.

        Does apply file name transformations during copying when requested.

        """

        Console.info("Copying assets...")

        counter = 0
        for assetItem in self.__copylist:
            srcFile = assetItem.getPath()
            dstFile = self.__computeDestinationPath(assetItem)

            if File.syncfile(srcFile, dstFile):
                counter += 1

        Console.info("Copied %s assets.", counter)
Example #12
0
	def postProcess(self, parsed, filename, languages):
		for key, value in parsed.items():
			if type(value) is str:
				parsed[key] = self.__fixJasyCommands(value)

		if "slug" in parsed:
			parsed["slug"] = Util.fixSlug(parsed["slug"])
		else:
			parsed["slug"] = Util.fixSlug(parsed["title"])

		parsed["content"] = Util.fixCoreTemplating(parsed["content"])

		if not "status" in parsed:
			parsed["status"] = "published"
		if not "pos" in parsed:
			parsed["pos"] = 0
		else:
			parsed["pos"] = int(parsed["pos"])

		if not "lang" in parsed:
			parsed["lang"] = self.__defaultLanguage

		if parsed["lang"] not in languages:
			languages.append(parsed["lang"])

		# Add modification time and short hash
		parsed["mtime"] = os.path.getmtime(filename)
		parsed["hash"] = File.sha1(filename)[0:8]

		# Create simple boolean flag for publish state check
		parsed["publish"] = parsed["status"] == "published"

		# Parse date if available
		if "date" in parsed:
			parsed["date"] = dateutil.parser.parse(parsed["date"]).replace(tzinfo=dateutil.tz.tzlocal())

		return parsed
Example #13
0
    def write(self, distFolder, classFilter=None, callback="apiload", showInternals=False, showPrivates=False, printErrors=True, highlightCode=True):
        """
        Writes API data generated from JavaScript into distFolder

        :param distFolder: Where to store the API data
        :param classFilter: Tuple of classes or method to use for filtering
        :param callback: Name of callback to use for loading or None if pure JSON should be used
        :param showInternals: Include internal methods inside API data
        :param showPrivates: Include private methods inside API data
        :param printErrors: Whether errors should be printed to the console
        :param highlightCode: Whether to enable code highlighting using Pygments 

        :type distFolder: str
        :type classFilter: tuple or function
        :type callback: function
        :type showInternals: bool
        :type showPrivates: bool
        :type printErrors: bool
        :type highlightCode: bool
        """
        
        #
        # Collecting
        #
        
        Console.info("Collecting API Data...")
        Console.indent()
        
        apiData = {}
        highlightedCode = {}
        
        for project in self.__session.getProjects():
            classes = project.getClasses()
            Console.info("Loading API of project %s: %s...", Console.colorize(project.getName(), "bold"), Console.colorize("%s classes" % len(classes), "cyan"))
            Console.indent()
            for className in classes:
                if self.__isIncluded(className, classFilter):

                    data = classes[className].getApi(highlightCode)

                    if not data.isEmpty:
                        apiData[className] = data
                        highlightedCode[className] = classes[className].getHighlightedCode()
                
                    else:
                        Console.info("Skipping %s, class is empty." % className)

            Console.outdent()
        
        Console.outdent()

        
        #
        # Processing
        #
        
        Console.info("Processing API Data...")
        Console.indent()
        
        data, index, search = self.__process(apiData, classFilter=classFilter, internals=showInternals, privates=showPrivates, printErrors=printErrors, highlightCode=highlightCode)
        
        Console.outdent()
        
        
        
        #
        # Writing
        #

        Console.info("Storing API data...")
        Console.indent()

        writeCounter = 0
        extension = "js" if callback else "json"
        compress = True


        class JsonEncoder(json.JSONEncoder):
            def default(self, obj):
                if isinstance(obj, set):
                    return list(obj)
                    
                return json.JSONEncoder.default(self, obj)


        def encode(content, name):

            if compress:
                jsonContent = json.dumps(content, sort_keys=True, cls=JsonEncoder, separators=(',',':'))
            else:
                jsonContent = json.dumps(content, sort_keys=True, cls=JsonEncoder, indent=2)

            if callback:
                return "%s(%s,'%s');" % (callback, jsonContent, name)
            else:
                return jsonContent


        Console.info("Saving class data (%s files)...", len(data))
        Console.indent()

        for className in data:
            try:
                classData = data[className]
                if type(classData) is dict:
                    classExport = classData
                else:
                    classExport = classData.export()

                File.write(self.__session.expandFileName(os.path.join(distFolder, "%s.%s" % (className, extension))), encode(classExport, className))
            except TypeError as writeError:
                Console.error("Could not write API data of: %s: %s", className, writeError)
                continue

        Console.outdent()

        if highlightCode:
            Console.info("Saving highlighted code (%s files)...", len(highlightedCode))
            Console.indent()

            for className in highlightedCode:
                try:
                    File.write(self.__session.expandFileName(os.path.join(distFolder, "%s.html" % className)), highlightedCode[className])
                except TypeError as writeError:
                    Console.error("Could not write highlighted code of: %s: %s", className, writeError)
                    continue

            Console.outdent()

        Console.info("Writing index...")

        Console.indent()
        File.write(self.__session.expandFileName(os.path.join(distFolder, "meta-index.%s" % extension)), encode(index, "meta-index"))
        File.write(self.__session.expandFileName(os.path.join(distFolder, "meta-search.%s" % extension)), encode(search, "meta-search"))
        Console.outdent()
        
        Console.outdent()
Example #14
0
 def getChecksum(self, mode="rb"):
     """Returns the SHA1 checksum of the item"""
     
     return File.sha1(open(self.getPath(), mode))
Example #15
0
    def write(self,
              distFolder,
              classFilter=None,
              callback="apiload",
              showInternals=False,
              showPrivates=False,
              printErrors=True,
              highlightCode=True):
        """
        Writes API data generated from JavaScript into distFolder.

        :param distFolder: Where to store the API data
        :param classFilter: Tuple of classes or method to use for filtering
        :param callback: Name of callback to use for loading or None if pure JSON should be used
        :param showInternals: Include internal methods inside API data
        :param showPrivates: Include private methods inside API data
        :param printErrors: Whether errors should be printed to the console
        :param highlightCode: Whether to enable code highlighting using Pygments

        :type distFolder: str
        :type classFilter: tuple or function
        :type callback: function
        :type showInternals: bool
        :type showPrivates: bool
        :type printErrors: bool
        :type highlightCode: bool

        """

        #
        # Collecting
        #

        Console.info("Collecting API Data...")
        Console.indent()

        apiData = {}
        highlightedCode = {}

        for project in self.__session.getProjects():
            classes = project.getScripts()

            Console.info("Loading API of project %s: %s...",
                         Console.colorize(project.getName(), "bold"),
                         Console.colorize("%s classes" % len(classes), "cyan"))
            Console.indent()

            for className in classes:
                if self.__isIncluded(className, classFilter):

                    data = classes[className].getApi(highlightCode)

                    if not data.isEmpty:
                        apiData[className] = data
                        highlightedCode[className] = classes[
                            className].getHighlightedCode()

                    else:
                        Console.info("Skipping %s, class is empty." %
                                     className)

            Console.outdent()

        Console.outdent()

        #
        # Processing
        #

        Console.info("Processing API Data...")
        Console.indent()

        data, index, search = self.__process(apiData,
                                             classFilter=classFilter,
                                             internals=showInternals,
                                             privates=showPrivates,
                                             printErrors=printErrors,
                                             highlightCode=highlightCode)

        Console.outdent()

        #
        # Writing
        #

        Console.info("Storing API data...")
        Console.indent()

        writeCounter = 0
        extension = "js" if callback else "json"
        compress = True

        class JsonEncoder(json.JSONEncoder):
            def default(self, obj):
                if isinstance(obj, set):
                    return list(obj)

                return json.JSONEncoder.default(self, obj)

        def encode(content, name):

            if compress:
                jsonContent = json.dumps(content,
                                         sort_keys=True,
                                         cls=JsonEncoder,
                                         separators=(',', ':'))
            else:
                jsonContent = json.dumps(content,
                                         sort_keys=True,
                                         cls=JsonEncoder,
                                         indent=2)

            if callback:
                return "%s(%s,'%s');" % (callback, jsonContent, name)
            else:
                return jsonContent

        Console.info("Saving class data (%s files)...", len(data))
        Console.indent()

        for className in data:
            try:
                classData = data[className]
                if isinstance(classData, dict):
                    classExport = classData
                else:
                    classExport = classData.export()

                File.write(
                    self.__profile.expandFileName(
                        os.path.join(distFolder,
                                     "%s.%s" % (className, extension))),
                    encode(classExport, className))
            except TypeError as writeError:
                Console.error("Could not write API data of: %s: %s", className,
                              writeError)
                continue

        Console.outdent()

        if highlightCode:
            Console.info("Saving highlighted code (%s files)...",
                         len(highlightedCode))
            Console.indent()

            for className in highlightedCode:
                try:
                    File.write(
                        self.__profile.expandFileName(
                            os.path.join(distFolder, "%s.html" % className)),
                        highlightedCode[className])
                except TypeError as writeError:
                    Console.error(
                        "Could not write highlighted code of: %s: %s",
                        className, writeError)
                    continue

            Console.outdent()

        Console.info("Writing index...")

        Console.indent()
        File.write(
            self.__profile.expandFileName(
                os.path.join(distFolder, "meta-index.%s" % extension)),
            encode(index, "meta-index"))
        File.write(
            self.__profile.expandFileName(
                os.path.join(distFolder, "meta-search.%s" % extension)),
            encode(search, "meta-search"))
        Console.outdent()

        Console.outdent()
Example #16
0
 def getChecksum(self):
     return File.sha1(self.fp)
Example #17
0
 def getChecksum(self):
     return File.sha1(self.fp)
Example #18
0
    def getChecksum(self, mode="rb"):
        """Returns the SHA1 checksum of the item."""

        return File.sha1(open(self.getPath(), mode))
Example #19
0
    def __init__(self, path, config=None, version=None):
        """
        Constructor call of the project. 

        - First param is the path of the project relative to the current working directory.
        - Config can be read from jasyproject.json or using constructor parameter @config
        - Parent is used for structural debug messages (dependency trees)
        """

        if not os.path.isdir(path):
            raise UserError("Invalid project path: %s" % path)

        # Only store and work with full path
        self.__path = os.path.abspath(os.path.expanduser(path))

        # Store given params
        self.version = version

        # Intialize item registries
        self.classes = {}
        self.assets = {}
        self.docs = {}
        self.translations = {}

        # Load project configuration
        self.__config = Config.Config(config)
        self.__config.loadValues(os.path.join(self.__path, "jasyproject"),
                                 optional=True)

        # Initialize cache
        try:
            File.mkdir(os.path.join(self.__path, ".jasy"))
            self.__cache = jasy.core.Cache.Cache(self.__path,
                                                 filename=".jasy/cache")
        except IOError as err:
            raise UserError(
                "Could not initialize project. Cache file in %s could not be initialized! %s"
                % (self.__path, err))

        # Detect version changes
        if version is None:
            self.__modified = True
        else:
            cachedVersion = self.__cache.read("project[version]")
            self.__modified = cachedVersion != version
            self.__cache.store("project[version]", version)

        # Read name from manifest or use the basename of the project's path
        self.__name = self.__config.get("name",
                                        getProjectNameFromPath(self.__path))

        # Read requires
        self.__requires = self.__config.get("requires", {})

        # Defined whenever no package is defined and classes/assets are not stored in the toplevel structure.
        self.__package = self.__config.get(
            "package", self.__name if self.__config.has("name") else None)

        # Read fields (for injecting data into the project and build permutations)
        self.__fields = self.__config.get("fields", {})

        # Read setup for running command pre-scan
        self.__setup = self.__config.get("setup")