/* Copyright 2022 flyinghead This file is part of Flycast. Flycast is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. Flycast is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Flycast. If not, see . */ #pragma once #include "types.h" #include "json.hpp" #include #include using namespace nlohmann; struct GameBoxart { std::string fileName; std::string name; std::string uniqueId; std::string searchName; u32 region = 0; std::string releaseDate; std::string overview; std::string gamePath; std::string boxartPath; std::string boxartUrl; bool parsed = false; bool scraped = false; bool busy = false; enum Region { JAPAN = 1, USA = 2, EUROPE = 4 }; json to_json() const { json j = { { "file_name", fileName }, { "name", name }, { "unique_id", uniqueId }, { "search_name", searchName }, { "region", region }, { "release_date", releaseDate }, { "overview", overview }, { "boxart_path", boxartPath }, { "boxart_url", boxartUrl }, { "parsed", parsed }, { "scraped", scraped }, }; return j; } template static void loadProperty(T& i, const json& j, const std::string& propName) { try { i = j.at(propName).get(); } catch (const json::exception& e) { i = T(); } } GameBoxart() = default; GameBoxart(const json& j) { loadProperty(fileName, j, "file_name"); loadProperty(name, j, "name"); loadProperty(uniqueId, j, "unique_id"); loadProperty(searchName, j, "search_name"); loadProperty(region, j, "region"); loadProperty(releaseDate, j, "release_date"); loadProperty(overview, j, "overview"); loadProperty(boxartPath, j, "boxart_path"); loadProperty(boxartUrl, j, "boxart_url"); loadProperty(parsed, j, "parsed"); loadProperty(scraped, j, "scraped"); } void setBoxartPath(const std::string& path) { if (!boxartPath.empty()) nowide::remove(boxartPath.c_str()); boxartPath = path; } }; class Scraper { public: virtual bool initialize(const std::string& saveDirectory) { this->saveDirectory = saveDirectory; return true; } virtual void scrape(GameBoxart& item) = 0; virtual void scrape(std::vector& items) { for (GameBoxart& item : items) scrape(item); } virtual ~Scraper() = default; protected: bool downloadImage(const std::string& url, const std::string& localName); std::string makeUniqueFilename(const std::string& url); private: std::string saveDirectory; }; class OfflineScraper : public Scraper { public: void scrape(GameBoxart& item) override; };