diff options
author | Edwin van Leeuwen <edwinvanl@tuta.io> | 2022-09-10 11:08:46 +0100 |
---|---|---|
committer | Edwin van Leeuwen <edwinvanl@tuta.io> | 2022-09-10 11:08:46 +0100 |
commit | cfe88a8b213ccaddc2915797344776ae69602161 (patch) | |
tree | 50853d0eb1208dc12fb1b154d95c4bdfee6b365d | |
parent | 6d0d40cc6901237b6908b85133cf24d40879563a (diff) | |
parent | 178b4316ba7f87f298777699c213603512e7fe9c (diff) |
Merge branch 'release/1.1.1'v1.1.1
Bugfix release to support newest version of cpr
-rw-r--r-- | src/rttt/reddit.hpp | 77 | ||||
-rw-r--r-- | src/rttt/rss.hpp | 15 | ||||
-rw-r--r-- | src/rttt/twitter.hpp | 7 | ||||
-rw-r--r-- | test/catch_login.cpp | 92 | ||||
-rw-r--r-- | test/catch_rss.cpp | 8 |
5 files changed, 133 insertions, 66 deletions
diff --git a/src/rttt/reddit.hpp b/src/rttt/reddit.hpp index df4150c..db06273 100644 --- a/src/rttt/reddit.hpp +++ b/src/rttt/reddit.hpp @@ -12,8 +12,8 @@ #include "ftxui/component/component.hpp" #include "rttt.hpp" -#include "rttt/functional.hpp" #include "rttt/config.hpp" +#include "rttt/functional.hpp" #include "rttt/future.hpp" #include "rttt/logger.hpp" #include "rttt/request.hpp" @@ -27,7 +27,7 @@ namespace rttt { namespace reddit { struct credentials { - cpr::Header header = cpr::Header{{"User-Agent", "rttt/1.1.0"}}; + cpr::Header header = cpr::Header{{"User-Agent", "rttt/1.1.1"}}; std::string client_id; std::string device_id; std::string refresh_token; @@ -62,7 +62,13 @@ inline std::optional<std::string> try_to_extract_code(const std::string &line) { state retrieve_access_token(state &&state) { auto &credentials = state.credentials; - auto auth = cpr::Authentication{credentials.client_id, ""}; + auto auth = cpr::Authentication { + credentials.client_id, "" +#if (CPR_VERSION_MAJOR > 1 || CPR_VERSION_MINOR > 8) + , + cpr::AuthMode::BASIC +#endif + }; auto uri = cpr::Url{"https://www.reddit.com/api/v1/access_token"}; credentials.access_token = ""; @@ -162,7 +168,13 @@ state retrieve_refresh_token(state &&state) { {"redirect_uri", redirect_uri}}; // TODO: Consider moving auth to credentials - auto auth = cpr::Authentication{credentials.client_id, ""}; + auto auth = cpr::Authentication { + credentials.client_id, "" +#if (CPR_VERSION_MAJOR > 1 || CPR_VERSION_MINOR > 8) + , + cpr::AuthMode::BASIC +#endif + }; auto uri = cpr::Url{"https://www.reddit.com/api/v1/access_token"}; return cpr::Post(uri, payload, credentials.header, auth, @@ -423,34 +435,35 @@ bool catch_ui_event(state &state, ui::state &ui_state, const rttt::Path &path, event == ftxui::Event::Character('z')) { return rttt::try_vote(item) | try_with([&event](auto vote) { - if (event == ftxui::Event::Character('a')) { - if (vote != 1) - return "1"; - } else if (event == ftxui::Event::Character('z')) { - if (vote != -1) - return "-1"; - } - return "0"; - }) | - try_with([&item, &state, &path](const auto &direction) { - auto maybe_fullname = rttt::try_fullname(item); - logger::log_ifnot(maybe_fullname); - auto parameters = cpr::Parameters{{"dir", direction}, - {"id", maybe_fullname.value()}}; - state.wait_list.push_back( - {cpr::PostAsync(cpr::Url{"https://oauth.reddit.com/api/vote"}, - state.credentials.header, - cpr::Bearer{state.credentials.access_token}, - parameters, cpr::Timeout{5000}), - [name = path.name]([[maybe_unused]] cpr::Response &&req) { - // FIXME: Handle errors - if (req.status_code == 200) { - reddit::items.mark_for_update(name); - reddit::items.mark_active(name); - } - }}); - return true; - }) | with([](auto maybe) { return maybe.value_or(false); }); + if (event == ftxui::Event::Character('a')) { + if (vote != 1) + return "1"; + } else if (event == ftxui::Event::Character('z')) { + if (vote != -1) + return "-1"; + } + return "0"; + }) | + try_with([&item, &state, &path](const auto &direction) { + auto maybe_fullname = rttt::try_fullname(item); + logger::log_ifnot(maybe_fullname); + auto parameters = cpr::Parameters{{"dir", direction}, + {"id", maybe_fullname.value()}}; + state.wait_list.push_back( + {cpr::PostAsync(cpr::Url{"https://oauth.reddit.com/api/vote"}, + state.credentials.header, + cpr::Bearer{state.credentials.access_token}, + parameters, cpr::Timeout{5000}), + [name = path.name]([[maybe_unused]] cpr::Response &&req) { + // FIXME: Handle errors + if (req.status_code == 200) { + reddit::items.mark_for_update(name); + reddit::items.mark_active(name); + } + }}); + return true; + }) | + with([](auto maybe) { return maybe.value_or(false); }); } if (event == ftxui::Event::Character('u')) { state.credentials.refresh_token = ""; diff --git a/src/rttt/rss.hpp b/src/rttt/rss.hpp index 5e9e17b..8e2fb13 100644 --- a/src/rttt/rss.hpp +++ b/src/rttt/rss.hpp @@ -55,7 +55,7 @@ inline std::map<std::string, std::string> parse_opml(pugi::xml_node doc) { inline std::tm parse_pubdate(std::string time_string) { // parse_pubdate("Wed, 24 Nov 2021 13:46:56 +0000"); std::tm time = {}; - std::regex e("(\\d+) ([A-z]{3}) (\\d{4}) (\\d+):(\\d+)"); + std::regex e("(\\d+) ([A-z]{3}) (\\d{4})"); std::smatch sm; std::regex_search(time_string, sm, e); if (sm.size() > 1) { @@ -88,8 +88,14 @@ inline std::tm parse_pubdate(std::string time_string) { logger::log_ifnot(false); } time.tm_year = std::stoi(sm[3]) - 1900; - time.tm_hour = std::stoi(sm[4]); - time.tm_min = std::stoi(sm[5]); + } + + // Try matching hour and minute + e = std::regex("\\d+ [A-z]{3} \\d{4} (\\d+):(\\d+)"); + std::regex_search(time_string, sm, e); + if (sm.size() > 1) { + time.tm_hour = std::stoi(sm[1]); + time.tm_min = std::stoi(sm[2]); } return time; } @@ -166,6 +172,9 @@ rss::story_set parse_rss(const pugi::xml_document &doc, if (entry.child("pubDate")) { auto time_tm = parse_pubdate(entry.child("pubDate").text().get()); story.time = std::mktime(&time_tm); + } else if (entry.child("lastBuildDate")) { + auto time_tm = parse_pubdate(entry.child("lastBuildDate").text().get()); + story.time = std::mktime(&time_tm); } else if (entry.child("dc:date")) { auto time_tm = parse_time(entry.child("dc:date").text().get()); story.time = std::mktime(&time_tm); diff --git a/src/rttt/twitter.hpp b/src/rttt/twitter.hpp index d6c5fbf..43b870b 100644 --- a/src/rttt/twitter.hpp +++ b/src/rttt/twitter.hpp @@ -45,7 +45,12 @@ struct state { void retrieve_bearer_token(state &state, const std::string &api_key, const std::string &api_secret_key) { auto payload = cpr::Payload{{"grant_type", "client_credentials"}}; - auto auth = cpr::Authentication{api_key, api_secret_key}; + auto auth = cpr::Authentication{api_key, api_secret_key +#if (CPR_VERSION_MAJOR > 1 || CPR_VERSION_MINOR > 8) + , + cpr::AuthMode::BASIC +#endif + }; state.priority_wait_list.push_back( {cpr::PostAsync(cpr::Url{"https://api.twitter.com/oauth2/token"}, payload, diff --git a/test/catch_login.cpp b/test/catch_login.cpp index 43e5308..55d9f76 100644 --- a/test/catch_login.cpp +++ b/test/catch_login.cpp @@ -6,9 +6,9 @@ #include "cpr/cpr.h" #include "nlohmann/json.hpp" +#include "rttt.hpp" #include "rttt/config.hpp" #include "rttt/reddit.hpp" -#include "rttt.hpp" #include "rttt/socket.hpp" #include "login_credentials.hpp" @@ -31,8 +31,13 @@ inline std::string getAccessToken(const Credentials &credentials) { auto payload = cpr::Payload{{"grant_type", "password"}, {"username", credentials.username}, {"password", credentials.password}}; - auto auth = - cpr::Authentication{credentials.client_id, credentials.secret_token}; + auto auth = cpr::Authentication { + credentials.client_id, credentials.secret_token +#if (CPR_VERSION_MAJOR > 1 || CPR_VERSION_MINOR > 8) + , + cpr::AuthMode::BASIC +#endif + }; auto header = cpr::Header{{"User-Agent", "rttt/0.5.0"}}; auto uri = cpr::Url{"https://www.reddit.com/api/v1/access_token"}; auto r = cpr::Post(uri, payload, header, auth); @@ -167,7 +172,13 @@ SCENARIO("Load reddit using refresh token", "[.]") { // Note that for later refresh we need different payload: // grant_type=refresh_token&refresh_token=TOKEN - auto auth = cpr::Authentication{client_id, ""}; + auto auth = cpr::Authentication { + client_id, "" +#if (CPR_VERSION_MAJOR > 1 || CPR_VERSION_MINOR > 8) + , + cpr::AuthMode::BASIC +#endif + }; auto uri = cpr::Url{"https://www.reddit.com/api/v1/access_token"}; auto r = cpr::Post(uri, payload, header, auth); @@ -216,8 +227,15 @@ SCENARIO("Retrieve access token for the application only (not logged in)", auto header = cpr::Header{{"User-Agent", "rttt/0.5.0"}}; // auto auth = - // cpr::Authentication{credentials.client_id, credentials.secret_token}; - auto auth = cpr::Authentication{client_id, ""}; + // cpr::Authentication{credentials.client_id, credentials.secret_token, + // cpr::AuthMode::BASIC}; + auto auth = cpr::Authentication { + client_id, "" +#if (CPR_VERSION_MAJOR > 1 || CPR_VERSION_MINOR > 8) + , + cpr::AuthMode::BASIC +#endif + }; auto uri = cpr::Url{"https://www.reddit.com/api/v1/access_token"}; auto r = cpr::Post(uri, payload, header, auth); @@ -283,7 +301,7 @@ SCENARIO("Load reddit using config file", "[.]") { state_reddit.credentials.header, cpr::Bearer{state_reddit.credentials.access_token}); - //std::cout << nlohmann::json::parse(r.text).dump(2) << std::endl; + // std::cout << nlohmann::json::parse(r.text).dump(2) << std::endl; /*auto parameters = cpr::Parameters{{"dir", "0"}, {"id", "t1_i0h1fsv"}}; r = cpr::Post(cpr::Url{"https://oauth.reddit.com/api/vote"}, @@ -295,54 +313,68 @@ SCENARIO("Load reddit using config file", "[.]") { } /** -* twitter - * - * Get bearer token: https://developer.twitter.com/en/docs/authentication/oauth-2-0/bearer-tokens - * User authentication: https://developer.twitter.com/en/docs/authentication/oauth-2-0/user-access-token - * - */ + * twitter + * + * Get bearer token: + * https://developer.twitter.com/en/docs/authentication/oauth-2-0/bearer-tokens + * User authentication: + * https://developer.twitter.com/en/docs/authentication/oauth-2-0/user-access-token + * + */ SCENARIO("Get bearer token", "[.]") { TwitterCredentials crs; auto payload = cpr::Payload{{"grant_type", "client_credentials"}}; - auto auth = - cpr::Authentication{crs.api_key, crs.api_secret_key}; + auto auth = cpr::Authentication { + crs.api_key, crs.api_secret_key +#if (CPR_VERSION_MAJOR > 1 || CPR_VERSION_MINOR > 8) + , + cpr::AuthMode::BASIC +#endif + }; - auto r = cpr::Post(cpr::Url{"https://api.twitter.com/oauth2/token"}, payload, auth); + auto r = cpr::Post(cpr::Url{"https://api.twitter.com/oauth2/token"}, payload, + auth); std::cout << r.text << std::endl; } - SCENARIO("Load tweets from a user", "[.]") { TwitterCredentials crs; // Get tweets from a user - auto r = cpr::Get(cpr::Url{"https://api.twitter.com/2/users/by/username/awesomekling"}, - cpr::Bearer{crs.bearer}); + auto r = cpr::Get( + cpr::Url{"https://api.twitter.com/2/users/by/username/awesomekling"}, + cpr::Bearer{crs.bearer}); auto j = nlohmann::json::parse(r.text); std::cout << r.text << std::endl; std::cout << j["data"]["id"] << std::endl; - auto parameters = cpr::Parameters{{"exclude", "replies,retweets"}, - {"tweet.fields", "conversation_id,referenced_tweets,reply_settings,public_metrics"}, - {"max_results", "100"} - }; - r = cpr::Get(cpr::Url{"https://api.twitter.com/2/users/" + j["data"]["id"].get<std::string>() + "/tweets"}, - cpr::Bearer{crs.bearer}, parameters); + auto parameters = cpr::Parameters{ + {"exclude", "replies,retweets"}, + {"tweet.fields", + "conversation_id,referenced_tweets,reply_settings,public_metrics"}, + {"max_results", "100"}}; + r = cpr::Get(cpr::Url{"https://api.twitter.com/2/users/" + + j["data"]["id"].get<std::string>() + "/tweets"}, + cpr::Bearer{crs.bearer}, parameters); std::cout << r.text << std::endl; // Get replies to a specific tweet std::cout << std::endl; - parameters = cpr::Parameters{{"tweet.fields", "conversation_id,referenced_tweets,reply_settings,public_metrics"}}; + parameters = cpr::Parameters{ + {"tweet.fields", + "conversation_id,referenced_tweets,reply_settings,public_metrics"}}; r = cpr::Get(cpr::Url{"https://api.twitter.com/2/tweets/1512794180568985601"}, - cpr::Bearer{crs.bearer}, parameters); + cpr::Bearer{crs.bearer}, parameters); std::cout << r.text << std::endl; std::cout << std::endl; std::cout << "Using search " << std::endl; - parameters = cpr::Parameters{{"query", "conversation_id:1515239984185450497"}, - {"tweet.fields", "author_id,in_reply_to_user_id,referenced_tweets,reply_settings,public_metrics"}}; + parameters = cpr::Parameters{ + {"query", "conversation_id:1515239984185450497"}, + {"tweet.fields", "author_id,in_reply_to_user_id,referenced_tweets,reply_" + "settings,public_metrics"}}; r = cpr::Get(cpr::Url{"https://api.twitter.com/2/tweets/search/recent"}, - cpr::Bearer{crs.bearer}, parameters); + cpr::Bearer{crs.bearer}, parameters); std::cout << r.text << std::endl; } diff --git a/test/catch_rss.cpp b/test/catch_rss.cpp index 7797ba4..718eb5e 100644 --- a/test/catch_rss.cpp +++ b/test/catch_rss.cpp @@ -104,6 +104,14 @@ SCENARIO("We can parse time string") { REQUIRE(time_tm.tm_hour == 13); REQUIRE(time_tm.tm_min == 46); REQUIRE(time_tm.tm_sec == 0); + + time_tm = rttt::rss::parse_pubdate("22 Aug 2022"); + REQUIRE(time_tm.tm_year == 2022 - 1900); + REQUIRE(time_tm.tm_mon == 7); + REQUIRE(time_tm.tm_mday == 22); + REQUIRE(time_tm.tm_hour == 0); + REQUIRE(time_tm.tm_min == 0); + REQUIRE(time_tm.tm_sec == 0); } SCENARIO("We can parse atom correctly") { |