jasy.core.Console.info

Here are the examples of the python api jasy.core.Console.info taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

46 Examples 7

Example 1

Project: jasy Source File: SpritePacker.py
Function: clear
    def clear(self):
        """
        Removes all generated sprite files found in the base directory
        """

        Console.info("Cleaning sprite files...")
        Console.indent()
        
        for dirPath, dirNames, fileNames in os.walk(self.base):
            for fileName in fileNames:
                if fileName.startswith("jasysprite"):
                    filePath = os.path.join(dirPath, fileName)
                    Console.debug("Removing file: %s", filePath)
                    os.remove(filePath)
        
        Console.outdent()

Example 2

Project: jasy Source File: SpritePacker.py
    def packDir(self, path='', recursive=True, autorotate=False, debug=False):
        """Pack images inside a dir into sprite sheets"""

        Console.info('Packing sprites in: %s' % os.path.join(self.base, path))
        Console.indent()
        
        self.files = []
        self.addDir(path, recursive=recursive)
        Console.info('Found %d images' % len(self.files))

        if len(self.files) > 0:
            self.generate(path, autorotate, debug)
            
        Console.outdent()

Example 3

Project: jasy Source File: FileManager.py
Function: remove_dir
    def removeDir(self, dirname):
        """Removes the given directory"""
        
        dirname = self.__session.expandFileName(dirname)
        if os.path.exists(dirname):
            Console.info("Deleting folder %s" % dirname)
            shutil.rmtree(dirname)

Example 4

Project: jasy Source File: FileManager.py
Function: remove_file
    def removeFile(self, filename):
        """Removes the given file"""
        
        filename = self.__session.expandFileName(filename)
        if os.path.exists(filename):
            Console.info("Deleting file %s" % filename)
            os.remove(filename)

Example 5

Project: jasy Source File: Locale.py
Function: export
    def export(self, path):
        Console.info("Writing result...")
        Console.info("Target directory: %s", path)
        Console.indent()
        
        jasy.core.File.write(os.path.join(path, "jasyproject.yaml"), 'name: locale\npackage: ""\n')
        count = self.__exportRecurser(self.__data, "locale", path)

        Console.info("Created %s classes", count)
        Console.outdent()

Example 6

Project: jasy Source File: Session.py
Function: clean
    def clean(self):
        """Clears all caches of all registered projects"""

        if not self.__projects:
            return

        Console.info("Cleaning session...")
        Console.indent()

        for project in self.__projects:
            project.clean()

        Console.outdent()

Example 7

Project: jasy Source File: Session.py
Function: pause
    def pause(self):
        """
        Pauses the session. This release cache files etc. and makes 
        it possible to call other jasy processes on the same projects.
        """
        
        Console.info("Pausing session...")

        for project in self.__projects:
            project.pause()

Example 8

Project: jasy Source File: Session.py
Function: resume
    def resume(self):
        """Resumes the session after it has been paused."""

        Console.info("Resuming session...")

        for project in self.__projects:
            project.resume()

Example 9

Project: jasy Source File: Context.py
@task
def about():
    """Print outs the Jasy about page"""

    import jasy

    jasy.info()

    from jasy.env.Task import getCommand

    Console.info("Command: %s", getCommand())
    Console.info("Version: %s", jasy.__version__)

Example 10

Project: jasy Source File: Context.py
@task
def showapi():
    """Shows the official API available in jasyscript.py"""

    from jasy.core.Inspect import generateApi
    Console.info(generateApi(__api__))

Example 11

Project: jasy Source File: Server.py
    def __init__(self, id, config):
        self.id = id
        self.config = config
        self.host = getKey(config, "host")
        self.auth = getKey(config, "auth")
        
        self.enableDebug = getKey(config, "debug", False)
        self.enableMirror = getKey(config, "mirror", False)
        self.enableOffline = getKey(config, "offline", False)

        if self.enableMirror:
            self.mirror = Cache.Cache(os.getcwd(), ".jasy/mirror-%s" % self.id, hashkeys=True)

        Console.info('Proxy "%s" => "%s" [debug:%s|mirror:%s|offline:%s]', self.id, self.host, self.enableDebug, self.enableMirror, self.enableOffline)

Example 12

Project: jasy Source File: Server.py
    def __init__(self, id, config, mimeTypes=None):
        self.id = id
        self.config = config
        self.mimeTypes = mimeTypes
        self.root = getKey(config, "root", ".")
        self.enableDebug = getKey(config, "debug", False)

        Console.info('Static "%s" => "%s" [debug:%s]', self.id, self.root, self.enableDebug)

Example 13

Project: jasy Source File: Server.py
Function: start
    def start(self):
        """
        Starts the web server and blocks execution. 

        Note: This stops further execution of the current task or method.
        """

        app = cherrypy.tree.mount(self.__root, "", self.__config)
        cherrypy.process.plugins.PIDFile(cherrypy.engine, ".jasy/server-%s" % self.__port).subscribe()
        
        cherrypy.engine.start()
        Console.info("Started HTTP server at port %s... [PID=%s]", self.__port, os.getpid())
        Console.indent()
        cherrypy.engine.block()

        Console.outdent()
        Console.info("Stopped HTTP server at port %s.", self.__port)  

Example 14

Project: jasy Source File: Manager.py
Function: init
    def __init__(self, session):

        Console.info("Initializing assets...")
        Console.indent()

        # Store session reference (one asset manager per session)
        self.__session = session

        # Stores manager contextual asset information (like relative paths)
        self.__data = {}
        
        # Registry for profiles aka asset groups
        self.__profiles = []
        
        # Loop though all projects and merge assets
        assets = self.__assets = {}
        for project in self.__session.getProjects():
            assets.update(project.getAssets())
        
        self.__processSprites()
        self.__processAnimations()
        
        Console.outdent()
        Console.info("Activated %s assets", len(assets))

Example 15

Project: jasy Source File: Manager.py
    def __processSprites(self):
        """Processes jasysprite.json files to merge sprite data into asset registry"""
        
        assets = self.__assets
        configs = [fileId for fileId in assets if assets[fileId].isImageSpriteConfig()]
        
        if configs:
            Console.info("Processing %s image sprite configs...", len(configs))
        
        sprites = []
        Console.indent()
        for fileId in configs:
            Console.debug("Processing %s...", fileId)
            
            asset = assets[fileId]
            spriteBase = os.path.dirname(fileId)
                
            try:
                spriteConfig = asset.getParsedObject();
            except ValueError as err:
                raise UserError("Could not parse jasysprite.json at %s: %s" % (fileId, err))
                
            Console.indent()
            for spriteImage in spriteConfig:
                spriteImageId = "%s/%s" % (spriteBase, spriteImage)
                
                singleRelPaths = spriteConfig[spriteImage]
                Console.debug("Image %s combines %s images", spriteImageId, len(singleRelPaths))

                for singleRelPath in singleRelPaths:
                    singleId = "%s/%s" % (spriteBase, singleRelPath)
                    singleData = singleRelPaths[singleRelPath]

                    if singleId in assets:
                        singleAsset = assets[singleId]
                    else:
                        Console.info("Creating new asset: %s", singleId)
                        singleAsset = jasy.item.Asset.AssetItem(None)
                        assets[singleId] = singleAsset
                        
                    if not spriteImageId in sprites:
                        spriteImageIndex = len(sprites) 
                        sprites.append(spriteImageId)
                    else:
                        spriteImageIndex = sprites.index(spriteImageId)
                        
                    singleAsset.addImageSpriteData(spriteImageIndex, singleData["left"], singleData["top"])
                    
                    if "width" in singleData and "height" in singleData:
                        singleAsset.addImageDimensionData(singleData["width"], singleData["height"])
                    
                    # Verify that sprite sheet is up-to-date
                    if "checksum" in singleData:
                        fileChecksum = singleAsset.getChecksum()
                        storedChecksum = singleData["checksum"]
                        
                        Console.debug("Checksum Compare: %s <=> %s", fileChecksum[0:6], storedChecksum[0:6])
                        
                        if storedChecksum != fileChecksum:
                            raise UserError("Sprite Sheet is not up-to-date. Checksum of %s differs.", singleId)
        
            Console.outdent()
            Console.debug("Deleting sprite config from assets: %s", fileId)
            del assets[fileId]
            
        Console.outdent()
        self.__sprites = sprites

