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
    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
示例#3
0
def dummyAppRunner(tokens=[], argv=None):
    """ This function creates a dummy global AppRunner object, which
    is useful for testing running in a packaged environment without
    actually bothering to package up the application.  Call this at
    the start of your application to enable it.

    It places the current working directory under /mf, as if it were
    mounted from a packed multifile.  It doesn't convert egg files to
    bam files, of course; and there are other minor differences from
    running in an actual packaged environment.  But it can be a useful
    first-look sanity check. """

    if AppRunnerGlobal.appRunner:
        print "Already have AppRunner, not creating a new one."
        return AppRunnerGlobal.appRunner

    appRunner = AppRunner()
    appRunner.dummy = True
    AppRunnerGlobal.appRunner = appRunner

    platform = PandaSystem.getPlatform()
    version = PandaSystem.getPackageVersionString()
    hostUrl = PandaSystem.getPackageHostUrl()

    if platform.startswith('win'):
        rootDir = Filename(Filename.getUserAppdataDirectory(), 'Panda3D')
    elif platform.startswith('osx'):
        rootDir = Filename(Filename.getHomeDirectory(),
                           'Library/Caches/Panda3D')
    else:
        rootDir = Filename(Filename.getHomeDirectory(), '.panda3d')

    appRunner.rootDir = rootDir
    appRunner.logDirectory = Filename(rootDir, 'log')

    # Of course we will have the panda3d application loaded.
    appRunner.addPackageInfo('panda3d', platform, version, hostUrl)

    appRunner.tokens = tokens
    appRunner.tokenDict = dict(tokens)
    if argv is None:
        argv = sys.argv
    appRunner.argv = argv
    appRunner.altHost = appRunner.tokenDict.get('alt_host', None)

    appRunner.p3dInfo = None
    appRunner.p3dPackage = None

    # Mount the current directory under the multifileRoot, as if it
    # were coming from a multifile.
    cwd = ExecutionEnvironment.getCwd()
    vfs = VirtualFileSystem.getGlobalPtr()
    vfs.mount(cwd, appRunner.multifileRoot, vfs.MFReadOnly)

    appRunner.initPackedAppEnvironment()

    return appRunner
def dummyAppRunner(tokens = [], argv = None):
    """ This function creates a dummy global AppRunner object, which
    is useful for testing running in a packaged environment without
    actually bothering to package up the application.  Call this at
    the start of your application to enable it.

    It places the current working directory under /mf, as if it were
    mounted from a packed multifile.  It doesn't convert egg files to
    bam files, of course; and there are other minor differences from
    running in an actual packaged environment.  But it can be a useful
    first-look sanity check. """

    if AppRunnerGlobal.appRunner:
        print "Already have AppRunner, not creating a new one."
        return AppRunnerGlobal.appRunner

    appRunner = AppRunner()
    appRunner.dummy = True
    AppRunnerGlobal.appRunner = appRunner

    platform = PandaSystem.getPlatform()
    version = PandaSystem.getPackageVersionString()
    hostUrl = PandaSystem.getPackageHostUrl()

    if platform.startswith('win'):
        rootDir = Filename(Filename.getUserAppdataDirectory(), 'Panda3D')
    elif platform.startswith('osx'):
        rootDir = Filename(Filename.getHomeDirectory(), 'Library/Caches/Panda3D')
    else:
        rootDir = Filename(Filename.getHomeDirectory(), '.panda3d')

    appRunner.rootDir = rootDir
    appRunner.logDirectory = Filename(rootDir, 'log')

    # Of course we will have the panda3d application loaded.
    appRunner.addPackageInfo('panda3d', platform, version, hostUrl)

    appRunner.tokens = tokens
    appRunner.tokenDict = dict(tokens)
    if argv is None:
        argv = sys.argv
    appRunner.argv = argv
    appRunner.altHost = appRunner.tokenDict.get('alt_host', None)

    appRunner.p3dInfo = None
    appRunner.p3dPackage = None

    # Mount the current directory under the multifileRoot, as if it
    # were coming from a multifile.
    cwd = ExecutionEnvironment.getCwd()
    vfs = VirtualFileSystem.getGlobalPtr()
    vfs.mount(cwd, appRunner.multifileRoot, vfs.MFReadOnly)

    appRunner.initPackedAppEnvironment()

    return appRunner
示例#5
0
 def getResourceAsString(self, filename, fullPath = False):
     """
     Returns a string that represents the file's contents.
     @param filename: The resource filename.
     @param fullPath: Specifies if the filename parameter denotes a full path or a base filename. 
     """    
     vfs = VirtualFileSystem.getGlobalPtr()        
     fs = vfs.readFile(Filename(filename), False)
     if fs is not None:
         return codecs.decode(fs, "utf-8")
