def __init__(self, *args, **kwargs):
		# Don't put GUI sensitive stuff here (as the xml hasn't been read yet)
		log.info("init ContextMenu")

		self.gui = kwargs["gui"]

		self.doModal()
Пример #2
0
    def insertFile(self, fileName, gameId, fileType, romCollectionId, publisherId, developerId):
        log.debug("Begin Insert file: %s" % fileName)

        parentId = None

        # TODO console and romcollection could be done only once per RomCollection
        # fileTypeRow[3] = parent
        if fileType.parent == 'game':
            parentId = gameId
        elif fileType.parent == 'romcollection':
            parentId = romCollectionId
        elif fileType.parent == 'publisher':
            parentId = publisherId
        elif fileType.parent == 'developer':
            parentId = developerId

        log.info("Inserting file with parent {0} (type {1})".format(parentId, fileType.parent))

        fileRow = File(self.gdb).getFileByNameAndTypeAndParent(fileName, fileType.id, parentId)
        if fileRow is None:
            log.info("File does not exist in database. Insert file: %s" % fileName)
            f = File(self.gdb)
            try:
                f.insert((fileName, fileType.id, parentId))
            except Exception, (exc):
                log.warn("Error inserting into database: %s" % fileName)
	def updateSelectedRomCollection(self):

		log.info("updateSelectedRomCollection")

		sites = []
		sites = self.addScraperToSiteList(CONTROL_LIST_SCRAPER1, sites, self.selectedRomCollection)

		self.selectedRomCollection.scraperSites = sites

		# Image Placing Main
		control = self.getControlById(CONTROL_LIST_IMAGEPLACING_MAIN)
		imgPlacingItem = control.getSelectedItem()
		imgPlacingName = imgPlacingItem.getLabel()
		# HACK search key by value
		for item in config.imagePlacingDict.items():
			if item[1] == imgPlacingName:
				imgPlacingName = item[0]
		imgPlacing, errorMsg = self.gui.config.readImagePlacing(imgPlacingName, self.gui.config.tree)
		self.selectedRomCollection.imagePlacingMain = imgPlacing

		# Image Placing Info
		control = self.getControlById(CONTROL_LIST_IMAGEPLACING_INFO)
		imgPlacingItem = control.getSelectedItem()
		imgPlacingName = imgPlacingItem.getLabel()
		# HACK search key by value
		for item in config.imagePlacingDict.items():
			if item[1] == imgPlacingName:
				imgPlacingName = item[0]
		imgPlacing, errorMsg = self.gui.config.readImagePlacing(imgPlacingName, self.gui.config.tree)
		self.selectedRomCollection.imagePlacingInfo = imgPlacing

		# Update values for each of the buttons
		for btn in self._control_buttons:
			control = self.getControlById(btn['control'])
			setattr(self.selectedRomCollection, btn['value'], bool(control.isSelected()))
Пример #4
0
	def __checkGameHasSaveStates(self, gameRow, filenameRows):

		if self.romCollection.saveStatePath == '':
			log.debug("No save state path set")
			return ''

		rom = filenameRows[0][0]
		saveStatePath = self.__replacePlaceholdersInParams(self.romCollection.saveStatePath, rom, gameRow)

		saveStateFiles = glob.glob(saveStatePath)

		if len(saveStateFiles) == 0:
			log.debug("No save state files found")
			return ''

		log.info('saveStateFiles found: ' + str(saveStateFiles))

		# don't select savestatefile if ASKNUM is requested in Params
		if re.search('(?i)%ASKNUM%', self.romCollection.saveStateParams):
			return saveStateFiles[0]

		options = [util.localize(32165)]
		for f in saveStateFiles:
			options.append(os.path.basename(f))
		selectedFile = xbmcgui.Dialog().select(util.localize(32166), options)
		# If selections is canceled or "Don't launch statefile" option
		if selectedFile < 1:
			return ''

		return saveStateFiles[selectedFile - 1]
	def addScraperToSiteList(self, controlId, sites, romCollection):

		log.info("addScraperToSiteList")

		control = self.getControlById(controlId)
		scraperItem = control.getSelectedItem()
		scraper = scraperItem.getLabel()

		if scraper == util.localize(32854):
			return sites

		#check if this site is already available for current RC
		for site in romCollection.scraperSites:
			if site.name == scraper:
				sites.append(site)
				return sites

		siteRow = None
		siteRows = self.gui.config.tree.findall('Scrapers/Site')
		for element in siteRows:
			if element.attrib.get('name') == scraper:
				siteRow = element
				break

		if siteRow is None:
			xbmcgui.Dialog().ok(util.localize(32021), util.localize(32022) % scraper)
			return None

		site, errorMsg = self.gui.config.readScraper(siteRow, romCollection.name, '', '', True, self.gui.config.tree)
		if site is not None:
			sites.append(site)

		return sites
	def selectScrapersInList(self, sitesInRomCollection, sitesInList):

		log.info("selectScrapersInList")

		if len(sitesInRomCollection) >= 1:
			self.selectItemInList(sitesInRomCollection[0].name, CONTROL_LIST_SCRAPER1)
		else:
			self.selectItemInList(util.localize(32854), CONTROL_LIST_SCRAPER1)
	def updateControls(self):

		log.info('updateControls')

		control = self.getControlById(CONTROL_LIST_ROMCOLLECTIONS)
		selectedRomCollectionName = str(control.getSelectedItem().getLabel())

		self.selectedRomCollection = self.gui.config.getRomCollectionByName(selectedRomCollectionName)
Пример #8
0
    def walkDownPath(self, files, romPath, maxFolderDepth):

        log.info("alkDownPath romPath: %s" % romPath)

        files = self.walkDown(files, romPath, maxFolderDepth)
        log.info("files after walkDown = %s" % files)

        return files
	def __init__(self, *args, **kwargs):
		log.info("init Edit Rom Collection")

		self.gui = kwargs["gui"]
		self.romCollections = self.gui.config.romCollections
		self.scraperSites = self.gui.config.scraperSites

		self.doModal()
Пример #10
0
    def open_xml_url(self, **kwargs):
        log.info('Retrieving url %s, params = %s' %(kwargs['url'], kwargs['params']))

        r = requests.get(kwargs['url'], headers=self._headers, params=kwargs['params'])

        log.debug(u"Retrieving {0} as XML - HTTP{1}".format(r.url, r.status_code))

        # Need to ensure we are sending back Unicode text
        return r.text.encode('utf-8')
	def selectItemInList(self, options, itemName, controlId):

		log.info('selectItemInList')

		for i in range(0, len(options)):
			option = options[i]
			if itemName == option:
				control = self.getControlById(controlId)
				control.selectItem(i)
				break
Пример #12
0
	def compareNames(self, gamename, searchkey, checkSubtitle):
		if checkSubtitle:
			if searchkey.find(gamename) > -1:
				log.info("%s is a subtitle of %s. Using result %s" % (gamename, searchkey, searchkey))
				return True
		else:
			if gamename == searchkey:
				log.info("Perfect match. Using result %s" % searchkey)
				return True

		return False
Пример #13
0
    def findFilesByGameDescription(self, key, fileDict):

        log.info("searching for Key: %s" % key)

        try:
            filename = fileDict[key]
            log.info("result found: %s" % filename)
        except KeyError:
            filename = None

        return filename
Пример #14
0
	def getScrapingMode(self):
		mode = 0
		scrape_options = {util.SCRAPING_OPTION_AUTO_ACCURATE_TXT: 0,
						  util.SCRAPING_OPTION_INTERACTIVE_TXT: 1}
		try:
			mode = scrape_options[__addon__.getSetting(util.SETTING_RCB_SCRAPINGMODE)]
		except KeyError:
			pass

		log.info("Scraping mode: {0}".format(mode))

		return mode
	def onInit(self):
		log.info('onInit Remove Rom Collection')

		# Rom Collections
		log.info('build rom collection list')

		self.addItemsToList(CONTROL_LIST_ROMCOLLECTIONS, self.gui.config.getRomCollectionNames())

		# Delete Options
		rcDeleteOptions = [util.localize(32137), util.localize(32138)]
		self.addItemsToList(CONTROL_LIST_DELETEOPTIONS, rcDeleteOptions, properties=['RCollection', 'Roms'])
		self.updateControls()
Пример #16
0
    def walkDown(self, files, romPath, maxFolderDepth):
        log.info("Running walkdown on: %s" % romPath)

        dirs, newFiles, dirname, filemask = self.getFilesByWildcardExt(romPath)
        files.extend(newFiles)

        for dir in dirs:
            newRomPath = util.joinPath(dirname, dir, filemask)
            maxFolderDepth = maxFolderDepth - 1
            if (maxFolderDepth > 0):
                self.walkDown(files, newRomPath, maxFolderDepth)

        return files
Пример #17
0
    def insertForeignKeyItem(self, result, itemName, gdbObject):

        item = self.resolveParseResult(result, itemName)

        if item != "" and item is not None:
            itemRow = gdbObject.getOneByName(item)
            if itemRow is None:
                log.info("%s does not exist in database. Insert: %s" % (itemName, item.encode('utf-8')))

                gdbObject.insert((item,))
                del item
                itemId = self.gdb.cursor.lastrowid
            else:
                itemId = itemRow[0]
        else:
            itemId = None

        return itemId
Пример #18
0
	def matchGamename(self, results, gamenameFromFile, checkSubtitle):
		for idx, result in enumerate(results):
			try:
				# Check if the result has the correct platform (if needed)
				found_platform = self.resolveParseResult(result, 'PlatformSearchKey')
				if found_platform != '' and self.expected_platform != found_platform:
					log.info("Platform mismatch. %s != %s. Result will be skipped." % (
					self.expected_platform, found_platform))
					continue

				searchKey = self.resolveParseResult(result, 'SearchKey')
				# keep it for later reference
				searchkey_orig = searchKey
				gamename_orig = gamenameFromFile

				# if no searchkey is specified first result is valid (1 file per game scenario)
				if searchkey_orig == '':
					log.info("No searchKey found. Using first result")
					return result

				log.info("Comparing %s with %s" % (gamename_orig, searchkey_orig))
				if gamename_orig == searchkey_orig:
					# perfect match
					return result

				# normalize name and searchkey before comparison
				gnu = GameNameUtil()
				gamename_normalized = gnu.normalize_name(gamename_orig)
				searchkey_normalized = gnu.normalize_name(searchkey_orig)
				log.info("Try normalized names. Comparing %s with %s" % (gamename_normalized, searchkey_normalized))
				if gamename_normalized == searchkey_normalized:
					# perfect match
					return result

				#strip additional info from gamename
				gamename_stripped = gnu.strip_addinfo_from_name(gamename_orig)
				gamename_stripped = gnu.normalize_name(gamename_stripped)
				log.info("Try with stripped additional info. Comparing %s with %s" % (gamename_stripped, searchkey_normalized))
				if gamename_stripped == searchkey_normalized:
					# perfect match
					return result

			except Exception, (exc):
				log.warn("An error occured while matching the best result: " + str(exc))
	def onInit(self):
		log.info("onInit ContextMenu")

		self.selectedGame = self.gui.getSelectedItem()

		# Set mark favorite text
		if self.selectedGame is not None:
			if self.selectedGame.getProperty('isfavorite') == '1':
				buttonMarkFavorite = self.getControlById(CONTROL_BUTTON_SETFAVORITE_GAME)
				if buttonMarkFavorite is not None:
					buttonMarkFavorite.setLabel(util.localize(32133))
				buttonMarkFavorite = self.getControlById(CONTROL_BUTTON_SETFAVORITE_SELECTION)
				if buttonMarkFavorite is not None:
					buttonMarkFavorite.setLabel(util.localize(32134))

		# Hide Set Gameclient option
		if not helper.isRetroPlayerSupported():
			control = self.getControlById(5224)
			control.setVisible(False)
			control.setEnabled(False)
