def editOfflineScraper(self): log.info('editOfflineScraper') control = self.getControlById(CONTROL_LIST_OFFLINE_SCRAPER) item = control.getSelectedItem() if item.getLabel() == '': scrapers = AbstractScraper().get_available_offline_scrapers(self.selectedRomCollection.name) scraperTypeIndex = xbmcgui.Dialog().select(util.localize(32642), scrapers) if scraperTypeIndex == -1: log.info('No Scraper Type selected.') return descfile = xbmcgui.Dialog().browse(1, util.localize(32643), 'files') if not descfile: log.info('No Scraper Path selected.') return scraper = Site() scraper.name = scrapers[scraperTypeIndex] scraper.path = descfile self.selectedRomCollection.scraperSites.append(scraper) self.addOfflineScrapersToList() else: path = os.path.dirname(item.getLabel2()) descfile = xbmcgui.Dialog().browse(1, util.localize(32643), 'files', defaultt=path) item.setLabel2(descfile)
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 onClick(self, controlID): if controlID == CONTROL_BUTTON_EXIT: # Close window button self.close() elif controlID == CONTROL_BUTTON_OK: self.close() self.doImport() elif controlID == CONTROL_BUTTON_CANCEL: self.close() elif controlID in (CONTROL_BUTTON_RC_DOWN, CONTROL_BUTTON_RC_UP): # Rom Collection list # 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) control = self.getControlById(CONTROL_LIST_ROMCOLLECTIONS) selectedRomCollectionName = str( control.getSelectedItem().getLabel()) #32120 = All if selectedRomCollectionName == util.localize(32120): sitesInList = AbstractScraper().get_available_online_scrapers() # 32804 = Use configured default scrapers sitesInList.append(util.localize(32804)) self.addItemsToList(CONTROL_LIST_SCRAPER1, sitesInList) self.selectItemInList(util.localize(32804), CONTROL_LIST_SCRAPER1) else: sitesInList = AbstractScraper().get_available_scrapers( selectedRomCollectionName) self.addItemsToList(CONTROL_LIST_SCRAPER1, sitesInList) # get selected rom collection object romCollection = self.gui.config.getRomCollectionByName( selectedRomCollectionName) self.selectScrapersInList(romCollection.scraperSites, CONTROL_LIST_SCRAPER1)
def onInit(self): log.info('onInit ImportOptions') # 32120 = All romCollectionList = [util.localize(32120) ] + self.gui.config.getRomCollectionNames() log.debug("Adding list of RC names: {0}".format(romCollectionList)) self.addItemsToList(CONTROL_LIST_ROMCOLLECTIONS, romCollectionList) # Deactivate Rom Collection list if self.romCollections is not None: # Set overwrite flag to false xbmc.executebuiltin( 'Skin.SetBool(%s)' % util.SETTING_RCB_IMPORTOPTIONS_DISABLEROMCOLLECTIONS) if not self.isRescrape: self.setFocus( self.getControl(CONTROL_BUTTON_SCRAPEINBACKGROUND)) else: xbmc.executebuiltin( 'Skin.Reset(%s)' % util.SETTING_RCB_IMPORTOPTIONS_DISABLEROMCOLLECTIONS) #disable background scraping control when in rescrape-mode if self.isRescrape: xbmc.executebuiltin('Skin.SetBool(%s)' % util.SETTING_RCB_IMPORTOPTIONS_ISRESCRAPE) self.setFocus(self.getControl(CONTROL_BUTTON_SCRAPER_DOWN)) else: xbmc.executebuiltin('Skin.Reset(%s)' % util.SETTING_RCB_IMPORTOPTIONS_ISRESCRAPE) #only provide online scrapers for option All Rom Collections sitesInList = AbstractScraper().get_available_online_scrapers() # add option for all rom collections # 32804 = Use configured default scrapers sitesInList.append(util.localize(32804)) self.addItemsToList(CONTROL_LIST_SCRAPER1, sitesInList) self.selectItemInList(util.localize(32804), CONTROL_LIST_SCRAPER1)
def useSingleScrapers(self, romCollection, romFile, gamenameFromFile, progDialogRCHeader, fileCount): """Scrape site for game metadata Args: romCollection: 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 = 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 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) self._gui.writeMsg(progDialogRCHeader, util.localize(32123) + ": " + gamenameFromFile, scraperSite.name + " - " + util.localize(32131), fileCount) # 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
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
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