From 3ff1e0471512ec30418ef06b65759f763ec79767 Mon Sep 17 00:00:00 2001 From: tastytea Date: Sat, 18 Apr 2020 16:35:41 +0200 Subject: [PATCH] [WIP] Add Mastodon threads. --- README.adoc | 4 +- lib/cmake/FediPotatoConfig.cmake.in | 4 +- lib/include/account_mastodon.hpp | 8 +++- lib/include/fedipotato.hpp | 7 +++- lib/pkg-config/FediPotato.pc.in | 6 ++- lib/src/CMakeLists.txt | 12 ++++-- lib/src/account_mastodon.cpp | 63 +++++++++++++++++++++++++++-- 7 files changed, 90 insertions(+), 14 deletions(-) diff --git a/README.adoc b/README.adoc index a939fa3..11e5d6d 100644 --- a/README.adoc +++ b/README.adoc @@ -19,6 +19,7 @@ :uri-rpm-build: http://www.rpm.org :uri-clang-tidy: https://clang.llvm.org/extra/clang-tidy/ :uri-qt: https://doc.qt.io/qt-5/gettingstarted.html +:uri-boost: https://www.boost.org/ *{project}* is a client for link:{uri-wp-fediverse}[Fediverse] servers. // It currently supports link:{uri-wp-mastodon}[Mastodon] and @@ -76,8 +77,9 @@ * C\++ compiler with C++17 support (tested: link:{uri-gcc}[GCC] 7/8/9, link:{uri-clang}[clang] 6/7) * link:{uri-cmake}[CMake] (at least: 3.9) -* link:{uri-mastodonpp}[mastodonpp] (at least: 0.5) +* link:{uri-mastodonpp}[mastodonpp] (at least: 0.5.4) * link:{uri-nlohmann-json}[nlohmann-json] (tested: 3.6) +* link:{uri-boost}[Boost] (at least: 1.62) * link:{uri-qt}[Qt] (tested: 5.13) * Optional ** Library documentation: link:{uri-doxygen}[Doxygen] (tested: 1.8) diff --git a/lib/cmake/FediPotatoConfig.cmake.in b/lib/cmake/FediPotatoConfig.cmake.in index 7288dd3..f4ab4f8 100644 --- a/lib/cmake/FediPotatoConfig.cmake.in +++ b/lib/cmake/FediPotatoConfig.cmake.in @@ -1,8 +1,8 @@ include(CMakeFindDependencyMacro) -find_dependency(mastodonpp 0.5 REQUIRED CONFIG) +find_dependency(mastodonpp 0.5.4 REQUIRED CONFIG) find_dependency(Filesystem REQUIRED) find_dependency(nlohmann_json REQUIRED CONFIG) -find_package(Threads REQUIRED) +find_package(Boost 1.62.0 REQUIRED COMPONENTS chrono thread) include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") diff --git a/lib/include/account_mastodon.hpp b/lib/include/account_mastodon.hpp index 3e31afb..1d46824 100644 --- a/lib/include/account_mastodon.hpp +++ b/lib/include/account_mastodon.hpp @@ -19,9 +19,11 @@ #include "config.hpp" +#include #include #include +#include #include #include #include @@ -31,6 +33,7 @@ namespace FediPotato { using std::map; +using std::unique_ptr; using std::optional; using std::string; using std::string_view; @@ -136,11 +139,14 @@ public: private: Config _config; - map _streams; mastodonpp::Instance _instance; + map> _streams; private: static string get_stream_id(stream_type type, optional id); + + static void make_stream_thread(mastodonpp::Instance &instance, + stream_type type, optional id); }; } // namespace FediPotato diff --git a/lib/include/fedipotato.hpp b/lib/include/fedipotato.hpp index 1a80452..89a76bc 100644 --- a/lib/include/fedipotato.hpp +++ b/lib/include/fedipotato.hpp @@ -21,6 +21,7 @@ #include "config.hpp" #include "version.hpp" +#include #include #include @@ -53,7 +54,11 @@ public: explicit FediPotato(const string_view application_name) : _application_name{application_name} , _config{application_name, "general.json"} - {} + { + MastodonAPI test{account_mastodon("test")}; + test.start_stream(MastodonAPI::stream_type::home_tl, std::nullopt); + test.stop_stream(MastodonAPI::stream_type::home_tl, std::nullopt); + } //! Copy constructor FediPotato(const FediPotato &other) = default; diff --git a/lib/pkg-config/FediPotato.pc.in b/lib/pkg-config/FediPotato.pc.in index 006d466..67706b4 100644 --- a/lib/pkg-config/FediPotato.pc.in +++ b/lib/pkg-config/FediPotato.pc.in @@ -5,7 +5,9 @@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: ${name} Description: @PROJECT_DESCRIPTION@ +URL: @PROJECT_HOMEPAGE_URL@ Version: @PROJECT_VERSION@ -Cflags: -I${includedir} -Libs: -L${libdir} -l${name} Requires: mastodonpp +Cflags: -I${includedir} +Libs: -L${libdir} -l${name} -lboost_thread +Libs.private: -lboost_chrono diff --git a/lib/src/CMakeLists.txt b/lib/src/CMakeLists.txt index 4b79f5d..36388d1 100644 --- a/lib/src/CMakeLists.txt +++ b/lib/src/CMakeLists.txt @@ -1,9 +1,9 @@ include(GNUInstallDirs) -find_package(mastodonpp 0.5 REQUIRED CONFIG) +find_package(mastodonpp 0.5.4 REQUIRED CONFIG) find_package(Filesystem REQUIRED) find_package(nlohmann_json REQUIRED CONFIG) -find_package(Threads REQUIRED) +find_package(Boost 1.62.0 REQUIRED COMPONENTS chrono thread) add_library(${PROJECT_NAME}) @@ -17,8 +17,12 @@ set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${${PROJECT_NAME}_VERSION_MAJOR}) target_link_libraries(${PROJECT_NAME} - PRIVATE mastodonpp::mastodonpp Threads::Threads - PUBLIC std::filesystem nlohmann_json::nlohmann_json) + PUBLIC + std::filesystem + nlohmann_json::nlohmann_json + mastodonpp::mastodonpp + Boost::chrono + Boost::thread) install(TARGETS ${PROJECT_NAME} EXPORT "${PROJECT_NAME}Targets" diff --git a/lib/src/account_mastodon.cpp b/lib/src/account_mastodon.cpp index 306479c..e1ab314 100644 --- a/lib/src/account_mastodon.cpp +++ b/lib/src/account_mastodon.cpp @@ -17,12 +17,19 @@ #include "account_mastodon.hpp" #include "version.hpp" -#include -#include +#include +#include +#include +#include +#include + +#include // TODO: remove iostream. namespace FediPotato { +using boost::chrono::seconds; +using std::make_unique; using std::logic_error; using std::runtime_error; @@ -34,19 +41,36 @@ MastodonAPI::MastodonAPI(const string_view application_name, { _instance.set_useragent(((string(application_name) += " (FediPotato/") += version) += ')'); - _instance.set_proxy(globalconfig.get("proxy")); + try + { + _instance.set_proxy(globalconfig.get("proxy")); + } + catch (nlohmann::detail::type_error &) // Setting not found. + {} } void MastodonAPI::start_stream(const stream_type type, const optional id) { const string strid{get_stream_id(type, id)}; + auto t{make_unique(MastodonAPI::make_stream_thread, + _instance, type, id)}; + _streams.insert({strid, std::move(t)}); } void MastodonAPI::stop_stream(const stream_type type, const optional id) { const string strid{get_stream_id(type, id)}; + if (_streams.find(strid) != _streams.end()) + { + boost::thread &thread{*_streams[strid]}; + if (thread.joinable()) + { + thread.interrupt(); + thread.join(); + } + } } string MastodonAPI::get_stream_id(const stream_type type, @@ -97,4 +121,37 @@ string MastodonAPI::get_stream_id(const stream_type type, throw logic_error{"Unhandled stream type."}; } +void MastodonAPI::make_stream_thread(mastodonpp::Instance &instance, + stream_type type, optional id) +{ + mastodonpp::Connection connection{instance}; + try + { + // TODO: Limit to 40, initial sleep to 5s. + // TODO: Adjust sleeping time based on number of statuses. + // TODO: use type and id. + mastodonpp::endpoint_variant endpoint + {mastodonpp::API::v1::timelines_public}; + mastodonpp::parametermap params{{"limit", "1"}}; + while (true) + { + auto answer{connection.get(endpoint, params)}; + if (!answer.next().empty()) + { + params = answer.next(); + } + else + { + std::cout << " OHNO-OHNO-OHNO!\n"; + } + std::cout << answer.body.substr(0, 100) << "\n\n"; + boost::this_thread::sleep_for(seconds(10)); // Is interruptable. + } + } + catch(const boost::thread_interrupted &) + { + std::cout << "Thread interrupted.\n"; + } +} + } // namespace FediPotato