diff options
| -rw-r--r-- | .gitmodules | 9 | ||||
| -rw-r--r-- | CMakeLists.txt | 15 | ||||
| -rw-r--r-- | src/auth.cpp | 45 | ||||
| -rw-r--r-- | src/auth.h | 29 | ||||
| -rw-r--r-- | src/client.cpp | 124 | ||||
| -rw-r--r-- | src/client.h | 29 | ||||
| -rw-r--r-- | src/tweet.cpp | 15 | ||||
| -rw-r--r-- | src/tweet.h | 17 | ||||
| -rw-r--r-- | src/twitter.h | 36 | ||||
| m--------- | vendor/curlcpp | 0 | ||||
| m--------- | vendor/json | 0 | ||||
| m--------- | vendor/liboauthcpp | 0 |
12 files changed, 319 insertions, 0 deletions
| diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6d8effa --- /dev/null +++ b/.gitmodules | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [submodule "vendor/liboauthcpp"] | ||
| 2 | path = vendor/liboauthcpp | ||
| 3 | url = https://github.com/sirikata/liboauthcpp | ||
| 4 | [submodule "vendor/json"] | ||
| 5 | path = vendor/json | ||
| 6 | url = https://github.com/nlohmann/json | ||
| 7 | [submodule "vendor/curlcpp"] | ||
| 8 | path = vendor/curlcpp | ||
| 9 | url = https://github.com/JosephP91/curlcpp | ||
| diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7507e25 --- /dev/null +++ b/CMakeLists.txt | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | cmake_minimum_required (VERSION 3.1) | ||
| 2 | project (twitter++) | ||
| 3 | |||
| 4 | include_directories(vendor/json/src) | ||
| 5 | |||
| 6 | add_subdirectory(vendor/liboauthcpp/build EXCLUDE_FROM_ALL) | ||
| 7 | include_directories(vendor/liboauthcpp/include) | ||
| 8 | |||
| 9 | add_subdirectory(vendor/curlcpp) | ||
| 10 | include_directories(${CURLCPP_SOURCE_DIR}/include) | ||
| 11 | |||
| 12 | add_library(twitter++ src/client.cpp src/auth.cpp src/tweet.cpp) | ||
| 13 | set_property(TARGET twitter++ PROPERTY CXX_STANDARD 11) | ||
| 14 | set_property(TARGET twitter++ PROPERTY CXX_STANDARD_REQUIRED ON) | ||
| 15 | target_link_libraries(twitter++ oauthcpp curlcpp) | ||
| diff --git a/src/auth.cpp b/src/auth.cpp new file mode 100644 index 0000000..325c521 --- /dev/null +++ b/src/auth.cpp | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | #include "twitter.h" | ||
| 2 | |||
| 3 | namespace twitter { | ||
| 4 | |||
| 5 | void auth::setConsumerKey(std::string _arg) | ||
| 6 | { | ||
| 7 | _consumer_key = _arg; | ||
| 8 | } | ||
| 9 | |||
| 10 | void auth::setConsumerSecret(std::string _arg) | ||
| 11 | { | ||
| 12 | _consumer_secret = _arg; | ||
| 13 | } | ||
| 14 | |||
| 15 | void auth::setAccessKey(std::string _arg) | ||
| 16 | { | ||
| 17 | _access_key = _arg; | ||
| 18 | } | ||
| 19 | |||
| 20 | void auth::setAccessSecret(std::string _arg) | ||
| 21 | { | ||
| 22 | _access_secret = _arg; | ||
| 23 | } | ||
| 24 | |||
| 25 | std::string auth::getConsumerKey() const | ||
| 26 | { | ||
| 27 | return _consumer_key; | ||
| 28 | } | ||
| 29 | |||
| 30 | std::string auth::getConsumerSecret() const | ||
| 31 | { | ||
| 32 | return _consumer_secret; | ||
| 33 | } | ||
| 34 | |||
| 35 | std::string auth::getAccessKey() const | ||
| 36 | { | ||
| 37 | return _access_key; | ||
| 38 | } | ||
| 39 | |||
| 40 | std::string auth::getAccessSecret() const | ||
| 41 | { | ||
| 42 | return _access_secret; | ||
| 43 | } | ||
| 44 | |||
| 45 | }; | ||
| diff --git a/src/auth.h b/src/auth.h new file mode 100644 index 0000000..ef07e81 --- /dev/null +++ b/src/auth.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | #ifndef AUTH_H_48EF85FD | ||
| 2 | #define AUTH_H_48EF85FD | ||
| 3 | |||
| 4 | #include <string> | ||
| 5 | |||
| 6 | namespace twitter { | ||
| 7 | |||
| 8 | class auth { | ||
| 9 | public: | ||
| 10 | void setConsumerKey(std::string _arg); | ||
| 11 | void setConsumerSecret(std::string _arg); | ||
| 12 | void setAccessKey(std::string _arg); | ||
| 13 | void setAccessSecret(std::string _arg); | ||
| 14 | |||
| 15 | std::string getConsumerKey() const; | ||
| 16 | std::string getConsumerSecret() const; | ||
| 17 | std::string getAccessKey() const; | ||
| 18 | std::string getAccessSecret() const; | ||
| 19 | |||
| 20 | private: | ||
| 21 | std::string _consumer_key; | ||
| 22 | std::string _consumer_secret; | ||
| 23 | std::string _access_key; | ||
| 24 | std::string _access_secret; | ||
| 25 | }; | ||
| 26 | |||
| 27 | }; | ||
| 28 | |||
| 29 | #endif /* end of include guard: AUTH_H_48EF85FD */ | ||
| diff --git a/src/client.cpp b/src/client.cpp new file mode 100644 index 0000000..b71ff70 --- /dev/null +++ b/src/client.cpp | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | #include "client.h" | ||
| 2 | #include <curl_easy.h> | ||
| 3 | #include <curl_header.h> | ||
| 4 | #include <sstream> | ||
| 5 | #include <set> | ||
| 6 | #include <algorithm> | ||
| 7 | #include <liboauthcpp/liboauthcpp.h> | ||
| 8 | |||
| 9 | namespace twitter { | ||
| 10 | |||
| 11 | client::client(const auth& _arg) | ||
| 12 | { | ||
| 13 | _oauth_consumer = new OAuth::Consumer(_arg.getConsumerKey(), _arg.getConsumerSecret()); | ||
| 14 | _oauth_token = new OAuth::Token(_arg.getAccessKey(), _arg.getAccessSecret()); | ||
| 15 | _oauth_client = new OAuth::Client(_oauth_consumer, _oauth_token); | ||
| 16 | } | ||
| 17 | |||
| 18 | client::~client() | ||
| 19 | { | ||
| 20 | delete _oauth_client; | ||
| 21 | delete _oauth_token; | ||
| 22 | delete _oauth_consumer; | ||
| 23 | } | ||
| 24 | |||
| 25 | response client::updateStatus(std::string msg, tweet& result) | ||
| 26 | { | ||
| 27 | std::ostringstream output; | ||
| 28 | curl::curl_ios<std::ostringstream> ios(output); | ||
| 29 | curl::curl_easy conn(ios); | ||
| 30 | |||
| 31 | std::stringstream datastrstream; | ||
| 32 | datastrstream << "status=" << OAuth::PercentEncode(msg); | ||
| 33 | |||
| 34 | std::string datastr = datastrstream.str(); | ||
| 35 | std::string url = "https://api.twitter.com/1.1/statuses/update.json"; | ||
| 36 | |||
| 37 | curl::curl_header headers; | ||
| 38 | std::string oauth_header = _oauth_client->getFormattedHttpHeader(OAuth::Http::Post, url, datastr); | ||
| 39 | if (!oauth_header.empty()) | ||
| 40 | { | ||
| 41 | headers.add(oauth_header); | ||
| 42 | } | ||
| 43 | |||
| 44 | try { | ||
| 45 | conn.add<CURLOPT_URL>(url.c_str()); | ||
| 46 | conn.add<CURLOPT_COPYPOSTFIELDS>(datastr.c_str()); | ||
| 47 | conn.add<CURLOPT_POST>(1); | ||
| 48 | conn.add<CURLOPT_HTTPHEADER>(headers.get()); | ||
| 49 | |||
| 50 | conn.perform(); | ||
| 51 | } catch (curl::curl_easy_exception error) | ||
| 52 | { | ||
| 53 | error.print_traceback(); | ||
| 54 | |||
| 55 | return response::curl_error; | ||
| 56 | } | ||
| 57 | |||
| 58 | long response_code = conn.get_info<CURLINFO_RESPONSE_CODE>().get(); | ||
| 59 | json response_data = json::parse(output.str()); | ||
| 60 | if (response_code == 200) | ||
| 61 | { | ||
| 62 | result = tweet(response_data); | ||
| 63 | return response::ok; | ||
| 64 | } | ||
| 65 | |||
| 66 | std::set<int> error_codes; | ||
| 67 | if (response_data.find("errors") != response_data.end()) | ||
| 68 | { | ||
| 69 | std::transform(std::begin(response_data["errors"]), std::end(response_data["errors"]), std::inserter(error_codes, std::begin(error_codes)), [] (const json& error) { | ||
| 70 | return error["code"].get<int>(); | ||
| 71 | }); | ||
| 72 | } | ||
| 73 | |||
| 74 | if (error_codes.count(32) == 1 || error_codes.count(135) == 1 || error_codes.count(215) == 1) | ||
| 75 | { | ||
| 76 | return response::bad_auth; | ||
| 77 | } else if (error_codes.count(64) == 1) | ||
| 78 | { | ||
| 79 | return response::suspended; | ||
| 80 | } else if (error_codes.count(88) == 1 || error_codes.count(185) == 1) | ||
| 81 | { | ||
| 82 | return response::limited; | ||
| 83 | } else if (error_codes.count(89) == 1) | ||
| 84 | { | ||
| 85 | return response::bad_token; | ||
| 86 | } else if (error_codes.count(130) == 1) | ||
| 87 | { | ||
| 88 | return response::server_overloaded; | ||
| 89 | } else if (error_codes.count(131) == 1) | ||
| 90 | { | ||
| 91 | return response::server_error; | ||
| 92 | } else if (error_codes.count(186) == 1) | ||
| 93 | { | ||
| 94 | return response::bad_length; | ||
| 95 | } else if (error_codes.count(187) == 1) | ||
| 96 | { | ||
| 97 | return response::duplicate_status; | ||
| 98 | } else if (error_codes.count(226) == 1) | ||
| 99 | { | ||
| 100 | return response::suspected_spam; | ||
| 101 | } else if (error_codes.count(261) == 1) | ||
| 102 | { | ||
| 103 | return response::write_restricted; | ||
| 104 | } else if (response_code == 429) | ||
| 105 | { | ||
| 106 | return response::limited; | ||
| 107 | } else if (response_code == 500) | ||
| 108 | { | ||
| 109 | return response::server_error; | ||
| 110 | } else if (response_code == 502) | ||
| 111 | { | ||
| 112 | return response::server_unavailable; | ||
| 113 | } else if (response_code == 503) | ||
| 114 | { | ||
| 115 | return response::server_overloaded; | ||
| 116 | } else if (response_code == 504) | ||
| 117 | { | ||
| 118 | return response::server_timeout; | ||
| 119 | } else { | ||
| 120 | return response::unknown_error; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | }; | ||
| diff --git a/src/client.h b/src/client.h new file mode 100644 index 0000000..1ab5c70 --- /dev/null +++ b/src/client.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | #ifndef TWITTER_H_ABFF6A12 | ||
| 2 | #define TWITTER_H_ABFF6A12 | ||
| 3 | |||
| 4 | #include "twitter.h" | ||
| 5 | |||
| 6 | namespace OAuth { | ||
| 7 | class Consumer; | ||
| 8 | class Token; | ||
| 9 | class Client; | ||
| 10 | }; | ||
| 11 | |||
| 12 | namespace twitter { | ||
| 13 | |||
| 14 | class client { | ||
| 15 | public: | ||
| 16 | client(const auth& _auth); | ||
| 17 | ~client(); | ||
| 18 | |||
| 19 | response updateStatus(std::string msg, tweet& result); | ||
| 20 | |||
| 21 | private: | ||
| 22 | OAuth::Consumer* _oauth_consumer; | ||
| 23 | OAuth::Token* _oauth_token; | ||
| 24 | OAuth::Client* _oauth_client; | ||
| 25 | }; | ||
| 26 | |||
| 27 | }; | ||
| 28 | |||
| 29 | #endif /* end of include guard: TWITTER_H_ABFF6A12 */ | ||
| diff --git a/src/tweet.cpp b/src/tweet.cpp new file mode 100644 index 0000000..165187e --- /dev/null +++ b/src/tweet.cpp | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | #include "twitter.h" | ||
| 2 | |||
| 3 | namespace twitter { | ||
| 4 | |||
| 5 | tweet::tweet() | ||
| 6 | { | ||
| 7 | _valid = false; | ||
| 8 | } | ||
| 9 | |||
| 10 | tweet::tweet(const json& data) | ||
| 11 | { | ||
| 12 | _valid = true; | ||
| 13 | } | ||
| 14 | |||
| 15 | }; | ||
| diff --git a/src/tweet.h b/src/tweet.h new file mode 100644 index 0000000..1d83aae --- /dev/null +++ b/src/tweet.h | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #ifndef TWEET_H_CE980721 | ||
| 2 | #define TWEET_H_CE980721 | ||
| 3 | |||
| 4 | namespace twitter { | ||
| 5 | |||
| 6 | class tweet { | ||
| 7 | public: | ||
| 8 | tweet(); | ||
| 9 | tweet(const json& _data); | ||
| 10 | |||
| 11 | private: | ||
| 12 | bool _valid; | ||
| 13 | }; | ||
| 14 | |||
| 15 | }; | ||
| 16 | |||
| 17 | #endif /* end of include guard: TWEET_H_CE980721 */ | ||
| diff --git a/src/twitter.h b/src/twitter.h new file mode 100644 index 0000000..39618c9 --- /dev/null +++ b/src/twitter.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | #ifndef TWITTER_H_AC7A7666 | ||
| 2 | #define TWITTER_H_AC7A7666 | ||
| 3 | |||
| 4 | namespace twitter { | ||
| 5 | |||
| 6 | enum class response { | ||
| 7 | ok, | ||
| 8 | curl_error, | ||
| 9 | bad_auth, | ||
| 10 | limited, | ||
| 11 | server_error, | ||
| 12 | server_unavailable, | ||
| 13 | server_overloaded, | ||
| 14 | server_timeout, | ||
| 15 | suspended, | ||
| 16 | bad_token, | ||
| 17 | duplicate_status, | ||
| 18 | suspected_spam, | ||
| 19 | write_restricted, | ||
| 20 | bad_length, | ||
| 21 | unknown_error | ||
| 22 | }; | ||
| 23 | |||
| 24 | class tweet; | ||
| 25 | |||
| 26 | }; | ||
| 27 | |||
| 28 | #include <json.hpp> | ||
| 29 | |||
| 30 | using nlohmann::json; | ||
| 31 | |||
| 32 | #include "auth.h" | ||
| 33 | #include "client.h" | ||
| 34 | #include "tweet.h" | ||
| 35 | |||
| 36 | #endif /* end of include guard: TWITTER_H_AC7A7666 */ | ||
| diff --git a/vendor/curlcpp b/vendor/curlcpp new file mode 160000 | |||
| Subproject 0cdfb670d726252bdce4fb2a194e11de38a42e0 | |||
| diff --git a/vendor/json b/vendor/json new file mode 160000 | |||
| Subproject 507322e6f2f63d028c68b2a666aefe902b77f66 | |||
| diff --git a/vendor/liboauthcpp b/vendor/liboauthcpp new file mode 160000 | |||
| Subproject 4219b6576c53545d5f6b6f18a28ec93ec796968 | |||
