#include #include "../routes.h" #include "../../numberhelper.h" #include "../../servehelper.h" #include "../../pixivclient.h" #include "common.h" static Element generate_pager(const Illusts& illusts, size_t page, bool first_selector); static inline Element generate_content(const httplib::Request& req, const Config& config, const Illusts& illusts); void user_illustrations_route(const httplib::Request& req, httplib::Response& res, const Config& config, PixivClient& pixiv_client) { uint64_t user_id = to_ull(req.matches[1].str()); uint64_t page = req.has_param("p") ? to_ull(req.get_param_value("p")) - 1 : 0; User user; Illusts illusts; try { user = pixiv_client.get_user(user_id); illusts = pixiv_client.get_illusts(user_id, page); } catch (const PixivException& e) { if (e.status == 404) { res.status = 404; serve_error(req, res, config, "404: User not found", e.what()); } else { res.status = 500; serve_error(req, res, config, "500: Internal server error", "Failed to fetch user information", e.what()); } return; } catch (const std::exception& e) { res.status = 500; serve_error(req, res, config, "500: Internal server error", "Failed to fetch user information", e.what()); return; } Element body("body", { generate_user_header(std::move(user), config), generate_pager(illusts, page, true), Element("br"), generate_content(req, config, illusts), generate_pager(illusts, page, false) }); serve(req, res, config, user.display_name + " illustrations", std::move(body)); } static Element generate_pager(const Illusts& illusts, size_t page, bool first_selector) { auto link = [](size_t new_page, const char* text, bool add_link) { using namespace std::string_literals; Element b("b"); std::string href = "?p="s + std::to_string(new_page) + "#pageselector"; if (add_link) { b.nodes.push_back(Element("a", {{"href", std::move(href)}}, {text})); } else { b.nodes.push_back(text); } return b; }; Element div("div", {{"class", "center"}}, { link(1, "First", page != 0), " ", link(page, "Prev", page != 0), " ", std::to_string(page + 1), "/", std::to_string(illusts.total_pages), " ", link(page + 2, "Next", page + 1 < illusts.total_pages), " ", link(illusts.total_pages, "Last", page + 1 < illusts.total_pages) }); if (first_selector) { div.attributes.push_back({"id", "pageselector"}); } return div; } static inline Element generate_content(const httplib::Request& req, const Config& config, const Illusts& illusts) { Element div("div", {{"class", "userillustrations"}}, {}); div.nodes.reserve(illusts.illusts.size()); for (const Illust& i : illusts.illusts) { std::string illust_url = get_origin(req, config) + "/artworks/" + std::to_string(i.illust_id); std::string image_url = proxy_image_url(config, i.images[0].thumbnail_or_original()); div.nodes.push_back(Element("a", {{"href", {std::move(illust_url)}}}, { Element("img", {{"loading", "lazy"}, {"src", std::move(image_url)}}, {}), Element("p", {i.title}) })); } return div; }