Beispiel #1
0
    def addScene(self, name=None, sceneFile=None):
        if (name == None):
            suffix = len(self.scenes)
            defaultname = "default_"

            name = defaultname + str(suffix)
            sceneFile = Filename(name + ".scene")
            f = Filename(sceneFile)
            f.setDirname(self.dir.getFullpath())
            while (os.path.exists(f.toOsSpecific())
                   or self.filenameIndexes.has_key(
                       sceneFile.getBasenameWoExtension())):
                suffix += 1
                name = defaultname + str(suffix)
                sceneFile = Filename(name + ".scene")
                f = Filename(sceneFile)
                f.setDirname(self.dir.getFullpath())
        #if there is a name but no  sceneFile given for that name
        #create a file with that name
        #TO DO: make it more error prone, for example this is not checking
        #if the file with the name already exist in the folder. This part may not be
        #be used at all but should be thought about.
        if (sceneFile == None):
            sceneFile = Filename(name + ".scene")
        self.scenes[name] = sceneFile
        self.filenameIndexes[sceneFile.getBasenameWoExtension()] = sceneFile
        if (len(self.scenes) == 1):
            #self.sceneFilename = sceneFile
            self.sceneName = name

        #f = Filename(sceneFile)
        #f.setDirname(self.dir.getFullpath())
        self.scenesOrder = sorted(self.scenes)
        return (name, sceneFile)
Beispiel #2
0
 def addScene(self,name=None, sceneFile=None):
     if(name == None):
         suffix = len(self.scenes)
         defaultname = "default_"
         
         name = defaultname+str(suffix)
         sceneFile = Filename(name+".scene")
         f = Filename(sceneFile)
         f.setDirname(self.dir.getFullpath())
         while(os.path.exists(f.toOsSpecific())or self.filenameIndexes.has_key(sceneFile.getBasenameWoExtension())):
             suffix += 1
             name = defaultname+str(suffix)
             sceneFile = Filename(name+".scene")
             f = Filename(sceneFile)
             f.setDirname(self.dir.getFullpath())
     #if there is a name but no  sceneFile given for that name
     #create a file with that name
     #TO DO: make it more error prone, for example this is not checking
     #if the file with the name already exist in the folder. This part may not be
     #be used at all but should be thought about.
     if(sceneFile == None):
          sceneFile = Filename(name+".scene")            
     self.scenes[name] = sceneFile
     self.filenameIndexes[sceneFile.getBasenameWoExtension()] = sceneFile
     if(len(self.scenes) == 1 ):
         #self.sceneFilename = sceneFile
         self.sceneName = name
     
     #f = Filename(sceneFile)
     #f.setDirname(self.dir.getFullpath())
     self.scenesOrder = sorted(self.scenes)
     return (name,sceneFile)
