#include #include #include #include #include "CacheManager.h" #include "DownloadManager.h" #include "Pokedex.h" #include "PokemonTCGAPIClient.h" #include "PokemonCard.h" Pokedex::Pokedex() { this->cache = new CacheManager("./cache"); this->api = new PokemonTCGAPIClient(); this->download_manager = new DownloadManager(); if (this->cache->cache_exists("index")) this->load_collection_local(); else this->load_collection_remote(); } Pokedex::~Pokedex() { delete this->cache; } void Pokedex::load_collection_remote() { std::cout << "no local cards found, building cache..." << std::endl; std::vector remote_cards = api->get_set_cards("swshp"); for (PokemonCard* card : remote_cards) { card->set_pokedex(this); this->cards.push_back(card); } this->verify_collection(); cache->update_cache(); } void Pokedex::load_collection_local() { std::cout << "local cards found, using cache..." << std::endl; std::fstream& cache_collection = *cache->cache_get("index"); std::string id; while (std::getline(cache_collection, id)) { this->cards.push_back(new PokemonCard::from_cache(this, id)); } cache_collection.close(); } void Pokedex::verify_collection() { std::fstream& index = *cache->cache_get("index"); for (PokemonCard* card : this->cards) { card->verify_files(); index << card->id << "\n"; } index.close(); cache->update_cache(); } std::string Pokedex::lower(std::string input) { std::string out(input.size(), ' '); std::transform(input.begin(), input.end(), out.begin(), tolower); return out; } std::vector Pokedex::search_cards_local(std::string query) { std::vector out(this->cards.size()); // https://cplusplus.com/reference/algorithm/copy_if/ auto it = std::copy_if(this->cards.begin(), this->cards.end(), out.begin(), [&](const PokemonCard* card) { return lower(card->id).find(lower(query)) != std::string::npos || lower(card->name).find(lower(query)) != std::string::npos; }); out.resize(std::distance(out.begin(), it)); return out; } std::vector Pokedex::search_cards_remote(std::string query) { std::cout << "couldn't find card in cache, trying api..." << std::endl; std::vector api_cards = api->get_cards_by_query((std::string("name:\"") + query + "\" OR id:*" + query + "*").c_str()); std::vector out; for (PokemonCard* api_card : api_cards) { if (std::any_of(this->cards.begin(), this->cards.end(), [api_card] (PokemonCard* card) { return card->id == api_card->id; // remove any duplicate local/api cards })) { delete api_card; continue; } this->cards.push_back(api_card); api_card->set_pokedex(this); out.push_back(api_card); } this->verify_collection(); return out; } std::vector Pokedex::search_cards(std::string query) { std::vector out = search_cards_local(query); if (out.size() == 0) out = search_cards_remote(query); return out; } PokemonCard* Pokedex::get_card_by_id(std::string id) { for (PokemonCard* card : this->cards) if (card->id == id) return card; return nullptr; }