示例#6
0
 def getResourceAsByteArray(self, filename, fullPath = False):
     """
     Returns an array of bytes that represent the file's contents.
     It performs the same functionality with getResourceAsString since the str type is used to 
     store byte arrays but it won't decode the string since it doesn't make sense for binary data.
     @param filename: The resource filename.
     @param fullPath: Specifies if the filename parameter denotes a full path or a base filename.
     """
     vfs = VirtualFileSystem.getGlobalPtr()        
     return vfs.readFile(Filename(filename))
示例#7
0
 def getResourceFullPath(self, filename):
     vfs = VirtualFileSystem.getGlobalPtr()
     resFile = Filename(filename)
     if vfs.exists(resFile):
         searchPath = DSearchPath()
         searchPath.appendDirectory(self.mountPoint)
         
         # if the filename was resolved, resFile is updated to include the full path
         if vfs.resolveFilename(resFile, searchPath):                
             return resFile.getFullpath()
    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 readFavIcon(self):
        vfs = VirtualFileSystem.getGlobalPtr()
        filename = Filename('favicon.ico')

        searchPath = DSearchPath()
        searchPath.appendDirectory(Filename('.'))
        searchPath.appendDirectory(Filename('etc'))
        searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('$DIRECT/src/http')))
        searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('direct/src/http')))
        searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('direct/http')))
        found = vfs.resolveFilename(filename,searchPath)
        if not found:
            raise "Couldn't find direct/http/favicon.ico"

        return vfs.readFile(filename, 1)
    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)
示例#11
0
    def readFavIcon(self):
        vfs = VirtualFileSystem.getGlobalPtr()
        filename = Filename('favicon.ico')

        searchPath = DSearchPath()
        searchPath.appendDirectory(Filename('.'))
        searchPath.appendDirectory(Filename('etc'))
        searchPath.appendDirectory(
            Filename.fromOsSpecific(os.path.expandvars('$DIRECT/src/http')))
        searchPath.appendDirectory(
            Filename.fromOsSpecific(os.path.expandvars('direct/src/http')))
        searchPath.appendDirectory(
            Filename.fromOsSpecific(os.path.expandvars('direct/http')))
        found = vfs.resolveFilename(filename, searchPath)
        if not found:
            raise "Couldn't find direct/http/favicon.ico"

        return vfs.readFile(filename, 1)
示例#12
0
    def initPackedAppEnvironment(self):
        """ This function sets up the Python environment suitably for
        running a packed app.  It should only run once in any given
        session (and it includes logic to ensure this). """

        if self.packedAppEnvironmentInitialized:
            return

        self.packedAppEnvironmentInitialized = True

        vfs = VirtualFileSystem.getGlobalPtr()

        # Now set up Python to import this stuff.
        VFSImporter.register()
        sys.path.append(self.multifileRoot)

        # Make sure that $MAIN_DIR is set to the p3d root before we
        # start executing the code in this file.
        ExecutionEnvironment.setEnvironmentVariable(
            "MAIN_DIR",
            Filename(self.multifileRoot).toOsSpecific())

        # Put our root directory on the model-path, too.
        getModelPath().appendDirectory(self.multifileRoot)

        if not self.trueFileIO:
            # Replace the builtin open and file symbols so user code will get
            # our versions by default, which can open and read files out of
            # the multifile.
            __builtin__.file = file.file
            __builtin__.open = file.open
            __builtin__.execfile = file.execfile
            os.listdir = file.listdir
            os.walk = file.walk
            os.path.join = file.join
            os.path.isfile = file.isfile
            os.path.isdir = file.isdir
            os.path.exists = file.exists
            os.path.lexists = file.lexists
            os.path.getmtime = file.getmtime
            os.path.getsize = file.getsize
            sys.modules['glob'] = glob

        self.checkDiskUsage()
示例#13
0
    def _initFromFilename(self, filepath, filename):
        vfs = VirtualFileSystem.getGlobalPtr()
        filename = Filename(filename)
        searchPath = DSearchPath()
        #searchPath.appendDirectory(Filename('.'))
        #searchPath.appendDirectory(Filename('etc'))
        #searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('~')))
        #searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('$HOME')))
        searchPath.appendDirectory(
            Filename.fromOsSpecific(os.path.expandvars(filepath)))

        found = vfs.resolveFilename(filename, searchPath)

        if not found:
            raise IOError, "File not found!"

        str = vfs.readFile(filename, 1)

        self._initFromString(str)
示例#14
0
    def fromFile(self, packageDir, filename, pathname=None, st=None):
        """ Reads the file information from the indicated file.  If st
        is supplied, it is the result of os.stat on the filename. """

        vfs = VirtualFileSystem.getGlobalPtr()

        filename = Filename(filename)
        if pathname is None:
            pathname = Filename(packageDir, filename)

        self.filename = filename.cStr()
        self.basename = filename.getBasename()

        if st is None:
            st = os.stat(pathname.toOsSpecific())
        self.size = st.st_size
        self.timestamp = st.st_mtime

        self.readHash(pathname)
