From fd020ed756c5ee234ed6b8e9cfa19a1a89642036 Mon Sep 17 00:00:00 2001 From: blankie Date: Sun, 4 Jun 2023 14:09:03 +0700 Subject: [PATCH] Add OGP metadata for users --- pixivmodels.cpp | 7 +++++++ pixivmodels.h | 1 + routes/users/illustrations.cpp | 25 ++++++++++++++++++++++++- servehelper.cpp | 2 +- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/pixivmodels.cpp b/pixivmodels.cpp index f9f1d77..47776d9 100644 --- a/pixivmodels.cpp +++ b/pixivmodels.cpp @@ -38,6 +38,8 @@ const Image& Images::thumbnail_or_original(size_t back) const { } void from_json(const nlohmann::json& j, User& user) { + using namespace std::string_literals; + j.at("user_account").get_to(user.username); j.at("user_name").get_to(user.display_name); user.user_id = to_ull(j.at("user_id").get_ref()); @@ -79,6 +81,11 @@ void from_json(const nlohmann::json& j, User& user) { add_social_as_needed("circlems", "Circle.ms"); add_social_as_needed("pawoo", "Pawoo"); } + + blankie::murl::Url ogp_image = j.at("meta").at("ogp").at("image").get(); + if (ogp_image.is_host_equal("embed.pixiv.net")) { + user.ogp_image = "https://embed.pixiv.net/user_profile.php?id="s + std::to_string(user.user_id); + } } void from_json(const nlohmann::json& j, Tag& tag) { diff --git a/pixivmodels.h b/pixivmodels.h index 40c38a0..4745af4 100644 --- a/pixivmodels.h +++ b/pixivmodels.h @@ -31,6 +31,7 @@ struct User { std::optional cover_images; Images profile_pictures; std::vector> links; + std::optional ogp_image; }; struct Tag { diff --git a/routes/users/illustrations.cpp b/routes/users/illustrations.cpp index d9bdf87..e7f9351 100644 --- a/routes/users/illustrations.cpp +++ b/routes/users/illustrations.cpp @@ -6,6 +6,8 @@ #include "../../pixivclient.h" #include "common.h" +static inline Nodes generate_ogp_nodes(const httplib::Request& req, const Config& config, const User& user); + 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; @@ -34,5 +36,26 @@ void user_illustrations_route(const httplib::Request& req, httplib::Response& re generate_user_header(std::move(user), config), generate_illusts_pager(req, config, illusts, page, "illusts") }); - serve(req, res, config, user.display_name + "'s illustrations", std::move(body)); + serve(req, res, config, user.display_name + "'s illustrations", std::move(body), generate_ogp_nodes(req, config, user)); +} + +static inline Nodes generate_ogp_nodes(const httplib::Request& req, const Config& config, const User& user) { + Nodes nodes({ + Element("meta", {{"property", "og:title"}, {"content", user.display_name + " (@" + user.username + ')'}}, {}), + Element("meta", {{"property", "og:type"}, {"content", user.ogp_image ? "photo" : "website"}}, {}), + Element("meta", {{"property", "og:site_name"}, {"content", "Pixwhile"}}, {}), + Element("meta", {{"property", "og:url"}, {"content", get_origin(req, config) + "/users/" + std::to_string(user.user_id) + "/illustrations"}}, {}) + }); + if (user.ogp_image) { + nodes.push_back(Element("meta", {{"property", "og:image"}, {"content", proxy_image_url(config, *user.ogp_image)}}, {})); + } else { + const Image& image = user.profile_pictures.thumbnail_or_original(); + nodes.push_back(Element("meta", {{"property", "og:image"}, {"content", proxy_image_url(config, image.url)}}, {})); + if (image.size) { + nodes.push_back(Element("meta", {{"property", "og:image:width"}, {"content", std::to_string(image.size->first)}}, {})); + nodes.push_back(Element("meta", {{"property", "og:image:height"}, {"content", std::to_string(image.size->second)}}, {})); + } + } + + return nodes; } diff --git a/servehelper.cpp b/servehelper.cpp index 9cabd2e..ffc1f11 100644 --- a/servehelper.cpp +++ b/servehelper.cpp @@ -112,7 +112,7 @@ std::string proxy_url(blankie::murl::Url base, blankie::murl::Url url) { } std::string proxy_image_url(const Config& config, blankie::murl::Url url) { - if (url.is_host_equal("s.pximg.net")) { + if (url.is_host_equal("s.pximg.net") || url.is_host_equal("embed.pixiv.net")) { return url.to_string(); } return proxy_url(config.image_proxy_url, std::move(url));