def locateMountedFiles(path, gGator): if platform.system() == 'Windows': path = path.replace('/', '\\') localPath = util.localOSPath( os.path.join(gGator.getLocalGameOutputDir(), path)) if not os.path.exists(localPath): localPath = util.localOSPath( os.path.join(gGator.getLocalGameDataOutputDir(), path)) if not os.path.exists(localPath): localPath = util.localOSPath(os.path.join(gGator.outputDir, path)) # TODO Same as the first two ifs but without genre ? used ? # if not os.path.exists(localPath): # localPath = util.localOutputPath(os.path.join(gGator.outputDir, gGator.game + '.pc', path)) # if not os.path.exists(localPath): # localPath = util.localOutputPath(os.path.join(gGator.outputDir, gGator.game + '.pc', gGator.game, path)) return localPath
def cleanCDname(self, path, cdCount=None, gameInternalBatFile=False): if self.gGator.isWin3x(): # Find first game sub path and replace it gameSubPathIndex = path.lower().find('\\'+self.gGator.game.lower()) gameSubPathLength = len('\\'+self.gGator.game) path = path[:gameSubPathIndex] + path[gameSubPathIndex + gameSubPathLength:] cdFileFullPath = os.path.join(self.gGator.getLocalGameOutputDir(), path) \ if not gameInternalBatFile else os.path.join(self.gGator.getLocalGameDataOutputDir(), path) if os.path.exists(util.localOSPath(cdFileFullPath)): if os.path.isdir(util.localOSPath(cdFileFullPath)): return path else: pathList = path.split('\\') cdFile = pathList[-1] oldCdFilename = os.path.splitext(cdFile)[0].lower() cdFileExt = os.path.splitext(cdFile)[-1].lower() # Root path of CDs cdsPath = "\\".join(cdFileFullPath.split('\\')[:-1]) # Rename file to dos compatible name cdFilename = self.dosRename(cdsPath, cdFile, oldCdFilename, cdFileExt, cdCount) self.logger.log(" renamed %s to %s" % (cdFile, cdFilename + cdFileExt)) if cdFileExt == ".cue": self.cleanCue(cdsPath, cdFilename, cdCount) # Clean remaining ccd and sub file which might have the same name as the cue file otherCdFiles = [file for file in os.listdir(util.localOSPath(cdsPath)) if os.path.splitext(file)[0].lower() == oldCdFilename and os.path.splitext(file)[ -1].lower() in ['.ccd', '.sub']] for otherCdFile in otherCdFiles: otherCdFileExt = os.path.splitext(otherCdFile)[-1].lower() otherCdFilename = self.dosRename(cdsPath, otherCdFile, cdFilename, otherCdFileExt, cdCount) self.logger.log(" renamed %s to %s" % (otherCdFile, otherCdFilename + otherCdFileExt)) cleanedPath = "\\".join(pathList[:-1]) + "\\" + cdFilename + cdFileExt # self.logger.log(" modify dosbox.bat : %s -> %s" %(path,cleanedPath)) return cleanedPath else: if not os.path.exists(os.path.join(self.gGator.getLocalGameDataOutputDir(), util.localOSPath(path))): self.logger.log(" <ERROR> path %s doesn't exist" % util.localOSPath(cdFileFullPath), self.logger.ERROR) return path
def dosRename(self, path, originalFile, fileName, fileExt, cdCount): fileName = fileName.replace(" ", "").replace("[", "").replace("]", "") if len(fileName) > 8: if cdCount is None: fileName = fileName[0:7] else: fileName = fileName[0:5] + str(cdCount) # TESTCASE : Ripper (1996) / ripper shouldn't enter here if os.path.exists(os.path.join(path, fileName + fileExt)) and ( fileName + fileExt) != originalFile.lower() and cdCount is None: fileName = fileName[0:6] + "1" # Double rename file to avoid trouble with case on Windows source = os.path.join(path, originalFile) targetTemp = os.path.join(path, fileName + "1" + fileExt) target = os.path.join(path, fileName + fileExt) os.rename(util.localOSPath(source), util.localOSPath(targetTemp)) os.rename(util.localOSPath(targetTemp), util.localOSPath(target)) return fileName
def parseXmlMetadata(self): xmlPath = os.path.join( self.exoCollectionDir, 'xml', util.getCollectionMetadataID(self.collectionVersion) + '.xml') metadatas = dict() if os.path.exists(xmlPath): parser = etree.XMLParser(encoding="utf-8") games = etree.parse(xmlPath, parser=parser).findall(".//Game") for g in games: name = self.__getNode__(g, 'Title') if name not in list( map(lambda x: util.exoCollectionsDirs[x]['gamesDir'], list(util.exoCollectionsDirs.keys()))): try: path = self.__getNode__(g, 'ApplicationPath').split("\\") dosname = path[-2] metadataname = os.path.splitext(path[-1])[0] # print("%s %s %s" %(dosname, name, metadataname)) desc = self.__getNode__( g, 'Notes') if self.__getNode__( g, 'Notes') is not None else '' releasedate = self.__getNode__( g, 'ReleaseDate')[:4] if self.__getNode__( g, 'ReleaseDate') is not None else None developer = self.__getNode__(g, 'Developer') publisher = self.__getNode__(g, 'Publisher') genres = self.__getNode__( g, 'Genre').split(';') if self.__getNode__( g, 'Genre') is not None else [] manual = self.__getNode__(g, 'ManualPath') manualpath = util.localOSPath( os.path.join( self.exoCollectionDir, manual)) if manual is not None else None frontPic = util.findPics(name, self.cache) metadata = DosGame(dosname, metadataname, name, genres, publisher, developer, releasedate, frontPic, manualpath, desc) metadatas[metadata.dosname.lower()] = metadata except: self.logger.log( ' Error %s while getting metadata for %s\n' % (sys.exc_info()[0], self.__getNode__(g, 'Title')), self.logger.ERROR) self.logger.log('Loaded %i metadatas' % len(metadatas.keys())) self.metadatas = metadatas return metadatas
def cleanCue(self, path, fileName, cdCount): oldFile = open(os.path.join(util.localOSPath(path), fileName + ".cue"), 'r') newFile = open(os.path.join(util.localOSPath(path), fileName + "-fix.cue"), 'w') modifiedFirstLine = False for line in oldFile.readlines(): if line.startswith("FILE"): if not modifiedFirstLine: # Handle first line: img, iso, bin, etc params = line.split('"') isobin = os.path.splitext(params[1].lower()) fixedIsoBinName = self.dosRename(path, params[1], isobin[0], isobin[1], cdCount) self.logger.log(" renamed %s to %s" % (params[1], fixedIsoBinName + isobin[1])) # TESTCASE: Pinball Arcade (1994) / PBArc94: params[1] = fixedIsoBinName + isobin[-1] line = '"'.join(params) self.logger.log(" convert cue content -> " + line.rstrip('\n\r ')) # Only do it for the first Line modifiedFirstLine = True else: # Move music files in subfolders to cd folder params = line.split('"') if '\\' in params[1]: musicParams = params[1].split('\\') # Assume there are only two music file path components shutil.move(os.path.join(util.localOSPath(path), musicParams[0], musicParams[1]), os.path.join(util.localOSPath(path), musicParams[1])) self.logger.log(" move music %s from %s to . -> " % (musicParams[1], musicParams[0])) params[1] = musicParams[1] line = '"'.join(params) self.logger.log(" convert cue content -> " + line.rstrip('\n\r ')) newFile.write(line) oldFile.close() newFile.close() # Remove readonly attribute if present before deleting os.chmod(os.path.join(util.localOSPath(path), fileName + ".cue"), stat.S_IWRITE) os.remove(os.path.join(util.localOSPath(path), fileName + ".cue")) os.rename(os.path.join(util.localOSPath(path), fileName + "-fix.cue"), os.path.join(util.localOSPath(path), fileName + ".cue"))
def removeUnusedCds(game, localGameDataOutputDir, logger): unusedCds = { 'heromm2d': '.\\CD\\Heroes of Might and Magic 2.cue', 'VirtSqua': '.\\cd\\V_SQUAD.CUE', 'SSN21Se': '.\\cd\\SEAWOLF___.cue', 'FIFAInte': '.\\CD\\FIFA.International.Soccer.cue', 'vengexca': '..\\spirexc\\CD\\SPIRIT.cue', 'whalvoy2': '..\\whalvoy1\\cd\\whalvoy1.cue', 'WC2DLX': '..\\WC\\cd\\WC.cue' } if game in unusedCds: cue = os.path.join(localGameDataOutputDir, util.localOSPath(unusedCds[game])) cueDir = os.path.dirname(cue) cdFiles = [ file for file in os.listdir(cueDir) if os.path.splitext(ntpath.basename(cue))[0] == os.path.splitext( file)[0] and os.path.splitext(file)[-1].lower() in ['.ccd', '.sub', '.cue', '.iso', '.img', '.bin'] ] for cdFile in cdFiles: logger.log(" remove unused cd file %s" % cdFile) os.remove(os.path.join(cueDir, cdFile))
def handleBoot(self, line): bootPath = line.replace('boot ', '').replace('BOOT ', '').rstrip(' \n\r') if bootPath != '-l c' and bootPath != '-l c>null': # reduce except for boot -l c paths = bootPath.split(' ') cleanedPath = [] if paths[0].startswith('"') and ( paths[-1].lower().endswith('.ima"') or paths[-1].lower().endswith('.img"')): # TEST CASE : Grand Prix Tennis 87 (GPTen87) paths = [" ".join(paths)] path = paths[0].replace('"', '') path = self.reducePath(path) imgPath = os.path.dirname(util.localOSPath(path)) imgFullLocalPath = os.path.join(self.gGator.getLocalGameOutputDir(), util.localOSPath(imgPath)) imgFile = ntpath.basename(util.localOSPath(path)) oldImgFilename = os.path.splitext(imgFile)[0] imgFileExt = os.path.splitext(imgFile)[-1] newImgFilename = self.dosRename(imgFullLocalPath, imgFile, oldImgFilename, imgFileExt, None) self.logger.log(" renamed %s to %s" % (imgFile, newImgFilename + imgFileExt)) path = '"' + imgPath + '\\' + newImgFilename + imgFileExt + '"' cleanedPath.append(path) else: for path in paths: if path not in ['-l', 'a', 'a:']: path = self.reducePath(path.replace('"', "")) # Verify path postfix = path.find('-l') chkPath = path[:postfix].rstrip(' ') if postfix != -1 else path if not os.path.exists( os.path.join(self.gGator.getLocalGameOutputDir(), util.localOSPath(chkPath))): if not os.path.exists( os.path.join(self.gGator.getLocalGameDataOutputDir(), util.localOSPath(chkPath))): self.logger.log(" <ERROR> path %s doesn't exist" % os.path.join(self.gGator.getLocalGameOutputDir(), util.localOSPath(chkPath)), self.logger.ERROR) cleanedPath.append(path) bootPath = " ".join(cleanedPath) fullString = "boot " + bootPath.replace('/', '\\') + "\n" self.logger.log(" boot path: " + line.rstrip('\n\r ') + " --> " + fullString.rstrip('\n\r ')) return fullString
def handleMount(self, line): startTokens = ['a', 'b', 'd', 'e', 'f', 'g','h', 'i', 'j', 'k'] endTokens = ['-t'] paths, command, startIndex, endIndex = self.pathListInCommandLine(line, startTokens, endTokens) prString = "" if len(paths) == 1: # TESTCASE: Sidewalk (1987) / Sidewalk path = self.reducePath(paths[0].replace('"', "")) if self.gGator.isWin3x(): # Find first game sub path and replace it gameSubPathIndex = path.lower().find('\\' + self.gGator.game.lower()) gameSubPathLength = len('\\' + self.gGator.game) path = path[:gameSubPathIndex] + path[gameSubPathIndex + gameSubPathLength:] if not os.path.exists(os.path.join(self.gGator.getLocalGameOutputDir(), util.localOSPath(path))): self.logger.log(" <ERROR> path %s doesn't exist" % os.path.join(os.path.join(self.gGator.getLocalGameOutputDir(), util.localOSPath(path))), self.logger.ERROR) prString = prString + " " + path else: # See if path contains "" redoPath = " ".join(paths) countChar = redoPath.count('"') if countChar == 2: path = self.reducePath(paths[0].replace('"', "")) if self.gGator.isWin3x(): # Find first game sub path and replace it gameSubPathIndex = path.lower().find('\\' + self.gGator.game.lower()) gameSubPathLength = len('\\' + self.gGator.game) path = path[:gameSubPathIndex] + path[gameSubPathIndex + gameSubPathLength:] if not os.path.exists(os.path.join(self.gGator.getLocalGameOutputDir(), util.localOSPath(path))): self.logger.log(" <ERROR> path %s doesn't exist" % os.path.join(os.path.join(self.gGator.getLocalGameOutputDir(), util.localOSPath(path))), self.logger.ERROR) prString = prString + " " + path else: self.logger.log(" <ERROR> MULTIPATH/MULTISPACE", self.logger.ERROR) self.logger.logList(" paths", paths) for path in paths: path = self.reducePath(path.replace('"', "")) if self.gGator.isWin3x(): # Find first game sub path and replace it gameSubPathIndex = path.lower().find('\\' + self.gGator.game.lower()) gameSubPathLength = len('\\' + self.gGator.game) path = path[:gameSubPathIndex] + path[gameSubPathIndex + gameSubPathLength:] if not os.path.exists(os.path.join(self.gGator.getLocalGameOutputDir(), util.localOSPath(path))): self.logger.log(" <ERROR> path %s doesn't exist" % os.path.join(os.path.join(self.gGator.getLocalGameOutputDir(), util.localOSPath(path))), self.logger.ERROR) prString = prString + " " + path # Mount command needs to be absolute linux path if prString.strip().startswith('.'): prString = prString.strip()[1:] gameString = "/" + self.gGator.genre + "/" + self.gGator.game + ".pc" if self.gGator.useGenreSubFolders else "/" + self.gGator.game + ".pc" prString = util.getRomsFolderPrefix(self.gGator.conversionType, self.gGator.conversionConf) + gameString + prString.strip() prString = ' "' + prString.replace("\\", "/") + '"' # Needs windows absolute path for retrobat if self.gGator.conversionType == util.retrobat: prString = prString.replace("/", "\\") fullString = " ".join(command[0:startIndex + 1]) + prString + " " + " ".join(command[endIndex:]) self.logger.log(" mount path: " + line.rstrip('\n\r ') + " --> " + fullString.rstrip('\n\r ')) return fullString