From 9520f3f3b777e2a2143e887753d5c239c3b234f8 Mon Sep 17 00:00:00 2001 From: "Thomas J. Moore" Date: Sat, 20 Feb 2016 14:59:52 -0600 Subject: [PATCH] Improvements to orphan detection: - blacklist applies to installed files only; use ignorelist for orphans - blacklisted but present items are orphans, as they should be - use exact matching for file paths: files in wrong location are orphans --- include/config.h | 2 + main.cpp | 22 +++++++ man/lgogdownloader.supplemental.groff | 10 ++- src/downloader.cpp | 91 +++++++-------------------- 4 files changed, 54 insertions(+), 71 deletions(-) diff --git a/include/config.h b/include/config.h index 0bedfe6..1ef35d9 100644 --- a/include/config.h +++ b/include/config.h @@ -60,6 +60,7 @@ class Config std::string sCookiePath; std::string sConfigFilePath; std::string sBlacklistFilePath; + std::string sIgnorelistFilePath; std::string sOrphanRegex; std::string sCoverList; std::string sReportFilePath; @@ -87,6 +88,7 @@ class Config curl_off_t iDownloadRate; long int iTimeout; Blacklist blacklist; + Blacklist ignorelist; }; #endif // CONFIG_H__ diff --git a/main.cpp b/main.cpp index 9aef7c5..f0f044b 100644 --- a/main.cpp +++ b/main.cpp @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) config.sCookiePath = config.sConfigDirectory + "/cookies.txt"; config.sConfigFilePath = config.sConfigDirectory + "/config.cfg"; config.sBlacklistFilePath = config.sConfigDirectory + "/blacklist.txt"; + config.sIgnorelistFilePath = config.sConfigDirectory + "/ignorelist.txt"; std::string priority_help_text = "Set priority by separating values with \",\"\nCombine values by separating with \"+\""; // Create help text for --platform option @@ -272,6 +273,27 @@ int main(int argc, char *argv[]) } } + if (boost::filesystem::exists(config.sIgnorelistFilePath)) + { + std::ifstream ifs(config.sIgnorelistFilePath.c_str()); + if (!ifs) + { + std::cerr << "Could not open ignorelist file: " << config.sIgnorelistFilePath << std::endl; + return 1; + } + else + { + std::string line; + std::vector lines; + while (!ifs.eof()) + { + std::getline(ifs, line); + lines.push_back(std::move(line)); + } + config.ignorelist.initialize(lines); + } + } + if (vm.count("chunk-size")) config.iChunkSize <<= 20; // Convert chunk size from bytes to megabytes diff --git a/man/lgogdownloader.supplemental.groff b/man/lgogdownloader.supplemental.groff index e0eed30..a376412 100644 --- a/man/lgogdownloader.supplemental.groff +++ b/man/lgogdownloader.supplemental.groff @@ -62,7 +62,15 @@ If \fB$XDG_CACHE_HOME\fP is not set, it will use \fI$HOME/.cache/lgogdownloader/ .TP \fI$XDG_CONFIG_HOME/lgogdownloader/blacklist.txt\fP -Allows user to specify individual files that should not be downloaded or mentioned as orphans. +Allows user to specify individual files that should not be downloaded. +.br +It doesn't have to exist, but if it does exist, it must be readable to lgogdownloader. + +.TP +\fI$XDG_CONFIG_HOME/lgogdownloader/ignorelist.txt\fP +Allows user to specify individual files that should not be mentioned +as orphans. The file has the same format and interpretation as a +blacklist. .br It doesn't have to exist, but if it does exist, it must be readable to lgogdownloader. diff --git a/src/downloader.cpp b/src/downloader.cpp index a4f8432..9d6b077 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -2467,6 +2467,17 @@ std::string Downloader::getSerialsFromJSON(const Json::Value& json) return serials.str(); } +// Linear search. Good thing computers are fast and lists are small. +static int isPresent(std::vector& list, const boost::filesystem::path& path, Blacklist& blacklist) +{ + if(blacklist.isBlacklisted(path.native())) + return false; + for (unsigned int k = 0; k < list.size(); ++k) + if (list[k].getFilepath() == path.native()) + return true; + return false; +} + void Downloader::checkOrphans() { // Always check everything when checking for orphaned files @@ -2529,7 +2540,7 @@ void Downloader::checkOrphans() if (boost::filesystem::is_regular_file(dir_iter->status())) { std::string filepath = dir_iter->path().string(); - if (config.blacklist.isBlacklisted(filepath.substr(pathlen))) { + if (config.ignorelist.isBlacklisted(filepath.substr(pathlen))) { if (config.bVerbose) std::cerr << "skipped ignorelisted file " << filepath << std::endl; } else { @@ -2556,80 +2567,20 @@ void Downloader::checkOrphans() { for (unsigned int j = 0; j < filepath_vector.size(); ++j) { - bool bFoundFile = false; // Assume that the file is orphaned + bool bFoundFile = isPresent(games[i].installers, filepath_vector[j], config.blacklist) + || isPresent(games[i].extras, filepath_vector[j], config.blacklist) + || isPresent(games[i].patches, filepath_vector[j], config.blacklist) + || isPresent(games[i].languagepacks, filepath_vector[j], config.blacklist); - // Check installers - for (unsigned int k = 0; k < games[i].installers.size(); ++k) - { - if (games[i].installers[k].path.find(filepath_vector[j].filename().string()) != std::string::npos) - { - bFoundFile = true; - break; - } - } - if (!bFoundFile) - { // Check extras - for (unsigned int k = 0; k < games[i].extras.size(); ++k) - { - if (games[i].extras[k].path.find(filepath_vector[j].filename().string()) != std::string::npos) - { - bFoundFile = true; - break; - } - } - } - if (!bFoundFile) - { // Check patches - for (unsigned int k = 0; k < games[i].patches.size(); ++k) - { - if (games[i].patches[k].path.find(filepath_vector[j].filename().string()) != std::string::npos) - { - bFoundFile = true; - break; - } - } - } - if (!bFoundFile) - { // Check language packs - for (unsigned int k = 0; k < games[i].languagepacks.size(); ++k) - { - if (games[i].languagepacks[k].path.find(filepath_vector[j].filename().string()) != std::string::npos) - { - bFoundFile = true; - break; - } - } - } if (!bFoundFile) { // Check dlcs for (unsigned int k = 0; k < games[i].dlcs.size(); ++k) { - for (unsigned int index = 0; index < games[i].dlcs[k].installers.size(); ++index) - { - if (games[i].dlcs[k].installers[index].path.find(filepath_vector[j].filename().string()) != std::string::npos) - { - bFoundFile = true; - break; - } - } - if (bFoundFile) break; - for (unsigned int index = 0; index < games[i].dlcs[k].patches.size(); ++index) - { - if (games[i].dlcs[k].patches[index].path.find(filepath_vector[j].filename().string()) != std::string::npos) - { - bFoundFile = true; - break; - } - } - for (unsigned int index = 0; index < games[i].dlcs[k].extras.size(); ++index) - { - if (games[i].dlcs[k].extras[index].path.find(filepath_vector[j].filename().string()) != std::string::npos) - { - bFoundFile = true; - break; - } - } - if (bFoundFile) break; + bFoundFile = isPresent(games[i].dlcs[k].installers, filepath_vector[j], config.blacklist) + || isPresent(games[i].dlcs[k].extras, filepath_vector[j], config.blacklist) + || isPresent(games[i].dlcs[k].patches, filepath_vector[j], config.blacklist); + if(bFoundFile) + break; } } if (!bFoundFile)