From 987e053ad4204ff5a191d7622f9a7b77814712aa Mon Sep 17 00:00:00 2001 From: Sude Date: Sun, 6 Mar 2016 15:45:22 +0200 Subject: [PATCH] Add option to save changelogs --- include/config.h | 1 + include/downloader.h | 2 + include/gamedetails.h | 3 ++ main.cpp | 1 + src/downloader.cpp | 105 ++++++++++++++++++++++++++++++++++++++++++ src/gamedetails.cpp | 8 ++++ 6 files changed, 120 insertions(+) diff --git a/include/config.h b/include/config.h index 1ef35d9..75cc478 100644 --- a/include/config.h +++ b/include/config.h @@ -47,6 +47,7 @@ class Config bool bPlatformDetection; bool bShowWishlist; bool bAutomaticXMLCreation; + bool bSaveChangelogs; std::string sGameRegex; std::string sDirectory; std::string sCacheDirectory; diff --git a/include/downloader.h b/include/downloader.h index 6d69125..b52153c 100644 --- a/include/downloader.h +++ b/include/downloader.h @@ -98,6 +98,8 @@ class Downloader Json::Value getGameDetailsJSON(const std::string& gameid); std::string getSerialsFromJSON(const Json::Value& json); void saveSerials(const std::string& serials, const std::string& filepath); + std::string getChangelogFromJSON(const Json::Value& json); + void saveChangelog(const std::string& changelog, const std::string& filepath); static int progressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); static size_t writeMemoryCallback(char *ptr, size_t size, size_t nmemb, void *userp); diff --git a/include/gamedetails.h b/include/gamedetails.h index 4ccc601..1737fff 100644 --- a/include/gamedetails.h +++ b/include/gamedetails.h @@ -23,15 +23,18 @@ class gameDetails std::string title; std::string icon; std::string serials; + std::string changelog; void filterWithPriorities(const gameSpecificConfig& config); void makeFilepaths(const gameSpecificDirectoryConfig& config); std::string getSerialsFilepath(); + std::string getChangelogFilepath(); Json::Value getDetailsAsJson(); virtual ~gameDetails(); protected: void filterListWithPriorities(std::vector& list, const gameSpecificConfig& config); private: std::string serialsFilepath; + std::string changelogFilepath; }; #endif // GAMEDETAILS_H diff --git a/main.cpp b/main.cpp index f0f044b..a5ba6b7 100644 --- a/main.cpp +++ b/main.cpp @@ -176,6 +176,7 @@ int main(int argc, char *argv[]) ("include", bpo::value(&sIncludeOptions)->default_value("all"), ("Select what to download/list/repair\n" + include_options_text).c_str()) ("exclude", bpo::value(&sExcludeOptions)->default_value("covers"), ("Select what not to download/list/repair\n" + include_options_text).c_str()) ("automatic-xml-creation", bpo::value(&config.bAutomaticXMLCreation)->zero_tokens()->default_value(false), "Automatically create XML data after download has completed") + ("save-changelogs", bpo::value(&config.bSaveChangelogs)->zero_tokens()->default_value(false), "Save changelogs when downloading") ; // Options read from config file options_cfg_only.add_options() diff --git a/src/downloader.cpp b/src/downloader.cpp index 71f46b1..74f633e 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -330,6 +330,12 @@ int Downloader::getGameDetails() gameDetailsJSON = this->getGameDetailsJSON(gameItems[i].id); game.serials = this->getSerialsFromJSON(gameDetailsJSON); } + if (config.bSaveChangelogs) + { + if (gameDetailsJSON.empty()) + gameDetailsJSON = this->getGameDetailsJSON(gameItems[i].id); + game.changelog = this->getChangelogFromJSON(gameDetailsJSON); + } // Ignore DLC count and try to get DLCs from JSON if (game.dlcs.empty() && !bHasDLC && conf.bDLC && conf.bIgnoreDLCCount) @@ -395,6 +401,31 @@ int Downloader::getGameDetails() } } + if (config.bSaveChangelogs) + { + if (gameDetailsJSON.empty()) + gameDetailsJSON = this->getGameDetailsJSON(gameItems[i].id); + + // Make sure we save changelog for the right DLC + for (unsigned int k = 0; k < gameDetailsJSON["dlcs"].size(); ++k) + { + std::vector urls; + if (gameDetailsJSON["dlcs"][k].isMember("changelog") && gameDetailsJSON["dlcs"][k].isMember("downloads")) + { + // Assuming that only DLC with installers can have changelog + Util::getDownloaderUrlsFromJSON(gameDetailsJSON["dlcs"][k]["downloads"], urls); + } + + if (!urls.empty()) + { + if (urls[0].find("/" + gameItems[i].dlcnames[j] + "/") != std::string::npos) + { + dlc.changelog = this->getChangelogFromJSON(gameDetailsJSON["dlcs"][k]); + } + } + } + } + game.dlcs.push_back(dlc); } } @@ -881,6 +912,12 @@ void Downloader::download() this->saveSerials(games[i].serials, filepath); } + if (config.bSaveChangelogs && !games[i].changelog.empty()) + { + std::string filepath = games[i].getChangelogFilepath(); + this->saveChangelog(games[i].changelog, filepath); + } + // Download covers if (config.bCover && !config.bUpdateCheck) { @@ -1084,6 +1121,11 @@ void Downloader::download() std::string filepath = games[i].dlcs[j].getSerialsFilepath(); this->saveSerials(games[i].dlcs[j].serials, filepath); } + if (config.bSaveChangelogs && !games[i].dlcs[j].changelog.empty()) + { + std::string filepath = games[i].dlcs[j].getChangelogFilepath(); + this->saveChangelog(games[i].dlcs[j].changelog, filepath); + } if (config.bInstallers) { @@ -2457,6 +2499,27 @@ std::string Downloader::getSerialsFromJSON(const Json::Value& json) return serials.str(); } +std::string Downloader::getChangelogFromJSON(const Json::Value& json) +{ + std::string changelog; + std::string title = "Changelog"; + + if (!json.isMember("changelog")) + return std::string(); + + changelog = json["changelog"].asString(); + + if (changelog.empty()) + return std::string(); + + if (json.isMember("title")) + title = title + ": " + json["title"].asString(); + + changelog = "\n\n\n\n" + title + "\n\n" + changelog + "\n"; + + return changelog; +} + // Linear search. Good thing computers are fast and lists are small. static int isPresent(std::vector& list, const boost::filesystem::path& path, Blacklist& blacklist) { @@ -3043,6 +3106,7 @@ std::vector Downloader::getGameDetailsFromJsonNode(Json::Value root game.title = gameDetailsNode["title"].asString(); game.icon = gameDetailsNode["icon"].asString(); game.serials = gameDetailsNode["serials"].asString(); + game.changelog = gameDetailsNode["changelog"].asString(); // Make a vector of valid node names to make things easier std::vector nodes; @@ -3183,6 +3247,47 @@ void Downloader::saveSerials(const std::string& serials, const std::string& file return; } +// Save changelog to file +void Downloader::saveChangelog(const std::string& changelog, const std::string& filepath) +{ + // Get directory from filepath + boost::filesystem::path pathname = filepath; + std::string directory = pathname.parent_path().string(); + + // Check that directory exists and create subdirectories + boost::filesystem::path path = directory; + if (boost::filesystem::exists(path)) + { + if (!boost::filesystem::is_directory(path)) + { + std::cout << path << " is not directory" << std::endl; + return; + } + } + else + { + if (!boost::filesystem::create_directories(path)) + { + std::cout << "Failed to create directory: " << path << std::endl; + return; + } + } + + std::ofstream ofs(filepath); + if (ofs) + { + std::cout << "Saving changelog: " << filepath << std::endl; + ofs << changelog; + ofs.close(); + } + else + { + std::cout << "Failed to create file: " << filepath << std::endl; + } + + return; +} + void Downloader::downloadFileWithId(const std::string& fileid_string, const std::string& output_filepath) { size_t pos = fileid_string.find("/"); diff --git a/src/gamedetails.cpp b/src/gamedetails.cpp index 71bb347..2ac9067 100644 --- a/src/gamedetails.cpp +++ b/src/gamedetails.cpp @@ -71,6 +71,7 @@ void gameDetails::makeFilepaths(const gameSpecificDirectoryConfig& config) std::string directory = config.sDirectory + "/" + config.sGameSubdir + "/"; std::string subdir; this->serialsFilepath = Util::makeFilepath(directory, "serials.txt", this->gamename, subdir, 0); + this->changelogFilepath = Util::makeFilepath(directory, "changelog_" + gamename + ".html", this->gamename, subdir, 0); for (unsigned int i = 0; i < this->installers.size(); ++i) { @@ -104,6 +105,7 @@ void gameDetails::makeFilepaths(const gameSpecificDirectoryConfig& config) { subdir = config.bSubDirectories ? config.sDLCSubdir + "/" + config.sInstallersSubdir : ""; this->dlcs[i].serialsFilepath = Util::makeFilepath(directory, "serials.txt", this->gamename, subdir, 0); + this->dlcs[i].changelogFilepath = Util::makeFilepath(directory, "changelog_" + this->dlcs[i].gamename + ".html", this->gamename, subdir, 0); for (unsigned int j = 0; j < this->dlcs[i].installers.size(); ++j) { subdir = config.bSubDirectories ? config.sDLCSubdir + "/" + config.sInstallersSubdir : ""; @@ -135,6 +137,7 @@ Json::Value gameDetails::getDetailsAsJson() json["title"] = this->title; json["icon"] = this->icon; json["serials"] = this->serials; + json["changelog"] = this->changelog; for (unsigned int i = 0; i < this->extras.size(); ++i) json["extras"].append(this->extras[i].getAsJson()); @@ -160,3 +163,8 @@ std::string gameDetails::getSerialsFilepath() { return this->serialsFilepath; } + +std::string gameDetails::getChangelogFilepath() +{ + return this->changelogFilepath; +}