class Standalone:
    """ This class creates a standalone executable from a given .p3d file. """

    notify = directNotify.newCategory("Standalone")

    def __init__(self, p3dfile, tokens={}):
        self.p3dfile = Filename(p3dfile)
        self.basename = self.p3dfile.getBasenameWoExtension()
        self.tokens = tokens

        self.tempDir = Filename.temporary("", self.basename, "") + "/"
        self.tempDir.makeDir()
        self.host = HostInfo(
            PandaSystem.getPackageHostUrl(), appRunner=appRunner, hostDir=self.tempDir, asMirror=False, perPlatform=True
        )

        self.http = HTTPClient.getGlobalPtr()
        if not self.host.hasContentsFile:
            if not self.host.readContentsFile():
                if not self.host.downloadContentsFile(self.http):
                    Standalone.notify.error("couldn't read host")
                    return

    def __del__(self):
        try:
            appRunner.rmtree(self.tempDir)
        except:
            try:
                shutil.rmtree(self.tempDir.toOsSpecific())
            except:
                pass

    def buildAll(self, outputDir="."):
        """ Builds standalone executables for every known platform,
        into the specified output directory. """

        platforms = set()
        for package in self.host.getPackages(name="p3dembed"):
            platforms.add(package.platform)
        if len(platforms) == 0:
            Standalone.notify.warning("No platforms found to build for!")

        outputDir = Filename(outputDir + "/")
        outputDir.makeDir()
        for platform in platforms:
            if platform.startswith("win"):
                self.build(Filename(outputDir, platform + "/" + self.basename + ".exe"), platform)
            else:
                self.build(Filename(outputDir, platform + "/" + self.basename), platform)

    def build(self, output, platform=None, extraTokens={}):
        """ Builds a standalone executable and stores it into the path
        indicated by the 'output' argument. You can specify to build for
        a different platform by altering the 'platform' argument. """

        if platform == None:
            platform = PandaSystem.getPlatform()

        vfs = VirtualFileSystem.getGlobalPtr()

        for package in self.host.getPackages(name="p3dembed", platform=platform):
            if not package.downloadDescFile(self.http):
                Standalone.notify.warning("  -> %s failed for platform %s" % (package.packageName, package.platform))
                continue
            if not package.downloadPackage(self.http):
                Standalone.notify.warning("  -> %s failed for platform %s" % (package.packageName, package.platform))
                continue

            # Figure out where p3dembed might be now.
            if package.platform.startswith("win"):
                # Use p3dembedw unless console_environment was set.
                if extraTokens.get("console_environment", self.tokens.get("console_environment", 0)) != 0:
                    p3dembed = Filename(self.host.hostDir, "p3dembed/%s/p3dembed.exe" % package.platform)
                else:
                    p3dembed = Filename(self.host.hostDir, "p3dembed/%s/p3dembedw.exe" % package.platform)
                    # Fallback for older p3dembed versions
                    if not vfs.exists(p3dembed):
                        Filename(self.host.hostDir, "p3dembed/%s/p3dembed.exe" % package.platform)
            else:
                p3dembed = Filename(self.host.hostDir, "p3dembed/%s/p3dembed" % package.platform)

            if not vfs.exists(p3dembed):
                Standalone.notify.warning("  -> %s failed for platform %s" % (package.packageName, package.platform))
                continue

            return self.embed(output, p3dembed, extraTokens)

        Standalone.notify.error("Failed to build standalone for platform %s" % platform)

    def embed(self, output, p3dembed, extraTokens={}):
        """ Embeds the p3d file into the provided p3dembed executable.
        This function is not really useful - use build() or buildAll() instead. """

        # Load the p3dembed data into memory
        size = p3dembed.getFileSize()
        p3dembed_data = VirtualFileSystem.getGlobalPtr().readFile(p3dembed, True)
        assert len(p3dembed_data) == size

        # Find the magic size string and replace it with the real size,
        # regardless of the endianness of the p3dembed executable.
        hex_size = hex(size)[2:].rjust(8, "0")
        enc_size = "".join([chr(int(hex_size[i] + hex_size[i + 1], 16)) for i in range(0, len(hex_size), 2)])
        p3dembed_data = p3dembed_data.replace(P3DEMBED_MAGIC, enc_size)
        p3dembed_data = p3dembed_data.replace(P3DEMBED_MAGIC[::-1], enc_size[::-1])

        # Write the output file
        Standalone.notify.info("Creating %s..." % output)
        output.makeDir()
        ohandle = open(output.toOsSpecific(), "wb")
        ohandle.write(p3dembed_data)

        # Write out the tokens. Set log_basename to the basename by default
        tokens = {"log_basename": self.basename}
        tokens.update(self.tokens)
        tokens.update(extraTokens)
        for token in tokens.items():
            ohandle.write("\0%s=%s" % token)
        ohandle.write("\0\0")

        # Buffer the p3d file to the output file. 1 MB buffer size.
        phandle = open(self.p3dfile.toOsSpecific(), "rb")
        buf = phandle.read(1024 * 1024)
        while len(buf) != 0:
            ohandle.write(buf)
            buf = phandle.read(1024 * 1024)
        ohandle.close()
        phandle.close()

        os.chmod(output.toOsSpecific(), 0755)

    def getExtraFiles(self, platform):
        """ Returns a list of extra files that will need to be included
        with the standalone executable in order for it to run, such as
        dependent libraries. The returned paths are full absolute paths. """

        package = self.host.getPackages(name="p3dembed", platform=platform)[0]

        if not package.downloadDescFile(self.http):
            Standalone.notify.warning("  -> %s failed for platform %s" % (package.packageName, package.platform))
            return []
        if not package.downloadPackage(self.http):
            Standalone.notify.warning("  -> %s failed for platform %s" % (package.packageName, package.platform))
            return []

        filenames = []
        vfs = VirtualFileSystem.getGlobalPtr()
        for e in package.extracts:
            if e.basename not in [
                "p3dembed",
                "p3dembed.exe",
                "p3dembed.exe.manifest",
                "p3dembedw.exe",
                "p3dembedw.exe.manifest",
            ]:
                filename = Filename(package.getPackageDir(), e.filename)
                filename.makeAbsolute()
                if vfs.exists(filename):
                    filenames.append(filename)
                else:
                    Standalone.notify.error("%s mentioned in xml, but does not exist" % e.filename)

        return filenames