示例#15
0
    def fromFile(self, packageDir, filename, pathname = None, st = None):
        """ Reads the file information from the indicated file.  If st
        is supplied, it is the result of os.stat on the filename. """
        
        vfs = VirtualFileSystem.getGlobalPtr()

        filename = Filename(filename)
        if pathname is None:
            pathname = Filename(packageDir, filename)
        
        self.filename = filename.cStr()
        self.basename = filename.getBasename()

        if st is None:
            st = os.stat(pathname.toOsSpecific())
        self.size = st.st_size
        self.timestamp = st.st_mtime

        self.readHash(pathname)
示例#16
0
    def initPackedAppEnvironment(self):
        """ This function sets up the Python environment suitably for
        running a packed app.  It should only run once in any given
        session (and it includes logic to ensure this). """

        if self.packedAppEnvironmentInitialized:
            return

        self.packedAppEnvironmentInitialized = True

        vfs = VirtualFileSystem.getGlobalPtr()

        # Now set up Python to import this stuff.
        VFSImporter.register()
        sys.path.append(self.multifileRoot)

        # Make sure that $MAIN_DIR is set to the p3d root before we
        # start executing the code in this file.
        ExecutionEnvironment.setEnvironmentVariable("MAIN_DIR", Filename(self.multifileRoot).toOsSpecific())

        # Put our root directory on the model-path, too.
        getModelPath().appendDirectory(self.multifileRoot)

        if not self.trueFileIO:
            # Replace the builtin open and file symbols so user code will get
            # our versions by default, which can open and read files out of
            # the multifile.
            __builtin__.file = file.file
            __builtin__.open = file.open
            __builtin__.execfile = file.execfile
            os.listdir = file.listdir
            os.walk = file.walk
            os.path.join = file.join
            os.path.isfile = file.isfile
            os.path.isdir = file.isdir
            os.path.exists = file.exists
            os.path.lexists = file.lexists
            os.path.getmtime = file.getmtime
            os.path.getsize = file.getsize
            sys.modules['glob'] = glob

        self.checkDiskUsage()
    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)
示例#18
0
 def _listResourcesImpl(self, parent, resType, fullPaths = True):
     resFiles = []
     directories = []
     
     vfs = VirtualFileSystem.getGlobalPtr()
     filesList = vfs.scanDirectory(parent)
     if filesList is None:
         return directories
     
     for i in xrange(filesList.getNumFiles()):            
         fileEntry = filesList.getFile(i)            
         if fileEntry.isDirectory():
             directories.append(fileEntry.getFilename())
             continue
         
         if ResourcesTypes.isExtensionOfType(fileEntry.getFilename().getExtension(), resType):
             resFiles.append(fileEntry.getFilename().getFullpath() if fullPaths else fileEntry.getFilename().getBasename())
             
     for dir in directories:
         resFiles.extend(self._listResourcesImpl(dir, resType, fullPaths))
         
     return resFiles
    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)
示例#20
0
 def listResources(self, resType, fullPaths=True):
     '''
     Returns a list of all resource filenames, of the given type, which are contained in this multifile.
     '''
     vfs = VirtualFileSystem.getGlobalPtr()
     return self._listResourcesImpl(Filename(self.mountPoint), resType, fullPaths) 
