def downloadDescFileGenerator(self, http): """ A generator function that implements downloadDescFile() one piece at a time. It yields one of stepComplete, stepFailed, or stepContinue. """ assert self.descFile if self.hasDescFile: # We've already got one. yield self.stepComplete return if self.host.appRunner and self.host.appRunner.verifyContents != self.host.appRunner.P3DVCNever: # We're allowed to download it. self.http = http func = lambda step, self=self: self.__downloadFile( None, self.descFile, urlbase=self.descFile.filename, filename=self.descFileBasename ) step = self.InstallStep(func, self.descFile.size, self.downloadFactor, "downloadDesc") for token in step.func(): if token == self.stepContinue: yield token else: break while token == self.restartDownload: # Try again. func = lambda step, self=self: self.__downloadFile( None, self.descFile, urlbase=self.descFile.filename, filename=self.descFileBasename ) step = self.InstallStep(func, self.descFile.size, self.downloadFactor, "downloadDesc") for token in step.func(): if token == self.stepContinue: yield token else: break if token == self.stepFailed: # Couldn't download the desc file. yield self.stepFailed return assert token == self.stepComplete filename = Filename(self.getPackageDir(), self.descFileBasename) # Now that we've written the desc file, make it read-only. os.chmod(filename.toOsSpecific(), 0444) if not self.__readDescFile(): # Weird, it passed the hash check, but we still can't read # it. filename = Filename(self.getPackageDir(), self.descFileBasename) self.notify.warning("Failure reading %s" % (filename)) yield self.stepFailed return yield self.stepComplete return
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 downloadIndexTask(self, task): if self.ch.run(): return task.cont if not self.ch.isValid(): self.notify.warning('Unable to download %s' % self.url) self.redownloadingNews = False return task.done self.newsFiles = [] filename = self.rf.readline() while filename: filename = filename.strip() if filename: self.newsFiles.append(filename) filename = self.rf.readline() del self.rf self.newsFiles.sort() self.newsIndexEntries = list(self.newsFiles) self.notify.info('Server lists %s news files' % len(self.newsFiles)) self.notify.debug('self.newsIndexEntries=%s' % self.newsIndexEntries) self.readNewsCache() for basename in os.listdir(self.newsDir.toOsSpecific()): if basename != self.CacheIndexFilename and basename not in self.newsCache: junk = Filename(self.newsDir, basename) self.notify.info('Removing %s' % junk) junk.unlink() self.nextNewsFile = 0 return self.downloadNextFile(task)
def reloadTextures(textureName=''): """ Artfart command to reload all of the textures. TODO: A panel that says "Reloading textures... Please wait!" ...though it's not important since it's a staff command and only staff will see it. Stolen from ToontownStart.py Remount all phase files. This maybe might work? Idk. Lets see if Panda craps itself. Place raw files in /resources/non-mf/phase_*/ and they will be mounted without needing to multify! """ # Lock ... vfs = VirtualFileSystem.getGlobalPtr() for file in glob.glob('resources/non-mf/phase_*/'): # Slightly hacky. We remove the trailing slash so we have a tail, # and select the tail value from the returned tuple. Finally we # prepend a slash for the mount point. mount_point = '/' + str(os.path.split(file[:-1])[1]) vfs.mount(Filename(file), Filename(mount_point), 0) # ... and load. if textureName: pool = TexturePool.findAllTextures('*' + textureName + '*') else: pool = TexturePool.findAllTextures() for texture in pool: texture.reload() if textureName: return "Reloaded all textures matching '%s'" % textureName return "Reloaded all of the textures!"
def setInstanceInfo(self, rootDir, logDirectory, superMirrorUrl, verifyContents, main): """ Called by the browser to set some global information about the instance. """ # rootDir is the root Panda3D install directory on the local # machine. self.rootDir = Filename.fromOsSpecific(rootDir) # logDirectory is the directory name where all log files end # up. if logDirectory: self.logDirectory = Filename.fromOsSpecific(logDirectory) else: self.logDirectory = Filename(rootDir, 'log') # The "super mirror" URL, generally used only by panda3d.exe. self.superMirrorUrl = superMirrorUrl # How anxious should we be about contacting the server for # the latest code? self.verifyContents = verifyContents # The initial "main" object, if specified. if main is not None: self.main = main # Now that we have rootDir, we can read the config file. self.readConfigXml()
def parseNewsContent(self): """Open up the directory, read all the files, and figure out the structure.""" for section,ident in enumerate(self.SectionIdents): subSectionList = [] curSubSection = 0 endSearch = False; while not endSearch: justName = self.ContentPattern % (self.dateStr, ident, curSubSection +1) fullName = Filename(self.newsDir + '/' + justName) if self.strFilenames: # we already have a list of filenames, check if it's in there if justName in self.strFilenames: subSectionList.append(fullName) self.flatSubsectionList.append((section, curSubSection)) curSubSection +=1 else: endSearch = True else: theFile = vfs.getFile(Filename(fullName), status_only=1) if theFile: subSectionList.append(fullName) self.flatSubsectionList.append((section, curSubSection)) curSubSection +=1 else: endSearch = True if not subSectionList: # we have one of the required files missing, # put a string inside to indicate its gone wrong self.notify.warning("Could not load %s" % fullName) subSectionList.append("error_" + str(fullName)) self.flatSubsectionList.append((section,0)) self.sectionList.append(subSectionList) self.notify.debug("%s" % self.sectionList)
def getPackageDir(self): """ Returns the directory in which this package is installed. This may not be known until the host's contents.xml file has been downloaded, which informs us of the host's own install directory. """ if not self.packageDir: if not self.host.hasContentsFile: if not self.host.readContentsFile(): self.host.downloadContentsFile(self.http) # Derive the packageDir from the hostDir. self.packageDir = Filename(self.host.hostDir, self.packageName) if self.packageVersion: self.packageDir = Filename(self.packageDir, self.packageVersion) if self.host.perPlatform: # The server directory contains the platform name, # though the client directory normally doesn't (unless # perPlatform is set true). if self.platform: self.packageDir = Filename(self.packageDir, self.platform) return self.packageDir
def parseNewsContent(self): for (section, ident) in enumerate(self.SectionIdents): subSectionList = [] curSubSection = 0 endSearch = False while not endSearch: justName = self.ContentPattern % (self.dateStr, ident, curSubSection + 1) fullName = Filename(self.newsDir + '/' + justName) if self.strFilenames: if justName in self.strFilenames: subSectionList.append(fullName) self.flatSubsectionList.append( (section, curSubSection)) curSubSection += 1 else: endSearch = True justName in self.strFilenames theFile = vfs.getFile(Filename(fullName), status_only=1) if theFile: subSectionList.append(fullName) self.flatSubsectionList.append((section, curSubSection)) curSubSection += 1 continue endSearch = True if not subSectionList: self.notify.warning('Could not load %s' % fullName) subSectionList.append('error_' + str(fullName)) self.flatSubsectionList.append((section, 0)) self.sectionList.append(subSectionList) self.notify.debug('%s' % self.sectionList)
def redownloadNews(self): if self.redownloadingNews: self.notify.warning( 'averting potential crash redownloadNews called twice, just returning' ) return self.percentDownloaded = 0.0 self.notify.info('starting redownloadNews') self.startRedownload = datetime.datetime.now() self.redownloadingNews = True self.addDownloadingTextTask() for issue in self.issues: issue.destroy() self.issues = [] self.curIssueIndex = 0 self.strFilenames = None self.needsParseNews = True self.newsUrl = self.getInGameNewsUrl() self.newsDir = Filename(self.findNewsDir()) Filename(self.newsDir + '/.').makeDir() http = HTTPClient.getGlobalPtr() self.url = self.newsUrl + self.NewsIndexFilename self.ch = http.makeChannel(True) self.ch.beginGetDocument(self.url) self.rf = Ramfile() self.ch.downloadToRam(self.rf) taskMgr.remove(self.RedownloadTaskName) taskMgr.add(self.downloadIndexTask, self.RedownloadTaskName) return
def saveNewsCache(self): cacheIndexFilename = Filename(self.newsDir, self.CacheIndexFilename) try: file = open(cacheIndexFilename.toOsSpecific(), "w") except IOError, e: self.notify.warning("error opening news cache file %s: %s" % (cacheIndexFilename, str(e))) return
def onOpen(self, evt=None): filter = "Panda3D Egg Scene Format (*.egs)|*.[eE][gG][sS];*.egs" #filter += "|Panda3D Compressed Egg Format (*.egg.pz)|*.[eE][gG][gG].[pP][zZ];*.egg.pz" #filter += "|Panda3D Binary Format (*.bam)|*.[bB][aA][mM];*.bam" #filter += "|Panda3D Compressed Binary Format (*.bam)|*.[bB][aA][mM].[pP][zZ];*.bam.pz" ''' # disabled by hypnos, making the loading work filter += "|MultiGen (*.flt)|*.[fF][lL][tT]" filter += "|Lightwave (*.lwo)|*.[lL][wW][oO]" filter += "|AutoCAD (*.dxf)|*.[dD][xX][fF]" filter += "|VRML (*.wrl)|*.[wW][rR][lL]" filter += "|DirectX (*.x)|*.[xX]" filter += "|COLLADA (*.dae)|*.[dD][aA][eE]" ''' dlg = wx.FileDialog(self, "Load file", "", "", filter, wx.OPEN) try: if dlg.ShowModal() == wx.ID_OK: #self.filename = Filename.fromOsSpecific(dlg.GetPath()) p3dFilename = Filename.fromOsSpecific(dlg.GetPath()) self.filename = str(dlg.GetPath()) self.SetTitle(p3dFilename.getBasename() + " - Panda Editor") self.modified = False self.editorInstance.loadEggModelsFile(self.filename) # Reset the camera if base.trackball != None: base.trackball.node().setPos(0, 30, 0) base.trackball.node().setHpr(0, 15, 0) self.onCenterTrackball() if p3dFilename.getExtension().lower() != "bam": self.filename = Filename() self.modified = True self.sceneGraphTree.reload() finally: dlg.Destroy()
def makeSlopeMap(self): self.slopeMap = PNMImage() if SAVED_SLOPE_MAPS: fileName = "maps/slope/" + self.name + ".png" if self.slopeMap.read(Filename(fileName)): logging.info("read slopemap from " + fileName) return self.slopeMap = PNMImage(self.terrain.heightMapSize, self.terrain.heightMapSize) self.slopeMap.makeGrayscale() self.slopeMap.setMaxval(65535) size = self.slopeMap.getYSize() getNormal = self.getNormal setGray = self.slopeMap.setGray for x in range(size): for y in range(size): #note getNormal works at the same resolution as the heightmap normal = getNormal(x, y) # feed pixel into image # why is it necessary to invert the y axis I wonder? #logging.info( normal) normal.z /= self.terrain.getSz() normal.normalize() slope = 1.0 - normal.dot(Vec3(0, 0, 1)) setGray(x, y, slope) if SAVED_SLOPE_MAPS: fileName = "maps/slope/" + self.name + ".png" logging.info("saving slopemap to " + fileName) self.slopeMap.write(Filename(fileName))
def loaderPhaseChecker(self, path, loaderOptions): if 'audio/' in path: return 1 file = Filename(path) if not file.getExtension(): file.setExtension('bam') mp = getModelPath() path = mp.findFile(file).cStr() if not path: return match = re.match('.*phase_([^/]+)/', path) if not match: if 'dmodels' in path: return else: self.errorAccumulatorBuffer += 'file not in phase (%s, %s)\n' % (file, path) return basePhase = float(match.groups()[0]) if not launcher.getPhaseComplete(basePhase): self.errorAccumulatorBuffer += 'phase is not loaded for this model %s\n' % path model = loader.loader.loadSync(Filename(path), loaderOptions) if model: model = NodePath(model) for tex in model.findAllTextures(): texPath = tex.getFullpath().cStr() match = re.match('.*phase_([^/]+)/', texPath) if match: texPhase = float(match.groups()[0]) if texPhase > basePhase: self.errorAccumulatorBuffer += 'texture phase is higher than the models (%s, %s)\n' % (path, texPath)
def saveNewsCache(self): """ Saves self.newsCache to cache_index.txt """ cacheIndexFilename = Filename(self.newsDir, self.CacheIndexFilename) file = open(cacheIndexFilename.toOsSpecific(), 'w') for filename, (size, date) in self.newsCache.items(): print >> file, '%s\t%s\t%s' % (filename, size, date)
def downloadNextFile(self, task): while self.nextNewsFile < len(self.newsFiles) and "aaver" in self.newsFiles[self.nextNewsFile]: self.nextNewsFile += 1 if self.nextNewsFile >= len(self.newsFiles): self.notify.info("Done downloading news.") self.percentDownloaded = 1 del self.newsFiles del self.nextNewsFile del self.newsUrl del self.newsDir del self.ch del self.url if hasattr(self, "filename"): del self.filename self.redownloadingNews = False if self.active: self.parseNewsContent() return task.done self.percentDownloaded = float(self.nextNewsFile) / float(len(self.newsFiles)) self.filename = self.newsFiles[self.nextNewsFile] self.nextNewsFile += 1 self.url = self.newsUrl + self.filename localFilename = Filename(self.newsDir, self.filename) self.notify.info("testing for %s" % localFilename.getFullpath()) doc = DocumentSpec(self.url) if self.filename in self.newsCache: size, date = self.newsCache[self.filename] if date and localFilename.exists() and (size == 0 or localFilename.getFileSize() == size): doc.setDate(date) doc.setRequestMode(doc.RMNewer) self.ch.beginGetDocument(doc) self.ch.downloadToFile(localFilename) taskMgr.remove(self.RedownloadTaskName) taskMgr.add(self.downloadCurrentFileTask, self.RedownloadTaskName)
def __init__(self, useJOD=None): """ @keyword useJOD: connected to actual drumpads and spinners to read from (default: read from config.prc) @type useJOD: bool """ self.configPath = Filename("/c/jamoconfig.txt") self.logPath = Filename("/c/jamoconfig.log") self.clearConfig() self.simulate() self.log = sys.stdout self.configMissing = 0 self.hardwareChanged = 0 if (useJOD == None): useJOD = base.config.GetBool("want-jamodrum", True) self.useJOD = useJOD if (useJOD): self.setLog(self.logPath) self.devindices = range(1, base.win.getNumInputDevices()) self.readConfigFile(self.configPath) self.prepareDevices() props = WindowProperties() props.setCursorHidden(1) if (sys.platform == "win32"): props.setZOrder(WindowProperties.ZTop) base.win.requestProperties(props) self.setLog(None)
def test_load_invalid_file(self): store = DNAStorage() root = self.loader.loadDNAFile(store, Filename('invalid.pdna')) self.assertTrue(root.isEmpty()) root = self.loader.loadDNAFileAI(store, Filename('invalid.pdna')) self.assertTrue(root is None)
def downloadNextFile(self, task): while self.nextNewsFile < len(self.newsFiles) and 'aaver' in self.newsFiles[self.nextNewsFile]: self.nextNewsFile += 1 if self.nextNewsFile >= len(self.newsFiles): self.notify.info('Done downloading news.') self.percentDownloaded = 1 del self.newsFiles del self.nextNewsFile del self.newsUrl del self.newsDir del self.ch del self.url if hasattr(self, 'filename'): del self.filename self.redownloadingNews = False if self.active: self.parseNewsContent() return task.done self.percentDownloaded = float(self.nextNewsFile) / float(len(self.newsFiles)) self.filename = self.newsFiles[self.nextNewsFile] self.nextNewsFile += 1 self.url = self.newsUrl + self.filename localFilename = Filename(self.newsDir, self.filename) self.notify.info('testing for %s' % localFilename.getFullpath()) doc = DocumentSpec(self.url) if self.filename in self.newsCache: size, date = self.newsCache[self.filename] if date and localFilename.exists() and (size == 0 or localFilename.getFileSize() == size): doc.setDate(date) doc.setRequestMode(doc.RMNewer) self.ch.beginGetDocument(doc) self.ch.downloadToFile(localFilename) taskMgr.remove(self.RedownloadTaskName) taskMgr.add(self.downloadCurrentFileTask, self.RedownloadTaskName)
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 onOpen(self, evt = None): filter = "Panda3D Egg Scene Format (*.egs)|*.[eE][gG][sS];*.egs" #filter += "|Panda3D Compressed Egg Format (*.egg.pz)|*.[eE][gG][gG].[pP][zZ];*.egg.pz" #filter += "|Panda3D Binary Format (*.bam)|*.[bB][aA][mM];*.bam" #filter += "|Panda3D Compressed Binary Format (*.bam)|*.[bB][aA][mM].[pP][zZ];*.bam.pz" ''' # disabled by hypnos, making the loading work filter += "|MultiGen (*.flt)|*.[fF][lL][tT]" filter += "|Lightwave (*.lwo)|*.[lL][wW][oO]" filter += "|AutoCAD (*.dxf)|*.[dD][xX][fF]" filter += "|VRML (*.wrl)|*.[wW][rR][lL]" filter += "|DirectX (*.x)|*.[xX]" filter += "|COLLADA (*.dae)|*.[dD][aA][eE]" ''' dlg = wx.FileDialog(self, "Load file", "", "", filter, wx.OPEN) try: if dlg.ShowModal() == wx.ID_OK: #self.filename = Filename.fromOsSpecific(dlg.GetPath()) p3dFilename = Filename.fromOsSpecific(dlg.GetPath()) self.filename = str(dlg.GetPath()) self.SetTitle(p3dFilename.getBasename() + " - Panda Editor") self.modified = False self.editorInstance.loadEggModelsFile( self.filename ) # Reset the camera if base.trackball != None: base.trackball.node().setPos(0, 30, 0) base.trackball.node().setHpr(0, 15, 0) self.onCenterTrackball() if p3dFilename.getExtension().lower() != "bam": self.filename = Filename() self.modified = True self.sceneGraphTree.reload() finally: dlg.Destroy()
def __init__(self, filename, name = ""): self.filename = filename #absolute self.dir = Filename(filename.getDirname()) #[Zeina]CONSIDER: the sceneFilename can be changed to starting sceneFile or default sceneFile #The default scene file cannot be deleted. #self.sceneFilename = None #Filename(filename.getBasenameWoExtension() + '.scene') self.sceneName = None self.scenes = {}#key:Scene Name, value:Scene Filename self.scenesOrder = [] self.filenameIndexes = {} #self.addScene(filename.getBasenameWoExtension(), self.sceneFilename) self.journalFilename = Filename(filename.getBasenameWoExtension() + '.journal') self.inventoryMapFilename = Filename(filename.getBasenameWoExtension()+'.inventory') self.name = name try: f = open(filename.toOsSpecific()) self.decode(f) f.close() except IOError: pass self.addScene() #if self.scenes.has_key("startScene"): # self.sceneName = "startScene" #create the folder structure if not os.path.isdir(self.dir.toOsSpecific()): os.makedirs(self.dir.toOsSpecific()) for d in ('Models','Textures', 'Models/Thumbnails', 'Textures/Thumbnails', 'Shaders', 'Sounds', 'Journal_Entries', 'Conversations', 'Scripts'): dir = os.path.join(self.dir.toOsSpecific(),d) if not os.path.isdir(dir): os.mkdir(dir) self.lib = Library.Library(self.dir)
def saveNewsCache(self): cacheIndexFilename = Filename(self.newsDir, self.CacheIndexFilename) try: file = open(cacheIndexFilename.toOsSpecific(), 'w') except IOError, e: self.notify.warning('error opening news cache file %s: %s' % (cacheIndexFilename, str(e))) return
def loadMultifilePrcFiles(self, mf, root): """ Loads any prc files in the root of the indicated Multifile, which is presumed to have been mounted already under root. """ # We have to load these prc files explicitly, since the # ConfigPageManager can't directly look inside the vfs. Use # the Multifile interface to find the prc files, rather than # vfs.scanDirectory(), so we only pick up the files in this # particular multifile. cpMgr = ConfigPageManager.getGlobalPtr() for f in mf.getSubfileNames(): fn = Filename(f) if fn.getDirname() == '' and fn.getExtension() == 'prc': pathname = '%s/%s' % (root, f) alreadyLoaded = False for cpi in range(cpMgr.getNumImplicitPages()): if cpMgr.getImplicitPage(cpi).getName() == pathname: # No need to load this file twice. alreadyLoaded = True break if not alreadyLoaded: data = file.open(Filename(pathname), 'r').read() cp = loadPrcFileData(pathname, data) # Set it to sort value 20, behind the implicit pages. cp.setSort(20)
def downloadCurrentFileTask(self, task): if self.ch.run(): return task.cont if self.ch.getStatusCode() == 304: self.notify.info('already cached: %s' % self.filename) return self.downloadNextFile(task) localFilename = Filename(self.newsDir, self.filename) if not self.ch.isValid(): self.notify.warning('Unable to download %s' % self.url) localFilename.unlink() if self.filename in self.newsCache: del self.newsCache[self.filename] self.saveNewsCache() return self.downloadNextFile(task) self.notify.info('downloaded %s' % self.filename) size = self.ch.getFileSize() doc = self.ch.getDocumentSpec() date = '' if doc.hasDate(): date = doc.getDate().getString() self.newsCache[self.filename] = (size, date) self.saveNewsCache() return self.downloadNextFile(task)
def _compile(self, filename, source): """ Compiles the Python source code to a code object and attempts to write it to an appropriate .pyc file. """ if source and source[-1] != '\n': source = source + '\n' code = __builtin__.compile(source, filename.cStr(), 'exec') # try to cache the compiled code pycFilename = Filename(filename) pycFilename.setExtension(pycExtension) try: f = open(pycFilename, 'wb') except IOError: pass else: f.write('\0\0\0\0') f.write(struct.pack('<I', self.timestamp)) f.write(marshal.dumps(code)) f.flush() f.seek(0, 0) f.write(imp.get_magic()) f.close() return code
def downloadIndexTask(self, task): if self.ch.run(): return task.cont if not self.ch.isValid(): self.notify.warning("Unable to download %s" % self.url) self.redownloadingNews = False return task.done self.newsFiles = [] filename = self.rf.readline() while filename: filename = filename.strip() if filename: self.newsFiles.append(filename) filename = self.rf.readline() del self.rf self.newsFiles.sort() self.newsIndexEntries = list(self.newsFiles) self.notify.info("Server lists %s news files" % len(self.newsFiles)) self.notify.debug("self.newsIndexEntries=%s" % self.newsIndexEntries) self.readNewsCache() for basename in os.listdir(self.newsDir.toOsSpecific()): if basename != self.CacheIndexFilename and basename not in self.newsCache: junk = Filename(self.newsDir, basename) self.notify.info("Removing %s" % junk) junk.unlink() self.nextNewsFile = 0 return self.downloadNextFile(task)
def __init__(self, editorInstance): """EditorApp constructor.""" # Instance of the editor self.editorInstance = editorInstance # Create the Wx app self.wxApp = wx.App(redirect=False) self.wxApp.SetAppName("Panda Editor") self.wxApp.SetClassName("PEditor") self.modified = True self.filename = Filename() # Initialize the app shell and add some controls AppShell.__init__(self, title="Panda Editor", pos=origin) self.splitter1 = wx.SplitterWindow(self, style=wx.SP_3D | wx.SP_BORDER) self.splitter1.SetMinimumPaneSize(1) self.splitter2 = wx.SplitterWindow(self.splitter1, style=wx.SP_3D | wx.SP_BORDER) self.splitter2.SetMinimumPaneSize(1) self.leftBarSplitter = wx.SplitterWindow(self.splitter2, style=wx.SP_3D | wx.SP_BORDER) self.leftBarSplitter.SetMinimumPaneSize(1) #self.rightBarSplitter = wx.SplitterWindow(self.splitter1, style = wx.SP_3D | wx.SP_BORDER) #self.rightBarSplitter.SetMinimumPaneSize(1) self.sceneGraphTree = SceneGraphTree(self.leftBarSplitter) self.propertyGrid = PropertyGrid(self.leftBarSplitter) self.textureManager = TextureManager(self.splitter1, style=wx.SP_3D | wx.SUNKEN_BORDER) self.view = Viewport.makePerspective(self.splitter2) sizer = wx.BoxSizer(wx.VERTICAL) assert self.leftBarSplitter.SplitHorizontally(self.sceneGraphTree, self.propertyGrid) assert self.splitter2.SplitVertically(self.leftBarSplitter, self.view, 200) #assert self.rightBarSplitter.SplitHorizontally(self.textureManager, None) assert self.splitter1.SplitVertically(self.splitter2, self.textureManager, -200) sizer.Add(self.splitter1, 1, wx.EXPAND, 0) self.splitter1.Unsplit() # Yes, I know this looks odd. self.SetSizer(sizer) self.Layout() self.initialize() self.splitter2.SetSashPosition(200) # Setup some events base.accept("c", self.onCenterTrackball) base.accept(EVENT_MODELCONTROLLER_SELECTED_OBJECT_CHANGE, self.onModelSelect) # If a model-translate-rotate-scale tool is selected the automatic mouse # movement has to be disable to prevent camera & object movement. # Hmm doesnt really work as well... (camera is still moved) base.accept(EVENT_MODELCONTROLLER_EDITTOOL_SELECTED, lambda x=None: base.disableMouse()) base.accept(EVENT_MODELCONTROLLER_EDITTOOL_DESELECTED, lambda x=None: base.enableMouse()) base.accept(EVENT_MODELCONTROLLER_FULL_REFRESH, self.__setattr__, ["modified", True])
def __init__(self, platform, hostDir, hostUrl): self.platform = platform self.hosts = {} self.packages = {} self.hostUrl = hostUrl self.hostDir = Filename(hostDir) self.hostDir.makeDir() self.http = HTTPClient.getGlobalPtr()
def exportScripts(self, file): outputLines = [] tab = " " outputLines.append("SCRIPTS_LIST = []\n\n") #whole file for script, asset in self.editor.lib.scripts.iteritems(): #writing a script file to the whole file filename = self.editor.lib.scripts[script].getFullFilename() scriptFile = open(filename.toOsSpecific()) lines = scriptFile.readlines() mainArguments = self.getArgumentsFromScriptFile(lines) scriptFunctionName = script if(len(mainArguments) == 0): prefix = "world" else: prefix = "world, " functionHeader = "\ndef "+scriptFunctionName+"("+prefix+",".join(mainArguments)+"):\n" mainFunc = "main("+prefix+",".join(mainArguments)+")" mainFuncHeader = "def "+mainFunc+":\n" outputLines.append(functionHeader) isReturn = False for line in lines: #print line if line.strip().startswith("#"): continue if line.strip().startswith("def main"): newline = mainFuncHeader elif line.find("Interface")!=-1: newline = line.replace('Interface', "world.scriptInterface") else: newline = line if line.strip().startswith("return"): isReturn = True outputLines.append(tab+newline) if(isReturn): outputLines.append("\n"+tab+"return "+mainFunc) else: outputLines.append("\n"+tab+mainFunc) outputLines.append("\nSCRIPTS_LIST.append("+scriptFunctionName+")\n") scriptFile.close() scriptsFilename = Filename(Filename.fromOsSpecific(file).getDirname()+'/Scripts.py') try: scriptsFile = open(scriptsFilename.toOsSpecific(), 'w') except IOError: print "ERROR: Couldn't open the script file for writing" scriptsFile.writelines(outputLines) scriptsFile.close() return scriptsFilename
def exportScripts(self, file): outputLines = [] tab = " " outputLines.append("SCRIPTS_LIST = []\n\n") #whole file for script, asset in self.editor.lib.scripts.iteritems(): #writing a script file to the whole file filename = self.editor.lib.scripts[script].getFullFilename() scriptFile = open(filename.toOsSpecific()) lines = scriptFile.readlines() mainArguments = self.getArgumentsFromScriptFile(lines) scriptFunctionName = script if (len(mainArguments) == 0): prefix = "world" else: prefix = "world, " functionHeader = "\ndef " + scriptFunctionName + "(" + prefix + ",".join( mainArguments) + "):\n" mainFunc = "main(" + prefix + ",".join(mainArguments) + ")" mainFuncHeader = "def " + mainFunc + ":\n" outputLines.append(functionHeader) isReturn = False for line in lines: #print line if line.strip().startswith("#"): continue if line.strip().startswith("def main"): newline = mainFuncHeader elif line.find("Interface") != -1: newline = line.replace('Interface', "world.scriptInterface") else: newline = line if line.strip().startswith("return"): isReturn = True outputLines.append(tab + newline) if (isReturn): outputLines.append("\n" + tab + "return " + mainFunc) else: outputLines.append("\n" + tab + mainFunc) outputLines.append("\nSCRIPTS_LIST.append(" + scriptFunctionName + ")\n") scriptFile.close() scriptsFilename = Filename( Filename.fromOsSpecific(file).getDirname() + '/Scripts.py') try: scriptsFile = open(scriptsFilename.toOsSpecific(), 'w') except IOError: print "ERROR: Couldn't open the script file for writing" scriptsFile.writelines(outputLines) scriptsFile.close() return scriptsFilename
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(pathname.cStr(), '.xml') if doc.SaveFile(tfile.toOsSpecific()): tfile.renameTo(usageFilename)
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(pathname.cStr(), '.xml') if doc.SaveFile(tfile.toOsSpecific()): tfile.renameTo(usageFilename)
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 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 saveNewsCache(self): cacheIndexFilename = Filename(self.newsDir, self.CacheIndexFilename) try: file = open(cacheIndexFilename.toOsSpecific(), 'w') except IOError as e: self.notify.warning('error opening news cache file %s: %s' % (cacheIndexFilename, str(e))) return for filename, (size, date) in self.newsCache.items(): print >> file, '%s\t%s\t%s' % (filename, size, date)
def __uncompressArchive(self, step): """ Turns the compressed archive into the uncompressed archive. Yields one of stepComplete, stepFailed, restartDownload, or stepContinue. """ if self.host.appRunner and self.host.appRunner.verifyContents == self.host.appRunner.P3DVCNever: # We're not allowed to! yield self.stepFailed return self.updated = True sourcePathname = Filename(self.getPackageDir(), self.compressedArchive.filename) targetPathname = Filename(self.getPackageDir(), self.uncompressedArchive.filename) targetPathname.unlink() self.notify.info("Uncompressing %s to %s" % (sourcePathname, targetPathname)) decompressor = Decompressor() decompressor.initiate(sourcePathname, targetPathname) totalBytes = self.uncompressedArchive.size result = decompressor.run() while result == EUOk: step.bytesDone = int(totalBytes * decompressor.getProgress()) self.__updateStepProgress(step) result = decompressor.run() if taskMgr.destroyed: # If the task manager has been destroyed, we must # be shutting down. Get out of here. self.notify.warning( "Task Manager destroyed, aborting decompresss %s" % (sourcePathname)) yield self.stepFailed return yield self.stepContinue if result != EUSuccess: yield self.stepFailed return step.bytesDone = totalBytes self.__updateStepProgress(step) if not self.uncompressedArchive.quickVerify(self.getPackageDir(), notify=self.notify): self.notify.warning("after uncompressing, %s still incorrect" % (self.uncompressedArchive.filename)) yield self.stepFailed return # Now that we've verified the archive, make it read-only. os.chmod(targetPathname.toOsSpecific(), 0444) # Now we can safely remove the compressed archive. sourcePathname.unlink() yield self.stepComplete return
def find_module(self, fullname): basename = fullname.split('.')[-1] path = Filename(self.dir_path, basename) # First, look for Python files. filename = path filename.setExtension('py') vfile = vfs.getFile(filename, True) if vfile: return VFSLoader(self, vfile, filename, FTPythonSource) # If there's no .py file, but there's a .pyc file, load that # anyway. filename = path filename.setExtension(pycExtension) vfile = vfs.getFile(filename, True) if vfile: return VFSLoader(self, vfile, filename, FTPythonCompiled) # Look for a compiled C/C++ module. for desc in imp.get_suffixes(): if desc[2] != imp.C_EXTENSION: continue filename = path filename.setExtension(desc[0][1:]) vfile = vfs.getFile(filename, True) if vfile: return VFSLoader(self, vfile, filename, FTCompiledModule, desc=desc) # Finally, consider a package, i.e. a directory containing # __init__.py. filename = Filename(path, '__init__.py') vfile = vfs.getFile(filename, True) if vfile: return VFSLoader(self, vfile, filename, FTPythonSource, package=True) filename = Filename(path, '__init__.' + pycExtension) vfile = vfs.getFile(filename, True) if vfile: return VFSLoader(self, vfile, filename, FTPythonCompiled, package=True) return None
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 onCreateObject(self, e): """Invoked when the user hits one of the buttons in the "Create" menu.""" modelParent = modelController.getSelectedObject() if modelParent == None: modelParent = render objectInstance = None if e.Id == ID_NODEPATH: objectInstance = NodePathWrapper.onCreateInstance(modelParent) elif e.Id == ID_MODEL: filter = "Panda3D Egg Format (*.egg)|*.[eE][gG][gG];*.egg" filter += "|Panda3D Binary Format (*.bam)|*.[bB][aA][mM];*.bam" filter += "|MultiGen (*.flt)|*.[fF][lL][tT];*.flt" filter += "|Lightwave (*.lwo)|*.[lL][wW][oO];*.lwo" filter += "|AutoCAD (*.dxf)|*.[dD][xX][fF];*.dxf" filter += "|VRML (*.wrl)|*.[wW][rR][lL];*.wrl" filter += "|DirectX (*.x)|*.[xX];*.x" filter += "|COLLADA (*.dae)|*.[dD][aA][eE];*.dae" dlg = wx.FileDialog(self, "Select model", "", "", filter, wx.OPEN) try: if dlg.ShowModal() == wx.ID_OK: objectInstance = NodePathWrapper.onCreateInstance( modelParent, Filename.fromOsSpecific(dlg.GetPath()).getFullpath()) finally: dlg.Destroy() elif e.Id == ID_TERRAIN: filter = "Portable Network Graphics (*.png)|*.[pP][nN][gG];*.png" dlg = wx.FileDialog(self, "Select heightfield", "", "", filter, wx.OPEN) try: if dlg.ShowModal() == wx.ID_OK: objectInstance = GeoMipTerrainNodeWrapper.onCreateInstance( modelParent, Filename.fromOsSpecific(dlg.GetPath()).getFullpath()) finally: dlg.Destroy() elif e.Id == ID_AMBIENT: objectInstance = AmbientLightNodeWrapper.onCreateInstance( modelParent) elif e.Id == ID_DIRECTIONAL: objectInstance = DirectionalLightNodeWrapper.onCreateInstance( modelParent) elif e.Id == ID_POINT: objectInstance = PointLightNodeWrapper.onCreateInstance( modelParent) elif e.Id == ID_SPOT: objectInstance = SpotLightNodeWrapper.onCreateInstance(modelParent) if objectInstance != None: objectInstance.reparentTo(modelParent) objectInstance.enableEditmode() modelController.selectObject(objectInstance) messenger.send(EVENT_SCENEGRAPH_REFRESH)
def quickVerify(self, packageDir=None, pathname=None, notify=None): """ Performs a quick test to ensure the file has not been modified. This test is vulnerable to people maliciously attempting to fool the program (by setting datestamps etc.). Returns true if it is intact, false if it needs to be redownloaded. """ if not pathname: pathname = Filename(packageDir, self.filename) try: st = os.stat(pathname.toOsSpecific()) except OSError: # If the file is missing, the file fails. if notify: notify.debug("file not found: %s" % (pathname)) return False if st.st_size != self.size: # If the size is wrong, the file fails. if notify: notify.debug("size wrong: %s" % (pathname)) return False if st.st_mtime == self.timestamp: # If the size is right and the timestamp is right, the # file passes. if notify: notify.debug("file ok: %s" % (pathname)) return True if notify: notify.debug("modification time wrong: %s" % (pathname)) # If the size is right but the timestamp is wrong, the file # soft-fails. We follow this up with a hash check. if not self.checkHash(packageDir, pathname, st): # Hard fail, the hash is wrong. if notify: notify.debug("hash check wrong: %s" % (pathname)) notify.debug(" found %s, expected %s" % (self.actualFile.hash, self.hash)) return False if notify: notify.info("hash check ok: %s" % (pathname)) # The hash is OK after all. Change the file's timestamp back # to what we expect it to be, so we can quick-verify it # successfully next time. self.__updateTimestamp(pathname, st) return True
def quickVerify(self, packageDir = None, pathname = None, notify = None): """ Performs a quick test to ensure the file has not been modified. This test is vulnerable to people maliciously attempting to fool the program (by setting datestamps etc.). Returns true if it is intact, false if it needs to be redownloaded. """ if not pathname: pathname = Filename(packageDir, self.filename) try: st = os.stat(pathname.toOsSpecific()) except OSError: # If the file is missing, the file fails. if notify: notify.debug("file not found: %s" % (pathname)) return False if st.st_size != self.size: # If the size is wrong, the file fails. if notify: notify.debug("size wrong: %s" % (pathname)) return False if st.st_mtime == self.timestamp: # If the size is right and the timestamp is right, the # file passes. if notify: notify.debug("file ok: %s" % (pathname)) return True if notify: notify.debug("modification time wrong: %s" % (pathname)) # If the size is right but the timestamp is wrong, the file # soft-fails. We follow this up with a hash check. if not self.checkHash(packageDir, pathname, st): # Hard fail, the hash is wrong. if notify: notify.debug("hash check wrong: %s" % (pathname)) notify.debug(" found %s, expected %s" % (self.actualFile.hash, self.hash)) return False if notify: notify.info("hash check ok: %s" % (pathname)) # The hash is OK after all. Change the file's timestamp back # to what we expect it to be, so we can quick-verify it # successfully next time. self.__updateTimestamp(pathname, st) return True
def cogExists(filePrefix): searchPath = DSearchPath() if AppRunnerGlobal.appRunner: searchPath.appendDirectory(Filename.expandFrom('$TT_3_5_ROOT/phase_3.5')) else: basePath = os.path.expandvars('$TTMODELS') or './ttmodels' searchPath.appendDirectory(Filename.fromOsSpecific(basePath + '/built/phase_3.5')) filePrefix = filePrefix.strip('/') pfile = Filename(filePrefix) found = vfs.resolveFilename(pfile, searchPath) if not found: return False return True
def onOpenConvoEditor(self, x, item): convoKey = self.treeStoryObj.GetItemText(item) #print "treeStoryObj type: %s" %(type(self.treeStoryObj)) #print 'convo key: %s' %(convoKey) if convoKey in self.lib.conversations: convoFilename = Filename(self.editor.lib.conversations[convoKey].getFullFilename()) f = open(convoFilename.toOsSpecific()) doc = xml.dom.minidom.parse(f) root = doc.documentElement convo = Conversation.decode(doc) f.close() else: convo = None editor = ConversationEditor(self, self.editor, convo, convoKey)
def onSave(self, event=None): # dlg = wx.FileDialog(self.frame, "Choose a location to save the source file", \ # defaultDir= base.le.currentProj.dir.toOsSpecific(),\ # defaultFile = 'conversation' + '.xml', wildcard="*.xml", style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) dlg = wx.TextEntryDialog(self.frame, "Choose a name for this conversation", defaultValue=self.convoName) if dlg.ShowModal() == wx.ID_OK: name = dlg.GetValue() if name in base.le.lib.conversations: messageDlg = wx.MessageDialog(self.frame, "\"%s\" already exists, do you want to overwrite?" %(name)) if messageDlg.ShowModal() == wx.ID_OK: #print 'overwrite it' base.le.lib.removeConversation(name) else: #print 'do not overwrite it' messageDlg.Destroy() return else: self.convoName = name base.le.ui.SetCursor(wx.StockCursor(wx.CURSOR_WAIT)) #== Create temporary XML file for the asset doc = xml.dom.minidom.Document() root = doc.createElement("the_root") doc.appendChild(root) root.appendChild(self.conversation.encode(doc)) tempFilePath = base.le.lib.projDir.toOsSpecific() + '/' + name + '.xml' assetFilename = Filename(tempFilePath) #print 'temporary file path for asset: ' + assetFilename.toOsSpecific() f = open(assetFilename.toOsSpecific(), 'w') f.write(doc.toxml()) f.close() #== Make an Asset based on the temporary source file and add it to the library asset = ConversationAsset(name, assetFilename) base.le.lib.addConversation(asset, True) base.le.ui.storyObjUI.update() #== Remove the temporary source file tempFilename = Filename(tempFilePath) #print 'temporary file path to now delete: ' + tempFilename.toOsSpecific() os.remove(tempFilename.toOsSpecific()) self.changesSinceLastSave = False base.le.ui.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
def __scanDirectoryRecursively(self, dirname): """ Generates a list of Filename objects: all of the files (not directories) within and below the indicated dirname. """ contents = [] for dirpath, dirnames, filenames in os.walk(dirname.toOsSpecific()): dirpath = Filename.fromOsSpecific(dirpath) if dirpath == dirname: dirpath = Filename('') else: dirpath.makeRelativeTo(dirname) for filename in filenames: contents.append(Filename(dirpath, filename)) return contents
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 main(): parser = argparse.ArgumentParser() parser.add_argument('-d', '--dir', dest='directory', required=True, help='the directory where the config files are located') parser.add_argument('-p', '--port', dest='port', type=int, default=9099, help='the port the server should run on') parser.add_argument('-a', '--automatic', dest='mode', action='store_const', const=AUTOMATIC, default=MANUAL, help='set the mode of the simulation controller to automatic') parser.add_argument('-s', '--sync', dest='sync', action='store_true', default=False, help='a Sync session is used to control the time') parser.add_argument('-m', '--models', dest='models', help='the directory where the models are located') parser.add_argument('--debug', dest='debug', action='store_const', const=logging.DEBUG, default=logging.INFO, help='show debug messages') args = parser.parse_args() logging.basicConfig(format='%(levelname)s: %(message)s', level=args.debug) # Create the virtual world by loading all of the models that make up the # scene as well as all of the pedestrians. virtual_world = VirtualWorld(os.path.join(args.directory, 'scene.xml'), os.path.join(args.directory, 'pedestrians.xml'), Filename.fromOsSpecific(args.directory), args.mode) model = virtual_world.getModel() # Create the camera manager which keeps track of what cameras are linked to # what Vision Processing clients. Also acts as a message sender used to send # messages between cameras camera_manager = CameraManager() # Load all of the camera modules. # Each camera module is linked with a panda camera that has the ability to # render to a texture that can be processed using opencv. camera_file = os.path.join(args.directory, 'cameras.xml') if not os.path.exists(camera_file): logging.error("The path '%s' does not exist" % camera_file) sys.exit() parser = CameraFileParser() configs = parser.parse(camera_file) camera_builder = CameraBuilder() for config in configs: cam_module = camera_builder.buildCamera(config) if not cam_module: continue model.addCameraModule(cam_module) cam_type = cam_module.getType() camera_manager.addCamera(cam_module) camera = virtual_world.addCamera(config) cam_module.setPandaCamera(camera) cam_module.setCameraManager(camera_manager) # Create the server object that listens for incoming messages and connection # requests from other modules. if args.mode != AUTOMATIC: server = SocketServer(args.port, virtual_world, camera_manager, args.sync) # Start the main event loop that runs the world. virtual_world.run()
def loadMultifilePrcFiles(self, mf, root): """ Loads any prc files in the root of the indicated Multifile, which is presumed to have been mounted already under root. """ # We have to load these prc files explicitly, since the # ConfigPageManager can't directly look inside the vfs. Use # the Multifile interface to find the prc files, rather than # vfs.scanDirectory(), so we only pick up the files in this # particular multifile. for f in mf.getSubfileNames(): fn = Filename(f) if fn.getDirname() == '' and fn.getExtension() == 'prc': pathname = '%s/%s' % (root, f) data = file.open(Filename(pathname), 'r').read() loadPrcFileData(pathname, data)
def buildPandaPTZCamera(self, config): buffer = self.makeFBO("camera buffer") panda_camera = base.makeCamera(buffer) panda_camera.reparentTo(render) path = Filename.fromOsSpecific(os.path.dirname(__file__)) camera_model = loader.loadModel("%s/../camera/camera.egg" % path) camera_model.setScale(0.3) camera_model.reparentTo(render) panda_ptz_camera = PandaPTZCamera(buffer, panda_camera, camera_model) panda_ptz_camera.setColor(config.color) panda_ptz_camera.setId(config.id) panda_ptz_camera.setPos(config.position) panda_ptz_camera.setFovLimits(*config.fov_limits) panda_ptz_camera.setPanLimits(*config.pan_limits) panda_ptz_camera.setTiltLimits(*config.tilt_limits) panda_ptz_camera.setDefaultDirection(config.default_direction) panda_ptz_camera.setUp(config.up_vector) panda_ptz_camera.setNear(config.near_plane) panda_ptz_camera.setFar(config.far_plane) panda_ptz_camera.setFov(config.fov) panda_ptz_camera.setDefaultFov(config.default_fov) panda_ptz_camera.setPan(config.pan) panda_ptz_camera.setTilt(config.tilt) return panda_ptz_camera
def redownloadNews(self): if self.redownloadingNews: self.notify.warning("averting potential crash redownloadNews called twice, just returning") return self.percentDownloaded = 0.0 self.notify.info("starting redownloadNews") self.startRedownload = datetime.datetime.now() self.redownloadingNews = True self.addDownloadingTextTask() for issue in self.issues: issue.destroy() self.issues = [] self.curIssueIndex = 0 self.strFilenames = None self.needsParseNews = True self.newsUrl = self.getInGameNewsUrl() self.newsDir = Filename(self.findNewsDir()) Filename(self.newsDir + "/.").makeDir() http = HTTPClient.getGlobalPtr() self.url = self.newsUrl + self.NewsIndexFilename self.ch = http.makeChannel(True) self.ch.beginGetDocument(self.url) self.rf = Ramfile() self.ch.downloadToRam(self.rf) taskMgr.remove(self.RedownloadTaskName) taskMgr.add(self.downloadIndexTask, self.RedownloadTaskName) return
def onChooseFolder(self, evt): dialog = wx.DirDialog(None, "Choose a project directory", os.getcwd()) if dialog.ShowModal() == wx.ID_OK: self.dir = Filename.fromOsSpecific(dialog.GetPath()) self.dirText.SetLabel(self.dir.toOsSpecific()) if self.dir and self.projName: self.okButton.Enable(True)
def parseSysArgs(): """ Handles sys.argv, if there are any local arguments, and returns a new argv suitable for passing into the application. """ # We prefix a "+" sign, following the GNU convention, to tell # getopt not to parse options following the first non-option # parameter. opts, args = getopt.getopt(sys.argv[1:], '+h') for option, value in opts: if option == '-h': print __doc__ sys.exit(1) if not args or not args[0]: raise ArgumentError, "No Panda app specified. Use:\nrunp3d.py app.p3d" arg0 = args[0] p3dFilename = Filename.fromOsSpecific(arg0) if p3dFilename.exists(): p3dFilename.makeAbsolute() arg0 = p3dFilename.toOsSpecific() return [arg0] + args[1:]
def __init__(self): ShowBase.__init__(self) #Disable standard mouse camera movement #base.disableMouse() #Exit app on escape key base.accept("escape", sys.exit) #Get the location of MainGame.py projectdir = os.path.abspath(sys.path[0]) #convert it to Panda's unix-style notation. projectdir = Filename.fromOsSpecific(projectdir).getFullpath() #TODO - Load the level model here #base.wireframeOn() #self.environ = self.loader.loadModel(projectdir + "/models/levels/ThePlayground") #Load the default environment model from the panda Tutorial self.environ = self.loader.loadModel(projectdir + "/models/levels/environment") #Reparent the model to the root of the Scenegraph, aka the "render" node #this allows for the object to actually appear on screen self.environ.reparentTo(self.render) #Scale and position the level/environment model self.environ.setScale(0.25, 0.25, 0.25) self.environ.setPos(-8, 42, 0) #TODO add camera controls to a function that can be added to the taskMgr #Handle camera controls here controls = BasicControls() #controls.startMovement() self.taskMgr.add(controls.movement, 'movement') self.taskMgr.add(controls.walk, 'walk')
def decode_real_path (real_path): abs_real_path = os.path.abspath(real_path) enc_full_path = Filename.fromOsSpecific(abs_real_path).getFullpath() enc = locale.getpreferredencoding() full_path = enc_full_path.decode(enc) return full_path
def buildArch(self, output, platform): """ Builds an ArchLinux package and stores it in the path indicated by the 'output' argument. It will be built for the architecture specified by the 'arch' argument. If 'output' is a directory, the deb file will be stored in it. """ arch = platform.rsplit("_", 1)[-1] assert arch in ("i386", "amd64") arch = {"i386": "i686", "amd64": "x86_64"}[arch] pkgver = self.version + "-1" output = Filename(output) if output.isDirectory(): output = Filename(output, "%s-%s-%s.pkg.tar.gz" % (self.shortname.lower(), pkgver, arch)) Installer.notify.info("Creating %s..." % output) modtime = int(time.time()) # Create a temporary directory and write the launcher and dependencies to it. tempdir, totsize = self.__buildTempLinux(platform) # Create a pkginfo file in memory. pkginfo = StringIO() print >> pkginfo, "# Generated using pdeploy" print >> pkginfo, "# %s" % time.ctime(modtime) print >> pkginfo, "pkgname = %s" % self.shortname.lower() print >> pkginfo, "pkgver = %s" % pkgver print >> pkginfo, "pkgdesc = %s" % self.fullname print >> pkginfo, "builddate = %s" % modtime print >> pkginfo, "packager = %s <%s>" % (self.authorname, self.authoremail) print >> pkginfo, "size = %d" % totsize print >> pkginfo, "arch = %s" % arch if self.licensename != "": print >> pkginfo, "license = %s" % self.licensename pkginfoinfo = TarInfoRoot(".PKGINFO") pkginfoinfo.mtime = modtime pkginfoinfo.size = pkginfo.tell() pkginfo.seek(0) # Create the actual package now. pkgfile = tarfile.open(output.toOsSpecific(), "w:gz", tarinfo=TarInfoRoot) pkgfile.addfile(pkginfoinfo, pkginfo) pkgfile.add(tempdir.toOsSpecific(), "/") if not self.licensefile.empty(): pkgfile.add(self.licensefile.toOsSpecific(), "/usr/share/licenses/%s/LICENSE" % self.shortname.lower()) pkgfile.close() return output