about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.cpp104
-rw-r--r--src/client.h8
-rw-r--r--src/codes.h3
-rw-r--r--src/configuration.cpp109
-rw-r--r--src/configuration.h52
-rw-r--r--src/notification.cpp375
-rw-r--r--src/twitter.h1
7 files changed, 454 insertions, 198 deletions
diff --git a/src/client.cpp b/src/client.cpp index 51c288d..2c655e2 100644 --- a/src/client.cpp +++ b/src/client.cpp
@@ -105,7 +105,12 @@ namespace twitter {
105 std::string response_data; 105 std::string response_data;
106 if (performGet(url, response_code, response_data) && (response_code == 200)) 106 if (performGet(url, response_code, response_data) && (response_code == 200))
107 { 107 {
108 _current_user = user(response_data); 108 try {
109 _current_user = user(response_data);
110 } catch (std::invalid_argument e)
111 {
112 // Ignore
113 }
109 } 114 }
110 } 115 }
111 116
@@ -145,8 +150,13 @@ namespace twitter {
145 150
146 if (response_code == 200) 151 if (response_code == 200)
147 { 152 {
148 result = tweet(response_data); 153 try {
149 return response::ok; 154 result = tweet(response_data);
155 return response::ok;
156 } catch (std::invalid_argument e)
157 {
158 return response::invalid_response;
159 }
150 } else { 160 } else {
151 return codeForError(response_code, response_data); 161 return codeForError(response_code, response_data);
152 } 162 }
@@ -186,7 +196,14 @@ namespace twitter {
186 return codeForError(response_code, response_data); 196 return codeForError(response_code, response_data);
187 } 197 }
188 198
189 auto response_json = json::parse(response_data); 199 json response_json;
200 try {
201 response_json = json::parse(response_data);
202 } catch (std::invalid_argument e)
203 {
204 return response::invalid_response;
205 }
206
190 media_id = response_json["media_id"].get<long>(); 207 media_id = response_json["media_id"].get<long>();
191 208
192 curl_httppost* append_form_post = nullptr; 209 curl_httppost* append_form_post = nullptr;
@@ -226,7 +243,13 @@ namespace twitter {
226 return codeForError(response_code, response_data); 243 return codeForError(response_code, response_data);
227 } 244 }
228 245
229 response_json = json::parse(response_data); 246 try {
247 response_json = json::parse(response_data);
248 } catch (std::invalid_argument e)
249 {
250 return response::invalid_response;
251 }
252
230 if (response_json.find("processing_info") != response_json.end()) 253 if (response_json.find("processing_info") != response_json.end())
231 { 254 {
232 std::stringstream datastr; 255 std::stringstream datastr;
@@ -244,7 +267,13 @@ namespace twitter {
244 return codeForError(response_code, response_data); 267 return codeForError(response_code, response_data);
245 } 268 }
246 269
247 response_json = json::parse(response_data); 270 try {
271 response_json = json::parse(response_data);
272 } catch (std::invalid_argument e)
273 {
274 return response::invalid_response;
275 }
276
248 if (response_json["processing_info"]["state"] == "succeeded") 277 if (response_json["processing_info"]["state"] == "succeeded")
249 { 278 {
250 break; 279 break;
@@ -316,9 +345,42 @@ namespace twitter {
316 return unfollow(toUnfollow.getID()); 345 return unfollow(toUnfollow.getID());
317 } 346 }
318 347
319 const user& client::getUser() const 348 response client::getUser(user& result)
349 {
350 if (!_current_user)
351 {
352 std::string url = "https://api.twitter.com/1.1/account/verify_credentials.json";
353 long response_code;
354 std::string response_data;
355 if (performGet(url, response_code, response_data) && (response_code == 200))
356 {
357 try {
358 _current_user = user(response_data);
359 } catch (std::invalid_argument e)
360 {
361 return response::invalid_response;
362 }
363 }
364 }
365
366 result = _current_user;
367 return response::ok;
368 }
369
370 configuration client::getConfiguration()
320 { 371 {
321 return _current_user; 372 if (!_configuration || (difftime(time(NULL), _last_configuration_update) > 60*60*24))
373 {
374 long response_code;
375 std::string response_data;
376 if (performGet("https://api.twitter.com/1.1/help/configuration.json", response_code, response_data))
377 {
378 _configuration = configuration(response_data);
379 _last_configuration_update = time(NULL);
380 }
381 }
382
383 return _configuration;
322 } 384 }
323 385
324 response client::getFriends(std::set<user_id>& _ret) 386 response client::getFriends(std::set<user_id>& _ret)
@@ -350,7 +412,14 @@ namespace twitter {
350 412
351 if (response_code == 200) 413 if (response_code == 200)
352 { 414 {
353 json rjs = json::parse(response_data); 415 json rjs;
416 try {
417 rjs = json::parse(response_data);
418 } catch (std::invalid_argument e)
419 {
420 return response::invalid_response;
421 }
422
354 cursor = rjs.at("next_cursor"); 423 cursor = rjs.at("next_cursor");
355 result.insert(std::begin(rjs.at("ids")), std::end(rjs.at("ids"))); 424 result.insert(std::begin(rjs.at("ids")), std::end(rjs.at("ids")));
356 } else { 425 } else {
@@ -392,7 +461,14 @@ namespace twitter {
392 461
393 if (response_code == 200) 462 if (response_code == 200)
394 { 463 {
395 json rjs = json::parse(response_data); 464 json rjs;
465 try {
466 rjs = json::parse(response_data);
467 } catch (std::invalid_argument e)
468 {
469 return response::invalid_response;
470 }
471
396 cursor = rjs.at("next_cursor"); 472 cursor = rjs.at("next_cursor");
397 result.insert(std::begin(rjs.at("ids")), std::end(rjs.at("ids"))); 473 result.insert(std::begin(rjs.at("ids")), std::end(rjs.at("ids")));
398 } else { 474 } else {
@@ -544,7 +620,13 @@ namespace twitter {
544 620
545 response client::codeForError(int response_code, std::string response_data) const 621 response client::codeForError(int response_code, std::string response_data) const
546 { 622 {
547 auto response_json = json::parse(response_data); 623 json response_json;
624 try {
625 response_json = json::parse(response_data);
626 } catch (std::invalid_argument e)
627 {
628 return response::invalid_response;
629 }
548 630
549 std::set<int> error_codes; 631 std::set<int> error_codes;
550 if (response_json.find("errors") != response_json.end()) 632 if (response_json.find("errors") != response_json.end())
diff --git a/src/client.h b/src/client.h index c1c6344..6963412 100644 --- a/src/client.h +++ b/src/client.h
@@ -11,6 +11,7 @@
11#include <set> 11#include <set>
12#include <ctime> 12#include <ctime>
13#include <chrono> 13#include <chrono>
14#include "configuration.h"
14 15
15namespace OAuth { 16namespace OAuth {
16 class Consumer; 17 class Consumer;
@@ -79,7 +80,9 @@ namespace twitter {
79 response getFriends(std::set<user_id>& result); 80 response getFriends(std::set<user_id>& result);
80 response getFollowers(std::set<user_id>& result); 81 response getFollowers(std::set<user_id>& result);
81 82
82 const user& getUser() const; 83 response getUser(user& result);
84
85 configuration getConfiguration();
83 86
84 // NOTE: stream setting function calls will fail silently when stream is running 87 // NOTE: stream setting function calls will fail silently when stream is running
85 void setUserStreamNotifyCallback(stream::notify_callback callback); 88 void setUserStreamNotifyCallback(stream::notify_callback callback);
@@ -99,6 +102,9 @@ namespace twitter {
99 user _current_user; 102 user _current_user;
100 stream _user_stream{*this}; 103 stream _user_stream{*this};
101 104
105 configuration _configuration;
106 time_t _last_configuration_update;
107
102 bool performGet(std::string url, long& response_code, std::string& result); 108 bool performGet(std::string url, long& response_code, std::string& result);
103 bool performPost(std::string url, std::string dataStr, long& response_code, std::string& result); 109 bool performPost(std::string url, std::string dataStr, long& response_code, std::string& result);
104 bool performMultiPost(std::string url, const curl_httppost* fields, long& response_code, std::string& result); 110 bool performMultiPost(std::string url, const curl_httppost* fields, long& response_code, std::string& result);
diff --git a/src/codes.h b/src/codes.h index 334f0ce..6767805 100644 --- a/src/codes.h +++ b/src/codes.h
@@ -21,7 +21,8 @@ namespace twitter {
21 write_restricted, 21 write_restricted,
22 bad_length, 22 bad_length,
23 unknown_error, 23 unknown_error,
24 invalid_media 24 invalid_media,
25 invalid_response
25 }; 26 };
26 27
27}; 28};
diff --git a/src/configuration.cpp b/src/configuration.cpp new file mode 100644 index 0000000..63464ed --- /dev/null +++ b/src/configuration.cpp
@@ -0,0 +1,109 @@
1#include "configuration.h"
2#include <json.hpp>
3#include <cassert>
4
5using nlohmann::json;
6
7namespace twitter {
8
9 configuration::configuration()
10 {
11 _valid = false;
12 }
13
14 configuration::configuration(std::string data)
15 {
16 _valid = true;
17
18 auto _data = json::parse(data);
19
20 _characters_reserved_per_media = _data.at("characters_reserved_per_media");
21 _dm_text_character_limit = _data.at("dm_text_character_limit");
22 _max_media_per_upload = _data.at("max_media_per_upload");
23 _photo_size_limit = _data.at("photo_size_limit");
24 _short_url_length = _data.at("short_url_length");
25 _short_https_url_length = _data.at("short_url_length_https");
26
27 for (json::iterator sizedata = _data.at("photo_sizes").begin(); sizedata != _data.at("photo_sizes").end(); ++sizedata)
28 {
29 photosize size;
30 size.height = sizedata.value().at("h");
31 size.width = sizedata.value().at("w");
32 if (sizedata.value().at("resize") == "fit")
33 {
34 size.resize = resizetype::fit;
35 } else {
36 size.resize = resizetype::crop;
37 }
38
39 _photo_sizes[sizedata.key()] = size;
40 }
41
42 for (auto path : _data.at("non_username_paths"))
43 {
44 _non_username_paths.insert(path.get<std::string>());
45 }
46 }
47
48 size_t configuration::getCharactersReservedPerMedia() const
49 {
50 assert(_valid);
51
52 return _characters_reserved_per_media;
53 }
54
55 size_t configuration::getDirectMessageCharacterLimit() const
56 {
57 assert(_valid);
58
59 return _dm_text_character_limit;
60 }
61
62 size_t configuration::getMaxMediaPerUpload() const
63 {
64 assert(_valid);
65
66 return _max_media_per_upload;
67 }
68
69 size_t configuration::getPhotoSizeLimit() const
70 {
71 assert(_valid);
72
73 return _photo_size_limit;
74 }
75
76 std::map<std::string, configuration::photosize> configuration::getPhotoSizes() const
77 {
78 assert(_valid);
79
80 return _photo_sizes;
81 }
82
83 size_t configuration::getShortUrlLength() const
84 {
85 assert(_valid);
86
87 return _short_url_length;
88 }
89
90 size_t configuration::getShortHttpsUrlLength() const
91 {
92 assert(_valid);
93
94 return _short_https_url_length;
95 }
96
97 std::set<std::string> configuration::getNonUsernamePaths() const
98 {
99 assert(_valid);
100
101 return _non_username_paths;
102 }
103
104 configuration::operator bool() const
105 {
106 return _valid;
107 }
108
109};
diff --git a/src/configuration.h b/src/configuration.h new file mode 100644 index 0000000..a15be3d --- /dev/null +++ b/src/configuration.h
@@ -0,0 +1,52 @@
1#ifndef CONFIGURATION_H_A7164D18
2#define CONFIGURATION_H_A7164D18
3
4#include <map>
5#include <string>
6#include <set>
7
8namespace twitter {
9
10 class configuration {
11 public:
12 enum class resizetype {
13 fit,
14 crop
15 };
16
17 struct photosize {
18 size_t height;
19 size_t width;
20 resizetype resize;
21 };
22
23 configuration();
24 configuration(std::string data);
25
26 size_t getCharactersReservedPerMedia() const;
27 size_t getDirectMessageCharacterLimit() const;
28 size_t getMaxMediaPerUpload() const;
29 size_t getPhotoSizeLimit() const;
30 std::map<std::string, photosize> getPhotoSizes() const;
31 size_t getShortUrlLength() const;
32 size_t getShortHttpsUrlLength() const;
33 std::set<std::string> getNonUsernamePaths() const;
34
35 operator bool() const;
36
37 private:
38 bool _valid = false;
39
40 size_t _characters_reserved_per_media;
41 size_t _dm_text_character_limit;
42 size_t _max_media_per_upload;
43 size_t _photo_size_limit;
44 std::map<std::string, photosize> _photo_sizes;
45 size_t _short_url_length;
46 size_t _short_https_url_length;
47 std::set<std::string> _non_username_paths;
48 };
49
50};
51
52#endif /* end of include guard: CONFIGURATION_H_A7164D18 */
diff --git a/src/notification.cpp b/src/notification.cpp index 3dcdd90..0397ce5 100644 --- a/src/notification.cpp +++ b/src/notification.cpp
@@ -19,240 +19,245 @@ namespace twitter {
19 19
20 notification::notification(std::string data, const user& current_user) 20 notification::notification(std::string data, const user& current_user)
21 { 21 {
22 auto _data = json::parse(data); 22 try {
23 auto _data = json::parse(data);
23 24
24 if (_data.find("in_reply_to_status_id") != _data.end()) 25 if (_data.find("in_reply_to_status_id") != _data.end())
25 {
26 _type = type::tweet;
27
28 new(&_tweet) tweet(data);
29 } else if (_data.find("event") != _data.end())
30 {
31 std::string event = _data.at("event");
32 user source(_data.at("source").dump());
33 user target(_data.at("target").dump());
34
35 if (event == "user_update")
36 { 26 {
37 _type = type::update_user; 27 _type = type::tweet;
38 28
39 new(&_user) user(source); 29 new(&_tweet) tweet(data);
40 } else if (event == "block") 30 } else if (_data.find("event") != _data.end())
41 { 31 {
42 _type = type::block; 32 std::string event = _data.at("event");
33 user source(_data.at("source").dump());
34 user target(_data.at("target").dump());
35
36 if (event == "user_update")
37 {
38 _type = type::update_user;
43 39
44 new(&_user) user(target); 40 new(&_user) user(source);
45 } else if (event == "unblock") 41 } else if (event == "block")
46 { 42 {
47 _type = type::unblock; 43 _type = type::block;
48 44
49 new(&_user) user(target); 45 new(&_user) user(target);
50 } else if (event == "favorite") 46 } else if (event == "unblock")
51 { 47 {
52 new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump()); 48 _type = type::unblock;
53 49
54 if (current_user == source) 50 new(&_user) user(target);
51 } else if (event == "favorite")
55 { 52 {
56 _type = type::favorite; 53 new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump());
54
55 if (current_user == source)
56 {
57 _type = type::favorite;
57 58
58 new(&_user_and_tweet._user) user(target); 59 new(&_user_and_tweet._user) user(target);
59 } else { 60 } else {
60 _type = type::favorited; 61 _type = type::favorited;
61 62
62 new(&_user_and_tweet._user) user(source); 63 new(&_user_and_tweet._user) user(source);
63 } 64 }
64 } else if (event == "unfavorite") 65 } else if (event == "unfavorite")
65 {
66 new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump());
67
68 if (current_user == source)
69 { 66 {
70 _type = type::unfavorite; 67 new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump());
68
69 if (current_user == source)
70 {
71 _type = type::unfavorite;
71 72
72 new(&_user_and_tweet._user) user(target); 73 new(&_user_and_tweet._user) user(target);
73 } else { 74 } else {
74 _type = type::unfavorited; 75 _type = type::unfavorited;
75 76
76 new(&_user_and_tweet._user) user(source); 77 new(&_user_and_tweet._user) user(source);
77 } 78 }
78 } else if (event == "follow") 79 } else if (event == "follow")
79 {
80 if (current_user == source)
81 { 80 {
82 _type = type::follow; 81 if (current_user == source)
82 {
83 _type = type::follow;
83 84
84 new(&_user) user(target); 85 new(&_user) user(target);
85 } else { 86 } else {
86 _type = type::followed; 87 _type = type::followed;
87 88
88 new(&_user) user(source); 89 new(&_user) user(source);
89 } 90 }
90 } else if (event == "unfollow") 91 } else if (event == "unfollow")
91 { 92 {
92 _type = type::unfollow; 93 _type = type::unfollow;
93
94 new(&_user) user(target);
95 } else if (event == "list_created")
96 {
97 _type = type::list_created;
98 94
99 new(&_list) list(_data.at("target_object").dump()); 95 new(&_user) user(target);
100 } else if (event == "list_destroyed") 96 } else if (event == "list_created")
101 { 97 {
102 _type = type::list_destroyed; 98 _type = type::list_created;
103 99
104 new(&_list) list(_data.at("target_object").dump()); 100 new(&_list) list(_data.at("target_object").dump());
105 } else if (event == "list_updated") 101 } else if (event == "list_destroyed")
106 { 102 {
107 _type = type::list_updated; 103 _type = type::list_destroyed;
108 104
109 new(&_list) list(_data.at("target_object").dump()); 105 new(&_list) list(_data.at("target_object").dump());
110 } else if (event == "list_member_added") 106 } else if (event == "list_updated")
111 { 107 {
112 new(&_user_and_list._list) list(_data.at("target_object").dump()); 108 _type = type::list_updated;
113 109
114 if (current_user == source) 110 new(&_list) list(_data.at("target_object").dump());
111 } else if (event == "list_member_added")
115 { 112 {
116 _type = type::list_add; 113 new(&_user_and_list._list) list(_data.at("target_object").dump());
114
115 if (current_user == source)
116 {
117 _type = type::list_add;
117 118
118 new(&_user_and_list._user) user(target); 119 new(&_user_and_list._user) user(target);
119 } else { 120 } else {
120 _type = type::list_added; 121 _type = type::list_added;
121 122
122 new(&_user_and_list._user) user(source); 123 new(&_user_and_list._user) user(source);
123 } 124 }
124 } else if (event == "list_member_removed") 125 } else if (event == "list_member_removed")
125 {
126 new(&_user_and_list._list) list(_data.at("target_object").dump());
127
128 if (current_user == source)
129 { 126 {
130 _type = type::list_remove; 127 new(&_user_and_list._list) list(_data.at("target_object").dump());
128
129 if (current_user == source)
130 {
131 _type = type::list_remove;
131 132
132 new(&_user_and_list._user) user(target); 133 new(&_user_and_list._user) user(target);
133 } else { 134 } else {
134 _type = type::list_removed; 135 _type = type::list_removed;
135 136
136 new(&_user_and_list._user) user(source); 137 new(&_user_and_list._user) user(source);
137 } 138 }
138 } else if (event == "list_member_subscribe") 139 } else if (event == "list_member_subscribe")
139 { 140 {
140 new(&_user_and_list._list) list(_data.at("target_object").dump()); 141 new(&_user_and_list._list) list(_data.at("target_object").dump());
141 142
142 if (current_user == source) 143 if (current_user == source)
144 {
145 _type = type::list_subscribe;
146
147 new(&_user_and_list._user) user(target);
148 } else {
149 _type = type::list_subscribed;
150
151 new(&_user_and_list._user) user(source);
152 }
153 } else if (event == "list_member_unsubscribe")
143 { 154 {
144 _type = type::list_subscribe; 155 new(&_user_and_list._list) list(_data.at("target_object").dump());
156
157 if (current_user == source)
158 {
159 _type = type::list_unsubscribe;
145 160
146 new(&_user_and_list._user) user(target); 161 new(&_user_and_list._user) user(target);
147 } else { 162 } else {
148 _type = type::list_subscribed; 163 _type = type::list_unsubscribed;
149 164
150 new(&_user_and_list._user) user(source); 165 new(&_user_and_list._user) user(source);
166 }
167 } else if (event == "quoted_tweet")
168 {
169 _type = type::quoted;
170
171 new(&_user_and_tweet._user) user(source);
172 new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump());
151 } 173 }
152 } else if (event == "list_member_unsubscribe") 174 } else if (_data.find("warning") != _data.end())
153 { 175 {
154 new(&_user_and_list._list) list(_data.at("target_object").dump()); 176 new(&_warning) std::string(_data.at("warning").at("message").get<std::string>());
155 177
156 if (current_user == source) 178 if (_data.at("warning").at("code") == "FALLING_BEHIND")
157 { 179 {
158 _type = type::list_unsubscribe; 180 _type = type::stall;
159 181 } else if (_data.at("warning").at("code") == "FOLLOWS_OVER_LIMIT")
160 new(&_user_and_list._user) user(target); 182 {
183 _type = type::follow_limit;
161 } else { 184 } else {
162 _type = type::list_unsubscribed; 185 _type = type::unknown_warning;
163
164 new(&_user_and_list._user) user(source);
165 } 186 }
166 } else if (event == "quoted_tweet") 187 } else if (_data.find("delete") != _data.end())
167 { 188 {
168 _type = type::quoted; 189 _type = type::deletion;
169
170 new(&_user_and_tweet._user) user(source);
171 new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump());
172 }
173 } else if (_data.find("warning") != _data.end())
174 {
175 new(&_warning) std::string(_data.at("warning").at("message").get<std::string>());
176 190
177 if (_data.at("warning").at("code") == "FALLING_BEHIND") 191 _user_id_and_tweet_id._tweet_id = _data.at("delete").at("status").at("id");
192 _user_id_and_tweet_id._user_id = _data.at("delete").at("status").at("user_id");
193 } else if (_data.find("scrub_geo") != _data.end())
178 { 194 {
179 _type = type::stall; 195 _type = type::scrub_location;
180 } else if (_data.at("warning").at("code") == "FOLLOWS_OVER_LIMIT") 196
197 _user_id_and_tweet_id._tweet_id = _data.at("scrub_geo").at("up_to_status_id");
198 _user_id_and_tweet_id._user_id = _data.at("scrub_geo").at("user_id");
199 } else if (_data.find("limit") != _data.end())
181 { 200 {
182 _type = type::follow_limit; 201 _type = type::limit;
183 } else {
184 _type = type::unknown_warning;
185 }
186 } else if (_data.find("delete") != _data.end())
187 {
188 _type = type::deletion;
189 202
190 _user_id_and_tweet_id._tweet_id = _data.at("delete").at("status").at("id"); 203 _limit = _data.at("limit").at("track");
191 _user_id_and_tweet_id._user_id = _data.at("delete").at("status").at("user_id"); 204 } else if (_data.find("status_withheld") != _data.end())
192 } else if (_data.find("scrub_geo") != _data.end()) 205 {
193 { 206 _type = type::withhold_status;
194 _type = type::scrub_location;
195 207
196 _user_id_and_tweet_id._tweet_id = _data.at("scrub_geo").at("up_to_status_id"); 208 _withhold_status._user_id = _data.at("status_withheld").at("user_id");
197 _user_id_and_tweet_id._user_id = _data.at("scrub_geo").at("user_id"); 209 _withhold_status._tweet_id = _data.at("status_withheld").at("id");
198 } else if (_data.find("limit") != _data.end())
199 {
200 _type = type::limit;
201 210
202 _limit = _data.at("limit").at("track"); 211 new(&_withhold_status._countries) std::vector<std::string>();
203 } else if (_data.find("status_withheld") != _data.end()) 212 for (auto s : _data.at("status_withheld").at("withheld_in_countries"))
204 { 213 {
205 _type = type::withhold_status; 214 _withhold_status._countries.push_back(s);
215 }
216 } else if (_data.find("user_withheld") != _data.end())
217 {
218 _type = type::withhold_user;
206 219
207 _withhold_status._user_id = _data.at("status_withheld").at("user_id"); 220 _withhold_user._user_id = _data.at("user_withheld").at("id");
208 _withhold_status._tweet_id = _data.at("status_withheld").at("id");
209 221
210 new(&_withhold_status._countries) std::vector<std::string>(); 222 new(&_withhold_user._countries) std::vector<std::string>();
211 for (auto s : _data.at("status_withheld").at("withheld_in_countries")) 223 for (auto s : _data.at("user_withheld").at("withheld_in_countries"))
224 {
225 _withhold_user._countries.push_back(s);
226 }
227 } else if (_data.find("disconnect") != _data.end())
212 { 228 {
213 _withhold_status._countries.push_back(s); 229 _type = type::disconnect;
214 }
215 } else if (_data.find("user_withheld") != _data.end())
216 {
217 _type = type::withhold_user;
218 230
219 _withhold_user._user_id = _data.at("user_withheld").at("id"); 231 switch (_data.at("disconnect").at("code").get<int>())
232 {
233 case 1: _disconnect = disconnect_code::shutdown; break;
234 case 2: _disconnect = disconnect_code::duplicate; break;
235 case 4: _disconnect = disconnect_code::stall; break;
236 case 5: _disconnect = disconnect_code::normal; break;
237 case 6: _disconnect = disconnect_code::token_revoked; break;
238 case 7: _disconnect = disconnect_code::admin_logout; break;
239 case 9: _disconnect = disconnect_code::limit; break;
240 case 10: _disconnect = disconnect_code::exception; break;
241 case 11: _disconnect = disconnect_code::broker; break;
242 case 12: _disconnect = disconnect_code::load; break;
243 default: _disconnect = disconnect_code::unknown;
244 }
245 } else if (_data.find("friends") != _data.end())
246 {
247 _type = type::friends;
220 248
221 new(&_withhold_user._countries) std::vector<std::string>(); 249 new(&_friends) std::set<user_id>(_data.at("friends").begin(), _data.at("friends").end());
222 for (auto s : _data.at("user_withheld").at("withheld_in_countries")) 250 } else if (_data.find("direct_message") != _data.end())
223 { 251 {
224 _withhold_user._countries.push_back(s); 252 _type = type::direct;
225 }
226 } else if (_data.find("disconnect") != _data.end())
227 {
228 _type = type::disconnect;
229
230 switch (_data.at("disconnect").at("code").get<int>())
231 {
232 case 1: _disconnect = disconnect_code::shutdown; break;
233 case 2: _disconnect = disconnect_code::duplicate; break;
234 case 4: _disconnect = disconnect_code::stall; break;
235 case 5: _disconnect = disconnect_code::normal; break;
236 case 6: _disconnect = disconnect_code::token_revoked; break;
237 case 7: _disconnect = disconnect_code::admin_logout; break;
238 case 9: _disconnect = disconnect_code::limit; break;
239 case 10: _disconnect = disconnect_code::exception; break;
240 case 11: _disconnect = disconnect_code::broker; break;
241 case 12: _disconnect = disconnect_code::load; break;
242 default: _disconnect = disconnect_code::unknown;
243 }
244 } else if (_data.find("friends") != _data.end())
245 {
246 _type = type::friends;
247 253
248 new(&_friends) std::set<user_id>(_data.at("friends").begin(), _data.at("friends").end()); 254 new(&_direct_message) direct_message(_data.at("direct_message").dump());
249 } else if (_data.find("direct_message") != _data.end()) 255 } else {
256 _type = type::unknown;
257 }
258 } catch (std::invalid_argument e)
250 { 259 {
251 _type = type::direct; 260 _type = type::invalid;
252
253 new(&_direct_message) direct_message(_data.at("direct_message").dump());
254 } else {
255 _type = type::unknown;
256 } 261 }
257 } 262 }
258 263
diff --git a/src/twitter.h b/src/twitter.h index d0b469e..90925df 100644 --- a/src/twitter.h +++ b/src/twitter.h
@@ -16,5 +16,6 @@ namespace twitter {
16#include "notification.h" 16#include "notification.h"
17#include "list.h" 17#include "list.h"
18#include "direct_message.h" 18#include "direct_message.h"
19#include "configuration.h"
19 20
20#endif /* end of include guard: TWITTER_H_AC7A7666 */ 21#endif /* end of include guard: TWITTER_H_AC7A7666 */