|
|
|
|
@ -14,6 +14,7 @@
|
|
|
|
|
#include "util/animated_image.h"
|
|
|
|
|
#include "util/cd_image.h"
|
|
|
|
|
#include "util/elf_file.h"
|
|
|
|
|
#include "util/http_cache.h"
|
|
|
|
|
#include "util/http_downloader.h"
|
|
|
|
|
#include "util/image.h"
|
|
|
|
|
#include "util/ini_settings_interface.h"
|
|
|
|
|
@ -1865,13 +1866,6 @@ bool GameList::DownloadCovers(const std::vector<std::string>& url_templates, boo
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<HTTPDownloader> downloader(HTTPDownloader::Create(Core::GetHTTPUserAgent(), error));
|
|
|
|
|
if (!downloader)
|
|
|
|
|
{
|
|
|
|
|
Error::AddPrefix(error, "Failed to create HTTP downloader: ");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
progress->SetCancellable(true);
|
|
|
|
|
progress->SetState(0, static_cast<u32>(download_urls.size()));
|
|
|
|
|
|
|
|
|
|
@ -1895,44 +1889,47 @@ bool GameList::DownloadCovers(const std::vector<std::string>& url_templates, boo
|
|
|
|
|
|
|
|
|
|
// we could actually do a few in parallel here...
|
|
|
|
|
std::string filename = Path::URLDecode(url);
|
|
|
|
|
downloader->CreateRequest(std::move(url), [use_serial, &save_callback, entry_path = std::move(entry_path),
|
|
|
|
|
filename = std::move(filename)](s32 status_code, const Error& error,
|
|
|
|
|
const std::string& content_type,
|
|
|
|
|
HTTPDownloader::Request::Data data) {
|
|
|
|
|
if (status_code != HTTPDownloader::HTTP_STATUS_OK || data.empty())
|
|
|
|
|
{
|
|
|
|
|
ERROR_LOG("Download for {} failed: {}", Path::GetFileName(filename), error.GetDescription());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unique_lock lock(s_state.mutex);
|
|
|
|
|
const GameList::Entry* entry = GetEntryForPath(entry_path);
|
|
|
|
|
if (!entry || !GetCoverImagePathForEntry(entry).empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// prefer the content type from the response for the extension
|
|
|
|
|
// otherwise, if it's missing, and the request didn't have an extension.. fall back to jpegs.
|
|
|
|
|
std::string template_filename;
|
|
|
|
|
std::string content_type_extension(HTTPDownloader::GetExtensionForContentType(content_type));
|
|
|
|
|
|
|
|
|
|
// don't treat the domain name as an extension..
|
|
|
|
|
const std::string::size_type last_slash = filename.find('/');
|
|
|
|
|
const std::string::size_type last_dot = filename.find('.');
|
|
|
|
|
if (!content_type_extension.empty())
|
|
|
|
|
template_filename = fmt::format("cover.{}", content_type_extension);
|
|
|
|
|
else if (last_slash != std::string::npos && last_dot != std::string::npos && last_dot > last_slash)
|
|
|
|
|
template_filename = Path::GetFileName(filename);
|
|
|
|
|
else
|
|
|
|
|
template_filename = "cover.jpg";
|
|
|
|
|
if (const auto downloader = HTTPCache::GetDownloader(error))
|
|
|
|
|
{
|
|
|
|
|
downloader->CreateRequest(std::move(url), [use_serial, &save_callback, entry_path = std::move(entry_path),
|
|
|
|
|
filename = std::move(filename)](s32 status_code, const Error& error,
|
|
|
|
|
const std::string& content_type,
|
|
|
|
|
HTTPDownloader::Request::Data data) {
|
|
|
|
|
if (status_code != HTTPDownloader::HTTP_STATUS_OK || data.empty())
|
|
|
|
|
{
|
|
|
|
|
ERROR_LOG("Download for {} failed: {}", Path::GetFileName(filename), error.GetDescription());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unique_lock lock(s_state.mutex);
|
|
|
|
|
const GameList::Entry* entry = GetEntryForPath(entry_path);
|
|
|
|
|
if (!entry || !GetCoverImagePathForEntry(entry).empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// prefer the content type from the response for the extension
|
|
|
|
|
// otherwise, if it's missing, and the request didn't have an extension.. fall back to jpegs.
|
|
|
|
|
std::string template_filename;
|
|
|
|
|
std::string content_type_extension(HTTPDownloader::GetExtensionForContentType(content_type));
|
|
|
|
|
|
|
|
|
|
// don't treat the domain name as an extension..
|
|
|
|
|
const std::string::size_type last_slash = filename.find('/');
|
|
|
|
|
const std::string::size_type last_dot = filename.find('.');
|
|
|
|
|
if (!content_type_extension.empty())
|
|
|
|
|
template_filename = fmt::format("cover.{}", content_type_extension);
|
|
|
|
|
else if (last_slash != std::string::npos && last_dot != std::string::npos && last_dot > last_slash)
|
|
|
|
|
template_filename = Path::GetFileName(filename);
|
|
|
|
|
else
|
|
|
|
|
template_filename = "cover.jpg";
|
|
|
|
|
|
|
|
|
|
std::string write_path(GetNewCoverImagePathForEntry(entry, template_filename.c_str(), use_serial));
|
|
|
|
|
if (write_path.empty())
|
|
|
|
|
return;
|
|
|
|
|
std::string write_path(GetNewCoverImagePathForEntry(entry, template_filename.c_str(), use_serial));
|
|
|
|
|
if (write_path.empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (FileSystem::WriteBinaryFile(write_path.c_str(), data.data(), data.size()) && save_callback)
|
|
|
|
|
save_callback(entry, std::move(write_path));
|
|
|
|
|
});
|
|
|
|
|
downloader->WaitForAllRequests();
|
|
|
|
|
if (FileSystem::WriteBinaryFile(write_path.c_str(), data.data(), data.size()) && save_callback)
|
|
|
|
|
save_callback(entry, std::move(write_path));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
HTTPCache::WaitForAllRequests();
|
|
|
|
|
progress->IncrementProgressValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|