diff options
| author | Aotrix <[email protected]> | 2026-03-27 18:48:55 +0100 |
|---|---|---|
| committer | Aotrix <[email protected]> | 2026-03-27 18:48:55 +0100 |
| commit | f01072eb4166fc68f59519ebf84de46e7386abf5 (patch) | |
| tree | 72885a1d6296b787bcd2d19d45ccce4777274717 | |
| parent | a20c4abc424404518bcb656a3f22f43991a6c164 (diff) | |
Generate json card lists with static methods
Instead of creating a useless instance of HearthstoneApi class, calls
static methods.
| -rw-r--r-- | battleNetApi/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | battleNetApi/include/hearthstoneApi.hpp | 11 | ||||
| -rw-r--r-- | battleNetApi/include/tokenPool.hpp | 16 | ||||
| -rw-r--r-- | battleNetApi/src/hearthstoneApi.cpp | 30 | ||||
| -rw-r--r-- | battleNetApi/src/main.cpp | 35 | ||||
| -rw-r--r-- | battleNetApi/src/tokenPool.cpp | 12 |
6 files changed, 69 insertions, 39 deletions
diff --git a/battleNetApi/CMakeLists.txt b/battleNetApi/CMakeLists.txt index 1b417a4..440392b 100644 --- a/battleNetApi/CMakeLists.txt +++ b/battleNetApi/CMakeLists.txt @@ -6,7 +6,7 @@ set(ProjectName ${FNAME}) project(${ProjectName} LANGUAGES CXX) set(CMAKE_COMPILE_COMMANDS ON) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CXX_STANDARD_REQUIRED ON) set(CMAKE_BUILD_TYPE Debug) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall") @@ -17,10 +17,12 @@ 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/tokenPool.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}/src/tokenPool.cpp ${PROJECT_SOURCE_DIR}/tests/tests.cpp) find_package(Catch2 3 REQUIRED) diff --git a/battleNetApi/include/hearthstoneApi.hpp b/battleNetApi/include/hearthstoneApi.hpp index c3fbfac..ecf785a 100644 --- a/battleNetApi/include/hearthstoneApi.hpp +++ b/battleNetApi/include/hearthstoneApi.hpp @@ -8,17 +8,14 @@ using json = nlohmann::json; class HearthstoneApi { public: - HearthstoneApi(const Token &iToken); - HearthstoneApi(Token &&iToken); - json makeApiRequest(const std::string &iUrl) const; - std::vector<json> makeApiRequest(const std::vector<std::string> &iUrls) const; - void downloadAllCards(ApiUrl &iApiUrl, const std::string &iOutputJsonPath) const; + static json makeApiRequest(const std::string &iUrl, const std::string &iTokenText); + static std::vector<json> makeApiRequest(const std::vector<std::string> &iUrls, const std::string &iTokenText); + static json downloadCards(ApiUrl &iApiUrl, Token &iToken); private: - std::string authorizationHeader() const; + static std::string authorizationHeader(const std::string &iTokenText); static size_t curlCallbackStringOutput(void *iContent, size_t iSize, size_t iNmemb, std::string *iS); - Token mToken; std::string mAuthorizationHeader; //<! Bearer authorization string for OAuth 2.0 header friend class HearthstoneApiMock; diff --git a/battleNetApi/include/tokenPool.hpp b/battleNetApi/include/tokenPool.hpp new file mode 100644 index 0000000..6aa2b15 --- /dev/null +++ b/battleNetApi/include/tokenPool.hpp @@ -0,0 +1,16 @@ +#include <queue> +#include <token.hpp> + +class TokenPool { + private: + TokenPool() = default; + TokenPool(const TokenPool &) = delete; + TokenPool(TokenPool &&) = delete; + TokenPool &operator=(const TokenPool &) = delete; + TokenPool &operator=(TokenPool &&) = delete; + static std::queue<Token> mTokenContainer; + + public: + static void fillTokenSource(const std::string &iJsonPath); + static std::optional<std::string> unusedToken(); +}; diff --git a/battleNetApi/src/hearthstoneApi.cpp b/battleNetApi/src/hearthstoneApi.cpp index 7290a5d..32c3164 100644 --- a/battleNetApi/src/hearthstoneApi.cpp +++ b/battleNetApi/src/hearthstoneApi.cpp @@ -4,14 +4,10 @@ #include <curl/easy.h> #include <curl/multi.h> #include <format> -#include <fstream> #include <iostream> -HearthstoneApi::HearthstoneApi(Token &&iToken) : mToken(iToken), mAuthorizationHeader(authorizationHeader()) {} -HearthstoneApi::HearthstoneApi(const Token &iToken) : mToken(iToken), mAuthorizationHeader(authorizationHeader()) {} - -std::string HearthstoneApi::authorizationHeader() const { - return std::format("Authorization: Bearer {}", mToken.text()); +std::string HearthstoneApi::authorizationHeader(const std::string &iTokenText) { + return std::format("Authorization: Bearer {}", iTokenText); } size_t HearthstoneApi::curlCallbackStringOutput(void *iContent, size_t iSize, size_t iNmemb, std::string *iS) { @@ -25,7 +21,7 @@ size_t HearthstoneApi::curlCallbackStringOutput(void *iContent, size_t iSize, si return kNewLength; } -json HearthstoneApi::makeApiRequest(const std::string &iUrl) const { +json HearthstoneApi::makeApiRequest(const std::string &iUrl, const std::string &iTokenText) { CURL *curl = curl_easy_init(); std::string aRequestOutput; if (curl) { @@ -35,7 +31,7 @@ json HearthstoneApi::makeApiRequest(const std::string &iUrl) const { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallbackStringOutput); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &aRequestOutput); struct curl_slist *chunk = nullptr; - chunk = curl_slist_append(chunk, mAuthorizationHeader.c_str()); + chunk = curl_slist_append(chunk, authorizationHeader(iTokenText).c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); curl_easy_perform(curl); curl_easy_cleanup(curl); @@ -44,7 +40,7 @@ json HearthstoneApi::makeApiRequest(const std::string &iUrl) const { return aOutputJson; } -std::vector<json> HearthstoneApi::makeApiRequest(const std::vector<std::string> &iUrls) const { +std::vector<json> HearthstoneApi::makeApiRequest(const std::vector<std::string> &iUrls, const std::string &iTokenText) { std::vector<std::string> aResponses(iUrls.size()); CURLM *curlm = curl_multi_init(); if (curlm) { @@ -56,7 +52,7 @@ std::vector<json> HearthstoneApi::makeApiRequest(const std::vector<std::string> curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallbackStringOutput); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &(aResponses[i])); struct curl_slist *chunk = nullptr; - chunk = curl_slist_append(chunk, mAuthorizationHeader.c_str()); + chunk = curl_slist_append(chunk, authorizationHeader(iTokenText).c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); curl_multi_add_handle(curlm, curl); } @@ -102,24 +98,22 @@ std::vector<json> HearthstoneApi::makeApiRequest(const std::vector<std::string> return aJsonOutputs; } -void HearthstoneApi::downloadAllCards(ApiUrl &iApiUrl, const std::string &iOutputJsonPath) const { - HearthstoneApi aHearthstoneApi(mToken); +json HearthstoneApi::downloadCards(ApiUrl &iApiUrl, Token &iToken) { iApiUrl.setPage("1"); std::vector<std::string> aRequests; - json aFirstPageJson = aHearthstoneApi.makeApiRequest(iApiUrl()); + json aFirstPageJson = makeApiRequest(iApiUrl(), iToken.text()); 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<json> kApiResponses = aHearthstoneApi.makeApiRequest(aRequests); + json::reference &aOutputJson = aFirstPageJson["cards"]; + std::vector<json> kApiResponses = makeApiRequest(aRequests, iToken.text()); for (json &aPage : kApiResponses) { for (json::reference &aCard : aPage["cards"]) { - aMergedCards.push_back(std::move(aCard)); + aOutputJson.push_back(std::move(aCard)); } } - std::ofstream aOutputJson(iOutputJsonPath); - aOutputJson << aMergedCards.dump(4); + return aOutputJson; } diff --git a/battleNetApi/src/main.cpp b/battleNetApi/src/main.cpp index 3c36a8d..7f2450e 100644 --- a/battleNetApi/src/main.cpp +++ b/battleNetApi/src/main.cpp @@ -1,27 +1,34 @@ #include "apiUrl.hpp" #include <hearthstoneApi.hpp> #include <iostream> -#include <stdexcept> +#include <print> +#include <tokenPool.hpp> class DownloadMethod { public: virtual void download() = 0; + virtual ~DownloadMethod() = default; }; class DefaultDownloadMethod : public DownloadMethod { public: - void download() { - std::cout << "OMG je suis une méthode de téléchargement !\n"; - // 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"; - } + DefaultDownloadMethod() = default; + ~DefaultDownloadMethod() = default; + void download() override { + 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::println("Downloading cards..."); + TokenPool::fillTokenSource("tests/resources/credentials.json"); + std::optional<Token> aToken{TokenPool::unusedToken()}; + if (aToken.has_value()) { + HearthstoneApi::downloadCards(aApiUrl, aToken.value()); + std::println("Download done."); + } + }; }; class DownloaderContext { @@ -61,5 +68,7 @@ int main(int argc, char *argv[]) { } aDownloaderContext.download(); + // std::ofstream aOutputJson(iOutputJsonPath); + // aOutputJson << aMergedCards.dump(4); return 0; } diff --git a/battleNetApi/src/tokenPool.cpp b/battleNetApi/src/tokenPool.cpp new file mode 100644 index 0000000..20ea6cd --- /dev/null +++ b/battleNetApi/src/tokenPool.cpp @@ -0,0 +1,12 @@ +#include <tokenPool.hpp> + +std::optional<std::string> TokenPool::unusedToken() { + if (mTokenContainer.empty()) { + return std::nullopt; + } + Token aOutputToken{mTokenContainer.front()}; + mTokenContainer.pop(); + return aOutputToken.text(); +} + +void TokenPool::fillTokenSource(const std::string &iJsonPath) { mTokenContainer.emplace(Token(iJsonPath)); } |
