summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAotrix <[email protected]>2026-03-27 18:48:55 +0100
committerAotrix <[email protected]>2026-03-27 18:48:55 +0100
commitf01072eb4166fc68f59519ebf84de46e7386abf5 (patch)
tree72885a1d6296b787bcd2d19d45ccce4777274717
parenta20c4abc424404518bcb656a3f22f43991a6c164 (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.txt4
-rw-r--r--battleNetApi/include/hearthstoneApi.hpp11
-rw-r--r--battleNetApi/include/tokenPool.hpp16
-rw-r--r--battleNetApi/src/hearthstoneApi.cpp30
-rw-r--r--battleNetApi/src/main.cpp35
-rw-r--r--battleNetApi/src/tokenPool.cpp12
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)); }