Example 16

Project: jasy Source File: Manager.py
    def __processAnimations(self):
        """Processes jasyanimation.json files to merge animation data into asset registry"""
        
        assets = self.__assets
        configs = [fileId for fileId in assets if assets[fileId].isImageAnimationConfig()]
        
        if configs:
            Console.info("Processing %s image animation configs...", len(configs))
        
        Console.indent()
        for fileId in configs:
            Console.debug("Processing %s...", fileId)
        
            asset = assets[fileId]
            base = os.path.dirname(fileId)
                
            try:
                config = json.loads(asset.getText())
            except ValueError as err:
                raise UserError("Could not parse jasyanimation.json at %s: %s" % (fileId, err))
            
            for relPath in config:
                imageId = "%s/%s" % (base, relPath)
                data = config[relPath]
                
                if not imageId in assets:
                    raise UserError("Unknown asset %s in %s" % (imageId, fileId))
                
                animationAsset = assets[imageId]
                
                if "rows" in data or "columns" in data:
                    rows = Util.getKey(data, "rows", 1)
                    columns = Util.getKey(data, "columns", 1)
                    frames = Util.getKey(data, "frames")
                    
                    animationAsset.addImageAnimationData(columns, rows, frames)
                    
                    if frames is None:
                        frames = rows * columns
                    
                elif "layout" in data:
                    layout = data["layout"]
                    animationAsset.addImageAnimationData(None, None, layout=layout)
                    frames = len(layout)
                    
                else:
                    raise UserError("Invalid image frame data for: %s" % imageId)

                Console.debug("  - Animation %s has %s frames", imageId, frames)

            Console.debug("  - Deleting animation config from assets: %s", fileId)
            del assets[fileId]
            
        Console.outdent()

Example 17

Project: jasy Source File: Manager.py
Function: deploy
    def deploy(self, classes, assetFolder=None):
        """
        Deploys all asset files to the destination asset folder. This merges
        assets from different projects into one destination folder.
        """

        # Sometimes it's called with explicit None - we want to fill the default
        # in that case as well.
        if assetFolder is None:
            assetFolder = "$prefix/asset"

        assets = self.__assets
        projects = self.__session.getProjects()

        copyAssetFolder = self.__session.expandFileName(assetFolder)
        filterExpr = self.__compileFilterExpr(classes)
        
        Console.info("Deploying assets...")
        
        counter = 0
        length = len(assets)
        
        for fileId in assets:
            if not filterExpr.match(fileId):
                length -= 1
                continue

            srcFile = assets[fileId].getPath()
            dstFile = os.path.join(copyAssetFolder, fileId.replace("/", os.sep))
            
            if jasy.core.File.syncfile(srcFile, dstFile):
                counter += 1
        
        Console.info("Updated %s/%s files" % (counter, length))

Example 18

Project: jasy Source File: Manager.py
Function: export
    def export(self, classes=None):
        """
        Exports asset data for usage at the client side. Utilizes JavaScript
        class jasy.Asset to inject data into the client at runtime.
        """
        
        # Processing assets
        assets = self.__assets
        data = self.__data
        
        result = {}
        filterExpr = self.__compileFilterExpr(classes) if classes else None
        for fileId in assets:
            if filterExpr and not filterExpr.match(fileId):
                continue
            
            entry = {}
            
            asset = assets[fileId]
            entry["t"] = asset.getType(short=True)

            assetData = asset.exportData()
            if assetData:
                entry["d"] = assetData
            
            if fileId in data:
                entry.update(data[fileId])
                
            result[fileId] = entry
        
        # Ignore empty result
        if not result:
            return None

        Console.info("Exported %s assets", len(result))

        return json.dumps({
            "assets" : self.__structurize(result),
            "profiles" : self.__profiles,
            "sprites" : self.__sprites
        }, indent=2)

Example 19

Project: jasy Source File: SpritePacker.py
    def generate(self, path='', autorotate=False, debug=False):
        """Generate sheets/variants"""
        
        Console.info('Generating sprite sheet variants...')
        Console.indent()
        
        sheets, count = self.packBest(autorotate)

        # Write PNG files
        data = {}
        for pos, sheet in enumerate(sheets):

            Console.info('Writing image (%dx%dpx) with %d images' % (sheet.width, sheet.height, len(sheet)))
            name = 'jasysprite_%d.png' % pos

            # Export
            sheet.write(os.path.join(self.base, path, name), debug)
            data[name] = sheet.export()
            
        Console.outdent()

        # Generate JSON/YAML
        Console.info('Exporting data...')
        script = os.path.join(self.base, path, 'jasysprite.%s' % self.dataFormat)
        writeConfig(data, script)

Example 20

Project: jasy Source File: Create.py
def massFilePatcher(path, data):
    
    # Convert method with access to local data
    def convertPlaceholder(mo):
        field = mo.group(1)
        value = data.get(field)

        # Verify that None means missing
        if value is None and not data.has(field):
            raise ValueError('No value for placeholder "%s"' % field)
    
        # Requires value being a string
        return str(value)
        
    # Patching files recursively
    Console.info("Patching files...")
    Console.indent()
    for dirPath, dirNames, fileNames in os.walk(path):
        relpath = os.path.relpath(dirPath, path)

        # Filter dotted directories like .git, .bzr, .hg, .svn, etc.
        for dirname in dirNames:
            if dirname.startswith("."):
                dirNames.remove(dirname)
        
        for fileName in fileNames:
            filePath = os.path.join(dirPath, fileName)
            fileRel = os.path.normpath(os.path.join(relpath, fileName))
            
            Console.debug("Processing: %s..." % fileRel)

            fileHandle = open(filePath, "r", encoding="utf-8", errors="surrogateescape")
            fileContent = []
            
            # Parse file line by line to detect binary files early and omit
            # fully loading them into memory
            try:
                isBinary = False

                for line in fileHandle:
                    if '\0' in line:
                        isBinary = True
                        break 
                    else:
                        fileContent.append(line)
        
                if isBinary:
                    Console.debug("Ignoring binary file: %s", fileRel)
                    continue

            except UnicodeDecodeError as ex:
                Console.warn("Can't process file: %s: %s", fileRel, ex)
                continue

            fileContent = "".join(fileContent)

            # Update content with available data
            try:
                resultContent = fieldPattern.sub(convertPlaceholder, fileContent)
            except ValueError as ex:
                Console.warn("Unable to process file %s: %s!", fileRel, ex)
                continue

            # Only write file if there where any changes applied
            if resultContent != fileContent:
                Console.info("Updating: %s...", Console.colorize(fileRel, "bold"))
                
                fileHandle = open(filePath, "w", encoding="utf-8", errors="surrogateescape")
                fileHandle.write(resultContent)
                fileHandle.close()
                
    Console.outdent()

Example 21

