コード例 #1
0
ファイル: Web.py プロジェクト: dadicool/jasy
    def __init__(self, id, config):
        self.id = id
        self.config = config
        self.root = getKey(config, "root", ".")
        self.enableDebug = getKey(config, "debug", False)

        info('Static "%s" => "%s" [debug:%s]', self.id, self.root, self.enableDebug)
コード例 #2
0
ファイル: Config.py プロジェクト: Andais/jasy
    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
コード例 #3
0
ファイル: Server.py プロジェクト: Andais/jasy
    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)
コード例 #4
0
    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)
コード例 #5
0
ファイル: Project.py プロジェクト: Val9/jasy
    def getRequires(self, prefix="external"):
        """
        Return the project requirements as project instances
        """

        result = []
        
        for entry in self.__requires:
            repo = None
            revision = None
            
            if type(entry) is dict:
                source = entry["source"]
                config = getKey(entry, "config")
                version = getKey(entry, "version")
            else:
                source = entry
                config = None
                version = None
            
            if version:
                info("Processing: %s @ %s", source, version)
            else:
                info("Processing: %s", source)
                
            indent()
            
            if isGitRepositoryUrl(source):
                if not version:
                    version = "master"

                # Auto cloning always happens relative to main project root folder (not to project requiring it)
                retval = cloneGit(source, version, prefix=prefix)
                if not retval:
                    raise JasyError("Could not clone GIT repository %s" % source)
                    
                path, revision = retval
                path = os.path.abspath(path)
                repo = "git"
                
            else:
                if not source.startswith(("/", "~")):
                    path = os.path.join(self.__path, source)
                else:
                    path = source
                
                # Other references to requires projects are always relative to the project requiring it
                path = os.path.normpath(os.path.expanduser(path))
                repo = "local"
                
            project = getProjectFromPath(path, config, version, repo, revision)
            result.append(project)
            
            outdent()
            
        return result
コード例 #6
0
ファイル: Manager.py プロジェクト: Val9/jasy
    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:
            info("Processing %s image animation configs...", len(configs))
        
        indent()
        for fileId in configs:
            debug("Processing %s...", fileId)
        
            asset = assets[fileId]
            base = dirname(fileId)
                
            try:
                config = json.loads(asset.getText())
            except ValueError as err:
                raise JasyError("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 JasyError("Unknown asset %s in %s" % (imageId, fileId))
                
                animationAsset = assets[imageId]
                
                if "rows" in data or "columns" in data:
                    rows = getKey(data, "rows", 1)
                    columns = getKey(data, "columns", 1)
                    frames = 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 JasyError("Invalid image frame data for: %s" % imageId)

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

            debug("  - Deleting animation config from assets: %s", fileId)
            del assets[fileId]
            
        outdent()
コード例 #7
0
ファイル: Server.py プロジェクト: Andais/jasy
    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)
コード例 #8
0
ファイル: Config.py プロジェクト: isabella232/jasy
    def get(self, name, default=None):
        """Returns the value of the given field or None when field is not set."""

        if not "." in name:
            return getKey(self.__data, name, default)

        splits = name.split(".")
        current = self.__data

        for split in splits[:-1]:
            if split in current:
                current = current[split]
            else:
                return default

        return getKey(current, splits[-1], default)
コード例 #9
0
    def __init__(self, project, id=None):
        # Call Item's init method first
        super().__init__(project, id)

        self.extension = os.path.splitext(self.id.lower())[1]
        self.type = getKey(extensions, self.extension, "other")
        self.shortType = self.type[0]
コード例 #10
0
ファイル: Config.py プロジェクト: sebastian-software/jasy
    def get(self, name, default=None):
        """Returns the value of the given field or None when field is not set."""

        if not "." in name:
            return getKey(self.__data, name, default)

        splits = name.split(".")
        current = self.__data

        for split in splits[:-1]:
            if split in current:
                current = current[split]
            else:
                return default

        return getKey(current, splits[-1], default)
コード例 #11
0
    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)
コード例 #12
0
ファイル: Config.py プロジェクト: isabella232/jasy
    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
コード例 #13
0
ファイル: Cache.py プロジェクト: Val9/jasy
 def open(self):
     """Opens a cache file in the given path"""
     
     try:
         if os.path.exists(self.__file):
             self.__shelve = shelve.open(self.__file, flag="w")
         
             storedVersion = getKey(self.__shelve, "jasy-version")
             storedHost = getKey(self.__shelve, "jasy-host")
         
             if storedVersion == version and storedHost == hostId:
                 return
                 
             info("Jasy version or host has been changed. Recreating cache...")
             self.__shelve.close()
                 
         self.__shelve = shelve.open(self.__file, flag="n")
         self.__shelve["jasy-version"] = version
         self.__shelve["jasy-host"] = hostId
         
     except dbm.error as dbmerror:
         errno = None
         try:
             errno = dbmerror.errno
         except:
             pass
             
         if errno is 35:
             raise IOError("Cache file is locked by another process!")
             
         elif "type could not be determined" in str(dbmerror):
             error("Could not detect cache file format: %s" % self.__file)
             warn("Recreating cache database...")
             self.clear()
             
         elif "module is not available" in str(dbmerror):
             error("Unsupported cache file format: %s" % self.__file)
             warn("Recreating cache database...")
             self.clear()
             
         else:
             raise error
