From d783c17151a98466e304b1e5f33bfca0be885fd8 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Thu, 1 Dec 2016 08:49:01 -0500 Subject: Added a convenience overload to client::replyToTweet --- src/client.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/client.cpp') diff --git a/src/client.cpp b/src/client.cpp index e16e30b..ccfd9a3 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -376,6 +376,11 @@ namespace twitter { .perform()); } + tweet client::replyToTweet(std::string msg, const tweet& in_response_to, std::list media_ids) const + { + return replyToTweet(msg, in_response_to.getID(), media_ids); + } + long client::uploadMedia(std::string media_type, const char* data, long data_length) const try { curl::curl_form form; -- cgit 1.4.1 From 5014ad408ace1dda89e0e9852db4a001b605c0a2 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Fri, 23 Feb 2018 11:20:55 -0500 Subject: Added ability to get blocklist --- src/client.cpp | 34 +++++++++++++++++++++++++++++++++- src/client.h | 4 +++- 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'src/client.cpp') diff --git a/src/client.cpp b/src/client.cpp index ccfd9a3..c2ef06f 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -591,7 +591,39 @@ namespace twitter { { return getFollowers(getUser().getID()); } - + + std::set client::getBlocks() const + { + long long cursor = -1; + std::set result; + + while (cursor != 0) + { + std::stringstream urlstream; + urlstream << "https://api.twitter.com/1.1/blocks/ids.json?cursor="; + urlstream << cursor; + + std::string url = urlstream.str(); + std::string response_data = get(*_oauth_client, url).perform(); + + try + { + nlohmann::json rjs = nlohmann::json::parse(response_data); + + cursor = rjs["next_cursor"].get(); + result.insert(std::begin(rjs["ids"]), std::end(rjs["ids"])); + } catch (const std::invalid_argument& error) + { + std::throw_with_nested(invalid_response(response_data)); + } catch (const std::domain_error& error) + { + std::throw_with_nested(invalid_response(response_data)); + } + } + + return result; + } + void client::follow(user_id toFollow) const { std::stringstream datastrstream; diff --git a/src/client.h b/src/client.h index c920f82..9282321 100644 --- a/src/client.h +++ b/src/client.h @@ -38,7 +38,9 @@ namespace twitter { std::set getFollowers(user_id id) const; std::set getFollowers(const user& u) const; std::set getFollowers() const; - + + std::set getBlocks() const; + void follow(user_id toFollow) const; void follow(const user& toFollow) const; -- cgit 1.4.1 From 3e292e37a1313e22f13ef4b7f342c6002ea6a947 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Fri, 23 Feb 2018 11:21:10 -0500 Subject: Whitespace changes --- src/client.cpp | 220 ++++++++++++++++++++++++++++----------------------------- src/client.h | 30 ++++---- 2 files changed, 125 insertions(+), 125 deletions(-) (limited to 'src/client.cpp') diff --git a/src/client.cpp b/src/client.cpp index c2ef06f..6fea80a 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -17,13 +17,13 @@ void dump(const char *text, size_t i; size_t c; unsigned int width=80; - + fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n", text, (long)size, (long)size); - + for(i=0; i= 0x20 && ptr[i+c] < 0x80) ? ptr[i+c] : '.'; fputc(x, stream); } - + fputc('\n', stream); /* newline */ } } - + static int my_trace(CURL *handle, curl_infotype type, char *data, size_t size, @@ -49,13 +49,13 @@ int my_trace(CURL *handle, curl_infotype type, { const char *text; (void)handle; /* prevent compiler warning */ - + switch (type) { case CURLINFO_TEXT: fprintf(stderr, "== Info: %s", data); default: /* in case a new one is introduced to shock us */ return 0; - + case CURLINFO_HEADER_OUT: text = "=> Send header"; break; @@ -75,17 +75,17 @@ int my_trace(CURL *handle, curl_infotype type, text = "<= Recv SSL data"; break; } - + dump(text, stderr, (unsigned char *)data, size); return 0; } namespace twitter { - + class request { public: - + explicit request(std::string url) try : _ios(_output), _conn(_ios) { @@ -93,10 +93,10 @@ namespace twitter { } catch (const curl::curl_easy_exception& error) { error.print_traceback(); - + assert(false); } - + std::string perform() { try @@ -106,14 +106,14 @@ namespace twitter { { std::throw_with_nested(connection_error()); } - + int response_code = _conn.get_info().get(); std::string result = _output.str(); - + if (response_code / 100 != 2) { nlohmann::json response_json; - + try { response_json = nlohmann::json::parse(result); @@ -121,12 +121,12 @@ namespace twitter { { std::throw_with_nested(invalid_response(result)); } - + for (nlohmann::json& error : response_json["errors"]) { int error_code; std::string error_message; - + try { error_code = error["code"].get(); @@ -135,44 +135,44 @@ namespace twitter { { std::throw_with_nested(invalid_response(result)); } - + switch (error_code) { case 32: case 135: case 215: throw bad_auth(error_message); - + case 44: throw invalid_media(error_message); - + case 64: throw account_suspended(error_message); - + case 88: throw rate_limit_exceeded(error_message); - + case 89: throw bad_token(error_message); - + case 130: throw server_overloaded(error_message); - + case 131: throw server_error(error_message); - + case 185: throw update_limit_exceeded(error_message); - + case 186: throw bad_length(error_message); - + case 187: throw duplicate_status(error_message); - + case 226: throw suspected_spam(error_message); - + case 261: throw write_restricted(error_message); } @@ -194,27 +194,27 @@ namespace twitter { { throw server_timeout("HTTP 504 Gateway Timeout"); } - + throw unknown_error(response_code, result); } - + return result; } - + private: - + std::ostringstream _output; curl::curl_ios _ios; - + protected: - + curl::curl_easy _conn; }; - + class get : public request { public: - + get(const OAuth::Client& oauth_client, std::string url) try : request(url) { @@ -223,31 +223,31 @@ namespace twitter { { _headers.add(std::move(oauth_header)); } - + _conn.add(_headers.get()); } catch (const OAuth::ParseError& error) { std::cout << "Error generating OAuth header:" << std::endl; std::cout << error.what() << std::endl; std::cout << "This is likely due to a malformed URL." << std::endl; - + assert(false); } catch (const curl::curl_easy_exception& error) { error.print_traceback(); - + assert(false); } - + private: - + curl::curl_header _headers; }; - + class post : public request { public: - + post(const OAuth::Client& oauth_client, std::string url, std::string datastr) try : request(url) { @@ -256,7 +256,7 @@ namespace twitter { { _headers.add(std::move(oauth_header)); } - + _conn.add(_headers.get()); _conn.add(datastr.c_str()); } catch (const OAuth::ParseError& error) @@ -264,24 +264,24 @@ namespace twitter { std::cout << "Error generating OAuth header:" << std::endl; std::cout << error.what() << std::endl; std::cout << "This is likely due to a malformed URL." << std::endl; - + assert(false); } catch (const curl::curl_easy_exception& error) { error.print_traceback(); - + assert(false); } - + private: - + curl::curl_header _headers; }; - + class multipost : public request { public: - + multipost(const OAuth::Client& oauth_client, std::string url, const curl_httppost* fields) try : request(url) { @@ -290,7 +290,7 @@ namespace twitter { { _headers.add(std::move(oauth_header)); } - + _conn.add(_headers.get()); _conn.add(fields); } catch (const OAuth::ParseError& error) @@ -298,94 +298,94 @@ namespace twitter { std::cout << "Error generating OAuth header:" << std::endl; std::cout << error.what() << std::endl; std::cout << "This is likely due to a malformed URL." << std::endl; - + assert(false); } catch (const curl::curl_easy_exception& error) { error.print_traceback(); - + assert(false); } - + private: - + curl::curl_header _headers; }; - + client::client(const auth& _arg) { _oauth_consumer = make_unique( _arg.getConsumerKey(), _arg.getConsumerSecret()); - + _oauth_token = make_unique( _arg.getAccessKey(), _arg.getAccessSecret()); - + _oauth_client = make_unique( _oauth_consumer.get(), _oauth_token.get()); - + _current_user = make_unique( get(*_oauth_client, "https://api.twitter.com/1.1/account/verify_credentials.json") .perform()); } - + client::~client() = default; - + tweet client::updateStatus(std::string msg, std::list media_ids) const { std::stringstream datastrstream; datastrstream << "status=" << OAuth::PercentEncode(msg); - + if (!media_ids.empty()) { datastrstream << "&media_ids="; datastrstream << twitter::implode(std::begin(media_ids), std::end(media_ids), ","); } - + return tweet( post(*_oauth_client, "https://api.twitter.com/1.1/statuses/update.json", datastrstream.str()) .perform()); } - + tweet client::replyToTweet(std::string msg, tweet_id in_response_to, std::list media_ids) const { std::stringstream datastrstream; datastrstream << "status=" << OAuth::PercentEncode(msg); datastrstream << "&in_reply_to_status_id="; datastrstream << in_response_to; - + if (!media_ids.empty()) { datastrstream << "&media_ids="; datastrstream << twitter::implode(std::begin(media_ids), std::end(media_ids), ","); } - + return tweet( post(*_oauth_client, "https://api.twitter.com/1.1/statuses/update.json", datastrstream.str()) .perform()); } - + tweet client::replyToTweet(std::string msg, const tweet& in_response_to, std::list media_ids) const { return replyToTweet(msg, in_response_to.getID(), media_ids); } - + long client::uploadMedia(std::string media_type, const char* data, long data_length) const try { curl::curl_form form; std::string str_data_length = std::to_string(data_length); - + curl::curl_pair command_name(CURLFORM_COPYNAME, "command"); curl::curl_pair command_cont(CURLFORM_COPYCONTENTS, "INIT"); curl::curl_pair bytes_name(CURLFORM_COPYNAME, "total_bytes"); @@ -402,7 +402,7 @@ namespace twitter { curl::curl_pair category_cont(CURLFORM_COPYCONTENTS, "tweet_gif"); form.add(category_name, category_cont); } - + std::string init_response = multipost(*_oauth_client, "https://upload.twitter.com/1.1/media/upload.json", @@ -410,7 +410,7 @@ namespace twitter { .perform(); long media_id; - + try { nlohmann::json response_json = nlohmann::json::parse(init_response); @@ -434,21 +434,21 @@ namespace twitter { { assert(false); } - + multipost(*_oauth_client, "https://upload.twitter.com/1.1/media/upload.json", append_form_post).perform(); - + curl_formfree(append_form_post); - + curl::curl_form finalize_form; std::string str_media_id = std::to_string(media_id); - + curl::curl_pair command3_name(CURLFORM_COPYNAME, "command"); curl::curl_pair command3_cont(CURLFORM_COPYCONTENTS, "FINALIZE"); curl::curl_pair media_id_name(CURLFORM_COPYNAME, "media_id"); curl::curl_pair media_id_cont(CURLFORM_COPYCONTENTS, str_media_id); finalize_form.add(command3_name, command3_cont); finalize_form.add(media_id_name, media_id_cont); - + std::string finalize_response = multipost(*_oauth_client, "https://upload.twitter.com/1.1/media/upload.json", @@ -456,7 +456,7 @@ namespace twitter { .perform(); nlohmann::json finalize_json; - + try { finalize_json = nlohmann::json::parse(finalize_response); @@ -464,26 +464,26 @@ namespace twitter { { std::throw_with_nested(invalid_response(finalize_response)); } - + if (finalize_json.find("processing_info") != finalize_json.end()) { std::stringstream datastr; datastr << "https://upload.twitter.com/1.1/media/upload.json?command=STATUS&media_id=" << media_id; - + for (;;) { std::string status_response = get(*_oauth_client, datastr.str()).perform(); - + try { nlohmann::json status_json = nlohmann::json::parse(status_response); std::string state = status_json["processing_info"]["state"].get(); - + if (state == "succeeded") { break; } - + int ttw = status_json["processing_info"]["check_after_secs"].get(); std::this_thread::sleep_for(std::chrono::seconds(ttw)); } catch (const std::invalid_argument& error) @@ -495,20 +495,20 @@ namespace twitter { } } } - + return media_id; } catch (const curl::curl_exception& error) { error.print_traceback(); - + assert(false); } - + std::set client::getFriends(user_id id) const { long long cursor = -1; std::set result; - + while (cursor != 0) { std::stringstream urlstream; @@ -516,14 +516,14 @@ namespace twitter { urlstream << id; urlstream << "&cursor="; urlstream << cursor; - + std::string url = urlstream.str(); std::string response_data = get(*_oauth_client, url).perform(); - + try { nlohmann::json rjs = nlohmann::json::parse(response_data); - + cursor = rjs["next_cursor"].get(); result.insert(std::begin(rjs["ids"]), std::end(rjs["ids"])); } catch (const std::invalid_argument& error) @@ -534,25 +534,25 @@ namespace twitter { std::throw_with_nested(invalid_response(response_data)); } } - + return result; } - + std::set client::getFriends(const user& id) const { return getFriends(id.getID()); } - + std::set client::getFriends() const { return getFriends(getUser().getID()); } - + std::set client::getFollowers(user_id id) const { long long cursor = -1; std::set result; - + while (cursor != 0) { std::stringstream urlstream; @@ -560,14 +560,14 @@ namespace twitter { urlstream << id; urlstream << "&cursor="; urlstream << cursor; - + std::string url = urlstream.str(); std::string response_data = get(*_oauth_client, url).perform(); - + try { nlohmann::json rjs = nlohmann::json::parse(response_data); - + cursor = rjs["next_cursor"].get(); result.insert(std::begin(rjs["ids"]), std::end(rjs["ids"])); } catch (const std::invalid_argument& error) @@ -578,15 +578,15 @@ namespace twitter { std::throw_with_nested(invalid_response(response_data)); } } - + return result; } - + std::set client::getFollowers(const user& id) const { return getFollowers(id.getID()); } - + std::set client::getFollowers() const { return getFollowers(getUser().getID()); @@ -629,24 +629,24 @@ namespace twitter { std::stringstream datastrstream; datastrstream << "follow=true&user_id="; datastrstream << toFollow; - + post(*_oauth_client, "https://api.twitter.com/1.1/friendships/create.json", datastrstream.str()).perform(); } - + void client::follow(const user& toFollow) const { return follow(toFollow.getID()); } - + void client::unfollow(user_id toUnfollow) const { std::stringstream datastrstream; datastrstream << "user_id="; datastrstream << toUnfollow; - + post(*_oauth_client, "https://api.twitter.com/1.1/friendships/destroy.json", datastrstream.str()).perform(); } - + void client::unfollow(const user& toUnfollow) const { return unfollow(toUnfollow.getID()); @@ -656,7 +656,7 @@ namespace twitter { { return *_current_user; } - + const configuration& client::getConfiguration() const { if (!_configuration || (difftime(time(NULL), _last_configuration_update) > 60*60*24)) @@ -669,8 +669,8 @@ namespace twitter { _last_configuration_update = time(NULL); } - + return *_configuration; } - + }; diff --git a/src/client.h b/src/client.h index 9282321..1e1b1ab 100644 --- a/src/client.h +++ b/src/client.h @@ -18,23 +18,23 @@ namespace OAuth { }; namespace twitter { - + class client { public: - + client(const auth& _auth); ~client(); - + tweet updateStatus(std::string msg, std::list media_ids = {}) const; long uploadMedia(std::string media_type, const char* data, long data_length) const; - + tweet replyToTweet(std::string msg, tweet_id in_response_to, std::list media_ids = {}) const; tweet replyToTweet(std::string msg, const tweet& in_response_to, std::list media_ids = {}) const; - + std::set getFriends(user_id id) const; std::set getFriends(const user& u) const; std::set getFriends() const; - + std::set getFollowers(user_id id) const; std::set getFollowers(const user& u) const; std::set getFollowers() const; @@ -43,28 +43,28 @@ namespace twitter { void follow(user_id toFollow) const; void follow(const user& toFollow) const; - + void unfollow(user_id toUnfollow) const; void unfollow(const user& toUnfollow) const; - + const user& getUser() const; - + const configuration& getConfiguration() const; - + private: - + friend class stream; - + std::unique_ptr _oauth_consumer; std::unique_ptr _oauth_token; std::unique_ptr _oauth_client; - + std::unique_ptr _current_user; - + mutable std::unique_ptr _configuration; mutable time_t _last_configuration_update; }; - + }; #endif /* end of include guard: TWITTER_H_ABFF6A12 */ -- cgit 1.4.1