Project: jasy Source File: Create.py
def create(name="myproject", origin=None, originVersion=None, skeleton=None, destination=None, session=None, **argv):
    """
    Creates a new project from a defined skeleton or an existing project's root directory (only if there is a jasycreate.yaml/.json).

    :param name: The name of the new created project
    :type name: string
    :param origin: Path or git url to the base project
    :type origin: string
    :param originVersion: Version of the base project from wich will be created.
    :type originVersion: string
    :param skeleton: Name of a defined skeleton. None for creating from root
    :type skeleton: string
    :param destination: Destination path for the new created project
    :type destination: string
    :param session: An optional session to use as origin project
    :type session: object
    """

    if not validProjectName.match(name):
        raise UserError("Invalid project name: %s (Use lowercase characters and numbers only for broadest compabibility)" % name)


    #
    # Initial Checks
    #

    # Figuring out destination folder
    if destination is None:
        destination = name

    destinationPath = os.path.abspath(os.path.expanduser(destination))
    if os.path.exists(destinationPath):
        raise UserError("Cannot create project %s in %s. File or folder exists!" % (name, destinationPath))

    # Origin can be either:
    # 1) None, which means a skeleton from the current main project
    # 2) An repository URL
    # 3) A project name known inside the current session
    # 4) Relative or absolute folder path

    originPath = None;
    originName = None;

    if origin is None:
        originProject = session and session.getMain()

        if originProject is None:
            raise UserError("Auto discovery failed! No Jasy projects registered!")

        originPath = originProject.getPath()
        originName = originProject.getName()
        originRevision = None

    elif Repository.isUrl(origin):
        Console.info("Using remote skeleton")

        tempDirectory = tempfile.TemporaryDirectory()
        originPath = os.path.join(tempDirectory.name, "clone")
        originUrl = origin

        Console.indent()
        originRevision = Repository.update(originUrl, originVersion, originPath)
        Console.outdent()

        if originRevision is None:
            raise UserError("Could not clone origin repository!")

        Console.debug("Cloned revision: %s" % originRevision)
        if os.path.isfile(os.path.join(originPath, "jasycreate.yaml")) or os.path.isfile(os.path.join(originPath, "jasycreate.json")) or os.path.isfile(os.path.join(originPath, "jasycreate.py")):
            originProject = None
        else:
            originProject = getProjectFromPath(originPath)
            originName = originProject.getName()

    else:
        originProject = session and session.getProjectByName(origin)
        originVersion = None
        originRevision = None

        if originProject is not None:
            originPath = originProject.getPath()
            originName = origin

        elif os.path.isdir(origin):
            originPath = origin
            if os.path.isfile(os.path.join(originPath, "jasycreate.yaml")) or os.path.isfile(os.path.join(originPath, "jasycreate.json")) or os.path.isfile(os.path.join(originPath, "jasycreate.py")):
                originProject = None
            else:
                originProject = getProjectFromPath(originPath)
                originName = originProject.getName()

        else:
            raise UserError("Invalid value for origin: %s" % origin)


    # Figure out the skeleton root folder
    if originProject is not None:
        skeletonDir = os.path.join(originPath, originProject.getConfigValue("skeletonDir", "skeleton"))
    else:
        skeletonDir = originPath
    if not os.path.isdir(skeletonDir):
        raise UserError('The project %s offers no skeletons!' % originName)

    # For convenience: Use first skeleton in skeleton folder if no other selection was applied
    if skeleton is None:
        if originProject is not None:
            skeleton = getFirstSubFolder(skeletonDir)
        else:
            skeleton = skeletonDir

    # Finally we have the skeleton path (the root folder to copy for our app)
    skeletonPath = os.path.join(skeletonDir, skeleton)
    if not os.path.isdir(skeletonPath):
        raise UserError('Skeleton %s does not exist in project "%s"' % (skeleton, originName))


    #
    # Actual Work
    #

    # Prechecks done
    if originName:
        Console.info('Creating %s from %s %s...', Console.colorize(name, "bold"), Console.colorize(skeleton + " @", "bold"), Console.colorize(originName, "magenta"))
    else:
        Console.info('Creating %s from %s...', Console.colorize(name, "bold"), Console.colorize(skeleton, "bold"))
    Console.debug('Skeleton: %s', Console.colorize(skeletonPath, "grey"))
    Console.debug('Destination: %s', Console.colorize(destinationPath, "grey"))

    # Copying files to destination
    Console.info("Copying files...")
    shutil.copytree(skeletonPath, destinationPath)
    Console.debug("Files were copied successfully.")

    # Close origin project
    if originProject:
        originProject.close()

    # Change to directory before continuing
    os.chdir(destinationPath)

    # Create configuration file from question configs and custom scripts
    Console.info("Starting configuration...")
    config = Config()

    config.set("name", name)
    config.set("jasy.version", jasy.__version__)
    if originName:
        config.set("origin.name", originName)
    config.set("origin.version", originVersion)
    config.set("origin.revision", originRevision)
    config.set("origin.skeleton", os.path.basename(skeletonPath))

    config.injectValues(**argv)
    if originProject is not None:
        config.readQuestions("jasycreate", optional=True)
        config.executeScript("jasycreate.py", optional=True)

    # Do actual replacement of placeholders
    massFilePatcher(destinationPath, config)
    Console.debug("Files were patched successfully.")

    # Done
    Console.info('Your application %s was created successfully!', Console.colorize(name, "bold"))

Example 22

Project: jasy Source File: Daemon.py
Function: on_moved
        def on_moved(self, event):
            super(JasyEventHandler, self).on_moved(event)

            what = 'directory' if event.is_directory else 'file'
            Console.info("Moved %s: from %s to %s", what, event.src_path, event.dest_path)

Example 23

Project: jasy Source File: Daemon.py
Function: on_created
        def on_created(self, event):
            super(JasyEventHandler, self).on_created(event)

            what = 'directory' if event.is_directory else 'file'
            Console.info("Created %s: %s", what, event.src_path)

Example 24

Project: jasy Source File: Daemon.py
Function: on_deleted
        def on_deleted(self, event):
            super(JasyEventHandler, self).on_deleted(event)

            what = 'directory' if event.is_directory else 'file'
            Console.info("Deleted %s: %s", what, event.src_path)

Example 25

Project: jasy Source File: Daemon.py
Function: on_modified
        def on_modified(self, event):
            super(JasyEventHandler, self).on_modified(event)

            what = 'directory' if event.is_directory else 'file'
            Console.info("Modified %s: %s", what, event.src_path)

Example 26

Project: jasy Source File: Locale.py
    def __init__(self, locale):
        Console.info("Parsing CLDR files for %s..." % locale)
        Console.indent()

        splits = locale.split("_")

        # Store for internal usage
        self.__locale = locale
        self.__language = splits[0]
        self.__territory = splits[1] if len(splits) > 1 else None

        # This will hold all data extracted data
        self.__data = {}

        # Add info section
        self.__data["info"] = {
            "LOCALE" : self.__locale,
            "LANGUAGE" : self.__language,
            "TERRITORY" : self.__territory
        }

        # Add keys (fallback to C-default locale)
        path = "%s.xml" % os.path.join(CLDR_DIR, "keys", self.__language)
        try:
            Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
            tree = xml.etree.ElementTree.parse(path)
        except IOError:
            path = "%s.xml" % os.path.join(CLDR_DIR, "keys", "C")
            Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
            tree = xml.etree.ElementTree.parse(path)
            
        self.__data["key"] = {
            "Short" : { key.get("type"): key.text for key in tree.findall("./keys/short/key") },
            "Full" : { key.get("type"): key.text for key in tree.findall("./keys/full/key") }
        }
        
        # Add main CLDR data: Fallback chain for locales
        main = os.path.join(CLDR_DIR, "main")
        files = []
        while True:
            files.append("%s.xml" % os.path.join(main, locale))
            
            if "_" in locale:
                locale = locale[:locale.rindex("_")]
            else:
                break

        # Extend data with root data
        files.append(os.path.join(main, "root.xml"))

        # Finally import all these files in order
        for path in reversed(files):
            Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
            tree = xml.etree.ElementTree.parse(path)

            self.__addDisplayNames(tree)
            self.__addDelimiters(tree)
            self.__addCalendars(tree)
            self.__addNumbers(tree)  
                
        # Add supplemental CLDR data
        self.__addSupplementals(self.__territory)

        Console.outdent()

