From 34ba40ca622a7362eb48618deae3c91eac4b6f9a Mon Sep 17 00:00:00 2001 From: Aotrix <9aotrix@protonmail.com> Date: Sun, 1 Feb 2026 02:55:28 +0100 Subject: Download all the cards with API --- battleNetApi/CMakeLists.txt | 10 +++++++++- battleNetApi/include/hearthstoneApi.hpp | 4 +++- battleNetApi/src/hearthstoneApi.cpp | 28 +++++++++++++++++++++++++++- battleNetApi/src/main.cpp | 27 +++++++++++++++++++++++++++ battleNetApi/tests/tests.cpp | 3 +-- 5 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 battleNetApi/src/main.cpp (limited to 'battleNetApi') diff --git a/battleNetApi/CMakeLists.txt b/battleNetApi/CMakeLists.txt index 33887b3..1b417a4 100644 --- a/battleNetApi/CMakeLists.txt +++ b/battleNetApi/CMakeLists.txt @@ -15,12 +15,20 @@ add_definitions(-DSOURCE_DIR_PATH="${CMAKE_SOURCE_DIR}") set(INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) set(SRC + ${PROJECT_SOURCE_DIR}/src/hearthstoneApi.cpp + ${PROJECT_SOURCE_DIR}/src/token.cpp ${PROJECT_SOURCE_DIR}/src/apiUrl.cpp + ${PROJECT_SOURCE_DIR}/src/main.cpp) +set(SRC_TESTS ${PROJECT_SOURCE_DIR}/src/hearthstoneApi.cpp ${PROJECT_SOURCE_DIR}/src/token.cpp ${PROJECT_SOURCE_DIR}/src/apiUrl.cpp ${PROJECT_SOURCE_DIR}/tests/tests.cpp) find_package(Catch2 3 REQUIRED) find_package(nlohmann_json 3.12.0 REQUIRED) -add_executable(tests ${SRC}) +add_executable(tests ${SRC_TESTS}) target_include_directories(tests PRIVATE ${INCLUDE_DIR}) target_link_libraries(tests PRIVATE Catch2::Catch2WithMain curl) + +add_executable(downloadCards ${SRC}) +target_include_directories(downloadCards PRIVATE ${INCLUDE_DIR}) +target_link_libraries(downloadCards PRIVATE curl) diff --git a/battleNetApi/include/hearthstoneApi.hpp b/battleNetApi/include/hearthstoneApi.hpp index 56ac53c..c3fbfac 100644 --- a/battleNetApi/include/hearthstoneApi.hpp +++ b/battleNetApi/include/hearthstoneApi.hpp @@ -1,5 +1,6 @@ #pragma once #include "token.hpp" +#include #include #include @@ -11,9 +12,10 @@ class HearthstoneApi { HearthstoneApi(Token &&iToken); json makeApiRequest(const std::string &iUrl) const; std::vector makeApiRequest(const std::vector &iUrls) const; + void downloadAllCards(ApiUrl &iApiUrl, const std::string &iOutputJsonPath) const; private: - std::string authorizationHeader(); + std::string authorizationHeader() const; static size_t curlCallbackStringOutput(void *iContent, size_t iSize, size_t iNmemb, std::string *iS); Token mToken; diff --git a/battleNetApi/src/hearthstoneApi.cpp b/battleNetApi/src/hearthstoneApi.cpp index 1d2d870..7290a5d 100644 --- a/battleNetApi/src/hearthstoneApi.cpp +++ b/battleNetApi/src/hearthstoneApi.cpp @@ -1,14 +1,18 @@ #include "hearthstoneApi.hpp" +#include #include #include #include #include +#include #include HearthstoneApi::HearthstoneApi(Token &&iToken) : mToken(iToken), mAuthorizationHeader(authorizationHeader()) {} HearthstoneApi::HearthstoneApi(const Token &iToken) : mToken(iToken), mAuthorizationHeader(authorizationHeader()) {} -std::string HearthstoneApi::authorizationHeader() { return std::format("Authorization: Bearer {}", mToken.text()); } +std::string HearthstoneApi::authorizationHeader() const { + return std::format("Authorization: Bearer {}", mToken.text()); +} size_t HearthstoneApi::curlCallbackStringOutput(void *iContent, size_t iSize, size_t iNmemb, std::string *iS) { const size_t kNewLength = iSize * iNmemb; @@ -97,3 +101,25 @@ std::vector HearthstoneApi::makeApiRequest(const std::vector } return aJsonOutputs; } + +void HearthstoneApi::downloadAllCards(ApiUrl &iApiUrl, const std::string &iOutputJsonPath) const { + HearthstoneApi aHearthstoneApi(mToken); + iApiUrl.setPage("1"); + std::vector aRequests; + json aFirstPageJson = aHearthstoneApi.makeApiRequest(iApiUrl()); + + int kNumberOfPages{aFirstPageJson["pageCount"]}; + for (int i{1}; i < kNumberOfPages; ++i) { + iApiUrl.setPage(std::to_string(i + 1)); + aRequests.push_back(iApiUrl()); + } + json::reference &aMergedCards = aFirstPageJson["cards"]; + std::vector kApiResponses = aHearthstoneApi.makeApiRequest(aRequests); + for (json &aPage : kApiResponses) { + for (json::reference &aCard : aPage["cards"]) { + aMergedCards.push_back(std::move(aCard)); + } + } + std::ofstream aOutputJson(iOutputJsonPath); + aOutputJson << aMergedCards.dump(4); +} diff --git a/battleNetApi/src/main.cpp b/battleNetApi/src/main.cpp new file mode 100644 index 0000000..4e3885b --- /dev/null +++ b/battleNetApi/src/main.cpp @@ -0,0 +1,27 @@ +#include "apiUrl.hpp" +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc < 3) { + // Example of parameters: + // ./build/downloadCards tests/resources/credentials.json build/output.json + throw std::invalid_argument("/ "); + } + std::string aCredentialsFilePath{argv[1]}; + Token aToken(aCredentialsFilePath); + HearthstoneApi aHearthstoneApi(aToken); + std::string aOutputPath{argv[2]}; + const std::string kContentType{"cards"}; + const std::string kRegion{"eu"}; + ApiUrl aApiUrl(kContentType, kRegion); + aApiUrl.setLocale("fr_FR"); + aApiUrl.setGameMode("constructed"); + aApiUrl.setPageSize("100"); + std::cout << "Downloading cards...\n"; + aHearthstoneApi.downloadAllCards(aApiUrl, aOutputPath); + std::cout << "Download done.\n"; + + return 0; +} diff --git a/battleNetApi/tests/tests.cpp b/battleNetApi/tests/tests.cpp index bafcdcb..d3321d3 100644 --- a/battleNetApi/tests/tests.cpp +++ b/battleNetApi/tests/tests.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -117,7 +116,7 @@ TEST_CASE("Merge two card lists from two page requests", "[Merge pages]") { json::reference aMergedCards = kFirstPage["cards"]; for (auto &card : kSecondPage["cards"]) { - aMergedCards.push_back(card); + aMergedCards.push_back(std::move(card)); } REQUIRE(aMergedCards.size() == 32); std::ofstream aOutputJson("build/output_pages_merge.json"); -- cgit v1.2.3