Пример #20
0
    def insertGameFromDesc(self, gamedescription, gamename, romCollection, filenamelist, foldername, isUpdate, gameId):

        log.info("insertGameFromDesc")

        if gamedescription is not None:
            game = self.resolveParseResult(gamedescription, 'Game')
        else:
            game = ''

        # if no game name has been scraped we expect that no results have been found
        if game == '':
            self.missingDescFile.add_entry(gamename)

            if __addon__.getSetting(util.SETTING_RCB_IGNOREGAMEWITHOUTDESC).upper() == 'TRUE':
                log.warn("No description found for game '%s'. Game will not be imported." % gamename)
                return None
            gamedescription = {}

        gameId = self.insertData(gamedescription, gamename, romCollection, filenamelist, foldername, isUpdate, gameId)
        return gameId
Пример #21
0
    def insertForeignKeyItemList(self, result, itemName, gdbObject):
        idList = []

        try:
            itemList = result[itemName]
            log.info("Result %s = %s" % (itemName, itemList))
        except KeyError:
            log.warn("Error while resolving item: %s" % itemName)
            return idList

        for item in itemList:
            itemRow = gdbObject.getOneByName(item)
            if itemRow is None:
                log.info("%s does not exist in database. Insert: %s" % (itemName, item.encode('utf-8')))

                gdbObject.insert((item,))
                idList.append(self.gdb.cursor.lastrowid)
            else:
                idList.append(itemRow[0])

        return idList
Пример #22
0
	def __handleCompressedFile(self, gui, filext, rom, emuParams):

		log.info("__handleCompressedFile")

		# Note: Trying to delete temporary files (from zip or 7z extraction) from last run
		# Do this before launching a new game. Otherwise game could be deleted before launch
		tempDir = os.path.join(util.getTempDir(), 'extracted', self.romCollection.name)
		# check if folder exists
		if not xbmcvfs.exists(tempDir +'\\'):
			log.info("Create temporary folder: " +tempDir)
			xbmcvfs.mkdir(tempDir)

		try:
			if xbmcvfs.exists(tempDir +'\\'):
				log.info("Trying to delete temporary rom files")
				#can't use xbmcvfs.listdir here as it seems to cache the file list and RetroPlayer won't find newly created files anymore
				files = os.listdir(tempDir)
				for f in files:
					#RetroPlayer places savestate files next to the roms. Don't delete these files.
					fname, ext = os.path.splitext(f)
					if(ext not in ('.sav', '.xml', '.png')):
						xbmcvfs.delete(os.path.join(tempDir, f))
		except Exception, (exc):
			log.error("Error deleting files after launch emu: " + str(exc))
			gui.writeMsg(util.localize(32036) + ": " + str(exc))
Пример #23
0
    def open_json_url(self, **kwargs):
        log.info('Retrieving url %s, params = %s' %(kwargs['url'], kwargs['params']))
        
        try:
            r = requests.get(kwargs['url'], headers=self._headers, params=kwargs['params'])
        except ValueError as e:
            # Typically non-JSON response
            raise ScraperUnexpectedContentException("Non-JSON response received")

        log.debug(u"Retrieving {0} as JSON - HTTP{1}".format(r.url, r.status_code))

        if r.status_code == 401:
            # Mobygames and GiantBomb send a 401 if the API key is invalid
            raise ScraperUnauthorisedException("Invalid API key sent")

        if r.status_code == 429:
            raise ScraperExceededAPIQuoteException("Scraper exceeded API key limits")

        if r.status_code == 500:
            raise ScraperWebsiteUnavailableException("Website unavailable")

        return r.json()
Пример #24
0
	def __copyLauncherScriptsToUserdata(self):
		log.info('__copyLauncherScriptsToUserdata')

		oldBasePath = os.path.join(util.getAddonInstallPath(), 'resources', 'scriptfiles')
		newBasePath = os.path.join(util.getAddonDataPath(), 'scriptfiles')

		files = []
		# Copy applaunch shell script/batch file
		if self.env == 'win32':
			files.append('applaunch.bat')
		else:
			files.append('applaunch.sh')

		# Copy VBS files
		if self.env == 'win32' and __addon__.getSetting(util.SETTING_RCB_USEVBINSOLOMODE).lower() == 'true':
			files += ['applaunch-vbs.bat', 'LaunchKodi.vbs', 'Sleep.vbs']

		for f in files:
			if not xbmcvfs.exists(os.path.join(newBasePath, f)):
				log.debug("Copying file {0} from {1} to {2}".format(f, oldBasePath, newBasePath))
				if not xbmcvfs.copy(os.path.join(oldBasePath, f), os.path.join(newBasePath, f)):
					log.warn("Error copying file")
Пример #25
0
    def getArtworkForGame(self, romCollection, gamename, gamenameFromFile, gamedescription, foldername, publisher,
                          developer):
        artWorkFound = False
        artworkfiles = {}
        artworkurls = {}
        for path in romCollection.mediaPaths:

            log.info("FileType: {0}".format(path.fileType.name))

            # TODO replace %ROMCOLLECTION%, %PUBLISHER%, ...
            fileName = path.path.replace("%GAME%", gamenameFromFile)

            continueUpdate, artworkurls = self.getThumbFromOnlineSource(gamedescription, path.fileType.name,
                                                                        fileName, artworkurls)
            if not continueUpdate:
                return False, {}, {}

            log.debug("Additional data path: %s" % path.path)
            files = self.resolvePath((path.path,), gamename, gamenameFromFile, foldername, romCollection.name,
                                     publisher, developer)
            if len(files) > 0:
                artWorkFound = True

                # HACK: disable static image check as a preparation for new default image handling (this code has problems with [] in rom names)
                """
				imagePath = str(self.resolvePath((path.path,), gamename, gamenameFromFile, foldername, romCollection.name, publisher, developer))
				staticImageCheck = imagePath.upper().find(gamenameFromFile.upper())
				
				#make sure that it was no default image that was found here
				if(staticImageCheck != -1):
					artWorkFound = True
				"""
            else:
                self.missingArtworkFile.add_entry(gamename, gamenameFromFile, path.fileType.name)

            artworkfiles[path.fileType] = files

        return artWorkFound, artworkfiles, artworkurls