Example 27

Project: jasy Source File: Locale.py
    def __addSupplementals(self, territory):
        """ Converts data from supplemental folder """
        
        supplemental = os.path.join(CLDR_DIR, "supplemental")

        # Plurals
        path = os.path.join(supplemental, "plurals.xml")
        Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
        tree = xml.etree.ElementTree.parse(path)
        self.__data["Plural"] = {}
        for item in tree.findall("plurals/pluralRules"):
            attr = item.get("locales")
            if attr != None:
                if self.__language in attr.split(" "):
                    for rule in item.findall("pluralRule"):
                        jsPlural = pluralToJavaScript(rule.text)
                        self.__data["Plural"][rule.get("count").upper()] = jsPlural
        
        # Telephone Codes
        path = os.path.join(supplemental, "telephoneCodeData.xml")
        Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
        tree = xml.etree.ElementTree.parse(path)
        for item in tree.findall("telephoneCodeData/codesByTerritory"):
            territoryId = item.get("territory")
            if territoryId == territory:
                for rule in item.findall("telephoneCountryCode"):
                    self.__data["PhoneCode"] = {"CODE":int(rule.get("code"))}
                    # Respect first only
                    break
        
        # Postal Codes
        path = os.path.join(supplemental, "postalCodeData.xml")
        Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
        tree = xml.etree.ElementTree.parse(path)
        for item in tree.findall("postalCodeData/postCodeRegex"):
            territoryId = item.get("territoryId")
            if territory == territoryId:
                self.__data["PostalCode"] = {"CODE":item.text}
                break
        
        # Supplemental Data
        path = os.path.join(supplemental, "supplementalData.xml")
        Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
        tree = xml.etree.ElementTree.parse(path)
        
        # :: Calendar Preference
        ordering = None
        for item in tree.findall("calendarPreferenceData/calendarPreference"):
            if item.get("territories") == "001" and ordering == None:
                ordering = item.get("ordering")
            elif territory in item.get("territories").split(" "):
                ordering = item.get("ordering")
                break
        
        self.__data["CalendarPref"] = { "ORDERING" : ordering.split(" ") }
        
        # :: Week Data
        self.__data["Week"] = {}
        weekData = tree.find("weekData")
        for key in ["firstDay", "weekendStart", "weekendEnd"]:
            day = None
            for item in weekData.findall(key):
                if item.get("territories") == "001" and day == None:
                    day = item.get("day")
                elif territory in item.get("territories").split(" "):
                    day = item.get("day")
                    break
            
            self.__data["Week"][camelCaseToUpper(key)] = day

        # :: Measurement System
        self.__data["Measurement"] = {}
        measurementData = tree.find("measurementData")
        for key in ["measurementSystem", "paperSize"]:
            mtype = None
            for item in measurementData.findall(key):
                if item.get("territories") == "001" and mtype == None:
                    mtype = item.get("type")
                elif territory in item.get("territories").split(" "):
                    mtype = item.get("type")
                    break

            self.__data["Measurement"][camelCaseToUpper(key)] = mtype

Example 28

Project: jasy Source File: OutputManager.py
Function: init
    def __init__(self, session, assetManager=None, compressionLevel=1, formattingLevel=0):

        Console.info("Initializing OutputManager...")
        Console.indent()
        Console.info("Formatting Level: %s", formattingLevel)
        Console.info("Compression Level: %s", compressionLevel)

        self.__session = session

        self.__assetManager = assetManager
        self.__fileManager = FileManager(session)

        self.__scriptOptimization = Optimization()
        
        self.__compressGeneratedCode = False

        self.__kernelClasses = []

        if compressionLevel > 0:
            self.__scriptOptimization.enable("variables")
            self.__scriptOptimization.enable("declarations")
            
            self.__compressGeneratedCode = True

        if compressionLevel > 1:
            self.__scriptOptimization.enable("blocks")
            self.__scriptOptimization.enable("privates")

        self.__scriptFormatting = Formatting()

        if formattingLevel > 0:
            self.__scriptFormatting.enable("semicolon")
            self.__scriptFormatting.enable("comma")

        Console.outdent()

Example 29

Project: jasy Source File: OutputManager.py
    def deployAssets(self, classes, assetFolder=None):
        """
        Deploys assets for the given classes and all their dependencies

        :param classes: List of classes to deploy assets for
        :type classes: list
        :param assetFolder: Destination folder of assets (defaults to $prefix/asset)
        :type assetFolder: string
        """

        Console.info("Deploying assets...")
        Console.indent()

        resolver = Resolver(self.__session)

        for className in classes:
            resolver.addClassName(className)

        self.__assetManager.deploy(resolver.getIncludedClasses(), assetFolder=assetFolder)

        Console.outdent()

Example 30

Project: jasy Source File: OutputManager.py
    def storeKernel(self, fileName, classes=None, debug=False):
        """
        Writes a so-called kernel script to the given location. This script contains
        data about possible permutations based on current session values. It optionally
        might include asset data (useful when boot phase requires some assets) and 
        localization data (if only one locale is built).
        
        Optimization of the script is auto-enabled when no other information is given.
        
        This method returns the classes which are included by the script so you can 
        exclude it from the real other generated output files.
        """
        
        Console.info("Storing kernel...")
        Console.indent()
        
        # Use a new permutation based on debug settings and statically configured fields
        self.__session.setStaticPermutation(debug=debug)

        # Build resolver
        # We need the permutation here because the field configuration might rely on detection classes
        resolver = Resolver(self.__session)

        detectionClasses = self.__session.getFieldDetectionClasses()
        for className in detectionClasses:
            resolver.addClassName(className)

        # Jasy client side classes to hold data
        resolver.addClassName("jasy.Env")
        resolver.addClassName("jasy.Asset")
        resolver.addClassName("jasy.Translate")

        # Allow kernel level mass loading of scripts (required for source, useful for build)
        resolver.addClassName("core.io.Script")
        resolver.addClassName("core.io.Queue")

        if classes:
            for className in classes:
                resolver.addClassName(className)

        # Generate boot code 
        bootCode = "jasy.Env.setFields(%s);" % self.__session.exportFields()

        if self.__compressGeneratedCode:
            bootCode = packCode(bootCode)

        # Sort resulting class list
        sortedClasses = resolver.getSortedClasses()
        self.storeCompressed(sortedClasses, fileName, bootCode)
        
        # Remember classes for filtering in storeLoader/storeCompressed
        self.__kernelClasses = set(sortedClasses)

        # Reset static permutation
        self.__session.resetCurrentPermutation()

        Console.outdent()

Example 31

Project: jasy Source File: OutputManager.py
    def storeCompressed(self, classes, fileName, bootCode=None):
        """
        Combines the compressed result of the stored class list
        
        :param classes: List of sorted classes to compress
        :type classes: list
        :param fileName: Filename to write result to
        :type fileName: string
        :param bootCode: Code to execute once all the classes are loaded
        :type bootCode: string
        """

        if self.__kernelClasses:
            filtered = [ classObj for classObj in classes if not classObj in self.__kernelClasses ]
        else:
            filtered = classes

        Console.info("Compressing %s classes...", len(filtered))
        Console.indent()
        result = []

        if self.__assetManager:
            assetData = self.__assetManager.export(filtered)
            if assetData:
                assetCode = "jasy.Asset.addData(%s);" % assetData
                if self.__compressGeneratedCode:
                    result.append(packCode(assetCode))
                else:
                    result.append(assetCode)

        permutation = self.__session.getCurrentPermutation()

        try:
            for classObj in filtered:
                result.append(classObj.getCompressed(permutation, 
                    self.__session.getCurrentTranslationBundle(), self.__scriptOptimization, self.__scriptFormatting))
                
        except ClassError as error:
            raise UserError("Error during class compression! %s" % error)

        Console.outdent()

        if bootCode:
            bootCode = "(function(){%s})();" % bootCode

            if self.__compressGeneratedCode:
                result.append(packCode(bootCode))
            else:
                result.append(bootCode)

        if self.__compressGeneratedCode:
            compressedCode = "".join(result)
        else:
            compressedCode = "\n\n".join(result)

        self.__fileManager.writeFile(fileName, compressedCode)

