aboutsummaryrefslogtreecommitdiff
path: root/oop2eindopdr
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2022-12-25 14:16:55 +0100
committerlonkaars <loek@pipeframe.xyz>2022-12-25 14:16:55 +0100
commit9205f93bda48ffdc080d40140511b68b88c46fd7 (patch)
tree9de14ae45b18125c563eb01595238128453604b4 /oop2eindopdr
parent2b1145fb0aec3feb9cbab2df9be57ab43fc7f975 (diff)
cache working with asynchronous image downloads
Diffstat (limited to 'oop2eindopdr')
-rw-r--r--oop2eindopdr/CacheManager.cpp41
-rw-r--r--oop2eindopdr/CacheManager.h5
-rw-r--r--oop2eindopdr/DownloadManager.cpp14
-rw-r--r--oop2eindopdr/PokemonCard.cpp9
4 files changed, 58 insertions, 11 deletions
diff --git a/oop2eindopdr/CacheManager.cpp b/oop2eindopdr/CacheManager.cpp
index b8c368e..9324b81 100644
--- a/oop2eindopdr/CacheManager.cpp
+++ b/oop2eindopdr/CacheManager.cpp
@@ -5,6 +5,9 @@
#include <iostream>
#include <ctime>
+#include <thread>
+#include <chrono>
+
CacheManager::CacheManager(const char* cache_path) : CacheManager(std::string(cache_path)) { }
CacheManager::CacheManager(std::string cache_path) {
this->cache_path = cache_path;
@@ -41,10 +44,42 @@ void CacheManager::update_cache() {
std::fstream* CacheManager::cache_get(std::string filename) { return cache_get(filename.c_str()); }
std::fstream* CacheManager::cache_get(const char* filename) {
std::filesystem::path fixed_path = prefix_cache_path(filename); // fix duplicate slashes and add prefix
- std::filesystem::create_directories(fixed_path.parent_path()); // make sure folder exists
- if (!std::filesystem::exists(fixed_path))
+ unsigned int i = 0;
+
+ i = 0;
+ while (!std::filesystem::exists(fixed_path.parent_path())) {
+ std::filesystem::create_directories(fixed_path.parent_path()); // make sure folder exists
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ i++;
+ if (i > 100) {
+ std::cout << "folder touch doesn't succeed after 100 tries on file " << fixed_path << std::endl;
+ exit(1);
+ }
+ }
+
+ i = 0;
+ while (!std::filesystem::exists(fixed_path)) {
std::fstream(fixed_path, std::ios::trunc | std::ios::out).close(); // touch file
- std::fstream* file = new std::fstream(fixed_path.c_str(), std::ios::out | std::ios::in); // open file
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ i++;
+ if (i > 100) {
+ std::cout << "file touch doesn't succeed after 100 tries on file " << fixed_path << std::endl;
+ exit(1);
+ }
+ }
+
+ i = 0;
+ std::fstream* file = nullptr;
+ do {
+ delete file;
+ file = new std::fstream(fixed_path.c_str(), std::ios::out | std::ios::in); // open file
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ i++;
+ if (i > 100) {
+ std::cout << "file open doesn't succeed after 100 tries on file " << fixed_path << std::endl;
+ exit(1);
+ }
+ } while (!file->is_open());
this->files.push_back(file); // add file pointer (for closing all files on exit)
return file;
}
diff --git a/oop2eindopdr/CacheManager.h b/oop2eindopdr/CacheManager.h
index e441b1b..0b15cfa 100644
--- a/oop2eindopdr/CacheManager.h
+++ b/oop2eindopdr/CacheManager.h
@@ -10,8 +10,6 @@ private:
std::string cache_path;
/** @brief pointers to open file handles */
std::vector<std::fstream*> files;
- /** @brief add cache path before filename */
- virtual std::string prefix_cache_path(const char* filename);
public:
/** @brief initialize CacheManager class at `cache_path` */
CacheManager(const char* cache_path);
@@ -36,6 +34,9 @@ public:
virtual bool cache_exists(const char* filename);
virtual bool cache_exists(std::string filename);
+ /** @brief add cache path before filename */
+ virtual std::string prefix_cache_path(const char* filename);
+
/** @brief currently opened cache update unix timestamp */
uint64_t age;
};
diff --git a/oop2eindopdr/DownloadManager.cpp b/oop2eindopdr/DownloadManager.cpp
index ff24613..dacc04a 100644
--- a/oop2eindopdr/DownloadManager.cpp
+++ b/oop2eindopdr/DownloadManager.cpp
@@ -1,3 +1,4 @@
+#include <iostream>
#include <fstream>
#include <cpr/cpr.h>
@@ -15,7 +16,11 @@ DownloadManager::~DownloadManager() {
std::fstream* DownloadManager::open_file(std::string filename) {
while (this->file_queue.size() > this->max_files);
- std::fstream* out = new std::fstream(filename);
+ std::fstream* out = nullptr;
+ do {
+ delete out;
+ out = new std::fstream(filename, std::ios::out | std::ios::binary);
+ } while (!out->is_open());
this->file_queue.push_back(out);
return out;
}
@@ -28,9 +33,12 @@ void DownloadManager::close_file(std::fstream* file_ptr) {
std::thread* DownloadManager::wget(std::string url, std::string filename) {
std::thread* download = new std::thread([url, filename, this] {
- cpr::Response res = cpr::Get(cpr::Url{url});
+ cpr::Response res;
+ do res = cpr::Get(cpr::Url{url});
+ while (res.status_code != 200);
+
std::fstream* file = this->open_file(filename);
- *file << res.text;
+ file->write(res.text.data(), res.downloaded_bytes); // can't use << for binary data
this->close_file(file);
});
download_queue.push_back(download);
diff --git a/oop2eindopdr/PokemonCard.cpp b/oop2eindopdr/PokemonCard.cpp
index c7e4ea3..eb6a6e5 100644
--- a/oop2eindopdr/PokemonCard.cpp
+++ b/oop2eindopdr/PokemonCard.cpp
@@ -31,7 +31,7 @@ PokemonCard::PokemonCard(Pokedex* pokedex) {
}
PokemonCard::~PokemonCard() {
-
+ if (this->image_download_thread != nullptr) delete this->image_download_thread;
}
void PokemonCard::fetch_market_value() {
@@ -62,8 +62,11 @@ void PokemonCard::verify_files() {
}
void PokemonCard::download_files() {
- std::thread* card_normal_dl = this->pokedex->download_manager->wget(this->url_card_normal, prefix_cache_path("card.png"));
- std::thread* card_hires_dl = this->pokedex->download_manager->wget(this->url_card_hires, prefix_cache_path("card_hires.png"));
+ const std::string card_normal_path = this->pokedex->cache->prefix_cache_path(prefix_cache_path("card.png").c_str());
+ const std::string card_hires_path = this->pokedex->cache->prefix_cache_path(prefix_cache_path("card_hires.png").c_str());
+
+ std::thread* card_normal_dl = this->pokedex->download_manager->wget(this->url_card_normal, card_normal_path);
+ std::thread* card_hires_dl = this->pokedex->download_manager->wget(this->url_card_hires, card_hires_path);
this->image_download_thread = new std::thread([card_hires_dl, card_normal_dl, this] {
card_normal_dl->join();