diff --git a/include/downloader.h b/include/downloader.h index 45dddcd..b049019 100644 --- a/include/downloader.h +++ b/include/downloader.h @@ -106,6 +106,8 @@ class Downloader void downloadCloudSavesById(const std::string& product_id, int build_index = -1); void uploadCloudSaves(const std::string& product_id, int build_index = -1); void uploadCloudSavesById(const std::string& product_id, int build_index = -1); + void deleteCloudSaves(const std::string& product_id, int build_index = -1); + void deleteCloudSavesById(const std::string& product_id, int build_index = -1); void checkOrphans(); void checkStatus(); diff --git a/main.cpp b/main.cpp index fea712a..d54fbf1 100644 --- a/main.cpp +++ b/main.cpp @@ -166,6 +166,7 @@ int main(int argc, char *argv[]) std::string galaxy_product_id_show_cloud_paths; std::string galaxy_product_id_show_local_cloud_paths; std::string galaxy_product_cloud_saves; + std::string galaxy_product_cloud_saves_delete; std::string galaxy_upload_product_cloud_saves; std::string tags; @@ -296,6 +297,7 @@ int main(int argc, char *argv[]) ("galaxy-upload-cloud-saves", bpo::value(&galaxy_upload_product_cloud_saves)->default_value(""), "Upload cloud saves using product-id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345") ("galaxy-show-cloud-saves", bpo::value(&galaxy_product_id_show_cloud_paths)->default_value(""), "Show game cloud-saves using product id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345") ("galaxy-show-local-cloud-saves", bpo::value(&galaxy_product_id_show_local_cloud_paths)->default_value(""), "Show local cloud-saves using product id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345") + ("galaxy-delete-cloud-saves", bpo::value(&galaxy_product_cloud_saves_delete)->default_value(""), "Delete cloud-saves using product id [product_id/build_index] or gamename regex [gamename/build_id]\nBuild index is used to select a build and defaults to 0 if not specified.\n\nExample: 12345/2 selects build 2 for product 12345") ("galaxy-platform", bpo::value(&sGalaxyPlatform)->default_value("w"), galaxy_platform_text.c_str()) ("galaxy-language", bpo::value(&sGalaxyLanguage)->default_value("en"), galaxy_language_text.c_str()) ("galaxy-arch", bpo::value(&sGalaxyArch)->default_value("x64"), galaxy_arch_text.c_str()) @@ -817,6 +819,17 @@ int main(int argc, char *argv[]) } downloader.galaxyShowLocalCloudSaves(product_id, build_index); } + else if (!galaxy_product_cloud_saves_delete.empty()) + { + int build_index = -1; + std::vector tokens = Util::tokenize(galaxy_product_cloud_saves_delete, "/"); + std::string product_id = tokens[0]; + if (tokens.size() == 2) + { + build_index = std::stoi(tokens[1]); + } + downloader.deleteCloudSaves(product_id, build_index); + } else if (!galaxy_product_id_install.empty()) { int build_index = -1; diff --git a/src/downloader.cpp b/src/downloader.cpp index 20f9573..3ab82a4 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -4587,6 +4587,16 @@ void Downloader::uploadCloudSaves(const std::string& product_id, int build_index } } +void Downloader::deleteCloudSaves(const std::string& product_id, int build_index) +{ + std::string id; + if(this->galaxySelectProductIdHelper(product_id, id)) + { + if (!id.empty()) + this->deleteCloudSavesById(id, build_index); + } +} + void Downloader::downloadCloudSaves(const std::string& product_id, int build_index) { std::string id; @@ -4841,8 +4851,49 @@ void Downloader::uploadCloudSavesById(const std::string& product_id, int build_i vDownloadInfo.clear(); } -void Downloader::downloadCloudSavesById(const std::string& product_id, int build_index) -{ +void Downloader::deleteCloudSavesById(const std::string& product_id, int build_index) { + if(Globals::globalConfig.cloudWhiteList.empty() && !Globals::globalConfig.bCloudForce) { + std::cout << "No files have been whitelisted, either use \'--cloud-whitelist\' or \'--cloud-force\'" << std::endl; + return; + } + + + curl_slist *header = nullptr; + + std::string access_token; + if (!Globals::galaxyConf.isExpired()) { + access_token = Globals::galaxyConf.getAccessToken(); + } + + if (!access_token.empty()) { + std::string bearer = "Authorization: Bearer " + access_token; + header = curl_slist_append(header, bearer.c_str()); + } + + auto dlhandle = curl_easy_init(); + + curl_easy_setopt(dlhandle, CURLOPT_HTTPHEADER, header); + curl_easy_setopt(dlhandle, CURLOPT_CUSTOMREQUEST, "DELETE"); + + this->cloudSaveListByIdForEach(product_id, build_index, [dlhandle](cloudSaveFile &csf) { + auto url = "https://cloudstorage.gog.com/v1/" + Globals::galaxyConf.getUserId() + '/' + Globals::galaxyConf.getClientId() + '/' + csf.path; + curl_easy_setopt(dlhandle, CURLOPT_URL, url.c_str()); + + auto result = curl_easy_perform(dlhandle); + if(result == CURLE_HTTP_RETURNED_ERROR) { + long response_code = 0; + curl_easy_getinfo(dlhandle, CURLINFO_RESPONSE_CODE, &response_code); + + std::cout << response_code << ": " << curl_easy_strerror(result); + } + }); + + curl_slist_free_all(header); + + curl_easy_cleanup(dlhandle); +} + +void Downloader::downloadCloudSavesById(const std::string& product_id, int build_index) { auto res = this->cloudSaveListByIdForEach(product_id, build_index, [](cloudSaveFile &csf) { boost::filesystem::path filepath = csf.location;