Example 32

Project: jasy Source File: OutputManager.py
    def storeLoader(self, classes, fileName, bootCode="", urlPrefix=""):
        """
        Generates a source loader which is basically a file which loads the original JavaScript files.
        This is super useful during development of a project as it supports pretty fast workflows
        where most often a simple reload in the browser is enough to get the newest sources.
        
        :param classes: List of sorted classes to compress
        :type classes: list
        :param fileName: Filename to write result to
        :type fileName: string
        :param bootCode: Code to execute once all classes have been loaded
        :type bootCode: string
        :param urlPrefix: Prepends the given URL prefix to all class URLs to load
        :type urlPrefix: string
        """
        
        if self.__kernelClasses:
            filtered = [ classObj for classObj in classes if not classObj in self.__kernelClasses ]
        else:
            filtered = classes

        Console.info("Generating loader for %s classes...", len(classes))
        Console.indent()
        
        main = self.__session.getMain()
        files = []
        for classObj in filtered:
            path = classObj.getPath()

            # Support for multi path classes 
            # (typically in projects with custom layout/structure e.g. 3rd party)
            if type(path) is list:
                for singleFileName in path:
                    files.append(main.toRelativeUrl(singleFileName, urlPrefix))
            
            else:
                files.append(main.toRelativeUrl(path, urlPrefix))
        
        result = []
        Console.outdent()
        
        if self.__assetManager:
            assetData = self.__assetManager.export(filtered)
            if assetData:
                assetCode = "jasy.Asset.addData(%s);" % assetData
                if self.__compressGeneratedCode:
                    result.append(packCode(assetCode))
                else:
                    result.append(assetCode)

        translationBundle = self.__session.getCurrentTranslationBundle()
        if translationBundle:
            translationData = translationBundle.export(filtered)
            if translationData:
                translationCode = 'jasy.Translate.addData(%s);' % translationData
                if self.__compressGeneratedCode:
                    result.append(packCode(translationCode))        
                else:
                    result.append(translationCode)

        if self.__compressGeneratedCode:
            loaderList = '"%s"' % '","'.join(files)
        else:
            loaderList = '"%s"' % '",\n"'.join(files)

        wrappedBootCode = "function(){ %s }" % bootCode if bootCode else "null"
        loaderCode = 'core.io.Queue.load([%s], %s, null, true);' % (loaderList, wrappedBootCode)

        if self.__compressGeneratedCode:
            result.append(packCode(loaderCode))
        else:
            result.append(loaderCode)

        if self.__compressGeneratedCode:
            loaderCode = "".join(result)
        else:
            loaderCode = "\n\n".join(result)

        self.__fileManager.writeFile(fileName, loaderCode)

Example 33

Project: jasy Source File: Project.py
Function: clean
    def clean(self):
        """Clears the cache of the project"""
        
        Console.info("Clearing cache of %s..." % self.__name)
        self.__cache.clear()

Example 34

Project: jasy Source File: Session.py
    def __generateTranslationBundle(self):
        """ 
        Returns a translation object for the given language containing 
        all relevant translation files for the current project set. 
        """

        language = self.getCurrentPermutation().get("locale")
        if language is None:
            return None

        if language in self.__translationBundles:
            return self.__translationBundles[language]

        Console.info("Creating translation bundle: %s", language)
        Console.indent()

        # Initialize new Translation object with no project assigned
        # This object is used to merge all seperate translation instances later on.
        combined = jasy.item.Translation.TranslationItem(None, id=language)
        relevantLanguages = self.__expandLanguage(language)

        # Loop structure is build to prefer finer language matching over project priority
        for currentLanguage in reversed(relevantLanguages):
            for project in self.__projects:
                for translation in project.getTranslations().values():
                    if translation.getLanguage() == currentLanguage:
                        Console.debug("Adding %s entries from %s @ %s...", len(translation.getTable()), currentLanguage, project.getName())
                        combined += translation

        Console.debug("Combined number of translations: %s", len(combined.getTable()))
        Console.outdent()

        self.__translationBundles[language] = combined
        return combined

Example 35

Project: jasy Source File: Session.py
Function: permutate
    def permutate(self):
        """ Generator method for permutations for improving output capabilities """
        
        Console.info("Processing permutations...")
        Console.indent()
        
        permutations = self.__generatePermutations()
        length = len(permutations)
        
        for pos, current in enumerate(permutations):
            Console.info("Permutation %s/%s:" % (pos+1, length))
            Console.indent()

            self.__currentPermutation = current
            self.__currentTranslationBundle = self.__generateTranslationBundle()
            
            yield current
            Console.outdent()

        Console.outdent()

        self.__currentPermutation = None
        self.__currentTranslationBundle = None

Example 36

Project: jasy Source File: Request.py
def requestUrl(url, content_type="text/plain", headers=None, method="GET", port=None, body="", user=None, password=None):
    """Generic HTTP request wrapper with support for basic authentification and automatic parsing of response content"""
    
    Console.info("Opening %s request to %s..." % (method, url))

    parsed = urllib.parse.urlparse(url)
    
    if parsed.scheme== "http":
        request = http.client.HTTPConnection(parsed.netloc)
    elif parsed.scheme== "https":
        request = http.client.HTTPSConnection(parsed.netloc)
    else:
        raise Exception("Unsupported url: %s" % url)
    
    if parsed.query:
        request.putrequest(method, parsed.path + "?" + parsed.query)
    else:
        request.putrequest(method, parsed.path)
    
    request.putheader("Content-Type", content_type)
    request.putheader("Content-Length", str(len(body)))

    if user is not None and password is not None:
        auth = "Basic %s" % base64.b64encode(("%s:%s" % (user, password)).encode("utf-8")).decode("utf-8")
        request.putheader("Authorization", auth)
        
    request.endheaders()
    
    if body:
        Console.info("Sending data (%s bytes)..." % len(body))
    else:
        Console.info("Sending request...")

    Console.indent()

    request.send(body)

    response = request.getresponse()
    
    res_code = int(response.getcode())
    res_headers = dict(response.getheaders())
    res_content = response.read()
    res_success = False
    
    if res_code >= 200 and res_code <= 300:
        Console.debug("HTTP Success!")
        res_success = True
    else:
        Console.error("HTTP Failure Code: %s!", res_code)
        
    if "Content-Type" in res_headers:
        res_type = res_headers["Content-Type"]
        
        if ";" in res_type:
            res_type = res_type.split(";")[0]
            
        if res_type in ("application/json", "text/html", "text/plain"):
            res_content = res_content.decode("utf-8")

        if res_type == "application/json":
            res_content = json.loads(res_content)
            
            if "error" in res_content:
                Console.error("Error %s: %s", res_content["error"], res_content["reason"])
            elif "reason" in res_content:
                Console.info("Success: %s" % res_content["reason"])
                
    Console.outdent()
    
    return res_success, res_headers, res_content

Example 37

