Add PixivClient::get_illust

This commit is contained in:
blankie 2023-04-08 23:06:56 +07:00
parent 1a9c9d1a53
commit 6fc4bcbc16
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
5 changed files with 123 additions and 6 deletions

View File

@ -5,6 +5,7 @@
#include "config.h" #include "config.h"
#include "pixivclient.h" #include "pixivclient.h"
#include "servehelper.h" #include "servehelper.h"
#include "numberhelper.h"
#include "routes/routes.h" #include "routes/routes.h"
int main(int argc, char** argv) { int main(int argc, char** argv) {
@ -55,6 +56,11 @@ int main(int argc, char** argv) {
}); });
#ifndef NDEBUG #ifndef NDEBUG
// TODO remove
server.Get("/debug/illust", [&](const httplib::Request& req, httplib::Response& res) {
Illust illust = pixiv_client.get_illust(to_ull(req.get_param_value("id")));
res.set_content(illust.title, "text/plain; charset=utf-8");
});
server.Get("/debug/exception/known", [](const httplib::Request& req, httplib::Response& res) { server.Get("/debug/exception/known", [](const httplib::Request& req, httplib::Response& res) {
throw std::runtime_error("awoo"); throw std::runtime_error("awoo");
}); });

View File

@ -31,6 +31,13 @@ std::vector<uint64_t> PixivClient::get_illusts(uint64_t user_id) {
return ret; return ret;
} }
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)}
}, httplib::Headers());
return this->_handle_result(std::move(res)).get<Illust>();
}
nlohmann::json PixivClient::_handle_result(httplib::Result res) { nlohmann::json PixivClient::_handle_result(httplib::Result res) {
if (!res) { if (!res) {
throw HTTPLibException(res.error()); throw HTTPLibException(res.error());

View File

@ -12,6 +12,7 @@ public:
User get_user(uint64_t user_id); User get_user(uint64_t user_id);
std::vector<uint64_t> get_illusts(uint64_t user_id); std::vector<uint64_t> get_illusts(uint64_t user_id);
Illust get_illust(uint64_t illust_id);
private: private:
nlohmann::json _handle_result(httplib::Result res); nlohmann::json _handle_result(httplib::Result res);

View File

@ -8,6 +8,8 @@
static inline std::optional<std::string> get_1920x960_cover_image(blankie::murl::Url url); static inline std::optional<std::string> get_1920x960_cover_image(blankie::murl::Url url);
static inline std::optional<std::string> get_original_cover_image(blankie::murl::Url url); static inline std::optional<std::string> get_original_cover_image(blankie::murl::Url url);
static inline std::optional<std::string> get_original_profile_picture(blankie::murl::Url url); static inline std::optional<std::string> get_original_profile_picture(blankie::murl::Url url);
static Images get_profile_pictures(const nlohmann::json& j);
static Images get_illust_image(const nlohmann::json& j);
const std::string& Images::original_or_thumbnail() const { const std::string& Images::original_or_thumbnail() const {
if (this->original) { if (this->original) {
@ -46,12 +48,7 @@ void from_json(const nlohmann::json& j, User& user) {
} }
} }
nlohmann::json profile_img = j.at("profile_img"); user.profile_pictures = get_profile_pictures(j.at("profile_img"));
if (profile_img.contains("main_s")) {
user.profile_pictures.thumbnails.push_back(profile_img["main_s"].get<std::string>());
}
user.profile_pictures.thumbnails.push_back(profile_img.at("main").get<std::string>());
user.profile_pictures.original = get_original_profile_picture(user.profile_pictures.thumbnails.back());
if (j.contains("user_webpage")) { if (j.contains("user_webpage")) {
std::string user_webpage = j.at("user_webpage").get<std::string>(); std::string user_webpage = j.at("user_webpage").get<std::string>();
@ -78,6 +75,52 @@ void from_json(const nlohmann::json& j, User& user) {
} }
} }
void from_json(const nlohmann::json& j, Tag& tag) {
j.at("tag").get_to(tag.japanese);
if (j.contains("romaji")) {
tag.romaji = j["romaji"].get<std::string>();
}
if (j.contains("translation")) {
tag.english = j["translation"].get<std::string>();
}
}
void from_json(const nlohmann::json& j, Illust& illust) {
bool full_data = j.contains("illust_details");
const nlohmann::json& author_details = j.at("author_details");
const nlohmann::json& illust_details = full_data ? j.at("illust_details") : j;
author_details.at("user_account").get_to(illust.username);
author_details.at("user_name").get_to(illust.display_name);
illust.user_id = to_ull(author_details.at("user_id").get_ref<const nlohmann::json::string_t&>());
if (full_data) {
illust.user_profile_pictures = get_profile_pictures(author_details.at("profile_img"));
}
illust.illust_id = to_ull(illust_details.at("id").get_ref<const nlohmann::json::string_t&>());
illust_details.at("title").get_to(illust.title);
illust.ai_generated = illust_details.at("ai_type").get<int>() != 0;
illust_details.at("upload_timestamp").get_to(illust.upload_time);
std::string comment_html = illust_details.at("comment_html").get<std::string>();
if (!comment_html.empty()) {
illust.comment_html = std::move(comment_html);
}
if (illust_details.contains("display_tags")) {
illust_details["display_tags"].get_to(illust.tags);
}
if (illust_details.contains("manga_a")) {
const nlohmann::json& manga_a = illust_details["manga_a"];
illust.images.reserve(manga_a.size());
for (auto &[_, i] : manga_a.items()) {
illust.images.push_back(get_illust_image(i));
}
} else {
illust.images = {get_illust_image(illust_details)};
}
}
static std::regex resolution_path_regex("/c/(\\d+x\\d+)(.+)"); static std::regex resolution_path_regex("/c/(\\d+x\\d+)(.+)");
static inline std::optional<std::string> get_1920x960_cover_image(blankie::murl::Url url) { static inline std::optional<std::string> get_1920x960_cover_image(blankie::murl::Url url) {
std::smatch sm; std::smatch sm;
@ -110,3 +153,39 @@ static inline std::optional<std::string> get_original_profile_picture(blankie::m
url.path = sm.str(1) + sm.str(2); url.path = sm.str(1) + sm.str(2);
return url.to_string(); return url.to_string();
} }
static Images get_profile_pictures(const nlohmann::json& j) {
Images images;
if (j.contains("main_s")) {
images.thumbnails.push_back(j["main_s"].get<std::string>());
}
images.thumbnails.push_back(j.at("main").get<std::string>());
images.original = get_original_profile_picture(images.thumbnails.back());
return images;
}
static Images get_illust_image(const nlohmann::json& j) {
Images images;
auto add_if_exists = [&](const char* key) {
if (j.contains(key) && j[key].is_string()) {
images.thumbnails.push_back(j[key].get<std::string>());
}
};
add_if_exists("url_ss");
add_if_exists("url_placeholder");
add_if_exists("url_s");
add_if_exists("url");
if (j.contains("url_big") && j["url_big"].is_string()) {
std::string url_big = j["url_big"].get<std::string>();
if (url_big.starts_with("/img-original/")) {
images.original = std::move(url_big);
} else {
images.thumbnails.push_back(std::move(url_big));
}
}
return images;
}

View File

@ -25,4 +25,28 @@ struct User {
std::vector<std::pair<std::string, std::string>> links; std::vector<std::pair<std::string, std::string>> links;
}; };
struct Tag {
std::string japanese;
std::optional<std::string> romaji;
std::optional<std::string> english;
};
struct Illust {
std::string username;
std::string display_name;
uint64_t user_id;
Images user_profile_pictures;
uint64_t illust_id;
std::string title;
bool ai_generated;
time_t upload_time;
std::optional<std::string> comment_html;
std::vector<Tag> tags;
std::vector<Images> images;
};
void from_json(const nlohmann::json& j, User& user); void from_json(const nlohmann::json& j, User& user);
void from_json(const nlohmann::json& j, Tag& tag);
void from_json(const nlohmann::json& j, Illust& illust);