patch: Patch/ygo set 25th (#13)

This commit is contained in:
Sebastian Dine
2026-05-11 09:51:19 +02:00
committed by GitHub
parent 7935f2b18e
commit d6c7f60aee
12 changed files with 462 additions and 15 deletions
+11
View File
@@ -24,11 +24,21 @@ namespace ccm {
// only fires one outbound request at a time anyway.
class CprHttpClient final : public IHttpClient {
public:
struct RawResponse {
bool transportError{false};
std::string transportMessage;
int statusCode{0};
std::string body;
};
using GetExecutor = std::function<Result<std::string>(std::string_view)>;
using RawGetExecutor = std::function<RawResponse(std::string_view)>;
explicit CprHttpClient(std::chrono::milliseconds timeout = std::chrono::milliseconds{30000});
CprHttpClient(GetExecutor executor,
std::chrono::milliseconds timeout = std::chrono::milliseconds{30000});
CprHttpClient(RawGetExecutor rawExecutor,
std::chrono::milliseconds timeout = std::chrono::milliseconds{30000});
~CprHttpClient() override;
Result<std::string> get(std::string_view url) override;
@@ -37,6 +47,7 @@ private:
std::chrono::milliseconds timeout_;
std::unique_ptr<cpr::Session> session_;
GetExecutor executor_;
RawGetExecutor rawExecutor_;
std::mutex sessionMutex_;
};
+34
View File
@@ -3,9 +3,42 @@
#include <nlohmann/json.hpp>
#include <algorithm>
#include <array>
#include <string>
namespace ccm {
namespace {
struct YuGiOhSetAlias {
const char* code;
const char* name;
const char* releaseDate;
};
constexpr std::array<YuGiOhSetAlias, 6> kMissing25thAnniversaryReprints{{
{"LOB-25TH", "Legend of Blue Eyes White Dragon (25th Anniversary Edition)", "2023/04/20"},
{"MRD-25TH", "Metal Raiders (25th Anniversary Edition)", "2023/04/20"},
{"SRL-25TH", "Spell Ruler (25th Anniversary Edition)", "2023/04/20"},
{"PSV-25TH", "Pharaoh's Servant (25th Anniversary Edition)", "2023/04/20"},
{"DCR-25TH", "Dark Crisis (25th Anniversary Edition)", "2023/04/20"},
{"IOC-25TH", "Invasion of Chaos (25th Anniversary Edition)", "2023/06/08"},
}};
void appendMissingSetAliases(std::vector<Set>& sets) {
for (const auto& alias : kMissing25thAnniversaryReprints) {
const bool exists = std::any_of(
sets.begin(), sets.end(), [&](const Set& s) { return s.name == alias.name; });
if (exists) continue;
Set s;
s.id = alias.code;
s.name = alias.name;
s.releaseDate = alias.releaseDate;
sets.push_back(std::move(s));
}
}
} // namespace
YuGiOhSetSource::YuGiOhSetSource(IHttpClient& http) : http_(http) {}
@@ -29,6 +62,7 @@ Result<std::vector<Set>> YuGiOhSetSource::parseResponse(const std::string& body)
s.releaseDate = std::move(release);
out.push_back(std::move(s));
}
appendMissingSetAliases(out);
std::sort(out.begin(), out.end(),
[](const Set& a, const Set& b) { return a.releaseDate < b.releaseDate; });
return Result<std::vector<Set>>::ok(std::move(out));
+24 -11
View File
@@ -26,16 +26,15 @@ CprHttpClient::CprHttpClient(std::chrono::milliseconds timeout)
/*follow=*/true,
/*cont_send_cred=*/false,
cpr::PostRedirectFlags::POST_ALL});
executor_ = [this](std::string_view url) -> Result<std::string> {
rawExecutor_ = [this](std::string_view url) -> RawResponse {
session_->SetUrl(cpr::Url{std::string(url)});
cpr::Response r = session_->Get();
if (r.error) {
return mapHttpGetResponse(true, r.error.message, r.status_code, {},
url);
}
return mapHttpGetResponse(false, {}, r.status_code, std::move(r.text),
url);
return RawResponse{
.transportError = static_cast<bool>(r.error),
.transportMessage = r.error.message,
.statusCode = static_cast<int>(r.status_code),
.body = std::move(r.text),
};
};
}
@@ -45,6 +44,12 @@ CprHttpClient::CprHttpClient(GetExecutor executor,
session_(nullptr),
executor_(std::move(executor)) {}
CprHttpClient::CprHttpClient(RawGetExecutor rawExecutor,
std::chrono::milliseconds timeout)
: timeout_(timeout),
session_(nullptr),
rawExecutor_(std::move(rawExecutor)) {}
CprHttpClient::~CprHttpClient() = default;
Result<std::string> CprHttpClient::get(std::string_view url) {
@@ -53,10 +58,18 @@ Result<std::string> CprHttpClient::get(std::string_view url) {
// (one fetch per BaseSelectedCardPanel selection change), so contention
// is negligible.
std::lock_guard<std::mutex> lock(sessionMutex_);
if (!executor_) {
return Result<std::string>::err("HTTP error: no executor configured");
if (executor_) {
return executor_(url);
}
return executor_(url);
if (rawExecutor_) {
RawResponse raw = rawExecutor_(url);
return mapHttpGetResponse(raw.transportError,
raw.transportMessage,
raw.statusCode,
std::move(raw.body),
url);
}
return Result<std::string>::err("HTTP error: no executor configured");
}
} // namespace ccm