class Standalone:
    """ This class creates a standalone executable from a given .p3d file. """
    notify = directNotify.newCategory("Standalone")

    def __init__(self, p3dfile, tokens={}):
        self.p3dfile = Filename(p3dfile)
        self.basename = self.p3dfile.getBasenameWoExtension()
        self.tokens = tokens

        self.tempDir = Filename.temporary("", self.basename, "") + "/"
        self.tempDir.makeDir()
        self.host = HostInfo(PandaSystem.getPackageHostUrl(),
                             appRunner=appRunner,
                             hostDir=self.tempDir,
                             asMirror=False,
                             perPlatform=True)

        self.http = HTTPClient.getGlobalPtr()
        if not self.host.hasContentsFile:
            if not self.host.readContentsFile():
                if not self.host.downloadContentsFile(self.http):
                    Standalone.notify.error("couldn't read host")
                    return

    def __del__(self):
        try:
            appRunner.rmtree(self.tempDir)
        except:
            try:
                shutil.rmtree(self.tempDir.toOsSpecific())
            except:
                pass

    def buildAll(self, outputDir="."):
        """ Builds standalone executables for every known platform,
        into the specified output directory. """

        platforms = set()
        for package in self.host.getPackages(name="p3dembed"):
            platforms.add(package.platform)
        if len(platforms) == 0:
            Standalone.notify.warning("No platforms found to build for!")

        outputDir = Filename(outputDir + "/")
        outputDir.makeDir()
        for platform in platforms:
            if platform.startswith("win"):
                self.build(
                    Filename(outputDir,
                             platform + "/" + self.basename + ".exe"),
                    platform)
            else:
                self.build(Filename(outputDir, platform + "/" + self.basename),
                           platform)

    def build(self, output, platform=None, extraTokens={}):
        """ Builds a standalone executable and stores it into the path
        indicated by the 'output' argument. You can specify to build for
        a different platform by altering the 'platform' argument. """

        if platform == None:
            platform = PandaSystem.getPlatform()

        vfs = VirtualFileSystem.getGlobalPtr()

        for package in self.host.getPackages(name="p3dembed",
                                             platform=platform):
            if not package.downloadDescFile(self.http):
                Standalone.notify.warning(
                    "  -> %s failed for platform %s" %
                    (package.packageName, package.platform))
                continue
            if not package.downloadPackage(self.http):
                Standalone.notify.warning(
                    "  -> %s failed for platform %s" %
                    (package.packageName, package.platform))
                continue

            # Figure out where p3dembed might be now.
            if package.platform.startswith("win"):
                # Use p3dembedw unless console_environment was set.
                if extraTokens.get("console_environment",
                                   self.tokens.get("console_environment",
                                                   0)) != 0:
                    p3dembed = Filename(
                        self.host.hostDir,
                        "p3dembed/%s/p3dembed.exe" % package.platform)
                else:
                    p3dembed = Filename(
                        self.host.hostDir,
                        "p3dembed/%s/p3dembedw.exe" % package.platform)
                    # Fallback for older p3dembed versions
                    if not vfs.exists(p3dembed):
                        Filename(self.host.hostDir,
                                 "p3dembed/%s/p3dembed.exe" % package.platform)
            else:
                p3dembed = Filename(self.host.hostDir,
                                    "p3dembed/%s/p3dembed" % package.platform)

            if not vfs.exists(p3dembed):
                Standalone.notify.warning(
                    "  -> %s failed for platform %s" %
                    (package.packageName, package.platform))
                continue

            return self.embed(output, p3dembed, extraTokens)

        Standalone.notify.error("Failed to build standalone for platform %s" %
                                platform)

    def embed(self, output, p3dembed, extraTokens={}):
        """ Embeds the p3d file into the provided p3dembed executable.
        This function is not really useful - use build() or buildAll() instead. """

        # Load the p3dembed data into memory
        size = p3dembed.getFileSize()
        p3dembed_data = VirtualFileSystem.getGlobalPtr().readFile(
            p3dembed, True)
        assert len(p3dembed_data) == size

        # Find the magic size string and replace it with the real size,
        # regardless of the endianness of the p3dembed executable.
        hex_size = hex(size)[2:].rjust(8, "0")
        enc_size = "".join([
            chr(int(hex_size[i] + hex_size[i + 1], 16))
            for i in range(0, len(hex_size), 2)
        ])
        p3dembed_data = p3dembed_data.replace(P3DEMBED_MAGIC, enc_size)
        p3dembed_data = p3dembed_data.replace(P3DEMBED_MAGIC[::-1],
                                              enc_size[::-1])

        # Write the output file
        Standalone.notify.info("Creating %s..." % output)
        output.makeDir()
        ohandle = open(output.toOsSpecific(), "wb")
        ohandle.write(p3dembed_data)

        # Write out the tokens. Set log_basename to the basename by default
        tokens = {"log_basename": self.basename}
        tokens.update(self.tokens)
        tokens.update(extraTokens)
        for token in tokens.items():
            ohandle.write("\0%s=%s" % token)
        ohandle.write("\0\0")

        # Buffer the p3d file to the output file. 1 MB buffer size.
        phandle = open(self.p3dfile.toOsSpecific(), "rb")
        buf = phandle.read(1024 * 1024)
        while len(buf) != 0:
            ohandle.write(buf)
            buf = phandle.read(1024 * 1024)
        ohandle.close()
        phandle.close()

        os.chmod(output.toOsSpecific(), 0755)

    def getExtraFiles(self, platform):
        """ Returns a list of extra files that will need to be included
        with the standalone executable in order for it to run, such as
        dependent libraries. The returned paths are full absolute paths. """

        package = self.host.getPackages(name="p3dembed", platform=platform)[0]

        if not package.downloadDescFile(self.http):
            Standalone.notify.warning("  -> %s failed for platform %s" %
                                      (package.packageName, package.platform))
            return []
        if not package.downloadPackage(self.http):
            Standalone.notify.warning("  -> %s failed for platform %s" %
                                      (package.packageName, package.platform))
            return []

        filenames = []
        vfs = VirtualFileSystem.getGlobalPtr()
        for e in package.extracts:
            if e.basename not in [
                    "p3dembed", "p3dembed.exe", "p3dembed.exe.manifest",
                    "p3dembedw.exe", "p3dembedw.exe.manifest"
            ]:
                filename = Filename(package.getPackageDir(), e.filename)
                filename.makeAbsolute()
                if vfs.exists(filename):
                    filenames.append(filename)
                else:
                    Standalone.notify.error(
                        "%s mentioned in xml, but does not exist" % e.filename)

        return filenames