示例#21
0
    def installPackage(self, appRunner):
        """ Mounts the package and sets up system paths so it becomes
        available for use.  Returns true on success, false on failure. """

        assert self.hasPackage
        if self.installed:
            # Already installed.
            return True
        assert self not in appRunner.installedPackages

        mfPathname = Filename(self.getPackageDir(),
                              self.uncompressedArchive.filename)
        mf = Multifile()
        if not mf.openRead(mfPathname):
            self.notify.warning("Couldn't open %s" % (mfPathname))
            return False

        # We mount it under its actual location on disk.
        root = self.getPackageDir().cStr()

        vfs = VirtualFileSystem.getGlobalPtr()
        vfs.mount(mf, root, vfs.MFReadOnly)

        # Add this to the Python search path, if it's not already
        # there.  We have to take a bit of care to check if it's
        # already there, since there can be some ambiguity in
        # os-specific path strings.
        osRoot = self.getPackageDir().toOsSpecific()
        foundOnPath = False
        for p in sys.path:
            if osRoot == p:
                # Already here, exactly.
                foundOnPath = True
                break
            elif osRoot == Filename.fromOsSpecific(p).toOsSpecific():
                # Already here, with some futzing.
                foundOnPath = True
                break

        if not foundOnPath:
            # Not already here; add it.
            sys.path.append(osRoot)

        # Put it on the model-path, too.  We do this indiscriminantly,
        # because the Panda3D runtime won't be adding things to the
        # model-path, so it shouldn't be already there.
        getModelPath().appendDirectory(self.getPackageDir())

        # Set the environment variable to reference the package root.
        envvar = '%s_ROOT' % (self.packageName.upper())
        ExecutionEnvironment.setEnvironmentVariable(envvar, osRoot)

        # Add the package root to the system paths.
        if sys.platform.startswith('win'):
            path = os.environ.get('PATH', '')
            os.environ['PATH'] = "%s;%s" % (osRoot, path)
        else:
            path = os.environ.get('PATH', '')
            os.environ['PATH'] = "%s:%s" % (osRoot, path)
            path = os.environ.get('LD_LIBRARY_PATH', '')
            os.environ['LD_LIBRARY_PATH'] = "%s:%s" % (osRoot, path)

        if sys.platform == "darwin":
            path = os.environ.get('DYLD_LIBRARY_PATH', '')
            os.environ['DYLD_LIBRARY_PATH'] = "%s:%s" % (osRoot, path)

        # Now that the environment variable is set, read all of the
        # prc files in the package.
        appRunner.loadMultifilePrcFiles(mf, self.getPackageDir())

        # Also, find any toplevel Python packages, and add these as
        # shared packages.  This will allow different packages
        # installed in different directories to share Python files as
        # if they were all in the same directory.
        for filename in mf.getSubfileNames():
            if filename.endswith('/__init__.pyc') or \
               filename.endswith('/__init__.pyo') or \
               filename.endswith('/__init__.py'):
                components = filename.split('/')[:-1]
                moduleName = '.'.join(components)
                VFSImporter.sharedPackages[moduleName] = True

        # Fix up any shared directories so we can load packages from
        # disparate locations.
        VFSImporter.reloadSharedPackages()

        self.installed = True
        appRunner.installedPackages.append(self)

        self.markUsed()

        return True
示例#22
0
    def installPackage(self, appRunner):
        """ Mounts the package and sets up system paths so it becomes
        available for use.  Returns true on success, false on failure. """

        assert self.hasPackage
        if self.installed:
            # Already installed.
            return True
        assert self not in appRunner.installedPackages

        mfPathname = Filename(self.getPackageDir(), self.uncompressedArchive.filename)
        mf = Multifile()
        if not mf.openRead(mfPathname):
            self.notify.warning("Couldn't open %s" % (mfPathname))
            return False

        # We mount it under its actual location on disk.
        root = self.getPackageDir().cStr()

        vfs = VirtualFileSystem.getGlobalPtr()
        vfs.mount(mf, root, vfs.MFReadOnly)

        # Add this to the Python search path, if it's not already
        # there.  We have to take a bit of care to check if it's
        # already there, since there can be some ambiguity in
        # os-specific path strings.
        osRoot = self.getPackageDir().toOsSpecific()
        foundOnPath = False
        for p in sys.path:
            if osRoot == p:
                # Already here, exactly.
                foundOnPath = True
                break
            elif osRoot == Filename.fromOsSpecific(p).toOsSpecific():
                # Already here, with some futzing.
                foundOnPath = True
                break

        if not foundOnPath:
            # Not already here; add it.
            sys.path.append(osRoot)

        # Put it on the model-path, too.  We do this indiscriminantly,
        # because the Panda3D runtime won't be adding things to the
        # model-path, so it shouldn't be already there.
        getModelPath().appendDirectory(self.getPackageDir())

        # Set the environment variable to reference the package root.
        envvar = '%s_ROOT' % (self.packageName.upper())
        ExecutionEnvironment.setEnvironmentVariable(envvar, osRoot)

        # Now that the environment variable is set, read all of the
        # prc files in the package.
        appRunner.loadMultifilePrcFiles(mf, self.getPackageDir())

        # Also, find any toplevel Python packages, and add these as
        # shared packages.  This will allow different packages
        # installed in different directories to share Python files as
        # if they were all in the same directory.
        for filename in mf.getSubfileNames():
            if filename.endswith('/__init__.pyc') or \
               filename.endswith('/__init__.pyo') or \
               filename.endswith('/__init__.py'):
                components = filename.split('/')[:-1]
                moduleName = '.'.join(components)
                VFSImporter.sharedPackages[moduleName] = True

        # Fix up any shared directories so we can load packages from
        # disparate locations.
        VFSImporter.reloadSharedPackages()

        self.installed = True
        appRunner.installedPackages.append(self)

        self.markUsed()

        return True
示例#23
0
 def containsResource(self, filename):
     vfs = VirtualFileSystem.getGlobalPtr()
     vfs.chdir(self.mountPoint)
     flag = vfs.exists(Filename(filename))
     vfs.chdir(self.mountPoint)
     return flag
