Guess the size of thumbnails
This commit is contained in:
parent
b0b8e5c3c9
commit
421bbcd6a0
|
@ -11,9 +11,10 @@ static inline std::optional<std::string> get_original_profile_picture(blankie::m
|
||||||
static inline std::optional<std::string> get_360x360_illust_thumbnail(blankie::murl::Url url);
|
static inline std::optional<std::string> get_360x360_illust_thumbnail(blankie::murl::Url url);
|
||||||
static Images get_profile_pictures(const nlohmann::json& j);
|
static Images get_profile_pictures(const nlohmann::json& j);
|
||||||
static Images get_profile_pictures(const std::string& url);
|
static Images get_profile_pictures(const std::string& url);
|
||||||
static Images get_illust_image(const nlohmann::json& j);
|
static std::optional<std::pair<uint64_t, uint64_t>> get_thumbnail_size(blankie::murl::Url thumbnail_url, std::optional<std::pair<uint64_t, uint64_t>> original_size);
|
||||||
|
static Images get_illust_images(const nlohmann::json& image, std::optional<nlohmann::json> image_metadata);
|
||||||
|
|
||||||
const std::string& Images::original_or_thumbnail() const {
|
const Image& Images::original_or_thumbnail() const {
|
||||||
if (this->original) {
|
if (this->original) {
|
||||||
return *this->original;
|
return *this->original;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +24,7 @@ const std::string& Images::original_or_thumbnail() const {
|
||||||
throw std::runtime_error("Images does not contain any images");
|
throw std::runtime_error("Images does not contain any images");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Images::thumbnail_or_original(size_t back) const {
|
const Image& Images::thumbnail_or_original(size_t back) const {
|
||||||
if (this->thumbnails.size() > back) {
|
if (this->thumbnails.size() > back) {
|
||||||
return this->thumbnails[this->thumbnails.size() - back - 1];
|
return this->thumbnails[this->thumbnails.size() - back - 1];
|
||||||
}
|
}
|
||||||
|
@ -91,6 +92,7 @@ void from_json(const nlohmann::json& j, Illust& illust) {
|
||||||
bool full_data = j.contains("illust_details");
|
bool full_data = j.contains("illust_details");
|
||||||
const nlohmann::json& author_details = j.at("author_details");
|
const nlohmann::json& author_details = j.at("author_details");
|
||||||
const nlohmann::json& illust_details = full_data ? j.at("illust_details") : j;
|
const nlohmann::json& illust_details = full_data ? j.at("illust_details") : j;
|
||||||
|
const nlohmann::json& images_metadata = illust_details.at("illust_images");
|
||||||
|
|
||||||
author_details.at("user_account").get_to(illust.username);
|
author_details.at("user_account").get_to(illust.username);
|
||||||
author_details.at("user_name").get_to(illust.user_display_name);
|
author_details.at("user_name").get_to(illust.user_display_name);
|
||||||
|
@ -114,11 +116,12 @@ void from_json(const nlohmann::json& j, Illust& illust) {
|
||||||
if (illust_details.contains("manga_a")) {
|
if (illust_details.contains("manga_a")) {
|
||||||
const nlohmann::json& manga_a = illust_details["manga_a"];
|
const nlohmann::json& manga_a = illust_details["manga_a"];
|
||||||
illust.images.reserve(manga_a.size());
|
illust.images.reserve(manga_a.size());
|
||||||
for (auto &[_, i] : manga_a.items()) {
|
|
||||||
illust.images.push_back(get_illust_image(i));
|
for (size_t i = 0; i < manga_a.size(); i++) {
|
||||||
|
illust.images.push_back(get_illust_images(manga_a[i], images_metadata.at(i)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
illust.images = {get_illust_image(illust_details)};
|
illust.images = {get_illust_images(illust_details, images_metadata.at(0))};
|
||||||
}
|
}
|
||||||
illust.page_count = to_ull(illust_details.at("page_count").get_ref<const nlohmann::json::string_t&>());
|
illust.page_count = to_ull(illust_details.at("page_count").get_ref<const nlohmann::json::string_t&>());
|
||||||
}
|
}
|
||||||
|
@ -168,7 +171,7 @@ void from_json(const nlohmann::json& j, SearchResults& search_results) {
|
||||||
|
|
||||||
.comment = std::nullopt,
|
.comment = std::nullopt,
|
||||||
.tags = std::move(tags),
|
.tags = std::move(tags),
|
||||||
.images = {get_illust_image(i)},
|
.images = {get_illust_images(i, std::nullopt)},
|
||||||
.page_count = i.at("pageCount").get<size_t>()
|
.page_count = i.at("pageCount").get<size_t>()
|
||||||
};
|
};
|
||||||
search_results.illusts.illusts.push_back(illust);
|
search_results.illusts.illusts.push_back(illust);
|
||||||
|
@ -247,7 +250,7 @@ static Images get_profile_pictures(const nlohmann::json& j) {
|
||||||
images.thumbnails.push_back(j["main_s"].get<std::string>());
|
images.thumbnails.push_back(j["main_s"].get<std::string>());
|
||||||
}
|
}
|
||||||
images.thumbnails.push_back(j.at("main").get<std::string>());
|
images.thumbnails.push_back(j.at("main").get<std::string>());
|
||||||
images.original = get_original_profile_picture(images.thumbnails.back());
|
images.original = get_original_profile_picture(images.thumbnails.back().url);
|
||||||
|
|
||||||
return images;
|
return images;
|
||||||
}
|
}
|
||||||
|
@ -274,16 +277,50 @@ static inline std::optional<std::string> get_360x360_illust_thumbnail(blankie::m
|
||||||
return url.to_string();
|
return url.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Images get_illust_image(const nlohmann::json& j) {
|
static std::regex illust_size_regex(
|
||||||
|
"/c/(\\d+)x(\\d+)[/_].+"
|
||||||
|
);
|
||||||
|
static std::optional<std::pair<uint64_t, uint64_t>> get_thumbnail_size(blankie::murl::Url thumbnail_url, std::optional<std::pair<uint64_t, uint64_t>> original_size) {
|
||||||
|
if (!original_size) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::smatch sm;
|
||||||
|
if (!std::regex_match(thumbnail_url.path, sm, illust_size_regex)) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t thumbnail_width = to_ull(sm.str(1));
|
||||||
|
// uint64_t thumbnail_height = to_ull(sm.str(2));
|
||||||
|
|
||||||
|
std::pair<uint64_t, uint64_t> real_thumbnail_size = {
|
||||||
|
thumbnail_width,
|
||||||
|
// derived from original_size->second / (original_size->first / thumbnail_width)
|
||||||
|
// to make it more accurate without using floats
|
||||||
|
original_size->second * thumbnail_width / original_size->first
|
||||||
|
};
|
||||||
|
return real_thumbnail_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Images get_illust_images(const nlohmann::json& image, std::optional<nlohmann::json> image_metadata) {
|
||||||
Images images;
|
Images images;
|
||||||
ssize_t add_360x360_to = -1;
|
ssize_t add_360x360_to = -1;
|
||||||
|
std::optional<std::pair<uint64_t, uint64_t>> original_size;
|
||||||
|
|
||||||
|
if (image_metadata) {
|
||||||
|
original_size = {
|
||||||
|
to_ull(image_metadata->at("illust_image_width").get_ref<const nlohmann::json::string_t&>()),
|
||||||
|
to_ull(image_metadata->at("illust_image_height").get_ref<const nlohmann::json::string_t&>())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
auto add_if_exists = [&](const char* key) {
|
auto add_if_exists = [&](const char* key) {
|
||||||
if (j.contains(key) && j[key].is_string()) {
|
if (!image.contains(key) || !image[key].is_string()) {
|
||||||
images.thumbnails.push_back(j[key].get<std::string>());
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
std::string url = image[key].get<std::string>();
|
||||||
|
images.thumbnails.push_back({url, get_thumbnail_size(url, original_size)});
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
add_if_exists("url_ss");
|
add_if_exists("url_ss");
|
||||||
add_if_exists("url_placeholder");
|
add_if_exists("url_placeholder");
|
||||||
|
@ -292,14 +329,14 @@ static Images get_illust_image(const nlohmann::json& j) {
|
||||||
add_360x360_to = static_cast<ssize_t>(images.thumbnails.size());
|
add_360x360_to = static_cast<ssize_t>(images.thumbnails.size());
|
||||||
}
|
}
|
||||||
add_if_exists("url");
|
add_if_exists("url");
|
||||||
if (j.contains("url_big") && j["url_big"].is_string()) {
|
if (image.contains("url_big") && image["url_big"].is_string()) {
|
||||||
images.original = j["url_big"].get<std::string>();
|
images.original = {image["url_big"].get<std::string>(), original_size};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_360x360_to >= 0) {
|
if (add_360x360_to >= 0) {
|
||||||
std::optional<std::string> c_360x360 = get_360x360_illust_thumbnail(images.original_or_thumbnail());
|
std::optional<std::string> c_360x360 = get_360x360_illust_thumbnail(images.original_or_thumbnail().url);
|
||||||
if (c_360x360) {
|
if (c_360x360) {
|
||||||
images.thumbnails.insert(images.thumbnails.begin() + add_360x360_to, std::move(*c_360x360));
|
images.thumbnails.insert(images.thumbnails.begin() + add_360x360_to, {*c_360x360, get_thumbnail_size(*c_360x360, original_size)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,20 @@
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
struct Images {
|
struct Image {
|
||||||
std::optional<std::string> original;
|
std::string url;
|
||||||
std::vector<std::string> thumbnails;
|
std::optional<std::pair<uint64_t, uint64_t>> size;
|
||||||
|
|
||||||
const std::string& original_or_thumbnail() const;
|
Image(std::string url_) : url(std::move(url_)) {}
|
||||||
const std::string& thumbnail_or_original(size_t back = 0) const;
|
Image(std::string url_, std::optional<std::pair<uint64_t, uint64_t>> size_) : url(std::move(url_)), size(std::move(size_)) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Images {
|
||||||
|
std::optional<Image> original;
|
||||||
|
std::vector<Image> thumbnails;
|
||||||
|
|
||||||
|
const Image& original_or_thumbnail() const;
|
||||||
|
const Image& thumbnail_or_original(size_t back = 0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct User {
|
struct User {
|
||||||
|
|
|
@ -55,7 +55,7 @@ void artworks_route(const httplib::Request& req, httplib::Response& res, const C
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Element generate_user_link(const httplib::Request& req, const Config& config, const Illust& illust) {
|
static inline Element generate_user_link(const httplib::Request& req, const Config& config, const Illust& illust) {
|
||||||
std::string profile_picture = proxy_image_url(config, illust.user_profile_pictures.thumbnail_or_original());
|
std::string profile_picture = proxy_image_url(config, illust.user_profile_pictures.thumbnail_or_original().url);
|
||||||
std::string user_link = get_origin(req, config) + "/users/" + std::to_string(illust.user_id);
|
std::string user_link = get_origin(req, config) + "/users/" + std::to_string(illust.user_id);
|
||||||
|
|
||||||
return Element("a", {{"class", "usermetadata"}, {"href", std::move(user_link)}}, {
|
return Element("a", {{"class", "usermetadata"}, {"href", std::move(user_link)}}, {
|
||||||
|
@ -76,15 +76,21 @@ static inline Element generate_images(const httplib::Request& req, const Config&
|
||||||
div.nodes.reserve(div.nodes.size() + (show_pages ? illust.images.size() * 2 : illust.images.size()));
|
div.nodes.reserve(div.nodes.size() + (show_pages ? illust.images.size() * 2 : illust.images.size()));
|
||||||
for (size_t i = 0; i < illust.images.size(); i++) {
|
for (size_t i = 0; i < illust.images.size(); i++) {
|
||||||
const Images& images = illust.images[i];
|
const Images& images = illust.images[i];
|
||||||
std::string thumbnail = proxy_image_url(config, images.thumbnail_or_original());
|
const Image& thumbnail = images.thumbnail_or_original();
|
||||||
std::string original = proxy_image_url(config, images.original_or_thumbnail());
|
const Image& original = images.original_or_thumbnail();
|
||||||
|
|
||||||
if (show_pages) {
|
if (show_pages) {
|
||||||
std::string id = std::to_string(i + 1);
|
std::string id = std::to_string(i + 1);
|
||||||
div.nodes.push_back(Element("a", {{"class", "landmark"}, {"id", id}, {"href", "#"s + id}}, {id, "/", std::to_string(illust.images.size())}));
|
div.nodes.push_back(Element("a", {{"class", "landmark"}, {"id", id}, {"href", "#"s + id}}, {id, "/", std::to_string(illust.images.size())}));
|
||||||
}
|
}
|
||||||
div.nodes.push_back(Element("a", {{"href", std::move(original)}}, {
|
|
||||||
Element("img", {{"loading", "lazy"}, {"src", std::move(thumbnail)}}, {})
|
Element img("img", {{"loading", "lazy"}, {"src", proxy_image_url(config, thumbnail.url)}}, {});
|
||||||
|
if (thumbnail.size) {
|
||||||
|
img.attributes.push_back({"width", std::to_string(thumbnail.size->first)});
|
||||||
|
img.attributes.push_back({"height", std::to_string(thumbnail.size->second)});
|
||||||
|
}
|
||||||
|
div.nodes.push_back(Element("a", {{"href", proxy_image_url(config, original.url)}}, {
|
||||||
|
std::move(img)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +108,7 @@ static inline Element generate_preview_images(const httplib::Request& req, const
|
||||||
grid.nodes.reserve(illust.images.size());
|
grid.nodes.reserve(illust.images.size());
|
||||||
for (size_t i = 0; i < illust.images.size(); i++) {
|
for (size_t i = 0; i < illust.images.size(); i++) {
|
||||||
const Images& images = illust.images[i];
|
const Images& images = illust.images[i];
|
||||||
std::string thumbnail = proxy_image_url(config, images.thumbnail_or_original(1));
|
std::string thumbnail = proxy_image_url(config, images.thumbnail_or_original(1).url);
|
||||||
std::string link = no_preview_link + '#' + std::to_string(i + 1);
|
std::string link = no_preview_link + '#' + std::to_string(i + 1);
|
||||||
|
|
||||||
grid.nodes.push_back(Element("a", {{"href", std::move(link)}}, {
|
grid.nodes.push_back(Element("a", {{"href", std::move(link)}}, {
|
||||||
|
|
|
@ -8,15 +8,15 @@ static inline Element generate_user_links(const User& user);
|
||||||
Element generate_user_header(const User& user, const Config& config) {
|
Element generate_user_header(const User& user, const Config& config) {
|
||||||
Element header("header");
|
Element header("header");
|
||||||
if (user.cover_images) {
|
if (user.cover_images) {
|
||||||
std::string cover_original = proxy_image_url(config, user.cover_images->original_or_thumbnail());
|
std::string cover_original = proxy_image_url(config, user.cover_images->original_or_thumbnail().url);
|
||||||
std::string cover_thumbnail = proxy_image_url(config, user.cover_images->thumbnail_or_original());
|
std::string cover_thumbnail = proxy_image_url(config, user.cover_images->thumbnail_or_original().url);
|
||||||
header.nodes.push_back(Element("a", {{"href", std::move(cover_original)}}, {
|
header.nodes.push_back(Element("a", {{"href", std::move(cover_original)}}, {
|
||||||
Element("img", {{"class", "profilecover"}, {"loading", "lazy"}, {"src", std::move(cover_thumbnail)}}, {})
|
Element("img", {{"class", "profilecover"}, {"loading", "lazy"}, {"src", std::move(cover_thumbnail)}}, {})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string profile_picture_original = proxy_image_url(config, user.profile_pictures.original_or_thumbnail());
|
std::string profile_picture_original = proxy_image_url(config, user.profile_pictures.original_or_thumbnail().url);
|
||||||
std::string profile_picture_thumbnail = proxy_image_url(config, user.profile_pictures.thumbnail_or_original());
|
std::string profile_picture_thumbnail = proxy_image_url(config, user.profile_pictures.thumbnail_or_original().url);
|
||||||
header.nodes.push_back(Element("div", {{"class", "usermetadata"}}, {
|
header.nodes.push_back(Element("div", {{"class", "usermetadata"}}, {
|
||||||
Element("a", {{"href", std::move(profile_picture_original)}}, {
|
Element("a", {{"href", std::move(profile_picture_original)}}, {
|
||||||
Element("img", {{"class", "profilepicture"}, {"loading", "lazy"}, {"src", std::move(profile_picture_thumbnail)}}, {})
|
Element("img", {{"class", "profilepicture"}, {"loading", "lazy"}, {"src", std::move(profile_picture_thumbnail)}}, {})
|
||||||
|
|
|
@ -147,7 +147,7 @@ static inline Element generate_illusts_grid(const httplib::Request& req, const C
|
||||||
|
|
||||||
static inline Element generate_illusts_grid_item(const httplib::Request& req, const Config& config, const Illust& illust) {
|
static inline Element generate_illusts_grid_item(const httplib::Request& req, const Config& config, const Illust& illust) {
|
||||||
std::string illust_url = get_origin(req, config) + "/artworks/" + std::to_string(illust.illust_id);
|
std::string illust_url = get_origin(req, config) + "/artworks/" + std::to_string(illust.illust_id);
|
||||||
std::string image_url = proxy_image_url(config, illust.images[0].thumbnail_or_original(1));
|
std::string image_url = proxy_image_url(config, illust.images[0].thumbnail_or_original(1).url);
|
||||||
|
|
||||||
Element div("div", {{"class", "illustsgriditem"}}, {
|
Element div("div", {{"class", "illustsgriditem"}}, {
|
||||||
Element("a", {{"href", illust_url}}, {
|
Element("a", {{"href", illust_url}}, {
|
||||||
|
|
Loading…
Reference in New Issue