132 lines
3.4 KiB
C++
132 lines
3.4 KiB
C++
//
|
|
// Created by ricardo on 12/06/25.
|
|
//
|
|
|
|
#ifndef FETCHER_H
|
|
#define FETCHER_H
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <curl/curl.h>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
struct CurlDeleter
|
|
{
|
|
void operator()(CURL *curl) const
|
|
{
|
|
if (curl != nullptr)
|
|
{
|
|
curl_easy_cleanup(curl);
|
|
}
|
|
}
|
|
};
|
|
|
|
struct LeetCodeProblem
|
|
{
|
|
LeetCodeProblem(bool paidOnly,
|
|
std::string frontendQuestionId,
|
|
int questionId,
|
|
std::string questionTitle,
|
|
std::string questionTitleSlug)
|
|
: paidOnly(paidOnly)
|
|
, frontendQuestionId(std::move(frontendQuestionId))
|
|
, questionId(questionId)
|
|
, questionTitle(std::move(questionTitle))
|
|
, questionTitleSlug(std::move(questionTitleSlug))
|
|
{
|
|
}
|
|
|
|
bool paidOnly;
|
|
std::string frontendQuestionId;
|
|
int questionId;
|
|
std::string questionTitle;
|
|
std::string questionTitleSlug;
|
|
};
|
|
|
|
struct CodeDefinition
|
|
{
|
|
std::string value;
|
|
std::string text;
|
|
std::string defaultCode;
|
|
|
|
CodeDefinition(std::string value, std::string text, std::string defaultCode)
|
|
: value(std::move(value))
|
|
, text(std::move(text))
|
|
, defaultCode(std::move(defaultCode))
|
|
{
|
|
}
|
|
};
|
|
|
|
struct ProblemContent
|
|
{
|
|
std::string title;
|
|
std::string titleSlug;
|
|
std::string content;
|
|
std::vector<CodeDefinition> codeDefinitions;
|
|
int questionId;
|
|
|
|
ProblemContent(std::string title,
|
|
std::string titleSlug,
|
|
std::string content,
|
|
std::vector<CodeDefinition> codeDefinitions,
|
|
int questionId)
|
|
: title(std::move(title))
|
|
, titleSlug(std::move(titleSlug))
|
|
, content(std::move(content))
|
|
, codeDefinitions(std::move(codeDefinitions))
|
|
, questionId(questionId)
|
|
{
|
|
}
|
|
|
|
[[nodiscard]] std::string formatTemplate(const std::string &templateContent) const;
|
|
|
|
[[nodiscard]] std::string formatFilename() const;
|
|
};
|
|
|
|
struct Fetcher
|
|
{
|
|
Fetcher()
|
|
{
|
|
// Initialize the cURL global environment.
|
|
curl_global_init(CURL_GLOBAL_ALL);
|
|
client = std::unique_ptr<CURL, CurlDeleter>(curl_easy_init());
|
|
}
|
|
|
|
~Fetcher()
|
|
{
|
|
curl_global_cleanup();
|
|
}
|
|
|
|
void fetchProblem(const std::string &idString) const;
|
|
|
|
private:
|
|
std::unique_ptr<CURL, CurlDeleter> client;
|
|
|
|
std::string kProblemsUrl = "https://leetcode.cn/api/problems/algorithms/";
|
|
std::string kGraphQlUrl = "https://leetcode.cn/graphql";
|
|
|
|
[[nodiscard]] std::vector<LeetCodeProblem> getProblems() const;
|
|
|
|
[[nodiscard]] std::unique_ptr<ProblemContent> fetchProblemContent(const LeetCodeProblem &problem) const;
|
|
|
|
/// The callback function used by curl to write the http response content into a string.
|
|
static size_t httpWriteCallback(void *contents, const size_t size, size_t bufferLength, void *userData)
|
|
{
|
|
auto string = static_cast<std::string *>(userData);
|
|
auto body = static_cast<char *>(contents);
|
|
string->append(body, size * bufferLength);
|
|
|
|
return size * bufferLength;
|
|
}
|
|
|
|
static nlohmann::json formatQueryJson(const std::string &title);
|
|
|
|
static std::unique_ptr<ProblemContent> extractContentFromJson(
|
|
const nlohmann::json &json,
|
|
const LeetCodeProblem &problem);
|
|
|
|
static std::string readTemplateFile();
|
|
|
|
static bool validateExistedProblem(const ProblemContent &problem);
|
|
};
|
|
|
|
#endif //FETCHER_H
|