コード例 #14
0
ファイル: Project.py プロジェクト: dadicool/jasy
    def getRequires(self, prefix="external"):
        """
        Return the project requirements as project instances
        """

        global projects
        
        result = []
        
        for entry in self.__requires:
            
            if type(entry) is dict:
                source = entry["source"]
                config = getKey(entry, "config")
                version = getKey(entry, "version")
                kind = getKey(entry, "kind")
            else:
                source = entry
                config = None
                version = None
                kind = None

            revision = None
            
            if isRepository(source):
                kind = kind or getRepositoryType(source)
                path = os.path.abspath(os.path.join(prefix, getRepositoryFolder(source, version, kind)))
                
                # Only clone and update when the folder is unique in this session
                # This reduces git/hg/svn calls which are typically quite expensive
                if not path in projects:
                    revision = updateRepository(source, version, path)
                    if revision is None:
                        raise JasyError("Could not update repository %s" % source)
            
            else:
                kind = "local"
                if not source.startswith(("/", "~")):
                    path = os.path.join(self.__path, source)
                else:
                    path = os.path.abspath(os.path.expanduser(source))
            
            if path in projects:
                project = projects[path]
                
            else:
                fullversion = []
                
                # Produce user readable version when non is defined
                if version is None and revision is not None:
                    version = "master"
                
                if version is not None:
                    if "/" in version:
                        fullversion.append(version[version.rindex("/")+1:])
                    else:
                        fullversion.append(version)
                    
                if revision is not None:
                    # Shorten typical long revisions as used by e.g. Git
                    if type(revision) is str and len(revision) > 20:
                        fullversion.append(revision[:10])
                    else:
                        fullversion.append(revision)
                        
                if fullversion:
                    fullversion = "-".join(fullversion)
                else:
                    fullversion = None

                project = Project(path, config, fullversion)
                projects[path] = project
            
            result.append(project)
        
        return result
コード例 #15
0
ファイル: Asset.py プロジェクト: dadicool/jasy
 def __init__(self, project, id=None):
     self.id = id
     self.extension = splitext(self.id.lower())[1]
     self.type = getKey(extensions, self.extension, "other")
     self.shortType = self.type[0]
     self.project = project
コード例 #16
0
ファイル: Project.py プロジェクト: Val9/jasy
    def __init__(self, path, config=None, version=None, repo=None, revision=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 JasyError("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
        self.__repo = repo
        self.__revision = revision
        
        # Intialize item registries
        self.classes = {}
        self.assets = {}        
        self.docs = {}
        self.translations = {}

        # Load project configuration
        configFilePath = os.path.join(self.__path, "jasyproject.json")
        isJasyProject = os.path.exists(configFilePath)
        if isJasyProject:
            try:
                storedConfig = json.load(open(configFilePath))
            except ValueError as err:
                raise JasyError("Could not parse jasyproject.json at %s: %s" % (configFilePath, err))
                
            if config:
                for key in storedConfig:
                    if not key in config:
                        config[key] = storedConfig[key]
            else:
                config = storedConfig
                
        if config is None:
            raise JasyError("Could not initialize project configuration in %s!" % self.__path)
            
        # Initialize cache
        try:
            self.__cache = Cache(self.__path)
        except IOError as err:
            raise JasyError("Could not initialize project. Cache file could not be initialized! %s" % err)
        
        # Read name from manifest or use the basename of the project's path
        self.__name = getKey(config, "name", getProjectNameFromPath(self.__path))
            
        # Read requires
        self.__requires = getKey(config, "requires", {})
        
        # Defined whenever no package is defined and classes/assets are not stored in the toplevel structure.
        self.__package = getKey(config, "package", self.__name if isJasyProject else None)

        # Read fields (for injecting data into the project and build permuations)
        self.__fields = getKey(config, "fields", {})

        # Store config
        self.__config = config
        
        # This section is a must for non jasy projects
        if not "content" in config and not isJasyProject:
            raise JasyError("Missing 'content' section for compat project!")
コード例 #17
0
ファイル: Builtin.py プロジェクト: dadicool/jasy
def create(name="myproject", origin=None, skeleton=None, **argv):
    """Creates a new project"""

    header("Creating project %s" % name)

    if not validProjectName.match(name):
        raise JasyError("Invalid project name: %s" % name)

    #
    # Initial Checks
    #

    # Figuring out destination folder
    destinationPath = os.path.abspath(name)
    if os.path.exists(destinationPath):
        raise JasyError("Cannot create project in %s. File or folder exists!" % 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

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

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

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

    elif isRepository(origin):
        info("Using remote skeleton")

        tempDirectory = tempfile.TemporaryDirectory()
        originPath = os.path.join(tempDirectory.name, "clone")
        originUrl = origin
        originVersion = getKey(argv, "origin-version")

        indent()
        originRevision = updateRepository(originUrl, originVersion, originPath)
        outdent()

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

        debug("Cloned revision: %s" % originRevision)

        originProject = getProjectFromPath(originPath)
        originName = originProject.getName()

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

        elif os.path.isdir(origin):
            originPath = origin
            originProject = getProjectFromPath(originPath)
            originName = originProject.getName()

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

    # Figure out the skeleton root folder
    skeletonDir = os.path.join(originPath, originProject.getConfigValue("skeletonDir", "skeleton"))
    if not os.path.isdir(skeletonDir):
        raise JasyError("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:
        skeleton = getFirstSubFolder(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 JasyError('Skeleton %s does not exist in project "%s"' % (skeleton, originName))

    #
    # Actual Work
    #

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

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

    # Build data for template substitution
    data = {}
    data.update(argv)
    data["name"] = name
    data["origin"] = originName
    data["skeleton"] = os.path.basename(skeletonPath)
    data["jasy"] = jasy.__version__

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

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

    # Create configuration file from question configs and custom scripts
    info("Starting configuration...")
    config = Config()
    config.injectValues(**argv)
    config.readQuestions("jasycreate", optional=True)
    config.executeScript("jasycreate.py", optional=True)
    config.write("jasyscript.yaml")

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