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 files = vfs.scanDirectory(self.pathname) if files is None: files = [] for vfile in files: if hasattr(vfile, 'getMount'): if not isinstance(vfile.getMount(), VirtualFileMountSystem): # Not a real file; ignore it. continue if vfile.isDirectory(): # A nested directory. subdir = ScanDirectoryNode(vfile.getFilename(), ignoreUsageXml=ignoreUsageXml) self.nested.append(subdir) self.nestedSize += subdir.getTotalSize() elif vfile.isRegularFile(): # A nested file. self.filenames.append(vfile.getFilename()) self.fileSize += vfile.getFileSize() else: # Some other wacky file thing. self.filenames.append(vfile.getFilename()) if xusage: # Now update the usage.xml file with the newly-determined # disk space. xusage.SetAttribute('disk_space', str(self.getTotalSize())) tfile = Filename.temporary(str(pathname), '.xml') if doc.SaveFile(tfile.toOsSpecific()): tfile.renameTo(usageFilename)
def getUsage(self): """ Returns the xusage element that is read from the usage.xml file, or None if there is no usage.xml file. """ if not hasattr(core, 'TiXmlDocument'): return None filename = Filename(self.getPackageDir(), self.UsageBasename) doc = TiXmlDocument(filename.toOsSpecific()) if not doc.LoadFile(): return None xusage = doc.FirstChildElement('usage') if not xusage: return None return copy.copy(xusage)
def writeConfigXml(self): """ Rewrites the config.xml to the root directory. This isn't called automatically; an application may call this after adjusting some parameters (such as self.maxDiskUsage). """ from panda3d.core import TiXmlDocument, TiXmlDeclaration, TiXmlElement filename = Filename(self.rootDir, self.ConfigBasename) doc = TiXmlDocument(filename.toOsSpecific()) decl = TiXmlDeclaration("1.0", "utf-8", "") doc.InsertEndChild(decl) xconfig = TiXmlElement('config') xconfig.SetAttribute('max_disk_usage', str(self.maxDiskUsage)) doc.InsertEndChild(xconfig) # Write the file to a temporary filename, then atomically move # it to its actual filename, to avoid race conditions when # updating this file. tfile = Filename.temporary(str(self.rootDir), '.xml') if doc.SaveFile(tfile.toOsSpecific()): tfile.renameTo(filename)
def markUsed(self): """ Marks the package as having been used. This is normally called automatically by installPackage(). """ if not hasattr(core, 'TiXmlDocument'): return if self.host.appRunner and self.host.appRunner.verifyContents == self.host.appRunner.P3DVCNever: # Not allowed to write any files to the package directory. return if self.updated: # If we've just installed a new version of the package, # re-measure the actual disk space used. self.diskSpace = self.__measureDiskSpace() filename = Filename(self.getPackageDir(), self.UsageBasename) doc = TiXmlDocument(filename.toOsSpecific()) if not doc.LoadFile(): decl = TiXmlDeclaration("1.0", "utf-8", "") doc.InsertEndChild(decl) xusage = doc.FirstChildElement('usage') if not xusage: doc.InsertEndChild(TiXmlElement('usage')) xusage = doc.FirstChildElement('usage') now = int(time.time()) count = xusage.Attribute('count_app') try: count = int(count or '') except ValueError: count = 0 xusage.SetAttribute('first_use', str(now)) count += 1 xusage.SetAttribute('count_app', str(count)) xusage.SetAttribute('last_use', str(now)) if self.updated: xusage.SetAttribute('last_update', str(now)) self.updated = False else: # Since we haven't changed the disk space, we can just # read it from the previous xml file. diskSpace = xusage.Attribute('disk_space') try: diskSpace = int(diskSpace or '') except ValueError: # Unless it wasn't set already. self.diskSpace = self.__measureDiskSpace() xusage.SetAttribute('disk_space', str(self.diskSpace)) # Write the file to a temporary filename, then atomically move # it to its actual filename, to avoid race conditions when # updating this file. tfile = Filename.temporary(str(self.getPackageDir()), '.xml') if doc.SaveFile(tfile.toOsSpecific()): tfile.renameTo(filename)