示例#24
0
    def setP3DFilename(self,
                       p3dFilename,
                       tokens,
                       argv,
                       instanceId,
                       interactiveConsole,
                       p3dOffset=0):
        """ Called by the browser to specify the p3d file that
        contains the application itself, along with the web tokens
        and/or command-line arguments.  Once this method has been
        called, the application is effectively started. """

        # One day we will have support for multiple instances within a
        # Python session.  Against that day, we save the instance ID
        # for this instance.
        self.instanceId = instanceId

        self.tokens = tokens
        self.argv = argv

        # We build up a token dictionary with care, so that if a given
        # token appears twice in the token list, we record only the
        # first value, not the second or later.  This is consistent
        # with the internal behavior of the core API.
        self.tokenDict = {}
        for token, keyword in tokens:
            self.tokenDict.setdefault(token, keyword)

        # Also store the arguments on sys, for applications that
        # aren't instance-ready.
        sys.argv = argv

        # That means we now know the altHost in effect.
        self.altHost = self.tokenDict.get('alt_host', None)

        # Tell the browser that Python is up and running, and ready to
        # respond to queries.
        self.notifyRequest('onpythonload')

        # Now go load the applet.
        fname = Filename.fromOsSpecific(p3dFilename)
        vfs = VirtualFileSystem.getGlobalPtr()

        if not vfs.exists(fname):
            raise ArgumentError, "No such file: %s" % (p3dFilename)

        fname.makeAbsolute()
        mf = Multifile()
        if p3dOffset == 0:
            if not mf.openRead(fname):
                raise ArgumentError, "Not a Panda3D application: %s" % (
                    p3dFilename)
        else:
            if not mf.openRead(fname, p3dOffset):
                raise ArgumentError, "Not a Panda3D application: %s at offset: %s" % (
                    p3dFilename, p3dOffset)

        # Now load the p3dInfo file.
        self.p3dInfo = None
        self.p3dPackage = None
        self.p3dConfig = None
        self.allowPythonDev = False

        i = mf.findSubfile('p3d_info.xml')
        if i >= 0 and hasattr(PandaModules, 'readXmlStream'):
            stream = mf.openReadSubfile(i)
            self.p3dInfo = PandaModules.readXmlStream(stream)
            mf.closeReadSubfile(stream)
        if self.p3dInfo:
            self.p3dPackage = self.p3dInfo.FirstChildElement('package')
        if self.p3dPackage:
            self.p3dConfig = self.p3dPackage.FirstChildElement('config')

            xhost = self.p3dPackage.FirstChildElement('host')
            while xhost:
                self.__readHostXml(xhost)
                xhost = xhost.NextSiblingElement('host')

        if self.p3dConfig:
            allowPythonDev = self.p3dConfig.Attribute('allow_python_dev')
            if allowPythonDev:
                self.allowPythonDev = int(allowPythonDev)
            guiApp = self.p3dConfig.Attribute('gui_app')
            if guiApp:
                self.guiApp = int(guiApp)

            trueFileIO = self.p3dConfig.Attribute('true_file_io')
            if trueFileIO:
                self.trueFileIO = int(trueFileIO)

        # The interactiveConsole flag can only be set true if the
        # application has allow_python_dev set.
        if not self.allowPythonDev and interactiveConsole:
            raise StandardError, "Impossible, interactive_console set without allow_python_dev."
        self.interactiveConsole = interactiveConsole

        if self.allowPythonDev:
            # Set the fps text to remind the user that
            # allow_python_dev is enabled.
            ConfigVariableString('frame-rate-meter-text-pattern').setValue(
                'allow_python_dev %0.1f fps')

        if self.guiApp:
            initAppForGui()

        self.initPackedAppEnvironment()

        # Mount the Multifile under self.multifileRoot.
        vfs.mount(mf, self.multifileRoot, vfs.MFReadOnly)
        VFSImporter.reloadSharedPackages()

        self.loadMultifilePrcFiles(mf, self.multifileRoot)
        self.gotP3DFilename = True

        # Send this call to the main thread; don't call it directly.
        messenger.send('AppRunner_startIfReady', taskChain='default')
    def installPackagesInto(self, hostDir, platform):
        """ Installs the packages required by the .p3d file into
        the specified directory, for the given platform. """

        if not self.includeRequires:
            return

        pkgTree = PackageTree(platform, hostDir, self.hostUrl)
        pkgTree.installPackage("images", None, self.standalone.host.hostUrl)

        for name, version, hostUrl in self.requires:
            pkgTree.installPackage(name, version, hostUrl)

        # Remove the extracted files from the compressed archive, to save space.
        vfs = VirtualFileSystem.getGlobalPtr()
        for package in pkgTree.packages.values():
            if package.uncompressedArchive:
                archive = Filename(package.getPackageDir(), package.uncompressedArchive.filename)
                if not archive.exists():
                    continue

                mf = Multifile()
                # Make sure that it isn't mounted before altering it, just to be safe
                vfs.unmount(archive)
                os.chmod(archive.toOsSpecific(), 0644)
                if not mf.openReadWrite(archive):
                    Installer.notify.warning("Failed to open archive %s" % (archive))
                    continue

                # We don't iterate over getNumSubfiles because we're
                # removing subfiles while we're iterating over them.
                subfiles = mf.getSubfileNames()
                for subfile in subfiles:
                    # We do *NOT* call vfs.exists here in case the package is mounted.
                    if Filename(package.getPackageDir(), subfile).exists():
                        Installer.notify.debug("Removing already-extracted %s from multifile" % (subfile))
                        mf.removeSubfile(subfile)

                # This seems essential for mf.close() not to crash later.
                mf.repack()

                # If we have no subfiles left, we can just remove the multifile.
                # if mf.getNumSubfiles() == 0:
                #    Installer.notify.info("Removing empty archive %s" % (package.uncompressedArchive.filename))
                #    mf.close()
                #    archive.unlink()
                # else:
                mf.close()
                try:
                    os.chmod(archive.toOsSpecific(), 0444)
                except:
                    pass

        # Write out our own contents.xml file.
        doc = TiXmlDocument()
        decl = TiXmlDeclaration("1.0", "utf-8", "")
        doc.InsertEndChild(decl)

        xcontents = TiXmlElement("contents")
        for package in pkgTree.packages.values():
            xpackage = TiXmlElement("package")
            xpackage.SetAttribute("name", package.packageName)
            if package.platform:
                xpackage.SetAttribute("platform", package.platform)
                assert package.platform == platform
            if package.packageVersion:
                xpackage.SetAttribute("version", version)
                xpackage.SetAttribute(
                    "filename", package.packageName + "/" + package.packageVersion + "/" + package.descFileBasename
                )
            else:
                xpackage.SetAttribute("filename", package.packageName + "/" + package.descFileBasename)
            xcontents.InsertEndChild(xpackage)

        doc.InsertEndChild(xcontents)
        doc.SaveFile(Filename(hostDir, "contents.xml").toOsSpecific())
