def readContentsFile(self, tempFilename = None, freshDownload = False): """ Reads the contents.xml file for this particular host, once it has been downloaded into the indicated temporary file. Returns true on success, false if the contents file is not already on disk or is unreadable. If tempFilename is specified, it is the filename read, and it is copied the file into the standard location if it's not there already. If tempFilename is not specified, the standard filename is read if it is known. """ if not hasattr(PandaModules, 'TiXmlDocument'): return False if not tempFilename: if self.hostDir: # If the filename is not specified, we can infer it # if we already know our hostDir hostDir = self.hostDir else: # Otherwise, we have to guess the hostDir. hostDir = self.__determineHostDir(None, self.hostUrl) tempFilename = Filename(hostDir, 'contents.xml') doc = PandaModules.TiXmlDocument(tempFilename.toOsSpecific()) if not doc.LoadFile(): return False xcontents = doc.FirstChildElement('contents') if not xcontents: return False maxAge = xcontents.Attribute('max_age') if maxAge: try: maxAge = int(maxAge) except: maxAge = None if maxAge is None: # Default max_age if unspecified (see p3d_plugin.h). from direct.p3d.AppRunner import AppRunner maxAge = AppRunner.P3D_CONTENTS_DEFAULT_MAX_AGE # Get the latest possible expiration time, based on the max_age # indication. Any expiration time later than this is in error. now = int(time.time()) self.contentsExpiration = now + maxAge if freshDownload: self.contentsSpec.readHash(tempFilename) # Update the XML with the new download information. xorig = xcontents.FirstChildElement('orig') while xorig: xcontents.RemoveChild(xorig) xorig = xcontents.FirstChildElement('orig') xorig = PandaModules.TiXmlElement('orig') self.contentsSpec.storeXml(xorig) xorig.SetAttribute('expiration', str(self.contentsExpiration)) xcontents.InsertEndChild(xorig) else: # Read the download hash and expiration time from the XML. expiration = None xorig = xcontents.FirstChildElement('orig') if xorig: self.contentsSpec.loadXml(xorig) expiration = xorig.Attribute('expiration') if expiration: try: expiration = int(expiration) except: expiration = None if not self.contentsSpec.hash: self.contentsSpec.readHash(tempFilename) if expiration is not None: self.contentsExpiration = min(self.contentsExpiration, expiration) # Look for our own entry in the hosts table. if self.hostUrl: self.__findHostXml(xcontents) else: assert self.hostDir self.__findHostXmlForHostDir(xcontents) if not self.hostDir: self.hostDir = self.__determineHostDir(None, self.hostUrl) # Get the list of packages available for download and/or import. xpackage = xcontents.FirstChildElement('package') while xpackage: name = xpackage.Attribute('name') platform = xpackage.Attribute('platform') version = xpackage.Attribute('version') try: solo = int(xpackage.Attribute('solo') or '') except ValueError: solo = False package = self.__makePackage(name, platform, version, solo) package.descFile = FileSpec() package.descFile.loadXml(xpackage) package.setupFilenames() package.importDescFile = None ximport = xpackage.FirstChildElement('import') if ximport: package.importDescFile = FileSpec() package.importDescFile.loadXml(ximport) xpackage = xpackage.NextSiblingElement('package') self.hasContentsFile = True # Now save the contents.xml file into the standard location. if not self.appRunner or self.appRunner.verifyContents != self.appRunner.P3DVCNever: assert self.hostDir filename = Filename(self.hostDir, 'contents.xml') filename.makeDir() if freshDownload: doc.SaveFile(filename.toOsSpecific()) else: if filename != tempFilename: tempFilename.copyTo(filename) return True
def __readDescFile(self): """ Reads the desc xml file for this particular package, assuming it's been already downloaded and verified. Returns true on success, false on failure. """ if self.hasDescFile: # No need to read it again. return True if self.solo: # If this is a "solo" package, we don't actually "read" # the desc file; that's the entire contents of the # package. self.hasDescFile = True self.hasPackage = True return True filename = Filename(self.getPackageDir(), self.descFileBasename) if not hasattr(PandaModules, 'TiXmlDocument'): return False doc = PandaModules.TiXmlDocument(filename.toOsSpecific()) if not doc.LoadFile(): return False xpackage = doc.FirstChildElement('package') if not xpackage: return False try: self.patchVersion = int(xpackage.Attribute('patch_version') or '') except ValueError: self.patchVersion = None self.displayName = None xconfig = xpackage.FirstChildElement('config') if xconfig: # The name for display to an English-speaking user. self.displayName = xconfig.Attribute('display_name') # True if any apps that use this package must be GUI apps. guiApp = xconfig.Attribute('gui_app') if guiApp: self.guiApp = int(guiApp) # The uncompressed archive, which will be mounted directly, # and also used for patching. xuncompressedArchive = xpackage.FirstChildElement( 'uncompressed_archive') if xuncompressedArchive: self.uncompressedArchive = FileSpec() self.uncompressedArchive.loadXml(xuncompressedArchive) # The compressed archive, which is what is downloaded. xcompressedArchive = xpackage.FirstChildElement('compressed_archive') if xcompressedArchive: self.compressedArchive = FileSpec() self.compressedArchive.loadXml(xcompressedArchive) # The list of files that should be extracted to disk. self.extracts = [] xextract = xpackage.FirstChildElement('extract') while xextract: file = FileSpec() file.loadXml(xextract) self.extracts.append(file) xextract = xextract.NextSiblingElement('extract') # The list of additional packages that must be installed for # this package to function properly. self.requires = [] xrequires = xpackage.FirstChildElement('requires') while xrequires: packageName = xrequires.Attribute('name') version = xrequires.Attribute('version') hostUrl = xrequires.Attribute('host') if packageName and hostUrl: host = self.host.appRunner.getHostWithAlt(hostUrl) self.requires.append((packageName, version, host)) xrequires = xrequires.NextSiblingElement('requires') self.hasDescFile = True # Now that we've read the desc file, go ahead and use it to # verify the download status. if self.__checkArchiveStatus(): # It's all fully downloaded, unpacked, and ready. self.hasPackage = True return True # Still have to download it. self.__buildInstallPlans() return True