diff options
Diffstat (limited to 'src')
-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 |
7 files changed, 295 insertions, 0 deletions
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 */ | ||