From b5e1aa8b26b09446263b99d662bb508d8f29c6b5 Mon Sep 17 00:00:00 2001 From: Sude Date: Wed, 13 Dec 2023 15:10:09 +0200 Subject: [PATCH] Skip complete extras Check to see if extras are already complete by getting file size from content-length header or API response Don't trust file size from API responses for extras by default Add option --trust-api-for-extras to make lgogdownloader trust API responses for extras to be correct --- include/config.h | 1 + main.cpp | 1 + src/downloader.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/include/config.h b/include/config.h index 67da5f2..9850392 100644 --- a/include/config.h +++ b/include/config.h @@ -252,6 +252,7 @@ class Config bool bEnableLoginGUI; #endif bool bUseFastCheck; + bool bTrustAPIForExtras; // Cache bool bUseCache; diff --git a/main.cpp b/main.cpp index fb0883e..468e772 100644 --- a/main.cpp +++ b/main.cpp @@ -280,6 +280,7 @@ int main(int argc, char *argv[]) ("verbosity", bpo::value(&Globals::globalConfig.iMsgLevel)->default_value(0), "Set message verbosity level\n -1 = Less verbose\n 0 = Default\n 1 = Verbose\n 2 = Debug") ("check-free-space", bpo::value(&Globals::globalConfig.dlConf.bFreeSpaceCheck)->zero_tokens()->default_value(false), "Check for available free space before starting download") ("no-fast-status-check", bpo::value(&bNoFastStatusCheck)->zero_tokens()->default_value(false), "Don't use fast status check.\nMakes --status much slower but able to catch corrupted files by calculating local file hash for all files.") + ("trust-api-for-extras", bpo::value(&Globals::globalConfig.bTrustAPIForExtras)->zero_tokens()->default_value(false), "Trust API responses for extras to be correct.") ; options_cli_no_cfg_hidden.add_options() diff --git a/src/downloader.cpp b/src/downloader.cpp index 681fee5..0615922 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -2868,6 +2868,13 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid) } } + CURL* curlheader = curl_easy_init(); + Util::CurlHandleSetDefaultOptions(curlheader, conf.curlConf); + curl_easy_setopt(curlheader, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(curlheader, CURLOPT_WRITEFUNCTION, Util::CurlWriteMemoryCallback); + curl_easy_setopt(curlheader, CURLOPT_HEADER, 1L); + curl_easy_setopt(curlheader, CURLOPT_NOBODY, 1L); + CURL* dlhandle = curl_easy_init(); Util::CurlHandleSetDefaultOptions(dlhandle, conf.curlConf); curl_easy_setopt(dlhandle, CURLOPT_NOPROGRESS, 0); @@ -3046,6 +3053,54 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid) } } } + // Special case for extras because they don't have remote XML data + // and the API responses for extras can't be trusted + else if (gf.type & GlobalConstants::GFTYPE_EXTRA) + { + off_t filesize_local = boost::filesystem::file_size(filepath); + off_t filesize_api = 0; + try + { + filesize_api = std::stol(gf.size); + } + catch (std::invalid_argument& e) + { + filesize_api = 0; + } + + // Check file size against file size reported by API + if(Globals::globalConfig.bTrustAPIForExtras) + { + if (filesize_local == filesize_api) + { + bIsComplete = true; + } + } + else + { + // API is not trusted to give correct details for extras + // Get size from content-length header and compare to it instead + off_t filesize_content_length = 0; + std::ostringstream memory; + std::string url = downlinkJson["downlink"].asString(); + + curl_easy_setopt(curlheader, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curlheader, CURLOPT_WRITEDATA, &memory); + curl_easy_perform(curlheader); + curl_easy_getinfo(curlheader, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &filesize_content_length); + memory.str(std::string()); + + if (filesize_local == filesize_content_length) + { + bIsComplete = true; + } + + msgQueue.push(Message(filepath.filename().string() + ": filesize_local: " + std::to_string(filesize_local) + ", filesize_api: " + std::to_string(filesize_api) + ", filesize_content_length: " + std::to_string(filesize_content_length), MSGTYPE_INFO, msg_prefix, MSGLEVEL_DEBUG)); + } + + if (bIsComplete) + msgQueue.push(Message("Skipping complete file: " + filepath.filename().string(), MSGTYPE_INFO, msg_prefix, MSGLEVEL_VERBOSE)); + } } else { @@ -3258,6 +3313,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid) } } + curl_easy_cleanup(curlheader); curl_easy_cleanup(dlhandle); delete galaxy;