aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Fourchan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Fourchan.cpp')
-rw-r--r--src/plugins/Fourchan.cpp89
1 files changed, 88 insertions, 1 deletions
diff --git a/src/plugins/Fourchan.cpp b/src/plugins/Fourchan.cpp
index 212e197..d8c80b0 100644
--- a/src/plugins/Fourchan.cpp
+++ b/src/plugins/Fourchan.cpp
@@ -11,6 +11,37 @@ static const std::string fourchan_url = "https://a.4cdn.org/";
static const std::string fourchan_image_url = "https://i.4cdn.org/";
namespace QuickMedia {
+ Fourchan::Fourchan() : ImageBoard("4chan") {
+ thread_list_update_thread = std::thread([this]() {
+ BodyItems new_thread_list_items;
+ while(running) {
+ new_thread_list_items.clear();
+ auto start_time = std::chrono::steady_clock::now();
+
+ std::string board_url = get_board_url();
+ if(!board_url.empty()) {
+ PluginResult plugin_result = get_threads_internal(board_url, new_thread_list_items);
+ if(plugin_result == PluginResult::OK)
+ set_board_thread_list(std::move(new_thread_list_items));
+ }
+
+ auto time_passed = std::chrono::steady_clock::now() - start_time;
+ if(time_passed < std::chrono::seconds(15)) {
+ auto time_to_sleep = std::chrono::seconds(15) - time_passed;
+ std::unique_lock<std::mutex> lock(thread_list_cache_mutex);
+ thread_list_update_cv.wait_for(lock, time_to_sleep);
+ }
+ }
+ });
+ }
+
+ Fourchan::~Fourchan() {
+ running = false;
+ std::unique_lock<std::mutex> lock(thread_list_cache_mutex);
+ thread_list_update_cv.notify_one();
+ thread_list_update_thread.join();
+ }
+
PluginResult Fourchan::get_front_page(BodyItems &result_items) {
std::string server_response;
if(download_to_string(fourchan_url + "boards.json", server_response, {}, use_tor) != DownloadResult::OK)
@@ -156,7 +187,7 @@ namespace QuickMedia {
tidyRelease(doc);
}
- PluginResult Fourchan::get_threads(const std::string &url, BodyItems &result_items) {
+ PluginResult Fourchan::get_threads_internal(const std::string &url, BodyItems &result_items) {
std::string server_response;
if(download_to_string(fourchan_url + url + "/catalog.json", server_response, {}, use_tor) != DownloadResult::OK)
return PluginResult::NET_ERR;
@@ -284,6 +315,62 @@ namespace QuickMedia {
return PluginResult::OK;
}
+ void Fourchan::set_board_url(const std::string &new_url) {
+ {
+ std::lock_guard<std::mutex> lock(board_url_mutex);
+ if(current_board_url == new_url)
+ return;
+ current_board_url = new_url;
+ }
+
+ std::lock_guard<std::mutex> thread_list_lock(thread_list_cache_mutex);
+ thread_list_update_cv.notify_one();
+ thread_list_cached = false;
+ }
+
+ std::string Fourchan::get_board_url() {
+ std::lock_guard<std::mutex> lock(board_url_mutex);
+ return current_board_url;
+ }
+
+ void Fourchan::set_board_thread_list(BodyItems body_items) {
+ {
+ std::lock_guard<std::mutex> lock(board_list_mutex);
+ cached_thread_list_items.clear();
+ for(auto &body_item : body_items) {
+ cached_thread_list_items.push_back(std::make_unique<BodyItem>(*body_item));
+ }
+ }
+
+ std::unique_lock<std::mutex> thread_list_cache_lock(thread_list_cache_mutex);
+ if(!thread_list_cached) {
+ thread_list_cached = true;
+ thread_list_cached_cv.notify_one();
+ }
+ }
+
+ BodyItems Fourchan::get_board_thread_list() {
+ std::lock_guard<std::mutex> lock(board_list_mutex);
+ BodyItems body_items;
+ for(auto &cached_body_item : cached_thread_list_items) {
+ body_items.push_back(std::make_unique<BodyItem>(*cached_body_item));
+ }
+ return body_items;
+ }
+
+ PluginResult Fourchan::get_threads(const std::string &url, BodyItems &result_items) {
+ set_board_url(url);
+
+ std::unique_lock<std::mutex> lock(thread_list_cache_mutex);
+ if(!thread_list_cached) {
+ if(thread_list_cached_cv.wait_for(lock, std::chrono::seconds(10)) == std::cv_status::timeout)
+ return PluginResult::NET_ERR;
+ }
+
+ result_items = get_board_thread_list();
+ return PluginResult::OK;
+ }
+
PluginResult Fourchan::get_thread_comments(const std::string &list_url, const std::string &url, BodyItems &result_items) {
std::string server_response;
if(download_to_string(fourchan_url + list_url + "/thread/" + url + ".json", server_response, {}, use_tor) != DownloadResult::OK)