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
 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
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")
 def delete(self, gameId):
     log.info("Delete Files with gameId %s" % str(gameId))
     self.deleteObjectByQuery(self.deleteQuery, (gameId,))
 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()
    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