From f2794ededf51dc82aed797378c46673b425b21c9 Mon Sep 17 00:00:00 2001 From: Sude Date: Mon, 14 Oct 2013 22:31:12 +0300 Subject: [PATCH] Added --check-orphans to check for orphaned files Checks for orphaned files (files found on local filesystem that are not found on GOG servers) and prints their path --- include/config.h | 1 + include/downloader.h | 1 + main.cpp | 3 ++ src/downloader.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 121 insertions(+), 1 deletion(-) diff --git a/include/config.h b/include/config.h index e8d41c0..c848176 100644 --- a/include/config.h +++ b/include/config.h @@ -32,6 +32,7 @@ class Config bool bNoUnicode; // don't use Unicode in console output bool bNoColor; // don't use colors bool bVerifyPeer; + bool bCheckOrphans; std::string sGameRegex; std::string sDirectory; std::string sXMLFile; diff --git a/include/downloader.h b/include/downloader.h index 3473cd5..d6dd25a 100644 --- a/include/downloader.h +++ b/include/downloader.h @@ -48,6 +48,7 @@ class Downloader void updateCheck(); void repair(); void download(); + void checkOrphans(); CURL* curlhandle; Timer timer; Config config; diff --git a/main.cpp b/main.cpp index 2e9a581..e9cd8c5 100644 --- a/main.cpp +++ b/main.cpp @@ -103,6 +103,7 @@ int main(int argc, char *argv[]) ("verbose", bpo::value(&config.bVerbose)->zero_tokens()->default_value(false), "Print lots of information") ("insecure", bpo::value(&bInsecure)->zero_tokens()->default_value(false), "Don't verify authenticity of SSL certificates") ("timeout", bpo::value(&config.iTimeout)->default_value(10), "Set timeout for connection\nMaximum time in seconds that connection phase is allowed to take") + ("check-orphans", bpo::value(&config.bCheckOrphans)->zero_tokens()->default_value(false), "Check for orphaned files (files found on local filesystem that are not found on GOG servers)") ; bpo::store(bpo::parse_command_line(argc, argv, desc), vm); @@ -200,6 +201,8 @@ int main(int argc, char *argv[]) downloader.download(); else if (config.bListDetails || config.bList) // Detailed list of games/extras downloader.listGames(); + else if (config.bCheckOrphans) + downloader.checkOrphans(); else { // Show help message std::cout << config.sVersionString << std::endl diff --git a/src/downloader.cpp b/src/downloader.cpp index 151886b..c01407d 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -77,6 +77,14 @@ int Downloader::init() if (!config.bNoCover && config.bDownload && !config.bUpdateCheck) coverXML = this->getResponse("https://sites.google.com/site/gogdownloader/GOG_covers_v2.xml"); + if (config.bCheckOrphans) // Always check everything when checking for orphaned files + { + config.bNoInstallers = false; + config.bNoExtras = false; + config.bNoPatches = false; + config.bNoLanguagePacks = false; + } + if (!config.bUpdateCheck) // updateCheck() calls getGameList() if needed this->getGameList(); @@ -200,7 +208,7 @@ void Downloader::getGameList() } } - if (config.bListDetails || config.bDownload || config.bRepair) + if (config.bListDetails || config.bDownload || config.bRepair || config.bCheckOrphans) this->getGameDetails(); } @@ -1401,3 +1409,110 @@ std::vector Downloader::getExtras(const std::string& gamename, const s return extras; } + +void Downloader::checkOrphans() +{ + std::vector orphans; + for (unsigned int i = 0; i < games.size(); ++i) + { + std::cout << "Checking for orphaned files " << i+1 << " / " << games.size() << "\r" << std::flush; + boost::filesystem::path path (config.sDirectory + games[i].gamename); + std::vector filepath_vector; + + try + { + if (boost::filesystem::exists(path)) + { + if (boost::filesystem::is_directory(path)) + { + boost::filesystem::recursive_directory_iterator end_iter; + boost::filesystem::recursive_directory_iterator dir_iter(path); + while (dir_iter != end_iter) + { + if (boost::filesystem::is_regular_file(dir_iter->status())) + { + std::string filename = dir_iter->path().filename().string(); + boost::regex expression(".*\\.(zip|exe|bin|dmg|old)$"); + boost::match_results what; + if (boost::regex_search(filename, what, expression)) + filepath_vector.push_back(dir_iter->path()); + } + dir_iter++; + } + } + } + else + std::cout << path << " does not exist" << std::endl; + } + catch (const boost::filesystem::filesystem_error& ex) + { + std::cout << ex.what() << std::endl; + } + + if (!filepath_vector.empty()) + { + for (unsigned int j = 0; j < filepath_vector.size(); ++j) + { + bool bFoundFile = false; + 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) + { + 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) + { + 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) + { + 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) + orphans.push_back(filepath_vector[j].string()); + } + } + } + std::cout << std::endl; + + if (!orphans.empty()) + { + for (unsigned int i = 0; i < orphans.size(); ++i) + { + std::cout << orphans[i] << std::endl; + } + } + else + { + std::cout << "No orphaned files" << std::endl; + } + + return; +}