示例#26
0
 def dispose(self):
     vfs = VirtualFileSystem.getGlobalPtr()
     vfs.unmountPoint(Filename(self.mountPoint))
示例#27
0
from pandac.PandaModules import VirtualFileSystem, VirtualFileMountSystem, Filename, TiXmlDocument

vfs = VirtualFileSystem.getGlobalPtr()


class ScanDirectoryNode:
    """ This class is used to scan a list of files on disk. """
    def __init__(self, pathname, ignoreUsageXml=False):
        self.pathname = pathname
        self.filenames = []
        self.fileSize = 0
        self.nested = []
        self.nestedSize = 0

        xusage = None
        if not ignoreUsageXml:
            # Look for a usage.xml file in this directory.  If we find
            # one, we read it for the file size and then stop here, as
            # an optimization.
            usageFilename = Filename(pathname, 'usage.xml')
            doc = TiXmlDocument(usageFilename.toOsSpecific())
            if doc.LoadFile():
                xusage = doc.FirstChildElement('usage')
                if xusage:
                    diskSpace = xusage.Attribute('disk_space')
                    try:
                        diskSpace = int(diskSpace or '')
                    except ValueError:
                        diskSpace = None
                    if diskSpace is not None:
                        self.fileSize = diskSpace
示例#28
0
 def indexResources(self):        
     vfs = VirtualFileSystem.getGlobalPtr()
     vfs.mount(Filename(self.filename), self.mountPoint, VirtualFileSystem.MFReadOnly)        
    def setP3DFilename(self, p3dFilename, tokens, argv, instanceId,
                       interactiveConsole, p3dOffset = 0):
        """ Called by the browser to specify the p3d file that
        contains the application itself, along with the web tokens
        and/or command-line arguments.  Once this method has been
        called, the application is effectively started. """

        # One day we will have support for multiple instances within a
        # Python session.  Against that day, we save the instance ID
        # for this instance.
        self.instanceId = instanceId

        self.tokens = tokens
        self.argv = argv

        # We build up a token dictionary with care, so that if a given
        # token appears twice in the token list, we record only the
        # first value, not the second or later.  This is consistent
        # with the internal behavior of the core API.
        self.tokenDict = {}
        for token, keyword in tokens:
            self.tokenDict.setdefault(token, keyword)

        # Also store the arguments on sys, for applications that
        # aren't instance-ready.
        sys.argv = argv

        # That means we now know the altHost in effect.
        self.altHost = self.tokenDict.get('alt_host', None)

        # Tell the browser that Python is up and running, and ready to
        # respond to queries.
        self.notifyRequest('onpythonload')

        # Now go load the applet.
        fname = Filename.fromOsSpecific(p3dFilename)
        vfs = VirtualFileSystem.getGlobalPtr()

        if not vfs.exists(fname):
            raise ArgumentError, "No such file: %s" % (p3dFilename)

        fname.makeAbsolute()
        mf = Multifile()
        if p3dOffset == 0:
            if not mf.openRead(fname):
                raise ArgumentError, "Not a Panda3D application: %s" % (p3dFilename)
        else:
            if not mf.openRead(fname, p3dOffset):
                raise ArgumentError, "Not a Panda3D application: %s at offset: %s" % (p3dFilename, p3dOffset)

        # Now load the p3dInfo file.
        self.p3dInfo = None
        self.p3dPackage = None
        self.p3dConfig = None
        self.allowPythonDev = False

        i = mf.findSubfile('p3d_info.xml')
        if i >= 0 and hasattr(PandaModules, 'readXmlStream'):
            stream = mf.openReadSubfile(i)
            self.p3dInfo = PandaModules.readXmlStream(stream)
            mf.closeReadSubfile(stream)
        if self.p3dInfo:
            self.p3dPackage = self.p3dInfo.FirstChildElement('package')
        if self.p3dPackage:
            self.p3dConfig = self.p3dPackage.FirstChildElement('config')

            xhost = self.p3dPackage.FirstChildElement('host')
            while xhost:
                self.__readHostXml(xhost)
                xhost = xhost.NextSiblingElement('host')

        if self.p3dConfig:
            allowPythonDev = self.p3dConfig.Attribute('allow_python_dev')
            if allowPythonDev:
                self.allowPythonDev = int(allowPythonDev)
            guiApp = self.p3dConfig.Attribute('gui_app')
            if guiApp:
                self.guiApp = int(guiApp)

            trueFileIO = self.p3dConfig.Attribute('true_file_io')
            if trueFileIO:
                self.trueFileIO = int(trueFileIO)

        # The interactiveConsole flag can only be set true if the
        # application has allow_python_dev set.
        if not self.allowPythonDev and interactiveConsole:
            raise StandardError, "Impossible, interactive_console set without allow_python_dev."
        self.interactiveConsole = interactiveConsole

        if self.allowPythonDev:
            # Set the fps text to remind the user that
            # allow_python_dev is enabled.
            ConfigVariableString('frame-rate-meter-text-pattern').setValue('allow_python_dev %0.1f fps')

        if self.guiApp:
            initAppForGui()

        self.initPackedAppEnvironment()

        # Mount the Multifile under self.multifileRoot.
        vfs.mount(mf, self.multifileRoot, vfs.MFReadOnly)
        VFSImporter.reloadSharedPackages()

        self.loadMultifilePrcFiles(mf, self.multifileRoot)
        self.gotP3DFilename = True

        # Send this call to the main thread; don't call it directly.
        messenger.send('AppRunner_startIfReady', taskChain = 'default')
    def installPackagesInto(self, hostDir, platform):
        """ Installs the packages required by the .p3d file into
        the specified directory, for the given platform. """

        if not self.includeRequires:
            return

        pkgTree = PackageTree(platform, hostDir, self.hostUrl)
        pkgTree.installPackage("images", None, self.standalone.host.hostUrl)

        for name, version, hostUrl in self.requires:
            pkgTree.installPackage(name, version, hostUrl)

        # Remove the extracted files from the compressed archive, to save space.
        vfs = VirtualFileSystem.getGlobalPtr()
        for package in pkgTree.packages.values():
            if package.uncompressedArchive:
                archive = Filename(package.getPackageDir(),
                                   package.uncompressedArchive.filename)
                if not archive.exists():
                    continue

                mf = Multifile()
                # Make sure that it isn't mounted before altering it, just to be safe
                vfs.unmount(archive)
                os.chmod(archive.toOsSpecific(), 0644)
                if not mf.openReadWrite(archive):
                    Installer.notify.warning("Failed to open archive %s" %
                                             (archive))
                    continue

                # We don't iterate over getNumSubfiles because we're
                # removing subfiles while we're iterating over them.
                subfiles = mf.getSubfileNames()
                for subfile in subfiles:
                    # We do *NOT* call vfs.exists here in case the package is mounted.
                    if Filename(package.getPackageDir(), subfile).exists():
                        Installer.notify.debug(
                            "Removing already-extracted %s from multifile" %
                            (subfile))
                        mf.removeSubfile(subfile)

                # This seems essential for mf.close() not to crash later.
                mf.repack()

                # If we have no subfiles left, we can just remove the multifile.
                #if mf.getNumSubfiles() == 0:
                #    Installer.notify.info("Removing empty archive %s" % (package.uncompressedArchive.filename))
                #    mf.close()
                #    archive.unlink()
                #else:
                mf.close()
                try:
                    os.chmod(archive.toOsSpecific(), 0444)
                except:
                    pass

        # Write out our own contents.xml file.
        doc = TiXmlDocument()
        decl = TiXmlDeclaration("1.0", "utf-8", "")
        doc.InsertEndChild(decl)

        xcontents = TiXmlElement("contents")
        for package in pkgTree.packages.values():
            xpackage = TiXmlElement('package')
            xpackage.SetAttribute('name', package.packageName)
            if package.platform:
                xpackage.SetAttribute('platform', package.platform)
                assert package.platform == platform
            if package.packageVersion:
                xpackage.SetAttribute('version', version)
                xpackage.SetAttribute(
                    'filename', package.packageName + "/" +
                    package.packageVersion + "/" + package.descFileBasename)
            else:
                xpackage.SetAttribute(
                    'filename',
                    package.packageName + "/" + package.descFileBasename)
            xcontents.InsertEndChild(xpackage)

        doc.InsertEndChild(xcontents)
        doc.SaveFile(Filename(hostDir, "contents.xml").toOsSpecific())
