pixwhile/pixivclient.cpp

98 lines
3.7 KiB
C++

#include "blankie/murl.h"
#include "numberhelper.h"
#include "pixivclient.h"
static const constexpr char* touch_user_agent = "Mozilla/5.0 (Android 12; Mobile; rv:97.0) Gecko/97.0 Firefox/97.0";
static const constexpr char* desktop_user_agent = "Mozilla/5.0 (Windows NT 10.0; rv:111.0) Gecko/20100101 Firefox/111.0";
PixivClient::PixivClient() {
this->_www_pixiv_net_client.set_keep_alive(true);
this->_www_pixiv_net_client.set_default_headers({
{"Cookie", "webp_available=1"}
});
this->_i_pximg_net_client.set_keep_alive(true);
this->_i_pximg_net_client.set_default_headers({
{"Referer", "https://www.pixiv.net/"}
});
}
User PixivClient::get_user(uint64_t user_id) {
httplib::Result res = this->_www_pixiv_net_client.Get("/touch/ajax/user/details", {
{"lang", "en"}, {"id", std::to_string(user_id)}
}, {{"User-Agent", touch_user_agent}});
return this->_handle_result(std::move(res)).at("user_details").get<User>();
}
Illusts PixivClient::get_illusts(uint64_t user_id, size_t page) {
httplib::Params params = {{"lang", "en"}, {"id", std::to_string(user_id)}};
if (page != 0) {
params.insert({"p", std::to_string(page + 1)});
}
httplib::Result res = this->_www_pixiv_net_client.Get("/touch/ajax/user/illusts", std::move(params), {{"User-Agent", touch_user_agent}});
return this->_handle_result(std::move(res)).get<Illusts>();
}
Illust PixivClient::get_illust(uint64_t illust_id) {
httplib::Result res = this->_www_pixiv_net_client.Get("/touch/ajax/illust/details", {
{"lang", "en"}, {"illust_id", std::to_string(illust_id)}
}, {{"User-Agent", touch_user_agent}});
return this->_handle_result(std::move(res)).get<Illust>();
}
SearchResults PixivClient::search_illusts(const std::string& query, size_t page, const std::string& order) {
using namespace std::string_literals;
httplib::Result res = this->_www_pixiv_net_client.Get("/ajax/search/illustrations/"s + blankie::murl::escape(query), {
{"lang", "en"},
{"mode", "all"},
{"p", std::to_string(page + 1)},
{"s_mode", "s_tag_full"},
{"type", "illust_and_ugoira"},
{"order", order},
{"word", query}
}, {{"User-Agent", desktop_user_agent}});
return this->_handle_result(std::move(res)).get<SearchResults>();
}
std::vector<SearchSuggestion> PixivClient::get_search_suggestions(const std::string& query) {
httplib::Result res = this->_www_pixiv_net_client.Get("/rpc/cps.php", {
{"lang", "en"}, {"keyword", query}
}, {{"User-Agent", desktop_user_agent}, {"Referer", "https://www.pixiv.net/"}});
if (!res) {
throw HTTPLibException(res.error());
}
nlohmann::json j = nlohmann::json::parse(std::move(res->body)).at("candidates");
std::vector<SearchSuggestion> search_suggestions;
search_suggestions.reserve(j.size());
for (const nlohmann::json& i : j) {
SearchSuggestion search_suggestion = i.get<SearchSuggestion>();
if (search_suggestion.tag != query) {
search_suggestions.push_back(std::move(search_suggestion));
}
}
return search_suggestions;
}
nlohmann::json PixivClient::_handle_result(httplib::Result res) {
if (!res) {
throw HTTPLibException(res.error());
}
nlohmann::json j = nlohmann::json::parse(std::move(res->body));
if (j.at("error")) {
throw PixivException(res->status, j.at("message").get<std::string>());
}
return j.at("body");
}
bool PixivClient::i_pximg_url_valid(const std::string& path) {
httplib::Result res = this->_i_pximg_net_client.Head(path, {{"User-Agent", touch_user_agent}});
if (!res) {
throw HTTPLibException(res.error());
}
return res->status >= 200 && res->status <= 200;
}