Project: jasy Source File: Server.py
    @cherrypy.expose
    @cherrypy.tools.noBodyProcess()
    def default(self, *args, **query):
        """
        This method returns the content of existing files on the file system.
        Query string might be used for cache busting and are otherwise ignored.
        """
        
        url = self.config["host"] + "/".join(args)
        result = None
        body = None
        
        # Try using offline mirror if feasible
        if self.enableMirror and cherrypy.request.method == "GET":
            mirrorId = "%s[%s]" % (url, json.dumps(query, separators=(',',':'), sort_keys=True))
            result = self.mirror.read(mirrorId)
            if result is not None and self.enableDebug:
                Console.info("Mirrored: %s" % url)
            
        if cherrypy.request.method in ("POST", "PUT"):
            body = cherrypy.request.body.fp.read()
         
        # Check if we're in forced offline mode
        if self.enableOffline and result is None:
            Console.info("Offline: %s" % url)
            raise cherrypy.NotFound(url)
        
        # Load URL from remote server
        if result is None:

            # Prepare headers
            headers = CaseInsensitiveDict()
            for name in cherrypy.request.headers:
                if not name in self.__blockHeaders:
                    headers[name] = cherrypy.request.headers[name]
            
            # Load URL from remote host
            try:
                if self.enableDebug:
                    Console.info("Requesting: %s", url)
                    
                # Apply headers for basic HTTP authentification
                if "X-Proxy-Authorization" in headers:
                    headers["Authorization"] = headers["X-Proxy-Authorization"]
                    del headers["X-Proxy-Authorization"]                
                    
                # Add headers for different authentification approaches
                if self.auth:
                    
                    # Basic Auth
                    if self.auth["method"] == "basic":
                        headers["Authorization"] = b"Basic " + base64.b64encode(("%s:%s" % (self.auth["user"], self.auth["password"])).encode("ascii"))
                    
                # We disable verifícation of SSL certificates to be more tolerant on test servers
                result = requests.request(cherrypy.request.method, url, params=query, headers=headers, data=body, verify=False)
                
            except Exception as err:
                if self.enableDebug:
                    Console.info("Request failed: %s", err)
                    
                raise cherrypy.HTTPError(403)

            # Storing result into mirror
            if self.enableMirror and cherrypy.request.method == "GET" and result.status_code == 200:

                # Wrap result into mirrorable entry
                resultCopy = Result(result.headers, result.content, result.status_code)
                self.mirror.store(mirrorId, resultCopy)
        

        # Copy response headers to our reponse
        for name in result.headers:
            if not name.lower() in self.__blockHeaders:
                cherrypy.response.headers[name] = result.headers[name]

        # Set the proxyed reply status to the response status
        cherrypy.response.status = result.status_code

        # Append special header to all responses
        cherrypy.response.headers["X-Jasy-Version"] = jasyVersion
        
        # Enable cross domain access to this server
        enableCrossDomain()

        return result.content

Example 38

Project: jasy Source File: Server.py
    @cherrypy.expose
    def default(self, *args, **query):
        """
        This method returns the content of existing files on the file system.
        Query string might be used for cache busting and are otherwise ignored.
        """
        
        # Append special header to all responses
        cherrypy.response.headers["X-Jasy-Version"] = jasyVersion
        
        # Enable cross domain access to this server
        enableCrossDomain()
        
        # When it's a file name in the local folder... load it
        if args:
            path = os.path.join(*args)
        else:
            path = "index.html"
        
        path = os.path.join(self.root, path)
        
        # Check for existance first
        if os.path.isfile(path):
            if self.enableDebug:
                Console.info("Serving file: %s", path)

            # Default content type to autodetection by Python mimetype API            
            contentType = None

            # Support overriding by extensions
            extension = os.path.splitext(path)[1]
            if extension:
                extension = extension.lower()[1:]
                if extension in self.mimeTypes:
                    contentType = self.mimeTypes[extension] + "; charset=" + locale.getpreferredencoding()

            return cherrypy.lib.static.serve_file(os.path.abspath(path), content_type=contentType)
            
        # Otherwise return a classic 404
        else:
            if self.enableDebug:
                Console.warn("File at location %s not found at %s!", path, os.path.abspath(path))
            
            raise cherrypy.NotFound(path)

Example 39

Project: jasy Source File: Server.py
Function: init
    def __init__(self, port=8080, host="127.0.0.1", mimeTypes=None):

        Console.info("Initializing server...")
        Console.indent()

        # Shared configuration (global/app)
        self.__config = {
            "global" : {
                "environment" : "production",
                "log.screen" : False,
                "server.socket_port": port,
                "server.socket_host": host,
                "engine.autoreload_on" : False
            },
            
            "/" : {
                "log.screen" : False
            }
        }

        self.__port = port

        # Build dict of content types to override native mimetype detection
        combinedTypes = {}
        combinedTypes.update(additionalContentTypes)
        if mimeTypes:    
            combinedTypes.update(mimeTypes)

        # Update global config
        cherrypy.config.update(self.__config)

        # Somehow this screen disabling does not work
        # This hack to disable all access/error logging works
        def empty(*param, **args): pass
        def inspect(*param, **args): 
            if args["severity"] > 20:
                Console.error("Critical error occoured:")
                Console.error(param[0])
        
        cherrypy.log.access = empty
        cherrypy.log.error = inspect
        cherrypy.log.screen = False

        # Basic routing
        self.__root = Static("/", {}, mimeTypes=combinedTypes)

        Console.outdent()

Example 40

Project: jasy Source File: Server.py
    def setRoutes(self, routes):
        """
        Adds the given routes to the server configuration. Routes can be used
        to add special top level entries to the different features of the integrated
        webserver either mirroring a remote server or delivering a local directory.

        The parameters is a dict where every key is the name of the route
        and the value is the configuration of that route.
        """

        Console.info("Adding routes...")
        Console.indent()        

        for key in routes:
            entry = routes[key]
            if "host" in entry:
                node = Proxy(key, entry)
            else:
                node = Static(key, entry, mimeTypes=self.__root.mimeTypes)
            
            setattr(self.__root, key, node)

        Console.outdent()

Example 41

Project: jasy Source File: Writer.py
def mergeMixin(className, mixinName, classApi, mixinApi):
    Console.info("Merging %s into %s", mixinName, className)

    sectionLink = ["member", "property", "event"]
    
    for pos, section in enumerate(("members", "properties", "events")):
        mixinItems = getattr(mixinApi, section, None)
        if mixinItems:
            classItems = getattr(classApi, section, None)
            if not classItems:
                classItems = {}
                setattr(classApi, section, classItems)
            
            for name in mixinItems:

                # Overridden Check
                if name in classItems:
                
                    # If it was included, just store another origin
                    if "origin" in classItems[name]:
                        classItems[name]["origin"].append({
                            "name": mixinName,
                            "link": "%s:%s~%s" % (sectionLink[pos], mixinName, name)
                        })
                
                    # Otherwise add it to the overridden list
                    else:
                        if not "overridden" in classItems[name]:
                            classItems[name]["overridden"] = []

                        classItems[name]["overridden"].append({
                            "name": mixinName,
                            "link": "%s:%s~%s" % (sectionLink[pos], mixinName, name)
                        })

                # Remember where classes are included from
                else:
                    classItems[name] = {}
                    classItems[name].update(mixinItems[name])
                    if not "origin" in classItems[name]:
                        classItems[name]["origin"] = []

                    classItems[name]["origin"].append({
                        "name": mixinName,
                        "link": "%s:%s~%s" % (sectionLink[pos], mixinName, name)
                    })

Example 42

Project: jasy Source File: Writer.py
Function: write
    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 43