from pandac.PandaModules import VirtualFileSystem, VirtualFileMountSystem, Filename, TiXmlDocument
vfs = VirtualFileSystem.getGlobalPtr()

class ScanDirectoryNode:
    """ This class is used to scan a list of files on disk. """

    def __init__(self, pathname, ignoreUsageXml = False):
        self.pathname = pathname
        self.filenames = []
        self.fileSize = 0
        self.nested = []
        self.nestedSize = 0

        xusage = None
        if not ignoreUsageXml:
            # Look for a usage.xml file in this directory.  If we find
            # one, we read it for the file size and then stop here, as
            # an optimization.
            usageFilename = Filename(pathname, 'usage.xml')
            doc = TiXmlDocument(usageFilename.toOsSpecific())
            if doc.LoadFile():
                xusage = doc.FirstChildElement('usage')
                if xusage:
                    diskSpace = xusage.Attribute('disk_space')
                    try:
                        diskSpace = int(diskSpace or '')
                    except ValueError:
                        diskSpace = None
                    if diskSpace is not None:
                        self.fileSize = diskSpace
                        return
示例#32
0
def runPackedApp(args):
    if not args:
        raise ArgumentError, "No Panda app specified.  Use:\npython RunAppMF.py app.mf"

    vfs = VirtualFileSystem.getGlobalPtr()

    fname = Filename.fromOsSpecific(args[0])
    if not vfs.exists(fname):
        raise ArgumentError, "No such file: %s" % (args[0])

    mf = Multifile()
    if not mf.openRead(fname):
        raise ArgumentError, "Not a Panda Multifile: %s" % (args[0])

    # Clear *all* the mount points, including "/", so that we no
    # longer access the disk directly.
    vfs.unmountAll()

    # Mount the Multifile under /mf, by convention, and make that our
    # "current directory".
    vfs.mount(mf, MultifileRoot, vfs.MFReadOnly)
    vfs.chdir(MultifileRoot)

    # Make sure the directories on our standard Python path are mounted
    # read-only, so we can still load Python.
    for dirname in sys.path:
        vfs.mount(dirname, dirname, vfs.MFReadOnly)

    # Also mount some standard directories read-write (temporary and
    # app-data directories).
    tdir = Filename.temporary('', '')
    for dirname in set([
            tdir.getDirname(),
            Filename.getTempDirectory().cStr(),
            Filename.getUserAppdataDirectory().cStr(),
            Filename.getCommonAppdataDirectory().cStr()
    ]):
        vfs.mount(dirname, dirname, 0)

    # Now set up Python to import this stuff.
    VFSImporter.register()
    sys.path = [MultifileRoot] + sys.path

    # Put our root directory on the model-path and prc-path, too.
    getModelPath().prependDirectory(MultifileRoot)

    # Load the implicit App.prc file.
    loadPrcFileData(AppPrcFilename, AppPrc)

    # Load any prc files in the root.  We have to load them
    # explicitly, since the ConfigPageManager can't directly look
    # inside the vfs.
    for f in vfs.scanDirectory(MultifileRoot):
        if f.getFilename().getExtension() == 'prc':
            data = f.readFile(True)
            loadPrcFileData(f.getFilename().cStr(), data)

    # Replace the builtin open and file symbols so user code will get
    # our versions by default, which can open and read files out of
    # the multifile.
    __builtin__.file = file.file
    __builtin__.open = file.open
    os.listdir = file.listdir
    os.walk = file.walk

    import main
    if hasattr(main, 'main') and callable(main.main):
        main.main()
示例#33
0
 def getResourceStream(self, name):
     vfs = VirtualFileSystem.getGlobalPtr()
     istream = vfs.openReadFile(Filename(name))
     return istream