From 65ca9bcfb9ad23227967aa050cadc9db24b43bbc Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Tue, 26 Jan 2021 17:40:37 +0100 Subject: [PATCH] Changed the logic for overwriting game names during scraping. Also fixed an issue when refining searches during semi-automatic scraping. --- USERGUIDE.md | 4 ++-- es-app/src/guis/GuiMetaDataEd.cpp | 2 +- es-app/src/guis/GuiScraperMulti.cpp | 20 +++++++++++------- es-app/src/guis/GuiScraperMulti.h | 2 +- es-app/src/guis/GuiScraperSearch.cpp | 31 ++++++++++++++++++++++------ es-app/src/guis/GuiScraperSearch.h | 5 ++++- 6 files changed, 46 insertions(+), 18 deletions(-) diff --git a/USERGUIDE.md b/USERGUIDE.md index 34d486507..e4309cf3c 100644 --- a/USERGUIDE.md +++ b/USERGUIDE.md @@ -662,7 +662,7 @@ Describes the content types to include in the scraping. Most users will probably **Scrape game names** -Whether to scrape the names of the games. This does not affect the actual files on the filesystem and is only used for viewing and sorting purposes. The downloaded media files are also matched against the physical game files on the filesystem, and not against this name. +Whether to scrape the names of the games. This does not affect the actual files on the filesystem and is only used for viewing and sorting purposes. The downloaded media files are also matched against the physical game files on the filesystem, and not against this metadata. See the comments under _Overwrite files and data_ below to understand some additional implications regarding the game names. **Scrape ratings** _(ScreenScraper only)_ @@ -706,7 +706,7 @@ Currently only English or World are supported, not really significant at the mom **Overwrite files and data** -Affects both overwriting of metadata as well as actual game media files on the filesystem. Even with this option disabled, metadata entries which are set to their default values will of course be populated by the scraper. In other words, this option only affects overwriting of previously scraped data. The only exception is game names for newly added games (which are based on the physical filenames of the game files) which will not be overwritten unless this option is enabled. +Affects both overwriting of metadata as well as actual game media files on the filesystem. Even with this option disabled, metadata entries which are set to their default values will of course be populated by the scraper. In other words, this option only affects overwriting of previously scraped data. Game names are considered as set to their default vaules if either corresponding to the physical game file on disk minus the extension (e.g. the entry _Commando_ if the file is named _Commando.zip_), or for arcade games if corresponding to the MAME names as defined in the bundled mamenames.xml. **Halt on invalid media files** diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 5e5619bc5..beba54011 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -444,7 +444,7 @@ void GuiMetaDataEd::fetchDone(const ScraperSearchResult& result) metadata->set(key, mEditors[i]->getValue()); } - GuiScraperSearch::saveMetadata(result, *metadata); + GuiScraperSearch::saveMetadata(result, *metadata, mScraperParams.game); // Update the list with the scraped metadata values. for (unsigned int i = 0; i < mEditors.size(); i++) { diff --git a/es-app/src/guis/GuiScraperMulti.cpp b/es-app/src/guis/GuiScraperMulti.cpp index cbaf98dfd..95bacdb7d 100644 --- a/es-app/src/guis/GuiScraperMulti.cpp +++ b/es-app/src/guis/GuiScraperMulti.cpp @@ -29,7 +29,8 @@ GuiScraperMulti::GuiScraperMulti( : GuiComponent(window), mBackground(window, ":/graphics/frame.svg"), mGrid(window, Vector2i(1, 5)), - mSearchQueue(searches) + mSearchQueue(searches), + mApproveResults(approveResults) { assert(mSearchQueue.size()); @@ -56,13 +57,13 @@ GuiScraperMulti::GuiScraperMulti( Font::get(FONT_SIZE_SMALL), 0x888888FF, ALIGN_CENTER); mGrid.setEntry(mSubtitle, Vector2i(0, 2), false, true); - if (approveResults && !Settings::getInstance()->getBool("ScraperSemiautomatic")) + if (mApproveResults && !Settings::getInstance()->getBool("ScraperSemiautomatic")) mSearchComp = std::make_shared(mWindow, GuiScraperSearch::NEVER_AUTO_ACCEPT, mTotalGames); - else if (approveResults && Settings::getInstance()->getBool("ScraperSemiautomatic")) + else if (mApproveResults && Settings::getInstance()->getBool("ScraperSemiautomatic")) mSearchComp = std::make_shared(mWindow, GuiScraperSearch::ACCEPT_SINGLE_MATCHES, mTotalGames); - else if (!approveResults) + else if (!mApproveResults) mSearchComp = std::make_shared(mWindow, GuiScraperSearch::ALWAYS_ACCEPT_FIRST_RESULT, mTotalGames); mSearchComp->setAcceptCallback(std::bind(&GuiScraperMulti::acceptResult, @@ -74,7 +75,7 @@ GuiScraperMulti::GuiScraperMulti( std::vector< std::shared_ptr > buttons; - if (approveResults) { + if (mApproveResults) { buttons.push_back(std::make_shared(mWindow, "REFINE SEARCH", "refine search", [&] { mSearchComp->openInputScreen(mSearchQueue.front()); @@ -160,7 +161,7 @@ void GuiScraperMulti::acceptResult(const ScraperSearchResult& result) { ScraperSearchParams& search = mSearchQueue.front(); - GuiScraperSearch::saveMetadata(result, search.game->metadata); + GuiScraperSearch::saveMetadata(result, search.game->metadata, search.game); updateGamelist(search.system); @@ -175,6 +176,7 @@ void GuiScraperMulti::skip() mSearchQueue.pop(); mCurrentGame++; mTotalSkipped++; + mSearchComp->unsetRefinedSearch(); doNextSearch(); } @@ -201,7 +203,11 @@ void GuiScraperMulti::finish() std::vector GuiScraperMulti::getHelpPrompts() { - return mGrid.getHelpPrompts(); + std::vector prompts = mGrid.getHelpPrompts(); + // Remove the 'Choose' entry if in fully automatic mode. + if (!mApproveResults) + prompts.pop_back(); + return prompts; } HelpStyle GuiScraperMulti::getHelpStyle() diff --git a/es-app/src/guis/GuiScraperMulti.h b/es-app/src/guis/GuiScraperMulti.h index 26964910d..53b276968 100644 --- a/es-app/src/guis/GuiScraperMulti.h +++ b/es-app/src/guis/GuiScraperMulti.h @@ -42,13 +42,13 @@ private: void doNextSearch(); void finish(); - unsigned int mTotalGames; unsigned int mCurrentGame; unsigned int mTotalSuccessful; unsigned int mTotalSkipped; std::queue mSearchQueue; std::vector mMetaDataDecl; + bool mApproveResults; NinePatchComponent mBackground; ComponentGrid mGrid; diff --git a/es-app/src/guis/GuiScraperSearch.cpp b/es-app/src/guis/GuiScraperSearch.cpp index 428b68a8e..dbd271300 100644 --- a/es-app/src/guis/GuiScraperSearch.cpp +++ b/es-app/src/guis/GuiScraperSearch.cpp @@ -527,6 +527,7 @@ void GuiScraperSearch::returnResult(ScraperSearchResult result) mScrapeCount -= 1; mAcceptCallback(result); + mRefinedSearch = false; } void GuiScraperSearch::update(int deltaTime) @@ -700,10 +701,23 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams& params) } bool GuiScraperSearch::saveMetadata( - const ScraperSearchResult& result, MetaDataList& metadata) + const ScraperSearchResult& result, MetaDataList& metadata, FileData* scrapedGame) { - bool mMetadataUpdated = false; + bool metadataUpdated = false; + bool hasDefaultName = false; std::vector mMetaDataDecl = metadata.getMDD(); + std::string defaultName; + + // Get the default name, which is either the MAME name or the name of the physical file + // or directory. + if (scrapedGame->isArcadeGame()) + defaultName = MameNames::getInstance()->getCleanName(scrapedGame->getCleanName()); + else + defaultName = Utils::FileSystem::getStem(scrapedGame->getFileName()); + + // We want the comparison to be case sensitive. + if (defaultName == metadata.get("name")) + hasDefaultName = true; for (unsigned int i = 0; i < mMetaDataDecl.size(); i++) { @@ -746,21 +760,26 @@ bool GuiScraperSearch::saveMetadata( // Overwrite all the other values if the flag to overwrite data has been set. if (Settings::getInstance()->getBool("ScraperOverwriteData")) { metadata.set(key, result.mdl.get(key)); - mMetadataUpdated = true; + metadataUpdated = true; + } + // If the key is the game name and it's set to its default value, then update. + else if (key == "name" && hasDefaultName) { + metadata.set(key, result.mdl.get(key)); + metadataUpdated = true; } // Else only update the value if it is set to the default metadata value. else if (metadata.get(key) == mMetaDataDecl.at(i).defaultValue) { metadata.set(key, result.mdl.get(key)); - mMetadataUpdated = true; + metadataUpdated = true; } // For the description, expand any escaped HTML quotation marks to literal // quotation marks. - if (key == "desc" && mMetadataUpdated) + if (key == "desc" && metadataUpdated) metadata.set(key, Utils::String::replace(metadata.get(key), """, "\"")); } - return mMetadataUpdated; + return metadataUpdated; } std::vector GuiScraperSearch::getHelpPrompts() diff --git a/es-app/src/guis/GuiScraperSearch.h b/es-app/src/guis/GuiScraperSearch.h index 270437701..88319a9e2 100644 --- a/es-app/src/guis/GuiScraperSearch.h +++ b/es-app/src/guis/GuiScraperSearch.h @@ -44,7 +44,8 @@ public: void openInputScreen(ScraperSearchParams& from); void stop(); inline SearchType getSearchType() const { return mSearchType; } - static bool saveMetadata(const ScraperSearchResult& result, MetaDataList& metadata); + static bool saveMetadata(const ScraperSearchResult& result, + MetaDataList& metadata, FileData* scrapedGame); // Metadata assets will be resolved before calling the accept callback // (e.g. result.mdl's "image" is automatically downloaded and properly set). @@ -64,6 +65,8 @@ public: void onFocusGained() override; void onFocusLost() override; + void unsetRefinedSearch() { mRefinedSearch = false; } + private: void updateViewStyle(); void updateThumbnail();