Пример #26
0
    def getFilesByWildcardExt(self, pathName):

        log.info("Begin getFilesByWildcard. pathName = %s" % pathName)
        files = []
        dirs = []

        dirname = os.path.dirname(pathName)
        log.info("dirname: %s" % dirname)
        filemask = os.path.basename(pathName)
        # HACK: escape [] for use with fnmatch
        filemask = filemask.replace('[', '[[]')
        filemask = filemask.replace(']', '[]]')
        # This might be stupid but it was late...
        filemask = filemask.replace('[[[]]', '[[]')
        log.info("filemask: %s" % filemask)

        dirsLocal, filesLocal = xbmcvfs.listdir(dirname)
        log.info("xbmcvfs dirs: %s" % dirs)
        log.info("xbmcvfs files: %s" % filesLocal)

        for dir in dirsLocal:
            if type(dir) == str:
                dirs.append(dir.decode('utf-8'))
            else:
                dirs.append(dir)

        for file in filesLocal:
            if fnmatch.fnmatch(file, filemask):
                # allFiles = [f.decode(sys.getfilesystemencoding()).encode('utf-8') for f in glob.glob(newRomPath)]
                if type(file) == str:
                    file = file.decode('utf-8')
                file = util.joinPath(dirname, file)
                # return unicode filenames so relating scraping actions can handle them correctly
                files.append(file)

        return dirs, files, dirname, filemask

        """
Пример #27
0
    def getRomFilesByRomCollection(self, romCollection, enableFullReimport):

        log.info("Rom path: %s" % romCollection.romPaths)

        log.info("Reading rom files")
        files = []
        for romPath in romCollection.romPaths:
            log.info("Reading rom files in path: %s" % romPath)
            files = self.walkDownPath(files, unicode(romPath), romCollection.maxFolderDepth)

        # only use files that are not already present in database
        if enableFullReimport == False:
            inDBFiles = DataBaseObject(self.gdb, '').getFileAllFilesByRCId(romCollection.id)
            files = [f for f in files if not f in inDBFiles]

        files.sort()
        log.info("Files read: %s" % files)

        return files
Пример #28
0
    def insertGame(self, gameName, description, romCollectionId, publisherId, developerId, reviewerId, yearId,
                   players, rating, votes, url, region, media, perspective, controller, originalTitle, alternateTitle,
                   translatedBy, version, isFavorite, launchCount, isUpdate, gameId, allowUpdate):
        # Check if exists and insert/update as appropriate; move this functionality to the Game object
        try:
            if not isUpdate:
                log.info(u"Game does not exist in database. Insert game: %s" % gameName)
                Game(self.gdb).insert(
                    (gameName, description, None, None, romCollectionId, publisherId, developerId, reviewerId, yearId,
                     players, rating, votes, url, region, media, perspective, controller, int(isFavorite),
                     int(launchCount), originalTitle, alternateTitle, translatedBy, version))
                return self.gdb.cursor.lastrowid
            else:
                if allowUpdate:

                    # check if we are allowed to update with null values
                    allowOverwriteWithNullvalues = __addon__.getSetting(
                        util.SETTING_RCB_ALLOWOVERWRITEWITHNULLVALUES).upper() == 'TRUE'
                    log.info("allowOverwriteWithNullvalues: {0}".format(allowOverwriteWithNullvalues))

                    log.info(u"Game does exist in database. Update game: %s" % gameName)
                    Game(self.gdb).update(('name', 'description', 'romCollectionId', 'publisherId', 'developerId',
                                           'reviewerId', 'yearId', 'maxPlayers', 'rating', 'numVotes',
                                           'url', 'region', 'media', 'perspective', 'controllerType', 'originalTitle',
                                           'alternateTitle', 'translatedBy', 'version', 'isFavorite', 'launchCount'),
                                          (gameName, description, romCollectionId, publisherId, developerId, reviewerId,
                                           yearId, players, rating, votes, url, region, media, perspective, controller,
                                           originalTitle, alternateTitle, translatedBy, version, int(isFavorite),
                                           int(launchCount)),
                                          gameId, allowOverwriteWithNullvalues)
                else:
                    log.info(
                        u"Game does exist in database but update is not allowed for current rom collection. game: %s" % gameName)

                return gameId
        except Exception, (exc):
            log.error(u"An error occured while adding game '%s'. Error: %s" % (gameName, exc))
            return None
	def onInit(self):
		log.info("onInit Edit Rom Collection")

		# Rom Collections
		self.addItemsToList(CONTROL_LIST_ROMCOLLECTIONS, self.gui.config.getRomCollectionNames())

		log.info("build scraper lists")
		self.availableScrapers = self.getAvailableScrapers()
		self.addItemsToList(CONTROL_LIST_SCRAPER1, self.availableScrapers)

		log.info("build imagePlacing list")
		self.imagePlacingList = []
		imagePlacingRows = self.gui.config.tree.findall('ImagePlacing/fileTypeFor')
		for imagePlacing in imagePlacingRows:
			log.info("add image placing: {0}".format(imagePlacing.attrib.get('name')))
			option = imagePlacing.attrib.get('name')
			# HACK: remove all video options from config
			if option.upper().find('VIDEO') >= 0:
				continue
			try:
				option = config.imagePlacingDict[option]
			except IndexError:
				pass
			self.imagePlacingList.append(option)
		self.addItemsToList(CONTROL_LIST_IMAGEPLACING_MAIN, self.imagePlacingList)
		self.addItemsToList(CONTROL_LIST_IMAGEPLACING_INFO, self.imagePlacingList)

		if not helper.isRetroPlayerSupported():
			for ctrl_id in [CONTROL_BUTTON_USERETROPLAYER, CONTROL_BUTTON_GAMECLIENT]:
				try:
					control = self.getControlById(ctrl_id)
					control.setEnabled(False)
					control.setVisible(False)
				except AttributeError:
					pass

		self.updateRomCollectionControls()
Пример #30
0
    def checkRomfileAlreadyExists(self, filename, enableFullReimport):

        isUpdate = False
        gameId = None
        log.debug("Checking if file already exists in DB: %s" % filename)
        romFile = File(self.gdb).getFileByNameAndType(filename, 0)
        if romFile is not None:
            isUpdate = True
            gameId = romFile[3]  # FIXME TODO Replace with FILE_parentId
            log.info("File '%s' already exists in database." % filename)
            log.info("Always rescan imported games = {0}".format(enableFullReimport))
            if enableFullReimport is False:
                log.info("Won't scrape this game again. Set 'Always rescan imported games' to True to force scraping.")
                return False, isUpdate, gameId
        else:
            log.debug("Couldn't find file in DB")

        return True, isUpdate, gameId
    def onClick(self, controlID):
        log.info("onClick")

        if controlID == CONTROL_BUTTON_EXIT:  # Close window button
            log.info("close")
            self.close()
        # OK
        elif controlID == CONTROL_BUTTON_SAVE:
            log.info("save")
            # Store selectedRomCollection
            if self.selectedRomCollection is not None:
                self.updateSelectedRomCollection()
                self.romCollections[
                    self.selectedRomCollection.id] = self.selectedRomCollection

            configWriter = ConfigXmlWriter(False)
            success, message = configWriter.writeRomCollections(
                self.romCollections, True)

            if not success:
                xbmcgui.Dialog().ok(util.localize(32021), message)
            self.close()

        # Cancel
        elif controlID == CONTROL_BUTTON_CANCEL:
            self.close()
        elif controlID == CONTROL_BUTTON_ADD_RC:
            statusOk, errorMsg = wizardconfigxml.ConfigXmlWizard(
            ).addRomCollection(self.gui.config)
            if statusOk is False:
                xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32001),
                                    errorMsg)
                log.info("Error updating config.xml: {0}".format(errorMsg))
                return

            #update self.config
            self.gui.config = Config(None)
            statusOk, errorMsg = self.gui.config.readXml()
            if statusOk is False:
                xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32002),
                                    errorMsg)
                log.info("Error reading config.xml: {0}".format(errorMsg))
                return

            self.addItemsToList(CONTROL_LIST_ROMCOLLECTIONS,
                                self.gui.config.getRomCollectionNames())
            self.updateRomCollectionControls()

        elif controlID == CONTROL_BUTTON_REMOVE_RC:
            constructorParam = "720p"
            try:
                removeRCDialog = dialogdeleteromcollection.RemoveRCDialog(
                    "script-RCB-removeRC.xml",
                    util.getAddonInstallPath(),
                    util.getConfiguredSkin(),
                    constructorParam,
                    gui=self.gui)
            except:
                removeRCDialog = dialogdeleteromcollection.RemoveRCDialog(
                    "script-RCB-removeRC.xml",
                    util.getAddonInstallPath(),
                    "Default",
                    constructorParam,
                    gui=self.gui)
            rDelStat = removeRCDialog.getDeleteStatus()
            if rDelStat:
                selectedRCId = removeRCDialog.getSelectedRCId()
                rcDelStat = removeRCDialog.getRCDeleteStatus()
                self.gui.deleteRCGames(selectedRCId, rcDelStat, rDelStat)
                del removeRCDialog

            self.gui.config = Config(None)
            statusOk, errorMsg = self.gui.config.readXml()
            if statusOk is False:
                xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32002),
                                    errorMsg)
                log.info("Error reading config.xml: {0}".format(errorMsg))
                return

            self.addItemsToList(CONTROL_LIST_ROMCOLLECTIONS,
                                self.gui.config.getRomCollectionNames())
            self.updateRomCollectionControls()

        # Rom Collection list
        elif self.selectedControlId in (CONTROL_BUTTON_RC_DOWN,
                                        CONTROL_BUTTON_RC_UP):
            if self.selectedRomCollection is not None:
                # Save current values to selected Rom Collection
                self.updateSelectedRomCollection()
                # Store previous selectedRomCollections state
                self.romCollections[
                    self.selectedRomCollection.id] = self.selectedRomCollection

            # HACK: add a little wait time as XBMC needs some ms to execute the MoveUp/MoveDown actions from the skin
            xbmc.sleep(util.WAITTIME_UPDATECONTROLS)
            self.updateRomCollectionControls()

        # Media Path
        elif self.selectedControlId in (CONTROL_BUTTON_MEDIA_DOWN,
                                        CONTROL_BUTTON_MEDIA_UP):
            # HACK: add a little wait time as XBMC needs some ms to execute the MoveUp/MoveDown actions from the skin
            xbmc.sleep(util.WAITTIME_UPDATECONTROLS)
            self.updateMediaPathControls()

        elif controlID == CONTROL_LIST_OFFLINE_SCRAPER:
            self.editOfflineScraper()

        elif controlID == CONTROL_BUTTON_GAMECLIENT:
            success, gameclient = helper.selectlibretrocore(
                self.selectedRomCollection.name)
            if success:
                self.selectedRomCollection.gameclient = gameclient

            control = self.getControlById(CONTROL_BUTTON_GAMECLIENT)
            if gameclient == "":
                control.setLabel("None")
            else:
                control.setLabel(gameclient)

        elif controlID == CONTROL_BUTTON_EMUCMD:
            self.editEmuCmd()

        elif controlID == CONTROL_BUTTON_PARAMS:
            emulatorParams = self.editTextProperty(CONTROL_BUTTON_PARAMS,
                                                   util.localize(32625))
            self.selectedRomCollection.emulatorParams = emulatorParams

        elif controlID == CONTROL_BUTTON_ROMPATH:
            self.editRomPath()

        elif controlID == CONTROL_BUTTON_FILEMASK:
            self.editRomFileMask()

        elif controlID == CONTROL_BUTTON_MEDIAPATH:
            self.editMediaPath()

        elif controlID == CONTROL_BUTTON_MEDIAFILEMASK:
            self.editMediaFileMask()

        elif controlID == CONTROL_BUTTON_ADDMEDIAPATH:
            self.addMediaPath()

        elif controlID == CONTROL_BUTTON_REMOVEMEDIAPATH:
            self.removeMediaPath()

        elif controlID == CONTROL_BUTTON_MAXFOLDERDEPTH:
            maxFolderDepth = self.editTextProperty(
                CONTROL_BUTTON_MAXFOLDERDEPTH, util.localize(32610))
            self.selectedRomCollection.maxFolderDepth = maxFolderDepth

        elif controlID == CONTROL_BUTTON_DISKINDICATOR:
            diskIndicator = self.editTextProperty(CONTROL_BUTTON_DISKINDICATOR,
                                                  util.localize(32611))
            self.selectedRomCollection.diskPrefix = diskIndicator

        elif controlID == CONTROL_BUTTON_SAVESTATEPATH:
            saveStatePathComplete = self.editPathWithFileMask(
                CONTROL_BUTTON_SAVESTATEPATH,
                '%s ' % self.selectedRomCollection.name + util.localize(32629),
                CONTROL_BUTTON_SAVESTATEMASK)
            if saveStatePathComplete != '':
                self.selectedRomCollection.saveStatePath = saveStatePathComplete

        elif controlID == CONTROL_BUTTON_SAVESTATEMASK:
            self.selectedRomCollection.saveStatePath = self.editFilemask(
                CONTROL_BUTTON_SAVESTATEMASK, util.localize(32630),
                self.selectedRomCollection.saveStatePath)

        elif controlID == CONTROL_BUTTON_SAVESTATEPARAMS:
            saveStateParams = self.editTextProperty(
                CONTROL_BUTTON_SAVESTATEPARAMS, util.localize(32631))
            self.selectedRomCollection.saveStateParams = saveStateParams

        elif controlID == CONTROL_BUTTON_PRECMD:
            preCmd = self.editTextProperty(CONTROL_BUTTON_PRECMD,
                                           util.localize(32632))
            self.selectedRomCollection.preCmd = preCmd
            log.info("OnClick: precmd = {0}".format(
                self.selectedRomCollection.preCmd))

        elif controlID == CONTROL_BUTTON_POSTCMD:
            postCmd = self.editTextProperty(CONTROL_BUTTON_POSTCMD,
                                            util.localize(32633))
            self.selectedRomCollection.postCmd = postCmd
Пример #32
0
    def addRomCollections(self, rcId, configObj, consoleList, isUpdate):

        romCollections = {}
        dialog = xbmcgui.Dialog()

        # Scraping scenario - game descriptions and artwork retrieved from online or available locally
        scenarioIndex = dialog.select(
            util.localize(32173),
            [util.localize(32174),
             util.localize(32175),
             util.localize(32207)])
        log.info("scenarioIndex: " + str(scenarioIndex))
        if scenarioIndex == -1:
            del dialog
            log.info("No scenario selected. Action canceled.")
            return False, romCollections

        autoconfig = EmulatorAutoconfig(util.getEmuAutoConfigPath())

        while True:

            fileTypeList, errorMsg = self.buildMediaTypeList(
                configObj, isUpdate)
            romCollection = RomCollection()
            if (errorMsg):
                log.warn("Error building Media Type List: {0}" % errorMsg)
                break

            # Console
            platformIndex = dialog.select(util.localize(32176), consoleList)
            log.info("platformIndex: " + str(platformIndex))
            if platformIndex == -1:
                log.info("No Platform selected. Action canceled.")
                break

            console = consoleList[platformIndex]
            if console == 'Other':
                console = self.promptOtherConsoleName()
                if console == '':
                    break

            else:
                consoleList.remove(console)
                log.info("Selected platform: " + console)

            romCollection.name = console
            romCollection.id = rcId
            rcId = rcId + 1

            # Check if we have general RetroPlayer support
            if helper.isRetroPlayerSupported():
                #32198 = Use RetroPlayer to launch games?
                romCollection.useBuiltinEmulator = bool(
                    dialog.yesno(util.SCRIPTNAME, util.localize(32198)))

            # Only ask for emulator and params if we don't use builtin emulator
            if not romCollection.useBuiltinEmulator:

                # Maybe there is autoconfig support
                preconfiguredEmulator = None

                # Emulator
                if romCollection.name in ['Linux', 'Macintosh', 'Windows']:
                    # Check for standalone games
                    romCollection.emulatorCmd = '"%ROM%"'
                    log.info("emuCmd set to '%ROM%' for standalone games.")

                else:
                    emulist = []

                    log.info(
                        u'Running on {0}. Trying to find emulator per autoconfig.'
                        .format(util.current_os))
                    emulators = autoconfig.findEmulators(
                        util.current_os, romCollection.name, True)
                    for emulator in emulators:
                        if emulator.isInstalled:
                            emulist.append(
                                util.localize(32202) % emulator.name)
                        else:
                            emulist.append(emulator.name)

                    # Ask the user which one they want
                    if len(emulist) > 0:
                        try:
                            emuIndex = dialog.select(util.localize(32203),
                                                     emulist)
                            if emuIndex >= 0:
                                preconfiguredEmulator = emulators[emuIndex]
                        except IndexError:
                            log.info("No Emulator selected.")
                            preconfiguredEmulator = None

                    if preconfiguredEmulator:
                        romCollection.emulatorCmd = preconfiguredEmulator.emuCmd
                    else:
                        consolePath = dialog.browse(
                            1,
                            util.localize(32178) % console, 'files')
                        Logutil.log('consolePath: ' + str(consolePath),
                                    util.LOG_LEVEL_INFO)
                        if consolePath == '':
                            log.info(
                                "No consolePath selected. Action canceled.")
                            break
                        romCollection.emulatorCmd = consolePath

                # Set emulator parameters
                if romCollection.name in ['Linux', 'Macintosh', 'Windows']:
                    romCollection.emulatorParams = ''
                    log.info("emuParams set to " " for standalone games.")
                else:
                    if preconfiguredEmulator:
                        defaultParams = preconfiguredEmulator.emuParams
                    else:
                        defaultParams = '"%ROM%"'

                    romCollection.emulatorParams = self.promptEmulatorParams(
                        defaultParams)

            # Prompt for rompath
            romPath = self.promptRomPath(console)
            if romPath == '':
                log.info("No romPath selected. Action canceled.")
                break

            # Filemask
            fileMasks = self.promptEmulatorFileMasks()
            if fileMasks == []:
                break

            romCollection.romPaths = []
            for fileMask in fileMasks:
                romCollection.romPaths.append(
                    util.joinPath(romPath, fileMask.strip()))

            # Specific MAME settings
            if romCollection.name == 'MAME':
                romCollection.imagePlacingMain = ImagePlacing()
                romCollection.imagePlacingMain.name = 'gameinfomamecabinet'

                # MAME zip files contain several files but they must be passed to the emu as zip file
                romCollection.doNotExtractZipFiles = True

            if scenarioIndex == RETRIEVE_INFO_ONLINE_ARTWORK_ONLINE:
                # Prompt for artwork path
                artworkPath = self.promptArtworkPath(console, romPath)
                if artworkPath == '':
                    log.info("No artworkPath selected. Action canceled.")
                    break

                romCollection.descFilePerGame = True

                # Media Paths
                romCollection.mediaPaths = []

                if romCollection.name == 'MAME':
                    mediaTypes = [
                        'boxfront', 'action', 'title', 'cabinet', 'marquee',
                        'clearlogo', 'gameplay'
                    ]
                else:
                    mediaTypes = [
                        'boxfront', 'boxback', 'cartridge', 'screenshot',
                        'fanart', 'clearlogo', 'gameplay'
                    ]
                for t in mediaTypes:
                    romCollection.mediaPaths.append(
                        self.createMediaPath(t, artworkPath, scenarioIndex))
            else:
                romCollection.mediaPaths = []

                # Default to looking in the romPath for the first artwork path
                lastArtworkPath = romPath
                while True:
                    # Prompt the user for which artwork type we are selecting
                    fileTypeIndex = dialog.select(util.localize(32183),
                                                  fileTypeList)
                    if fileTypeIndex == -1:
                        log.info("No fileTypeIndex selected.")
                        break

                    fileType = fileTypeList[fileTypeIndex]
                    fileTypeList.remove(fileType)

                    # Prompt user for path for existing artwork
                    artworkPath = util.convertToUnicodeString(
                        dialog.browse(
                            0,
                            util.localize(32182) % (console, fileType),
                            'files', '', False, False, lastArtworkPath))
                    log.debug(u"artworkPath selected: {0}".format(artworkPath))
                    if artworkPath == '':
                        log.info("No artworkPath selected.")
                        break
                    lastArtworkPath = artworkPath

                    romCollection.mediaPaths.append(
                        self.createMediaPath(fileType, artworkPath,
                                             scenarioIndex))

                    # Ask to add another artwork path
                    #32184 = Do you want to add another Artwork Path?
                    if not dialog.yesno(util.SCRIPTNAME, util.localize(32184)):
                        break

                #not used atm as we don't have any offline scrapers with descfile per game
                """
                # Ask user for source of game descriptions (description file per game or for all games)
                descIndex = dialog.select(util.localize(32185), [util.localize(32186), util.localize(32187)])
                log.debug("descIndex: " + str(descIndex))
                if descIndex == -1:
                    log.info("No descIndex selected. Action canceled.")
                    break

                romCollection.descFilePerGame = (descIndex != GAME_DESCRIPTION_SINGLE_FILE)
                """

                if scenarioIndex == RETRIEVE_INFO_LOCAL_ARTWORK_LOCAL:
                    offline_scrapers = AbstractScraper(
                    ).get_available_offline_scrapers(console)
                    scraperIndex = dialog.select(util.localize(32206),
                                                 offline_scrapers)
                    if scraperIndex == -1:
                        log.info("No Scraper type selected. Action canceled.")
                        break

                    selectedscraper = offline_scrapers[scraperIndex]
                    log.info("Selected scraper = {0}".format(selectedscraper))

                    #not used atm as we don't have any offline scrapers with descfile per game
                    """
                    if romCollection.descFilePerGame:
                        # Assume the files are in a single directory with the mask %GAME%.txt
                        # Prompt the user for the path
                        pathValue = dialog.browse(0, util.localize(32189) % console, 'files')
                        if pathValue == '':
                            break

                        # Prompt the user for the description file mask
                        filemask = xbmcgui.Dialog().input(util.localize(32190), defaultt='%GAME%.xml', type=xbmcgui.INPUT_ALPHANUM)
                        descPath = util.joinPath(pathValue, filemask.strip())
                    else:
                    """
                    descPath = dialog.browse(1,
                                             util.localize(32189) % console,
                                             'files', '', False, False,
                                             lastArtworkPath)

                    log.info("descPath: " + str(descPath))
                    if descPath == '':
                        log.info("No descPath selected. Action canceled.")
                        break

                    # Create scraper
                    site = Site(name=selectedscraper,
                                path=descPath,
                                default=True)
                    romCollection.scraperSites = [site]

            log.debug("Created new rom collection: {0}".format(romCollection))

            romCollections[romCollection.id] = romCollection

            # Ask the user if they want to add another rom collection
            #32192 = Do you want to add another Rom Collection?
            if not dialog.yesno(util.SCRIPTNAME, util.localize(32192)):
                break

        del dialog

        return True, romCollections
	def onClick(self, controlID):
		log.info("onClick")

		if controlID == CONTROL_BUTTON_EXIT:  # Close window button
			log.info("close")
			self.close()
		# OK
		elif controlID == CONTROL_BUTTON_SAVE:
			log.info("save")
			# Store selectedRomCollection
			if self.selectedRomCollection is not None:
				self.updateSelectedRomCollection()
				self.romCollections[self.selectedRomCollection.id] = self.selectedRomCollection

			configWriter = ConfigXmlWriter(False)
			success, message = configWriter.writeRomCollections(self.romCollections, True)

			if not success:
				xbmcgui.Dialog().ok(util.localize(32021), message)
			self.close()

		# Cancel
		elif controlID == CONTROL_BUTTON_CANCEL:
			self.close()
		# Rom Collection list
		elif self.selectedControlId in (CONTROL_BUTTON_RC_DOWN, CONTROL_BUTTON_RC_UP):
			if self.selectedRomCollection is not None:
				# Save current values to selected Rom Collection
				self.updateSelectedRomCollection()
				# Store previous selectedRomCollections state
				self.romCollections[self.selectedRomCollection.id] = self.selectedRomCollection

			# HACK: add a little wait time as XBMC needs some ms to execute the MoveUp/MoveDown actions from the skin
			xbmc.sleep(util.WAITTIME_UPDATECONTROLS)
			self.updateRomCollectionControls()

		# Media Path
		elif self.selectedControlId in (CONTROL_BUTTON_MEDIA_DOWN, CONTROL_BUTTON_MEDIA_UP):
			# HACK: add a little wait time as XBMC needs some ms to execute the MoveUp/MoveDown actions from the skin
			xbmc.sleep(util.WAITTIME_UPDATECONTROLS)
			self.updateMediaPathControls()

		elif controlID == CONTROL_LIST_OFFLINE_SCRAPER:
			self.editOfflineScraper()

		elif controlID == CONTROL_BUTTON_GAMECLIENT:
			success, gameclient = helper.selectlibretrocore(self.selectedRomCollection.name)
			if success:
				self.selectedRomCollection.gameclient = gameclient

			control = self.getControlById(CONTROL_BUTTON_GAMECLIENT)
			if gameclient == "":
				control.setLabel("None")
			else:
				control.setLabel(gameclient)

		elif controlID == CONTROL_BUTTON_EMUCMD:
			self.editEmuCmd()

		elif controlID == CONTROL_BUTTON_PARAMS:
			emulatorParams = self.editTextProperty(CONTROL_BUTTON_PARAMS, util.localize(32625))
			self.selectedRomCollection.emulatorParams = emulatorParams

		elif controlID == CONTROL_BUTTON_ROMPATH:
			self.editRomPath()

		elif controlID == CONTROL_BUTTON_FILEMASK:
			self.editRomFileMask()

		elif controlID == CONTROL_BUTTON_MEDIAPATH:
			self.editMediaPath()

		elif controlID == CONTROL_BUTTON_MEDIAFILEMASK:
			self.editMediaFileMask()

		elif controlID == CONTROL_BUTTON_ADDMEDIAPATH:
			self.addMediaPath()

		elif controlID == CONTROL_BUTTON_REMOVEMEDIAPATH:
			self.removeMediaPath()

		elif controlID == CONTROL_BUTTON_MAXFOLDERDEPTH:
			maxFolderDepth = self.editTextProperty(CONTROL_BUTTON_MAXFOLDERDEPTH, util.localize(32610))
			self.selectedRomCollection.maxFolderDepth = maxFolderDepth

		elif controlID == CONTROL_BUTTON_DISKINDICATOR:
			diskIndicator = self.editTextProperty(CONTROL_BUTTON_DISKINDICATOR, util.localize(32611))
			self.selectedRomCollection.diskPrefix = diskIndicator

		elif controlID == CONTROL_BUTTON_SAVESTATEPATH:
			saveStatePathComplete = self.editPathWithFileMask(CONTROL_BUTTON_SAVESTATEPATH, '%s ' % self.selectedRomCollection.name + util.localize(32629), CONTROL_BUTTON_SAVESTATEMASK)
			if saveStatePathComplete != '':
				self.selectedRomCollection.saveStatePath = saveStatePathComplete

		elif controlID == CONTROL_BUTTON_SAVESTATEMASK:
			self.selectedRomCollection.saveStatePath = self.editFilemask(CONTROL_BUTTON_SAVESTATEMASK, util.localize(32630), self.selectedRomCollection.saveStatePath)

		elif controlID == CONTROL_BUTTON_SAVESTATEPARAMS:
			saveStateParams = self.editTextProperty(CONTROL_BUTTON_SAVESTATEPARAMS, util.localize(32631))
			self.selectedRomCollection.saveStateParams = saveStateParams

		elif controlID == CONTROL_BUTTON_PRECMD:
			preCmd = self.editTextProperty(CONTROL_BUTTON_PRECMD, util.localize(32632))
			self.selectedRomCollection.preCmd = preCmd
			log.info("OnClick: precmd = {0}".format(self.selectedRomCollection.preCmd))

		elif controlID == CONTROL_BUTTON_POSTCMD:
			postCmd = self.editTextProperty(CONTROL_BUTTON_POSTCMD, util.localize(32633))
			self.selectedRomCollection.postCmd = postCmd
Пример #34
0
 def post_launch(self, romCollection, gameRow, postcmd):
     log.info("AbstractLauncher.post_launch()")
     pass
Пример #35
0
    def _buildCmd(self, gui, filenameRows, gameRow, calledFromSkin):
        log.info("launcher.buildCmd")

        compressedExtensions = ['7z', 'zip']

        cmd = ""
        precmd = ""
        postcmd = ""
        roms = []

        emuCommandLine = self.romCollection.emulatorCmd
        log.info("emuCommandLine: " + emuCommandLine)
        log.info("preCmdLine: " + self.romCollection.preCmd)
        log.info("postCmdLine: " + self.romCollection.postCmd)

        # handle savestates
        stateFile = self.__checkGameHasSaveStates(gameRow, filenameRows)

        if stateFile == '':
            emuParams = self.romCollection.emulatorParams
        else:
            emuParams = self.romCollection.saveStateParams
            if self.escapeCmd:
                stateFile = re.escape(stateFile)
            emuParams = emuParams.replace('%statefile%', stateFile)
            emuParams = emuParams.replace('%STATEFILE%', stateFile)
            emuParams = emuParams.replace('%Statefile%', stateFile)

        # params could be: {-%I% %ROM%}
        # we have to repeat the part inside the brackets and replace the %I% with the current index
        emuParams, partToRepeat = self.__prepareMultiRomCommand(emuParams)

        # ask for disc number if multidisc game
        diskName = ""
        if self.romCollection.diskPrefix != '' and '%I%' not in emuParams:
            log.info("Getting Multiple Disc Parameter")
            options = []
            for disk in filenameRows:
                gamename = os.path.basename(disk[0])
                match = re.search(self.romCollection.diskPrefix, gamename, re.IGNORECASE)
                if match:
                    disk = gamename[match.start():match.end()]
                    options.append(disk)
            if len(options) > 1 and not calledFromSkin:
                diskNum = xbmcgui.Dialog().select(util.localize(32164) + ': ', options)
                if diskNum < 0:
                    # don't launch game
                    log.info("No disc was chosen. Won't launch game")
                    return "", "", "", None
                else:
                    diskName = options[diskNum]
                    log.info("Chosen Disc: %s" % diskName)

        # insert game specific command
        gameCmd = ''
        if gameRow[GameView.COL_gameCmd] is not None:
            gameCmd = str(gameRow[GameView.COL_gameCmd])
        # be case insensitive with (?i)
        emuParams = re.sub('(?i)%gamecmd%', gameCmd, emuParams)

        log.info("emuParams: " + emuParams)

        fileindex = int(0)
        for fileNameRow in filenameRows:
            rom = fileNameRow[0]
            log.info("rom: " + rom)

            if self.romCollection.makeLocalCopy:
                localDir = os.path.join(util.getTempDir(), self.romCollection.name)
                if xbmcvfs.exists(localDir + '\\'):
                    log.info("Trying to delete local rom files")
                    dirs, files = xbmcvfs.listdir(localDir)
                    for f in files:
                        xbmcvfs.delete(os.path.join(localDir, f))
                localRom = os.path.join(localDir, os.path.basename(str(rom)))
                log.info("Creating local copy: " + str(localRom))
                if xbmcvfs.copy(rom, localRom):
                    log.info("Local copy created")
                rom = localRom

            # If it's a .7z file
            # Don't extract zip files in case of savestate handling and when called From skin
            filext = rom.split('.')[-1]
            roms = [rom]
            if filext in compressedExtensions and not self.romCollection.doNotExtractZipFiles and stateFile == '' and not calledFromSkin:
                roms = self.__handleCompressedFile(gui, filext, rom, emuParams)
                log.debug("roms compressed = " + str(roms))
                if len(roms) == 0:
                    return "", "", "", None

            # no use for complete cmd as we just need the game name
            if self.romCollection.useBuiltinEmulator:
                log.debug("roms = " + str(roms))
                return "", "", "", roms

            del rom

            for rom in roms:
                if fileindex == 0:
                    emuParams = self.__replacePlaceholdersInParams(emuParams, rom, gameRow)
                    if self.escapeCmd:
                        emuCommandLine = re.escape(emuCommandLine)

                    if self.romCollection.name in ['Linux', 'Macintosh', 'Windows']:
                        cmd = self.__replacePlaceholdersInParams(emuCommandLine, rom, gameRow)
                    else:
                        cmd = '\"' + emuCommandLine + '\" ' + emuParams.replace('%I%', str(fileindex))
                else:
                    newrepl = partToRepeat
                    newrepl = self.__replacePlaceholdersInParams(newrepl, rom, gameRow)
                    if self.escapeCmd:
                        emuCommandLine = re.escape(emuCommandLine)

                    newrepl = newrepl.replace('%I%', str(fileindex))
                    if newrepl:
                        cmd += ' ' + newrepl

                cmdprefix = ''

                if self.env == "win32":
                    cmdprefix = 'call '

                precmd = cmdprefix + self.__replacePlaceholdersInParams(self.romCollection.preCmd, rom, gameRow)
                postcmd = cmdprefix + self.__replacePlaceholdersInParams(self.romCollection.postCmd, rom, gameRow)

                fileindex += 1

        # A disk was chosen by the user, select it here
        if diskName:
            log.info("Choosing Disk: " + str(diskName))
            match = re.search(self.romCollection.diskPrefix.lower(), cmd.lower())
            replString = cmd[match.start():match.end()]
            cmd = cmd.replace(replString, diskName)

        return cmd, precmd, postcmd, roms
Пример #36
0
    def launchEmu(self, gdb, gui, gameId, config, listitem):
        log.info("Begin launcher.launchEmu")

        gameRow = GameView(gdb).getObjectById(gameId)
        if gameRow is None:
            log.error("Game with id %s could not be found in database" % gameId)
            return

        try:
            self.romCollection = config.romCollections[str(gameRow[GameView.COL_romCollectionId])]
        except KeyError:
            log.error("Cannot get rom collection with id: " + str(gameRow[GameView.COL_romCollectionId]))
            gui.writeMsg(util.localize(32034))
            return

        gui.writeMsg(util.localize(32163) + " " + gameRow[DataBaseObject.COL_NAME])

        # Remember viewstate
        gui.saveViewState(False)

        filenameRows = File(gdb).getRomsByGameId(gameRow[DataBaseObject.COL_ID])
        log.info("files for current game: " + str(filenameRows))

        cmd, precmd, postcmd, roms = self._buildCmd(gui, filenameRows, gameRow, False)

        if not self.romCollection.useBuiltinEmulator:
            if cmd == '':
                log.info("No cmd created. Game will not be launched.")
                return
            if precmd.strip() == '' or precmd.strip() == 'call':
                log.info("No precmd created.")

            if postcmd.strip() == '' or postcmd.strip() == 'call':
                log.info("No postcmd created.")

            # solo mode
            if self.romCollection.useEmuSolo:

                self.__copyLauncherScriptsToUserdata()

                # communicate with service via settings
                __addon__.setSetting(util.SETTING_RCB_LAUNCHONSTARTUP, 'true')

                # invoke script file that kills xbmc before launching the emulator
                basePath = os.path.join(util.getAddonDataPath(), 'scriptfiles')

                if self.env == "win32":
                    if __addon__.getSetting(util.SETTING_RCB_USEVBINSOLOMODE).lower() == 'true':
                        # There is a problem with quotes passed as argument to windows command shell. This only works with "call"
                        # use vb script to restart xbmc
                        cmd = 'call \"' + os.path.join(basePath,
                                                       'applaunch-vbs.bat') + '\" ' + cmd
                    else:
                        # There is a problem with quotes passed as argument to windows command shell. This only works with "call"
                        cmd = 'call \"' + os.path.join(basePath, 'applaunch.bat') + '\" ' + cmd
                else:
                    cmd = os.path.join(basePath, 'applaunch.sh ') + cmd
            else:
                # use call to support paths with whitespaces
                if self.env == "win32":
                    cmd = 'call ' + cmd

        # update LaunchCount
        launchCount = gameRow[GameView.COL_launchCount]
        if launchCount is None:
           launchCount = 0
        Game(gdb).update(('launchCount',), (launchCount + 1,), gameRow[Game.COL_ID], True)
        gdb.commit()

        log.info("cmd: " + cmd)
        log.info("precmd: " + precmd)
        log.info("postcmd: " + postcmd)

        try:
            self.__launchNonXbox(cmd, gameRow, precmd, postcmd, roms, gui, listitem)

            gui.writeMsg("")

        except Exception as exc:
            log.error("Error while launching emu: " + str(exc))
            gui.writeMsg(util.localize(32035) + ": " + str(exc))

        log.info("End launcher.launchEmu")
Пример #37
0
 def replace_diskname(self, romCollection, cmd, diskName):
     log.info("AbstractLauncher.replace_disk_name()")
     return cmd
Пример #38
0
    def __handleCompressedFile(self, gui, filext, rom, emuParams):

        log.info("__handleCompressedFile")

        # Note: Trying to delete temporary files (from zip or 7z extraction) from last run
        # Do this before launching a new game. Otherwise game could be deleted before launch
        tempDir = os.path.join(util.getTempDir(), 'extracted', self.romCollection.name)
        # check if folder exists
        if not xbmcvfs.exists(tempDir + '\\'):
            log.info("Create temporary folder: " + tempDir)
            xbmcvfs.mkdir(tempDir)

        try:
            if xbmcvfs.exists(tempDir + '\\'):
                log.info("Trying to delete temporary rom files")
                #can't use xbmcvfs.listdir here as it seems to cache the file list and RetroPlayer won't find newly created files anymore
                files = os.listdir(tempDir)
                for f in files:
                    #RetroPlayer places savestate files next to the roms. Don't delete these files.
                    fname, ext = os.path.splitext(f)
                    if ext not in ('.sav', '.xml', '.png'):
                        xbmcvfs.delete(os.path.join(tempDir, f))
        except Exception as exc:
            log.error("Error deleting files after launch emu: " + str(exc))
            gui.writeMsg(util.localize(32036) + ": " + str(exc))

        roms = []

        log.info("Treating file as a compressed archive")

        try:
            names = self.__getNames(filext, rom)
        except Exception as exc:
            log.error("Error handling compressed file: " + str(exc))
            return []

        if names is None:
            log.error("Error handling compressed file")
            return []

        chosenROM = -1

        # check if we should handle multiple roms
        match = False
        if self.romCollection.diskPrefix != '':
            match = re.search(self.romCollection.diskPrefix.lower(), str(names).lower())

        if '%I%' in emuParams and match:
            log.info("Loading %d archives" % len(names))

            try:
                archives = self.__getArchives(filext, rom, names)
            except Exception as exc:
                log.error("Error handling compressed file: " + str(exc))
                return []

            if archives is None:
                log.warning("Error handling compressed file")
                return []
            for archive in archives:
                newPath = os.path.join(tempDir, archive[0])
                fp = open(newPath, 'wb')
                fp.write(archive[1])
                fp.close()
                roms.append(newPath)

        elif len(names) > 1:
            log.info("The Archive has %d files" % len(names))
            chosenROM = xbmcgui.Dialog().select('Choose a ROM', names)
        elif len(names) == 1:
            log.info("Archive only has one file inside; picking that one")
            chosenROM = 0
        else:
            log.error("Archive had no files inside!")
            return []

        if chosenROM != -1:
            # Extract all files to %TMP%
            archives = self.__getArchives(filext, rom, names)
            if archives is None:
                log.warn("Error handling compressed file")
                return []
            for archive in archives:
                newPath = os.path.join(tempDir, archive[0])
                log.info("Putting extracted file in %s" % newPath)
                fo = open(str(newPath), 'wb')
                fo.write(archive[1])
                fo.close()

            # Point file name to the chosen file and continue as usual
            roms = [os.path.join(tempDir, names[chosenROM])]

        return roms
    def onClick(self, controlID):

        log.info('onClick')

        if controlID == CONTROL_BUTTON_EXIT:
            # Close window button
            log.info('Close')
            self.close()
        elif controlID == CONTROL_BUTTON_CANCEL:
            # Cancel button
            self.close()
        elif controlID == CONTROL_BUTTON_SAVE:
            # OK
            log.info('Save')

            # Store selectedRomCollection
            if self.selectedRomCollection is not None:
                # Code to Remove Roms
                log.info('Removing Roms')
                self._setDeleteStatus(True)
                # Code to Remove Collection
                if self.romDelete == 'RCollection':
                    self._setRCDeleteStatus(True)
                    Logutil.log('Removing Rom Collection', util.LOG_LEVEL_INFO)
                    configWriterRCDel = ConfigXmlWriter(False)
                    RCName = str(self.selectedRomCollection.name)
                    success, message = configWriterRCDel.removeRomCollection(
                        RCName)
                    if success is False:
                        log.error(message)
                        xbmcgui.Dialog().ok(util.localize(32019),
                                            util.localize(32020))
            log.info('Click Close')
            self.close()

        elif self.selectedControlId in (CONTROL_BUTTON_RC_DOWN,
                                        CONTROL_BUTTON_RC_UP):
            # Changing selection in Rom Collection list
            if self.selectedRomCollection is not None:
                # Store previous selectedRomCollections state
                self.romCollections[
                    self.selectedRomCollection.id] = self.selectedRomCollection

            # HACK: add a little wait time as XBMC needs some ms to execute the MoveUp/MoveDown actions from the skin
            xbmc.sleep(util.WAITTIME_UPDATECONTROLS)
            self.updateControls()
        elif self.selectedControlId in (CONTROL_BUTTON_DEL_DOWN,
                                        CONTROL_BUTTON_DEL_UP):
            # Changing selection in Delete Option list
            control = self.getControlById(CONTROL_LIST_DELETEOPTIONS)
            selectedDeleteOption = str(control.getSelectedItem().getLabel2())
            log.info('selectedDeleteOption = {0}'.format(selectedDeleteOption))
            self.romDelete = selectedDeleteOption
Пример #40
0
    def __launchNonXbox(self, cmd, gameRow, precmd, postcmd, roms, gui, listitem):
        log.info("launchEmu on non-xbox")

        screenModeToggled = False

        # use libretro core to play game
        if self.romCollection.useBuiltinEmulator:
            log.info("launching game with internal emulator")
            rom = roms[0]
            gameclient = self.romCollection.gameclient
            # HACK: use alternateGameCmd as gameclient
            if gameRow[GameView.COL_alternateGameCmd] is not None and gameRow[GameView.COL_alternateGameCmd] != "":
                gameclient = str(gameRow[GameView.COL_alternateGameCmd])
            log.info("Preferred gameclient: " + gameclient)
            log.info("Setting platform: " + self.romCollection.name)

            #if game is launched from RCB widget there is no listitem
            if listitem is None:
                listitem = xbmcgui.ListItem(rom)

            parameters = {"platform": self.romCollection.name}
            if gameclient != "":
                parameters["gameclient"] = gameclient
            listitem.setInfo(type="game", infoLabels=parameters)
            log.info("launching rom: " + rom)

            gui.player.play(rom, listitem)
            # xbmc.executebuiltin('PlayMedia(\"%s\", platform=%s, gameclient=%s)' %(rom, romCollection.name, romCollection.gameclient))
            return

        if not self.romCollection.useEmuSolo:
            screenMode = xbmc.getInfoLabel("System.Screenmode")
            log.info("screenMode: " + screenMode)
            isFullScreen = screenMode.endswith("Full Screen")

            toggleScreenMode = __addon__.getSetting(util.SETTING_RCB_TOGGLESCREENMODE).upper() == 'TRUE'

            if isFullScreen and toggleScreenMode:
                log.info("Toggling to windowed mode")
                # this minimizes xbmc some apps seems to need it
                xbmc.executeJSONRPC(KODI_JSONRPC_TOGGLE_FULLSCREEN)

                screenModeToggled = True

        log.info("launch emu")

        self.__executePreCommand(precmd)

        self.__preDelay()

        self.__audioSuspend()

        self.__executeCommand(cmd)

        log.info("launch emu done")

        self.__postDelay()

        self.__audioResume()

        self.__executePostCommand(postcmd)

        if screenModeToggled:
            log.info("Toggle to Full Screen mode")
            # this brings xbmc back
            xbmc.executeJSONRPC(KODI_JSONRPC_TOGGLE_FULLSCREEN)
Пример #41
0
 def launch(self, romCollection, gameRow, cmd, roms, listitem):
     log.info("AbstractLauncher.launch()")
     pass
Пример #42
0
 def __executePreCommand(self, precmd):
     # pre launch command
     if precmd.strip() != '' and precmd.strip() != 'call':
         log.info("Got to PRE: " + precmd.strip())
         os.system(precmd)
 def is_archive(self, rom):
     log.info("ArchiveHandler.is_archive")
     if rom is None:
         return False
     return rom.split('.')[-1] in self.compressedExtensions
    def updateRomCollectionControls(self):
        log.info("updateRomCollectionControls")

        control = self.getControlById(CONTROL_LIST_ROMCOLLECTIONS)
        selectedRomCollectionName = str(control.getSelectedItem().getLabel())

        log.info(
            "selected rom collection: {0}".format(selectedRomCollectionName))
        self.selectedRomCollection = self.gui.config.getRomCollectionByName(
            selectedRomCollectionName)
        if self.selectedRomCollection is None:
            return

        log.info("build scraper lists")
        self.availableScrapers = AbstractScraper().get_available_scrapers(
            self.selectedRomCollection.name)
        self.addItemsToList(CONTROL_LIST_DEFAULT_SCRAPER,
                            self.availableScrapers)

        # Import Games
        self.updateRomParams()

        # Set the currently selected state for all the buttons
        for item in self._control_buttons:
            control = self.getControlById(item['control'])
            control.setSelected(
                getattr(self.selectedRomCollection, item['value']))
            log.info('Set button control ID ' + str(item['control']) +
                     ' to value ' +
                     str(getattr(self.selectedRomCollection, item['value'])))

        # Set the value for all the labels
        for item in self._control_labels:
            control = self.getControlById(item['control'])
            util.setLabel(getattr(self.selectedRomCollection, item['value']),
                          control)
            log.info('Set label control ID ' + str(item['control']) +
                     ' to value ' +
                     str(getattr(self.selectedRomCollection, item['value'])))

        # preferred scraper
        self.selectScrapersInList(self.selectedRomCollection.scraperSites,
                                  CONTROL_LIST_DEFAULT_SCRAPER)

        self.addOfflineScrapersToList()

        # Artwork
        # Media Types
        self.updateMediaTypes()

        # Browse Games
        optionMain = self.selectedRomCollection.imagePlacingMain.name
        try:
            optionMain = config.imagePlacingDict[optionMain]
        except IndexError:
            pass
        self.selectItemInList(optionMain, CONTROL_LIST_IMAGEPLACING_MAIN)

        optionInfo = self.selectedRomCollection.imagePlacingInfo.name
        try:
            optionInfo = config.imagePlacingDict[optionInfo]
        except IndexError:
            pass
        self.selectItemInList(optionInfo, CONTROL_LIST_IMAGEPLACING_INFO)
    def __init__(self, *args, **kwargs):
        log.info('init Edit RC Basic')

        self.gui = kwargs["gui"]
        self.romCollections = self.gui.config.romCollections
        self.doModal()
Пример #46
0
    def updateDB(self, gdb, gui, romCollections, isRescrape):
        self.gdb = gdb
        self._gui = gui

        log.info("Start Update DB")

        #at start, check if we need to create any artwork directories
        if not helper.createArtworkDirectories(romCollections):
            #32010: Error: Could not create artwork directory.
            return False, util.localize(32010)

        log.info("Iterating Rom Collections")
        rccount = 1

        # always do full reimports when in rescrape-mode
        enableFullReimport = isRescrape or __addon__.getSetting(util.SETTING_RCB_ENABLEFULLREIMPORT).upper() == 'TRUE'
        log.info("enableFullReimport: {0}".format(enableFullReimport))

        continueUpdate = True
        # Added variable to allow user to continue on errors
        ignoreErrors = False

        for romCollection in list(romCollections.values()):

            # timestamp1 = time.clock()

            # check if import was canceled
            if not continueUpdate:
                log.info("Game import canceled")
                break

            # prepare Header for ProgressDialog
            # 32122 = Importing Rom Collection
            progDialogRCHeader = util.localize(32122) + " (%i / %i): %s" % (
                rccount, len(romCollections), romCollection.name)
            rccount += 1

            log.info("current Rom Collection: {0}".format(romCollection.name))

            # Read settings for current Rom Collection
            log.info("ignoreOnScan: {0}".format(romCollection.ignoreOnScan))
            if romCollection.ignoreOnScan:
                log.info("current Rom Collection will be ignored.")
                # self.scrapeResultsFile.write('Rom Collection will be ignored.\n')
                continue

            log.info("update is allowed for current rom collection: {0}".format(romCollection.allowUpdate))
            log.info("max folder depth: {0}".format(romCollection.maxFolderDepth))

            files = self.getRomFilesByRomCollection(romCollection, enableFullReimport)
            if len(files) == 0:
                log.info(u"No files found for rom collection {0}, skipping".format(romCollection.name))
                continue

            log.info(u"Found {0} game files for rom collection {1}".format(len(files), romCollection.name))

            # itemCount is used for percentage in ProgressDialogGUI
            self._gui.itemCount = len(files) + 1

            successfulFiles = 0
            lastgamename = ''
            lastGameId = None

            for fileidx, filename in enumerate(files):

                try:
                    #Give kodi a chance to interrupt the process
                    #HACK: we should use monitor.abortRequested() or monitor.waitForAbort()
                    #but for some reason only xbmc.abortRequested returns True
                    if monitor.abortRequested():
                        log.info("Kodi requests abort. Cancel Update.")
                        break

                    log.info("Scraping for %s" % filename)
                    gamenameFromFile = romCollection.getGamenameFromFilename(filename)

                    # check if we are handling one of the additional disks of a multi rom game
                    isMultiRomGame = (gamenameFromFile == lastgamename)
                    lastgamename = gamenameFromFile

                    if isMultiRomGame:
                        # Add this entry as a file under the game ID and move on
                        log.info("Detected %s as a multirom game (previous game was %s)" % (filename, lastgamename))
                        if lastGameId is None:
                            log.error("Game detected as multi rom game, but lastGameId is None.")
                            continue
                        fileType = FileType()
                        fileType.id, fileType.name, fileType.parent = 0, "rcb_rom", "game"
                        self.insertFile(filename, lastGameId, fileType, None, None, None)
                        self.gdb.commit()
                        del fileType
                        continue

                    log.info("Start scraping info for game: %s" % gamenameFromFile)

                    # 32123 = Importing Game
                    msg = "%s: %s" %(util.localize(32123), gamenameFromFile)
                    continueUpdate = self._gui.writeMsg(msg, fileidx + 1)
                    if not continueUpdate:
                        log.info("Game import canceled by user")
                        break

                    # check if this file already exists in DB
                    continueUpdate, isUpdate, gameId = self.checkRomfileAlreadyExists(filename, enableFullReimport)
                    if not continueUpdate:
                        continue

                    foldername = self.getFoldernameFromRomFilename(filename)

                    results, artScrapers = self.useSingleScrapers(romCollection, filename, gamenameFromFile,
                                                                  progDialogRCHeader, fileidx + 1)

                    if len(results) == 0:
                        # lastgamename = ""
                        results = None

                    # Variables to process Art Download Info
                    self._guiDict.update({'dialogHeaderKey': progDialogRCHeader, 'gameNameKey': gamenameFromFile,
                                          'scraperSiteKey': artScrapers, 'fileCountKey': (fileidx + 1)})
                    del artScrapers

                    #Give kodi a chance to interrupt the process
                    #HACK: we should use monitor.abortRequested() or monitor.waitForAbort()
                    #but for some reason only xbmc.abortRequested returns True
                    if monitor.abortRequested():
                        log.info("Kodi requests abort. Cancel Update.")
                        break

                    # Add 'gui' and 'dialogDict' parameters to function
                    lastGameId = self.insertGameFromDesc(results, gamenameFromFile, romCollection, [filename],
                                                         foldername, isUpdate, gameId)
                    del results, foldername

                    if lastGameId is not None:
                        log.info("Successfully added %s" % gamenameFromFile)
                        successfulFiles += 1

                    # Check if all first 10 games have errors - Modified to allow user to continue on errors
                    if fileidx > 9 and successfulFiles == 0 and not ignoreErrors:
                        #32124 = Continue
                        #32125 = Continue and Ignore Errors
                        #32126 = Cancel
                        #32127 = First 10 games could not be imported.
                        options = [util.localize(32124), util.localize(32125), util.localize(32126)]
                        answer = xbmcgui.Dialog().select(util.localize(32127), options)
                        if answer == 1:
                            # Continue and ignore errors
                            ignoreErrors = True
                        elif answer == 2:
                            # Cancel
                            #32128 = Import canceled.
                            #32129 = Please check kodi.log for details.
                            message = "%s[CR]%s" % (util.localize(32128), util.localize(32129))
                            xbmcgui.Dialog().ok(util.SCRIPTNAME, message)
                            continueUpdate = False
                            break

                except ScraperExceededAPIQuoteException:
                    #32128 = Import canceled.
                    #32043 = API quota for current scraper exceeded.
                    xbmcgui.Dialog().ok(util.localize(32128), util.localize(32043))
                    # Abort the scraping entirely
                    break
                except Exception as exc:
                    log.warn(u"An error occurred while adding game %s: %s" % (gamenameFromFile, exc))
                    self.missingDescFile.add_entry(gamenameFromFile)

                    continue

        # timestamp2 = time.clock()
        # diff = (timestamp2 - timestamp1) * 1000
        # print "load %i games in %d ms" % (self.getListSize(), diff)

        self._gui.writeMsg("Done.", self._gui.itemCount)
        log.info("Update finished")
        return True, ''
Пример #47
0
 def prepare_solomode(self, romCollection, cmd):
     log.info("AbstractLauncher.prepare_solomode()")
     return cmd
Пример #48
0
    def useSingleScrapers(self, romCollection, romFile, gamenameFromFile, progDialogRCHeader, fileCount):
        """Scrape site for game metadata

        Args:
            romCollection:
            romFile:
            gamenameFromFile:
            progDialogRCHeader:
            fileCount:

        Returns:
            dict for the game result:
                {'SearchKey': ['Chrono Trigger'],
                 'Publisher': ['Squaresoft'],
                 'Description': ["The millennium. A portal is opened. The chain of time is broken...],
                 'Players': ['1'],
                 'Platform': ['Super Nintendo (SNES)'],
                 'Game': ['Chrono Trigger'],
                 'Filetypeboxfront': ['http://thegamesdb.net/banners/boxart/original/front/1255-1.jpg'],
                 'Filetypeboxback': ['http://thegamesdb.net/banners/boxart/original/back/1255-1.jpg'],
                 'Filetypescreenshot': ['http://thegamesdb.net/banners/screenshots/1255-1.jpg', 'http://thegamesdb.net/banners/screenshots/1255-2.jpg', 'http://thegamesdb.net/banners/screenshots/1255-3.jpg', 'http://thegamesdb.net/banners/screenshots/1255-4.jpg', 'http://thegamesdb.net/banners/screenshots/1255-5.jpg'],
                 'Filetypefanart': ['http://thegamesdb.net/banners/fanart/original/1255-1.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-10.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-11.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-2.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-3.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-4.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-5.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-6.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-7.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-8.jpg', 'http://thegamesdb.net/banners/fanart/original/1255-9.jpg'],
                 'Genre': ['Role-Playing'],
                 'Developer': ['Squaresoft']}
            dict for artwork urls:
                {'Filetypefanart': 'thegamesdb.net', 'Filetypeboxback': 'thegamesdb.net', 'Filetypescreenshot': 'thegamesdb.net', 'Filetypeboxfront': 'thegamesdb.net'}
                Note - this only contains entries for artwork that was found (i.e. is not empty list)
        """
        gameresult = {}
        artScrapers = {}

        scraperSite = None

        #search for default scraper if there are more than one
        for site in romCollection.scraperSites:
            if site.default:
                scraperSite = site
                break

        #if no default site was found, just use the first one
        if not scraperSite:
            if len(romCollection.scraperSites) >= 1:
                scraperSite = romCollection.scraperSites[0]

        try:
            #first check if a local nfo file is available
            nfoscraper = NFO_Scraper()
            nfofile = nfoscraper.get_nfo_path(gamenameFromFile, romCollection.name, romFile)
            if xbmcvfs.exists(nfofile) and __addon__.getSetting(util.SETTING_RCB_PREFERLOCALNFO).upper() == 'TRUE':
                log.info("Found local nfo file. Using this to scrape info.")
                newscraper = nfoscraper
            else:
                newscraper = AbstractScraper().get_scraper_by_name(scraperSite.name)
                #set path to desc file (only useful for offline scrapers)
                newscraper.path = scraperSite.path

            log.info("Using scraper: %s" % newscraper.name)
            # 32123 = Importing Game
            # 32131 = downloading info
            msg = "%s: %s[CR]%s: %s" %(util.localize(32123), gamenameFromFile, newscraper.name, util.localize(32131))
            self._gui.writeMsg(msg, fileCount)

            results = newscraper.search(gamenameFromFile, romCollection.name)
            log.debug(u"Searching for %s - found %s results: %s" % (gamenameFromFile, len(results), results))
        except ScraperExceededAPIQuoteException as ke:
            # API key is invalid - we need to stop scraping
            log.error("Scraper exceeded API key, stopping scraping")
            raise
        except Exception as e:
            log.error("Error searching for %s using scraper %s - %s %s" % (
                gamenameFromFile, scraperSite.name, type(e), e))
            return gameresult, artScrapers

        if results == []:
            log.warn("No search results found for %s using scraper %s" % (gamenameFromFile, scraperSite.name))
            return gameresult, artScrapers

        matched = Matcher().getBestResults(results, gamenameFromFile)
        if matched is None:
            log.error("No matches found for %s, skipping" % gamenameFromFile)
            return gameresult, artScrapers
        log.debug("After matching: %s" % matched)

        try:
            retrievedresult = newscraper.retrieve(matched['id'], romCollection.name)
            log.debug(u"Retrieving %s - found %s" % (matched['id'], retrievedresult))
        except Exception as e:
            # FIXME TODO Catch exceptions specifically
            log.error("Error retrieving %s - %s %s" % (matched['id'], type(e), e))
            return gameresult, artScrapers

        # Update the gameresult with any new fields
        gameresult = self.addNewElements(gameresult, retrievedresult)

        # Find Filetypes and Scrapers for Art Download
        # FIXME TODO The following is kept to keep artwork downloading working as it currently is. We already have
        # the URLs and so could handle/download here, rather than deferring
        if len(gameresult) > 0:
            for path in romCollection.mediaPaths:
                thumbKey = 'Filetype' + path.fileType.name
                if len(self.resolveParseResult(gameresult, thumbKey)) > 0:
                    if (thumbKey in artScrapers) == 0:
                        artScrapers[thumbKey] = scraperSite.name

        log.debug(u"After scraping, result = %s, artscrapers = %s" % (gameresult, artScrapers))
        return gameresult, artScrapers
Пример #49
0
 def build_cmd(self, romCollection, gameRow, roms, emuParams,
               part_to_repeat_in_emuparams):
     log.info("AbstractLauncher.build_cmd()")
     return "", "", ""
Пример #50
0
    def resolvePath(self, paths, gamename, gamenameFromFile, foldername, romCollectionName, publisher, developer):
        resolvedFiles = []

        for path in paths:
            files = []
            log.info("resolve path: %s" % path)

            if path.find("%GAME%") > -1:

                pathnameFromFile = path.replace("%GAME%", gamenameFromFile)
                log.info("resolved path from rom file name: %s" % pathnameFromFile)
                files = self.getFilesByWildcard(pathnameFromFile)
                if len(files) == 0:
                    files = self.getFilesByGameNameIgnoreCase(pathnameFromFile)

                if gamename != gamenameFromFile and len(files) == 0:
                    pathnameFromGameName = path.replace("%GAME%", gamename)
                    log.info("resolved path from game name: %s" % pathnameFromGameName)
                    files = self.getFilesByWildcard(pathnameFromGameName)
                    if len(files) == 0:
                        files = self.getFilesByGameNameIgnoreCase(pathnameFromGameName)

                if gamename != foldername and len(files) == 0:
                    pathnameFromFolder = path.replace("%GAME%", foldername)
                    log.info("resolved path from rom folder name: %s" % pathnameFromFolder)
                    files = self.getFilesByWildcard(pathnameFromFolder)
                    if len(files) == 0:
                        files = self.getFilesByGameNameIgnoreCase(pathnameFromFolder)

            # ODO could be done only once per RomCollection
            if path.find("%ROMCOLLECTION%") > -1 and romCollectionName is not None and len(files) == 0:
                pathnameFromRomCollection = path.replace("%ROMCOLLECTION%", romCollectionName)
                log.info("resolved path from rom collection name: {0}".format(pathnameFromRomCollection))
                files = self.getFilesByWildcard(pathnameFromRomCollection)

            if path.find("%PUBLISHER%") > -1 and publisher is not None and len(files) == 0:
                pathnameFromPublisher = path.replace("%PUBLISHER%", publisher)
                log.info("resolved path from publisher name: %s" % pathnameFromPublisher)
                files = self.getFilesByWildcard(pathnameFromPublisher)

            if path.find("%DEVELOPER%") > -1 and developer is not None and len(files) == 0:
                pathnameFromDeveloper = path.replace("%DEVELOPER%", developer)
                log.info("resolved path from developer name: %s" % pathnameFromDeveloper)
                files = self.getFilesByWildcard(pathnameFromDeveloper)

            if path.find("%GAME%") == -1 & path.find("%ROMCOLLECTION%") == -1 & path.find(
                    "%PUBLISHER%") == -1 & path.find("%DEVELOPER%") == -1:
                pathnameFromStaticFile = path
                log.info("using static defined media file from path: %s" % pathnameFromStaticFile)
                files = self.getFilesByWildcard(pathnameFromStaticFile)

            if len(files) == 0:
                log.warn("No files found for game '%s' at path '%s'. Make sure that file names are matching." % (
                    gamename, path))
            for f in files:
                if xbmcvfs.exists(f):
                    resolvedFiles.append(f)

        return resolvedFiles
Пример #51
0
 def replace_gamecmd(self, gameRow, emuParams):
     log.info("AbstractLauncher.replace_gamecmd()")
     return ""
Пример #52
0
    def download_thumb(self, thumburl, destfilename):
        log.info("begin download_thumb using requests module: thumburl = %s" % thumburl)

        # Download file to tmp folder
        tmp = util.joinPath(util.getTempDir(), os.path.basename(destfilename))

        log.info("download_thumb: start downloading to temp file: %s" % tmp)
        response = requests.get(thumburl, headers=WebScraper._headers, stream=True)
        log.info("download_thumb: status code = %s" % response.status_code)
        if response.status_code != 200:
            log.info("download_thumb: invalid response status code. Can't download image.")
            return

        with open(tmp, 'wb') as f:
            response.raw.decode_content = True
            shutil.copyfileobj(response.raw, f)

        log.info("download_thumb: copy from temp file to final destination: %s" % destfilename)

        # Copy from the tmp folder to the target location
        xbmcvfs.copy(tmp, destfilename)
        xbmcvfs.delete(tmp)
        log.info("end download_thumb")
Пример #53
0
 def prepareMultiRomCommand(self, emuParams):
     log.info("AbstractLauncher.prepareMultiRomCommand()")
     return "", ""
Пример #54
0
    def getThumbFromOnlineSource(self, gamedescription, fileType, fileName, artworkurls):
        log.info("Get thumb from online source")

        try:
            # maybe we got a thumb url from desc parser
            thumbKey = 'Filetype' + fileType
            log.info("using key: %s" % thumbKey)
            thumbUrl = self.resolveParseResult(gamedescription, thumbKey)
            if thumbUrl == '':
                return True, artworkurls

            artworkurls[fileType] = thumbUrl

            log.info("Get thumb from url: %s" % thumbUrl)

            rootExtFile = os.path.splitext(fileName)
            rootExtUrl = os.path.splitext(thumbUrl)

            files = []
            if len(rootExtUrl) == 2 and len(rootExtFile) != 0:
                fileName = rootExtFile[0] + rootExtUrl[1]
                gameName = rootExtFile[0] + ".*"
                files = self.getFilesByWildcard(gameName)
            del rootExtFile, rootExtUrl

            if len(files) > 0:
                log.info("File already exists. Won't download again.")
                return True, artworkurls

            log.info("File %s does not exist, starting download" % fileName)
            # Dialog Status Art Download

            # Update progress dialog to state we are downloading art
            try:
                #32123 = Importing Game
                #32210 = downloading artwork
                msg = "%s: %s[CR]%s: %s" % (util.localize(32123), self._guiDict["gameNameKey"],
                                            self._guiDict["scraperSiteKey"][thumbKey], util.localize(32210))
                self._gui.writeMsg(msg, self._guiDict["fileCountKey"])
            except KeyError:
                log.warn("Unable to retrieve key from GUI dict")

            try:
                self.download_thumb(thumbUrl, fileName)

            except Exception as exc:
                log.error("Could not create file: '%s'. Error message: '%s'" % (fileName, exc))
                # xbmcgui.Dialog().ok(util.localize(32012), util.localize(32011))
                return False, artworkurls

            log.info("Download finished.")

        except Exception as exc:
            log.warn("Error in getThumbFromOnlineSource: %s" % exc)

        return True, artworkurls
Пример #55
0
from builtins import str
from builtins import range
from builtins import object
import os, shutil
from sqlite3 import dbapi2 as sqlite
from util import Logutil as log

from util import *
import util

log.info("Loading sqlite3 as DB engine")


class GameDataBase(object):

    def __init__(self, databaseDir):
        self.dataBasePath = os.path.join(databaseDir, 'MyGames.db')
        #use scripts home for reading SQL files
        self.sqlDir = os.path.join(util.RCBHOME, 'resources', 'database')

    def connect(self):
        print (self.dataBasePath)
        self.connection = sqlite.connect(self.dataBasePath, check_same_thread=False)

        # Use row factory so we can retrieve values by column name
        self.connection.row_factory = sqlite.Row

        self.cursor = self.connection.cursor()
        #set cache size to 20000 pages (default is 2000)
        self.cursor.execute("PRAGMA cache_size = 20000")
Пример #56
0
 def delete(self, gameId):
     log.info("Delete Files with gameId %s" % str(gameId))
     self.deleteObjectByQuery(self.deleteQuery, (gameId,))
Пример #57
0
 def __executePostCommand(self, postcmd):
     # post launch command
     if postcmd.strip() != '' and postcmd.strip() != 'call':
         log.info("Got to POST: " + postcmd.strip())
         os.system(postcmd)
	def onClick(self, controlID):
		if controlID == 5101:  # Close window button
			self.close()
		elif controlID == 5110:  # Import games
			self.close()
			self.gui.updateDB()
		elif controlID == 5121:  # Rescrape single games
			self.close()

			if self.selectedGame is None:
				xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32013), util.localize(32014))
				return

			romCollectionId = self.selectedGame.getProperty('romCollectionId')
			romCollection = self.gui.config.romCollections[str(romCollectionId)]
			files = File(self.gui.gdb).getRomsByGameId(self.selectedGame.getProperty('gameId'))
			filename = files[0][0]
			romCollection.romPaths = (filename,)

			romCollections = {}
			romCollections[romCollection.id] = romCollection

			self.gui.rescrapeGames(romCollections)

		elif controlID == 5122:  # Rescrape selection
			self.close()

			romCollections = {}
			listSize = self.gui.getListSize()
			for i in range(0, listSize):
				listItem = self.gui.getListItem(i)

				romCollectionId = listItem.getProperty('romCollectionId')

				try:
					romCollection = romCollections[str(romCollectionId)]
				except:
					romCollection = self.gui.config.romCollections[str(romCollectionId)]
					romCollection.romPaths = []

				files = File(self.gui.gdb).getRomsByGameId(listItem.getProperty('gameId'))
				try:
					filename = files[0][0]
					romCollection.romPaths.append(filename)
					romCollections[romCollection.id] = romCollection
				except:
					log.info("Error getting filename for romCollectionId: {0}".format(romCollectionId))

			self.gui.rescrapeGames(romCollections)

			#self.gui.updateDB()
		elif controlID == 5111:  # Add Rom Collection
			self.close()
			statusOk, errorMsg = wizardconfigxml.ConfigXmlWizard().addRomCollection(self.gui.config)
			if statusOk is False:
				xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32001), errorMsg)
				log.info("Error updating config.xml: {0}".format(errorMsg))
				return

			#update self.config
			statusOk, errorMsg = self.gui.config.readXml()
			if statusOk is False:
				xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32002), errorMsg)
				log.info("Error reading config.xml: {0}".format(errorMsg))
				return

			#import Games
			self.gui.updateDB()

		elif controlID == 5112:  # Edit Rom Collection
			self.close()
			constructorParam = "720p"
			editRCdialog = dialogeditromcollection.EditRomCollectionDialog("script-RCB-editromcollection.xml", util.getAddonInstallPath(), util.getConfiguredSkin(), constructorParam, gui=self.gui)
			del editRCdialog

			self.gui.config = Config(None)
			self.gui.config.readXml()

		elif controlID == 5113:  # Edit Game Command
			self.close()

			if(self.selectedGame == None):
				xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32015), util.localize(32014))
				return

			origCommand = self.selectedGame.getProperty('gameCmd')
			command = xbmcgui.Dialog().input(util.localize(32135), defaultt=origCommand, type=xbmcgui.INPUT_ALPHANUM)

			if command != origCommand:
				log.info("Updating game '{0}' with command '{1}'".format(self.selectedGame.getLabel(), command))
				Game(self.gui.gdb).update(('gameCmd',), (command,), self.selectedGame.getProperty('gameId'), True)
				self.gui.gdb.commit()

		elif controlID == 5118:  # (Un)Mark as Favorite
			self.close()

			if self.selectedGame is None:
				xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32016), util.localize(32014))
				return

			isFavorite = '1'
			if self.selectedGame.getProperty('isfavorite') == '1':
				isFavorite = '0'

			log.info("Updating game '{0}' set isFavorite = {1}".format(self.selectedGame.getLabel(), isFavorite))
			Game(self.gui.gdb).update(('isfavorite',), (isFavorite,), self.selectedGame.getProperty('gameId'), True)
			self.gui.gdb.commit()

			if isFavorite == '0':
				isFavorite = ''
			self.selectedGame.setProperty('isfavorite', str(isFavorite))

		elif controlID == 5119:  # (Un)Mark as Favorite
			self.close()

			if self.selectedGame is None:
				xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32016), util.localize(32014))
				return

			isFavorite = '1'
			if self.selectedGame.getProperty('isfavorite') == '1':
				isFavorite = '0'

			listSize = self.gui.getListSize()
			for i in range(0, listSize):

				listItem = self.gui.getListItem(i)

				log.info("Updating game '{0}' set isfavorite = {1}".format(listItem.getLabel(), isFavorite))
				Game(self.gui.gdb).update(('isfavorite',), (isFavorite,), listItem.getProperty('gameId'), True)
				listItem.setProperty('isfavorite', str(isFavorite))
			self.gui.gdb.commit()

			#HACK: removing favorites does not update the UI. So do it manually.
			if isFavorite == 0:
				self.gui.loadViewState()

		elif controlID == 5120:  # Export nfo files
			self.close()
			nfowriter.NfoWriter().exportLibrary(self.gui.gdb, self.gui.config.romCollections)

		elif controlID == 5114:  # Delete Rom
			self.close()

			pos = self.gui.getCurrentListPosition()
			if pos == -1:
				xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32017), util.localize(32018))
				return
			dialog = xbmcgui.Dialog()
			if dialog.yesno(util.localize(32510), util.localize(32136)):
				gameID = self.selectedGame.getProperty('gameId')
				self.gui.deleteGame(gameID)
				self.gui.showGames()
				if pos > 0:
					pos = pos - 1
					self.gui.setFilterSelection(self.gui.CONTROL_GAMES_GROUP_START, pos)
				else:
					self.gui.setFilterSelection(self.gui.CONTROL_GAMES_GROUP_START, 0)

		elif controlID == 5115:  # Remove Rom Collection
			self.close()

			constructorParam = "720p"
			removeRCDialog = dialogdeleteromcollection.RemoveRCDialog("script-RCB-removeRC.xml", util.getAddonInstallPath(), util.getConfiguredSkin(), constructorParam, gui=self.gui)
			rDelStat = removeRCDialog.getDeleteStatus()
			if rDelStat:
				selectedRCId = removeRCDialog.getSelectedRCId()
				rcDelStat = removeRCDialog.getRCDeleteStatus()
				self.gui.deleteRCGames(selectedRCId, rcDelStat, rDelStat)
				del removeRCDialog

		elif controlID == 5116:  # Clean DB
			self.close()
			self.gui.cleanDB()

		elif controlID == 5223:  # Open Settings
			self.close()
			self.gui.Settings.openSettings()

		elif controlID == 5224:  # Set gameclient
			self.close()

			if not helper.isRetroPlayerSupported():
				log.info("This RetroPlayer branch does not support selecting gameclients.")
				return

			if self.selectedGame is None or self.gameRow is None:
				xbmcgui.Dialog().ok(util.SCRIPTNAME, util.localize(32015), util.localize(32014))
				return

			#HACK: use alternateGameCmd to store gameclient information
			origGameClient = self.selectedGame.getProperty('alternateGameCmd')
			gameclient = ''

			romCollectionId = self.selectedGame.getProperty('romCollectionId')
			romCollection = self.gui.config.romCollections[str(romCollectionId)]

			success, selectedcore = helper.selectlibretrocore(romCollection.name)
			if success:
				gameclient = selectedcore
			else:
				log.info("No libretro core was chosen. Won't update game command.")
				return

			if gameclient != origGameClient:
				log.info("Updating game '{0}' with gameclient '{1}'".format(self.selectedGame.getLabel(), gameclient))
				Game(self.gui.gdb).update(('alternateGameCmd',), (gameclient,), self.selectedGame.getProperty('gameId'), True)
				self.gui.gdb.commit()
Пример #59
0
    def launch(self, romCollection, gameRow, cmd, roms, listitem):
        log.info("Cmd_Launcher.launch()")

        self.__executeCommand(romCollection, cmd)
Пример #60
0
    def prepare(self, romCollection, gameRow):
        log.info("AbstractLauncher.prepare()")

        # Remember viewstate
        self.gui.saveViewState(False)

        filenameRows = File(self.gdb).getRomsByGameId(
            gameRow[DataBaseObject.COL_ID])
        log.info("files for current game: " + str(filenameRows))

        # handle savestates
        saveStateParams = self.checkGameHasSaveStates(romCollection, gameRow,
                                                      filenameRows)

        # ask for disc number if multidisc game
        diskName = self._selectdisc(romCollection, filenameRows,
                                    self.calledFromSkin)

        # params could be: {-%I% %ROM%}
        # we have to repeat the part inside the brackets and replace the %I% with the current index
        emuParams, part_to_repeat_in_emuparams = self.prepareMultiRomCommand(
            romCollection.emulatorParams)

        # insert game specific command
        emuParams = self.replace_gamecmd(gameRow, emuParams)

        #iterate rom files
        fileindex = int(0)
        roms = []
        archive_handler = ArchiveHandler()
        for fileNameRow in filenameRows:
            rom = fileNameRow[0]
            log.info("rom: " + rom)

            rom = self._copylocal(romCollection, rom)

            if (archive_handler.is_archive(rom)):
                # Don't extract zip files in case of savestate handling and when called From skin
                if (not romCollection.doNotExtractZipFiles
                        and saveStateParams == '' and not self.calledFromSkin):
                    extracted_roms = archive_handler.extract_archive(
                        romCollection, rom, emuParams)
                    roms.extend(extracted_roms)

        precmd, postcmd, cmd = self.build_cmd(romCollection, gameRow, roms,
                                              emuParams,
                                              part_to_repeat_in_emuparams)

        cmd = self.replace_diskname(romCollection, cmd, diskName)

        cmd = self.prepare_solomode(romCollection, cmd)

        self.__update_launchcount(gameRow)

        log.info("cmd: " + cmd)
        log.info("precmd: " + precmd)
        log.info("postcmd: " + postcmd)
        return precmd, postcmd, cmd, roms