Project: jasy Source File: Writer.py
Function: process
    def __process(self, apiData, classFilter=None, internals=False, privates=False, printErrors=True, highlightCode=True):
        
        knownClasses = set(list(apiData))


        #
        # Attaching Links to Source Code (Lines)
        # Building Docuementation Summaries
        #

        
        Console.info("Adding Source Links...")

        for className in apiData:
            classApi = apiData[className]

            constructData = getattr(classApi, "construct", None)
            if constructData is not None:
                if "line" in constructData:
                    constructData["sourceLink"] = "source:%s~%s" % (className, constructData["line"])

            for section in ("properties", "events", "statics", "members"):
                sectionData = getattr(classApi, section, None)

                if sectionData is not None:
                    for name in sectionData:
                        if "line" in sectionData[name]:
                            sectionData[name]["sourceLink"] = "source:%s~%s" % (className, sectionData[name]["line"])



        #
        # Including Mixins / IncludedBy
        #

        Console.info("Resolving Mixins...")
        Console.indent()

        # Just used temporary to keep track of which classes are merged
        mergedClasses = set()

        def getApi(className):
            classApi = apiData[className]

            if className in mergedClasses:
                return classApi

            classIncludes = getattr(classApi, "includes", None)
            if classIncludes:
                for mixinName in classIncludes:
                    if not mixinName in apiData:
                        Console.error("Invalid mixin %s in class %s", className, mixinName)
                        continue
                        
                    mixinApi = apiData[mixinName]
                    if not hasattr(mixinApi, "includedBy"):
                        mixinApi.includedBy = set()

                    mixinApi.includedBy.add(className)
                    mergeMixin(className, mixinName, classApi, getApi(mixinName))

            mergedClasses.add(className)

            return classApi

        for className in apiData:
            apiData[className] = getApi(className)

        Console.outdent()



        #
        # Checking links
        #
        
        Console.info("Checking Links...")
        
        additionalTypes = ("Call", "Identifier", "Map", "Integer", "Node", "Element")
        
        def checkInternalLink(link, className):
            match = internalLinkParse.match(link)
            if not match:
                return 'Invalid link "#%s"' % link
                
            if match.group(3) is not None:
                className = match.group(3)
                
            if not className in knownClasses and not className in apiData:
                return 'Invalid class in link "#%s"' % link
                
            # Accept all section/item values for named classes,
            # as it might be pretty complicated to verify this here.
            if not className in apiData:
                return True
                
            classApi = apiData[className]
            sectionName = match.group(2)
            itemName = match.group(5)
            
            if itemName is None:
                return True
                
            if sectionName is not None:
                if not sectionName in linkMap:
                    return 'Invalid section in link "#%s"' % link
                    
                section = getattr(classApi, linkMap[sectionName], None)
                if section is None:
                    return 'Invalid section in link "#%s"' % link
                else:
                    if itemName in section:
                        return True
                        
                    return 'Invalid item in link "#%s"' % link
            
            for sectionName in ("statics", "members", "properties", "events"):
                section = getattr(classApi, sectionName, None)
                if section and itemName in section:
                    return True
                
            return 'Invalid item link "#%s"' % link


        def checkLinksInItem(item):
            
            # Process types
            if "type" in item:
                
                if item["type"] == "Function":

                    # Check param types
                    if "params" in item:
                        for paramName in item["params"]:
                            paramEntry = item["params"][paramName]
                            if "type" in paramEntry:
                                for paramTypeEntry in paramEntry["type"]:
                                    if not paramTypeEntry["name"] in knownClasses and not paramTypeEntry["name"] in additionalTypes and not ("builtin" in paramTypeEntry or "pseudo" in paramTypeEntry):
                                        item["errornous"] = True
                                        Console.error('Invalid param type "%s" in %s' % (paramTypeEntry["name"], className))

                                    if not "pseudo" in paramTypeEntry and paramTypeEntry["name"] in knownClasses:
                                        paramTypeEntry["linkable"] = True
                
                
                    # Check return types
                    if "returns" in item:
                        for returnTypeEntry in item["returns"]:
                            if not returnTypeEntry["name"] in knownClasses and not returnTypeEntry["name"] in additionalTypes and not ("builtin" in returnTypeEntry or "pseudo" in returnTypeEntry):
                                item["errornous"] = True
                                Console.error('Invalid return type "%s" in %s' % (returnTypeEntry["name"], className))
                            
                            if not "pseudo" in returnTypeEntry and returnTypeEntry["name"] in knownClasses:
                                returnTypeEntry["linkable"] = True
                            
                elif not item["type"] in builtinTypes and not item["type"] in pseudoTypes and not item["type"] in additionalTypes:
                    item["errornous"] = True
                    Console.error('Invalid type "%s" in %s' % (item["type"], className))
            
            
            # Process doc
            if "doc" in item:
                
                def processInternalLink(match):
                    linkUrl = match.group(2)

                    if linkUrl.startswith("#"):
                        linkCheck = checkInternalLink(linkUrl[1:], className)
                        if linkCheck is not True:
                            item["errornous"] = True

                            if sectionName:
                                Console.error("%s in %s:%s~%s" % (linkCheck, sectionName, className, name))
                            else:
                                Console.error("%s in %s" % (linkCheck, className))
            
                linkExtract.sub(processInternalLink, item["doc"])


        Console.indent()

        # Process APIs
        for className in apiData:
            classApi = apiData[className]
            
            sectionName = None
            constructData = getattr(classApi, "construct", None)
            if constructData is not None:
                checkLinksInItem(constructData)

            for sectionName in ("properties", "events", "statics", "members"):
                section = getattr(classApi, sectionName, None)

                if section is not None:
                    for name in section:
                         checkLinksInItem(section[name])

        Console.outdent()



        #
        # Filter Internals/Privates
        #
        
        Console.info("Filtering Items...")
        
        def isVisible(entry):
            if "visibility" in entry:
                visibility = entry["visibility"]
                if visibility == "private" and not privates:
                    return False
                if visibility == "internal" and not internals:
                    return False

            return True

        def filterInternalsPrivates(classApi, field):
            data = getattr(classApi, field, None)
            if data:
                for name in list(data):
                    if not isVisible(data[name]):
                        del data[name]

        for className in apiData:
            filterInternalsPrivates(apiData[className], "statics")
            filterInternalsPrivates(apiData[className], "members")



        #
        # Connection Interfaces / ImplementedBy
        #
        
        Console.info("Connecting Interfaces...")
        Console.indent()
        
        for className in apiData:
            classApi = getApi(className)
            
            if not hasattr(classApi, "main"):
                continue
                
            classType = classApi.main["type"]
            if classType == "core.Class":
                
                classImplements = getattr(classApi, "implements", None)
                if classImplements:
                    
                    for interfaceName in classImplements:
                        interfaceApi = apiData[interfaceName]
                        implementedBy = getattr(interfaceApi, "implementedBy", None)
                        if not implementedBy:
                            implementedBy = interfaceApi.implementedBy = []
                            
                        implementedBy.append(className)
                        connectInterface(className, interfaceName, classApi, interfaceApi)
        
        Console.outdent()
        
        
        #
        # Merging Named Classes
        #
        
        Console.info("Merging Named Classes...")
        Console.indent()
        
        for className in list(apiData):
            classApi = apiData[className]
            destName = classApi.main["name"]
            
            if destName is not None and destName != className:

                Console.debug("Extending class %s with %s", destName, className)

                if destName in apiData:
                    destApi = apiData[destName]
                    destApi.main["from"].append(className)
                
                else:
                    destApi = apiData[destName] = Data.ApiData(destName, highlight=highlightCode)
                    destApi.main = {
                        "type" : "Extend",
                        "name" : destName,
                        "from" : [className]
                    }
                    
                # If there is a "main" tag found in the class use its API description
                if "tags" in classApi.main and classApi.main["tags"] is not None and "main" in classApi.main["tags"]:
                    if "doc" in classApi.main:
                        destApi.main["doc"] = classApi.main["doc"]
                
                classApi.main["extension"] = True
                    
                # Read existing data
                construct = getattr(classApi, "construct", None)
                statics = getattr(classApi, "statics", None)
                members = getattr(classApi, "members", None)

                if construct is not None:
                    if hasattr(destApi, "construct"):
                        Console.warn("Overriding constructor in extension %s by %s", destName, className)
                        
                    destApi.construct = copy.copy(construct)

                if statics is not None:
                    if not hasattr(destApi, "statics"):
                        destApi.statics = {}

                    for staticName in statics:
                        destApi.statics[staticName] = copy.copy(statics[staticName])
                        destApi.statics[staticName]["from"] = className
                        destApi.statics[staticName]["fromLink"] = "static:%s~%s" % (className, staticName)

                if members is not None:
                    if not hasattr(destApi, "members"):
                        destApi.members = {}
                        
                    for memberName in members:
                        destApi.members[memberName] = copy.copy(members[memberName])
                        destApi.members[memberName]["from"] = className
                        destApi.members[memberName]["fromLink"] = "member:%s~%s" % (className, memberName)

        Console.outdent()
        

        #
        # Connecting Uses / UsedBy
        #

        Console.info("Collecting Use Patterns...")

        # This matches all uses with the known classes and only keeps them if matched
        allClasses = set(list(apiData))
        for className in apiData:
            uses = apiData[className].uses

            # Rebuild use list
            cleanUses = set()
            for use in uses:
                if use != className and use in allClasses:
                    cleanUses.add(use)

                    useEntry = apiData[use]
                    if not hasattr(useEntry, "usedBy"):
                        useEntry.usedBy = set()

                    useEntry.usedBy.add(className)

            apiData[className].uses = cleanUses

        
        
        #
        # Collecting errors
        #
        
        Console.info("Collecting Errors...")
        Console.indent()
        
        for className in sorted(apiData):
            classApi = apiData[className]
            errors = []

            if isErrornous(classApi.main):
                errors.append({
                    "kind": "Main",
                    "name": None,
                    "line": 1
                })
            
            if hasattr(classApi, "construct"):
                if isErrornous(classApi.construct):
                    errors.append({
                        "kind": "Constructor",
                        "name": None,
                        "line": classApi.construct["line"]
                    })
            
            for section in ("statics", "members", "properties", "events"):
                items = getattr(classApi, section, {})
                for itemName in items:
                    item = items[itemName]
                    if isErrornous(item):
                        errors.append({
                            "kind": itemMap[section],
                            "name": itemName,
                            "line": item["line"]
                        })
                        
            if errors:
                if printErrors:
                    Console.warn("Found errors in %s", className)
                    
                errorsSorted = sorted(errors, key=lambda entry: entry["line"])
                
                if printErrors:
                    Console.indent()
                    for entry in errorsSorted:
                        if entry["name"]:
                            Console.warn("%s: %s (line %s)", entry["kind"], entry["name"], entry["line"])
                        else:
                            Console.warn("%s (line %s)", entry["kind"], entry["line"])
                
                    Console.outdent()
                    
                classApi.errors = errorsSorted
                
        Console.outdent()
        
        
        
        #
        # Building Search Index
        #

        Console.info("Building Search Index...")
        search = {}

        def addSearch(classApi, field):
            data = getattr(classApi, field, None)
            if data:
                for name in data:
                    if not name in search:
                        search[name] = set()

                    search[name].add(className)

        for className in apiData:

            classApi = apiData[className]

            addSearch(classApi, "statics")
            addSearch(classApi, "members")
            addSearch(classApi, "properties")
            addSearch(classApi, "events")
        
        
        
        #
        # Post Process (dict to sorted list)
        #
        
        Console.info("Post Processing Data...")
        
        for className in sorted(apiData):
            classApi = apiData[className]
            
            convertTags(classApi.main)
            
            construct = getattr(classApi, "construct", None)
            if construct:
                convertFunction(construct)
                convertTags(construct)

            for section in ("statics", "members", "properties", "events"):
                items = getattr(classApi, section, None)
                if items:
                    sortedList = []
                    for itemName in sorted(items):
                        item = items[itemName]
                        item["name"] = itemName
                        
                        if "type" in item and item["type"] == "Function":
                            convertFunction(item)
                                
                        convertTags(item)
                        sortedList.append(item)

                    setattr(classApi, section, sortedList)
        
        
        
        #
        # Collecting Package Docs
        #

        Console.info("Collecting Package Docs...")
        Console.indent()
        
        # Inject existing package docs into api data
        for project in self.__session.getProjects():
            docs = project.getDocs()
            
            for packageName in docs:
                if self.__isIncluded(packageName, classFilter):
                    Console.debug("Creating package docuementation %s", packageName)
                    apiData[packageName] = docs[packageName].getApi()
        
        
        # Fill missing package docs
        for className in sorted(apiData):
            splits = className.split(".")
            packageName = splits[0]
            for split in splits[1:]:
                if not packageName in apiData:
                    Console.warn("Missing package docuementation %s", packageName)
                    apiData[packageName] = Data.ApiData(packageName, highlight=highlightCode)
                    apiData[packageName].main = {
                        "type" : "Package",
                        "name" : packageName
                    }
                        
                packageName = "%s.%s" % (packageName, split)


        # Now register all classes in their parent namespace/package
        for className in sorted(apiData):
            splits = className.split(".")
            packageName = ".".join(splits[:-1])
            if packageName:
                package = apiData[packageName]
                # debug("- Registering class %s in parent %s", className, packageName)
                
                entry = {
                    "name" : splits[-1],
                    "link" : className,
                }
                
                classMain = apiData[className].main
                if "doc" in classMain and classMain["doc"]:
                    summary = Text.extractSummary(classMain["doc"])
                    if summary:
                        entry["summary"] = summary
                        
                if "type" in classMain and classMain["type"]:
                    entry["type"] = classMain["type"]
                
                if not hasattr(package, "content"):
                    package.content = [entry]
                else:
                    package.content.append(entry)
                    
        Console.outdent()



        #
        # Writing API Index
        #
        
        Console.debug("Building Index...")
        index = {}
        
        for className in sorted(apiData):
            
            classApi = apiData[className]
            mainInfo = classApi.main
            
            # Create structure for className
            current = index
            for split in className.split("."):
                if not split in current:
                    current[split] = {}
            
                current = current[split]
            
            # Store current type
            current["$type"] = mainInfo["type"]
            
            # Keep information if
            if hasattr(classApi, "content"):
                current["$content"] = True
        
        
        
        #
        # Return
        #
        
        return apiData, index, search

