Browse Source

add indiviual thumbs and openssl def guard

pull/3308/head
Maufeat 3 weeks ago
committed by crueter
parent
commit
f9e196691f
  1. 1
      src/core/CMakeLists.txt
  2. 116
      src/core/hle/service/bcat/news/builtin_news.cpp

1
src/core/CMakeLists.txt

@ -1267,6 +1267,7 @@ if(ENABLE_OPENSSL)
find_package(OpenSSL REQUIRED)
target_link_libraries(core PRIVATE OpenSSL::SSL OpenSSL::Crypto)
target_compile_definitions(core PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT)
elseif (APPLE)
target_sources(core PRIVATE
hle/service/ssl/ssl_backend_securetransport.cpp)

116
src/core/hle/service/bcat/news/builtin_news.cpp

@ -35,19 +35,27 @@ namespace {
constexpr const char* GitHubAPI_EdenReleases = "/repos/eden-emulator/Releases/releases";
// Cached logo data
std::vector<u8> logo_small;
std::vector<u8> logo_large;
bool logos_loaded = false;
std::vector<u8> default_logo_small;
std::vector<u8> default_logo_large;
bool default_logos_loaded = false;
std::unordered_map<std::string, std::vector<u8>> news_images_small;
std::unordered_map<std::string, std::vector<u8>> news_images_large;
std::filesystem::path GetCachePath() {
return Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "news" / "github_releases.json";
}
std::filesystem::path GetLogoPath(bool large) {
std::filesystem::path GetDefaultLogoPath(bool large) {
return Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "news" /
(large ? "eden_logo_large.jpg" : "eden_logo_small.jpg");
}
std::filesystem::path GetNewsImagePath(std::string_view news_id, bool large) {
const std::string filename = fmt::format("{}_{}.jpg", news_id, large ? "large" : "small");
return Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "news" / "images" / filename;
}
u32 HashToNewsId(std::string_view key) {
return static_cast<u32>(std::hash<std::string_view>{}(key) & 0x7FFFFFFF);
}
@ -70,26 +78,26 @@ u64 ParseIsoTimestamp(const std::string& iso) {
#endif
}
std::vector<u8> LoadLogoFromDiskOrDownload(bool large) {
const auto path = GetLogoPath(large);
const char* imgur_id = large ? "/eden_logo_large.jpg" : "/eden_logo_small.jpg";
// Try loading from cached disk
if (std::filesystem::exists(path)) {
std::ifstream f(path, std::ios::binary | std::ios::ate);
if (f) {
const auto file_size = static_cast<std::streamsize>(f.tellg());
if (file_size > 0 && file_size < 10 * 1024 * 1024) {
f.seekg(0);
std::vector<u8> data(static_cast<size_t>(file_size));
if (f.read(reinterpret_cast<char*>(data.data()), file_size)) {
return data;
}
}
}
}
std::vector<u8> TryLoadFromDisk(const std::filesystem::path& path) {
if (!std::filesystem::exists(path)) return {};
std::ifstream f(path, std::ios::binary | std::ios::ate);
if (!f) return {};
// Download from imgur
const auto file_size = static_cast<std::streamsize>(f.tellg());
if (file_size <= 0 || file_size > 10 * 1024 * 1024) return {};
f.seekg(0);
std::vector<u8> data(static_cast<size_t>(file_size));
if (!f.read(reinterpret_cast<char*>(data.data()), file_size)) return {};
return data;
}
std::vector<u8> DownloadImage(const std::string& url_path, const std::filesystem::path& cache_path) {
LOG_INFO(Service_BCAT, "Downloading image: https://eden-emu.dev{}", url_path);
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
try {
httplib::Client cli("https://eden-emu.dev");
cli.set_follow_location(true);
@ -100,29 +108,63 @@ std::vector<u8> LoadLogoFromDiskOrDownload(bool large) {
cli.load_ca_cert_store(kCert, sizeof(kCert));
#endif
if (auto res = cli.Get(imgur_id); res && res->status == 200 && !res->body.empty()) {
if (auto res = cli.Get(url_path); res && res->status == 200 && !res->body.empty()) {
std::vector<u8> data(res->body.begin(), res->body.end());
std::error_code ec;
std::filesystem::create_directories(path.parent_path(), ec);
if (std::ofstream out(path, std::ios::binary); out) {
std::filesystem::create_directories(cache_path.parent_path(), ec);
if (std::ofstream out(cache_path, std::ios::binary); out) {
out.write(res->body.data(), static_cast<std::streamsize>(res->body.size()));
}
return data;
}
} catch (...) {
LOG_WARNING(Service_BCAT, "failed to download logo (large={})", large);
LOG_WARNING(Service_BCAT, "Failed to download: {}", url_path);
}
#endif
return {};
}
void LoadLogos() {
if (logos_loaded) return;
logos_loaded = true;
std::vector<u8> LoadDefaultLogo(bool large) {
const auto path = GetDefaultLogoPath(large);
const std::string url = large ? "/eden_logo_large.jpg" : "/eden_logo_small.jpg";
auto data = TryLoadFromDisk(path);
if (!data.empty()) return data;
return DownloadImage(url, path);
}
void LoadDefaultLogos() {
if (default_logos_loaded) return;
default_logos_loaded = true;
default_logo_small = LoadDefaultLogo(false);
default_logo_large = LoadDefaultLogo(true);
}
std::vector<u8> GetNewsImage(std::string_view news_id, bool large) {
const std::string id_str{news_id};
auto& cache = large ? news_images_large : news_images_small;
if (auto it = cache.find(id_str); it != cache.end()) {
return it->second;
}
const auto cache_path = GetNewsImagePath(news_id, large);
auto data = TryLoadFromDisk(cache_path);
if (data.empty()) {
const std::string url = fmt::format("/news/{}_{}.jpg", news_id, large ? "large" : "small");
data = DownloadImage(url, cache_path);
}
logo_small = LoadLogoFromDiskOrDownload(false);
logo_large = LoadLogoFromDiskOrDownload(true);
if (data.empty()) {
data = large ? default_logo_large : default_logo_small;
}
return data;
}
std::optional<std::string> ReadCachedJson() {
@ -321,6 +363,10 @@ std::vector<u8> BuildMsgpack(std::string_view title, std::string_view body,
MsgPack::Writer w;
const u32 news_id = override_id.value_or(HashToNewsId(title.empty() ? "eden" : title));
const std::string news_id_str = fmt::format("{}", news_id);
const auto img_small = GetNewsImage(news_id_str, false);
const auto img_large = GetNewsImage(news_id_str, true);
w.WriteFixMap(23);
@ -379,7 +425,7 @@ std::vector<u8> BuildMsgpack(std::string_view title, std::string_view body,
w.WriteString("Eden");
w.WriteKey("list_image");
w.WriteBinary(logo_small);
w.WriteBinary(img_small);
// Footer
w.WriteKey("footer");
@ -410,7 +456,7 @@ std::vector<u8> BuildMsgpack(std::string_view title, std::string_view body,
w.WriteKey("movie_url");
w.WriteString("");
w.WriteKey("main_image");
w.WriteBinary(logo_large);
w.WriteBinary(img_large);
// no clue
w.WriteKey("contents_descriptors");
@ -424,7 +470,7 @@ std::vector<u8> BuildMsgpack(std::string_view title, std::string_view body,
void EnsureBuiltinNewsLoaded() {
static std::once_flag once;
std::call_once(once, [] {
LoadLogos();
LoadDefaultLogos();
if (const auto fresh = DownloadReleasesJson()) {
WriteCachedJson(*fresh);

Loading…
Cancel
Save