diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2016-04-12 18:40:52 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2016-04-12 18:40:52 -0400 |
commit | 891d57d200f55b91f80b6d3b4dd0c30479be6109 (patch) | |
tree | e87d1566ff941aa5003e1f937ccbb497fe1606a2 | |
download | libtwittercpp-891d57d200f55b91f80b6d3b4dd0c30479be6109.tar.gz libtwittercpp-891d57d200f55b91f80b6d3b4dd0c30479be6109.tar.bz2 libtwittercpp-891d57d200f55b91f80b6d3b4dd0c30479be6109.zip |
Added basic ability to tweet
-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 | |||