Example 44

Project: jasy Source File: Resolver.py
    def getIncludedClasses(self):
        """ Returns a final set of classes after resolving dependencies """

        if self.__included:
            return self.__included
        
        Console.info("Detecting class dependencies...")
        Console.indent()
        
        collection = set()
        for classObj in self.__required:
            self.__resolveDependencies(classObj, collection)
            
        # Filter excluded classes
        for classObj in self.__excluded:
            if classObj in collection:
                collection.remove(classObj)
        
        self.__included = collection

        Console.outdent()
        Console.debug("Including %s classes", len(collection))
        
        return self.__included

Example 45

Project: jasy Source File: Repository.py
Function: clean
def clean(path=None):
    """
    Cleans repository from untracked files.

    :param url: Path to the local repository
    :type url: string
    """

    old = os.getcwd()

    Console.info("Cleaning repository (clean)...")
    Console.indent()

    if path:
        os.chdir(path)

    if os.path.exists(".git"):
        Git.cleanRepository()

    os.chdir(old)
    Console.outdent()

Example 46

Project: jasy Source File: Repository.py
Function: distclean
def distclean(path=None):
    """
    Cleans repository from untracked and ignored files. This method
    is pretty agressive in a way that it deletes all non repository managed
    files e.g. external folder, uncommitted changes, unstaged files, etc.

    :param url: Path to the local repository
    :type url: string
    """

    old = os.getcwd()

    Console.info("Cleaning repository (distclean)...")
    Console.indent()

    if path:
        os.chdir(path)

    if os.path.exists(".git"):
        Git.distcleanRepository()

    os.chdir(old)
    Console.outdent()