summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdwin van Leeuwen <edwinvanl@tuta.io>2022-09-10 11:08:46 +0100
committerEdwin van Leeuwen <edwinvanl@tuta.io>2022-09-10 11:08:46 +0100
commitcfe88a8b213ccaddc2915797344776ae69602161 (patch)
tree50853d0eb1208dc12fb1b154d95c4bdfee6b365d
parent6d0d40cc6901237b6908b85133cf24d40879563a (diff)
parent178b4316ba7f87f298777699c213603512e7fe9c (diff)
Merge branch 'release/1.1.1'v1.1.1
Bugfix release to support newest version of cpr
-rw-r--r--src/rttt/reddit.hpp77
-rw-r--r--src/rttt/rss.hpp15
-rw-r--r--src/rttt/twitter.hpp7
-rw-r--r--test/catch_login.cpp92
-rw-r--r--test/catch_rss.cpp8
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") {