about summary refs log tree commit diff stats
path: root/src/notification.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/notification.cpp')
-rw-r--r--src/notification.cpp848
1 files changed, 848 insertions, 0 deletions
diff --git a/src/notification.cpp b/src/notification.cpp new file mode 100644 index 0000000..3dcdd90 --- /dev/null +++ b/src/notification.cpp
@@ -0,0 +1,848 @@
1#include "notification.h"
2#include <cassert>
3#include <new>
4#include <json.hpp>
5
6using nlohmann::json;
7
8namespace twitter {
9
10 notification::type notification::getType() const
11 {
12 return _type;
13 }
14
15 notification::notification() : _type(type::invalid)
16 {
17
18 }
19
20 notification::notification(std::string data, const user& current_user)
21 {
22 auto _data = json::parse(data);
23
24 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 {
37 _type = type::update_user;
38
39 new(&_user) user(source);
40 } else if (event == "block")
41 {
42 _type = type::block;
43
44 new(&_user) user(target);
45 } else if (event == "unblock")
46 {
47 _type = type::unblock;
48
49 new(&_user) user(target);
50 } else if (event == "favorite")
51 {
52 new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump());
53
54 if (current_user == source)
55 {
56 _type = type::favorite;
57
58 new(&_user_and_tweet._user) user(target);
59 } else {
60 _type = type::favorited;
61
62 new(&_user_and_tweet._user) user(source);
63 }
64 } else if (event == "unfavorite")
65 {
66 new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump());
67
68 if (current_user == source)
69 {
70 _type = type::unfavorite;
71
72 new(&_user_and_tweet._user) user(target);
73 } else {
74 _type = type::unfavorited;
75
76 new(&_user_and_tweet._user) user(source);
77 }
78 } else if (event == "follow")
79 {
80 if (current_user == source)
81 {
82 _type = type::follow;
83
84 new(&_user) user(target);
85 } else {
86 _type = type::followed;
87
88 new(&_user) user(source);
89 }
90 } else if (event == "unfollow")
91 {
92 _type = type::unfollow;
93
94 new(&_user) user(target);
95 } else if (event == "list_created")
96 {
97 _type = type::list_created;
98
99 new(&_list) list(_data.at("target_object").dump());
100 } else if (event == "list_destroyed")
101 {
102 _type = type::list_destroyed;
103
104 new(&_list) list(_data.at("target_object").dump());
105 } else if (event == "list_updated")
106 {
107 _type = type::list_updated;
108
109 new(&_list) list(_data.at("target_object").dump());
110 } else if (event == "list_member_added")
111 {
112 new(&_user_and_list._list) list(_data.at("target_object").dump());
113
114 if (current_user == source)
115 {
116 _type = type::list_add;
117
118 new(&_user_and_list._user) user(target);
119 } else {
120 _type = type::list_added;
121
122 new(&_user_and_list._user) user(source);
123 }
124 } 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 {
130 _type = type::list_remove;
131
132 new(&_user_and_list._user) user(target);
133 } else {
134 _type = type::list_removed;
135
136 new(&_user_and_list._user) user(source);
137 }
138 } else if (event == "list_member_subscribe")
139 {
140 new(&_user_and_list._list) list(_data.at("target_object").dump());
141
142 if (current_user == source)
143 {
144 _type = type::list_subscribe;
145
146 new(&_user_and_list._user) user(target);
147 } else {
148 _type = type::list_subscribed;
149
150 new(&_user_and_list._user) user(source);
151 }
152 } else if (event == "list_member_unsubscribe")
153 {
154 new(&_user_and_list._list) list(_data.at("target_object").dump());
155
156 if (current_user == source)
157 {
158 _type = type::list_unsubscribe;
159
160 new(&_user_and_list._user) user(target);
161 } else {
162 _type = type::list_unsubscribed;
163
164 new(&_user_and_list._user) user(source);
165 }
166 } else if (event == "quoted_tweet")
167 {
168 _type = type::quoted;
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
177 if (_data.at("warning").at("code") == "FALLING_BEHIND")
178 {
179 _type = type::stall;
180 } else if (_data.at("warning").at("code") == "FOLLOWS_OVER_LIMIT")
181 {
182 _type = type::follow_limit;
183 } else {
184 _type = type::unknown_warning;
185 }
186 } else if (_data.find("delete") != _data.end())
187 {
188 _type = type::deletion;
189
190 _user_id_and_tweet_id._tweet_id = _data.at("delete").at("status").at("id");
191 _user_id_and_tweet_id._user_id = _data.at("delete").at("status").at("user_id");
192 } else if (_data.find("scrub_geo") != _data.end())
193 {
194 _type = type::scrub_location;
195
196 _user_id_and_tweet_id._tweet_id = _data.at("scrub_geo").at("up_to_status_id");
197 _user_id_and_tweet_id._user_id = _data.at("scrub_geo").at("user_id");
198 } else if (_data.find("limit") != _data.end())
199 {
200 _type = type::limit;
201
202 _limit = _data.at("limit").at("track");
203 } else if (_data.find("status_withheld") != _data.end())
204 {
205 _type = type::withhold_status;
206
207 _withhold_status._user_id = _data.at("status_withheld").at("user_id");
208 _withhold_status._tweet_id = _data.at("status_withheld").at("id");
209
210 new(&_withhold_status._countries) std::vector<std::string>();
211 for (auto s : _data.at("status_withheld").at("withheld_in_countries"))
212 {
213 _withhold_status._countries.push_back(s);
214 }
215 } else if (_data.find("user_withheld") != _data.end())
216 {
217 _type = type::withhold_user;
218
219 _withhold_user._user_id = _data.at("user_withheld").at("id");
220
221 new(&_withhold_user._countries) std::vector<std::string>();
222 for (auto s : _data.at("user_withheld").at("withheld_in_countries"))
223 {
224 _withhold_user._countries.push_back(s);
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
248 new(&_friends) std::set<user_id>(_data.at("friends").begin(), _data.at("friends").end());
249 } else if (_data.find("direct_message") != _data.end())
250 {
251 _type = type::direct;
252
253 new(&_direct_message) direct_message(_data.at("direct_message").dump());
254 } else {
255 _type = type::unknown;
256 }
257 }
258
259 notification::notification(const notification& other)
260 {
261 _type = other._type;
262
263 switch (_type)
264 {
265 case type::tweet:
266 {
267 new(&_tweet) tweet(other._tweet);
268
269 break;
270 }
271
272 case type::update_user:
273 case type::block:
274 case type::unblock:
275 case type::follow:
276 case type::followed:
277 case type::unfollow:
278 {
279 new(&_user) user(other._user);
280
281 break;
282 }
283
284 case type::favorite:
285 case type::favorited:
286 case type::unfavorite:
287 case type::unfavorited:
288 case type::quoted:
289 {
290 new(&_user_and_tweet._user) user(other._user_and_tweet._user);
291 new(&_user_and_tweet._tweet) tweet(other._user_and_tweet._tweet);
292
293 break;
294 }
295
296 case type::list_created:
297 case type::list_destroyed:
298 case type::list_updated:
299 {
300 new(&_list) list(other._list);
301
302 break;
303 }
304
305 case type::list_add:
306 case type::list_added:
307 case type::list_remove:
308 case type::list_removed:
309 case type::list_subscribe:
310 case type::list_subscribed:
311 case type::list_unsubscribe:
312 case type::list_unsubscribed:
313 {
314 new(&_user_and_list._user) user(other._user_and_list._user);
315 new(&_user_and_list._list) list(other._user_and_list._list);
316
317 break;
318 }
319
320 case type::stall:
321 case type::follow_limit:
322 case type::unknown_warning:
323 {
324 new(&_warning) std::string(other._warning);
325
326 break;
327 }
328
329 case type::deletion:
330 case type::scrub_location:
331 {
332 _user_id_and_tweet_id._user_id = other._user_id_and_tweet_id._user_id;
333 _user_id_and_tweet_id._tweet_id = other._user_id_and_tweet_id._tweet_id;
334
335 break;
336 }
337
338 case type::limit:
339 {
340 _limit = other._limit;
341
342 break;
343 }
344
345 case type::withhold_status:
346 {
347 _withhold_status._user_id = other._withhold_status._user_id;
348 _withhold_status._tweet_id = other._withhold_status._tweet_id;
349 new(&_withhold_status._countries) std::vector<std::string>(other._withhold_status._countries);
350
351 break;
352 }
353
354 case type::withhold_user:
355 {
356 _withhold_user._user_id = other._withhold_user._user_id;
357 new(&_withhold_user._countries) std::vector<std::string>(other._withhold_user._countries);
358
359 break;
360 }
361
362 case type::disconnect:
363 {
364 _disconnect = other._disconnect;
365
366 break;
367 }
368
369 case type::friends:
370 {
371 new(&_friends) std::set<user_id>(other._friends);
372
373 break;
374 }
375
376 case type::direct:
377 {
378 new(&_direct_message) direct_message(other._direct_message);
379
380 break;
381 }
382 }
383 }
384
385 notification& notification::operator=(const notification& other)
386 {
387 this->~notification();
388
389 _type = other._type;
390
391 switch (_type)
392 {
393 case type::tweet:
394 {
395 new(&_tweet) tweet(other._tweet);
396
397 break;
398 }
399
400 case type::update_user:
401 case type::block:
402 case type::unblock:
403 case type::follow:
404 case type::followed:
405 case type::unfollow:
406 {
407 new(&_user) user(other._user);
408
409 break;
410 }
411
412 case type::favorite:
413 case type::favorited:
414 case type::unfavorite:
415 case type::unfavorited:
416 case type::quoted:
417 {
418 new(&_user_and_tweet._user) user(other._user_and_tweet._user);
419 new(&_user_and_tweet._tweet) tweet(other._user_and_tweet._tweet);
420
421 break;
422 }
423
424 case type::list_created:
425 case type::list_destroyed:
426 case type::list_updated:
427 {
428 new(&_list) list(other._list);
429
430 break;
431 }
432
433 case type::list_add:
434 case type::list_added:
435 case type::list_remove:
436 case type::list_removed:
437 case type::list_subscribe:
438 case type::list_subscribed:
439 case type::list_unsubscribe:
440 case type::list_unsubscribed:
441 {
442 new(&_user_and_list._user) user(other._user_and_list._user);
443 new(&_user_and_list._list) list(other._user_and_list._list);
444
445 break;
446 }
447
448 case type::stall:
449 case type::follow_limit:
450 case type::unknown_warning:
451 {
452 new(&_warning) std::string(other._warning);
453
454 break;
455 }
456
457 case type::deletion:
458 case type::scrub_location:
459 {
460 _user_id_and_tweet_id._user_id = other._user_id_and_tweet_id._user_id;
461 _user_id_and_tweet_id._tweet_id = other._user_id_and_tweet_id._tweet_id;
462
463 break;
464 }
465
466 case type::limit:
467 {
468 _limit = other._limit;
469
470 break;
471 }
472
473 case type::withhold_status:
474 {
475 _withhold_status._user_id = other._withhold_status._user_id;
476 _withhold_status._tweet_id = other._withhold_status._tweet_id;
477 new(&_withhold_status._countries) std::vector<std::string>(other._withhold_status._countries);
478
479 break;
480 }
481
482 case type::withhold_user:
483 {
484 _withhold_user._user_id = other._withhold_user._user_id;
485 new(&_withhold_user._countries) std::vector<std::string>(other._withhold_user._countries);
486
487 break;
488 }
489
490 case type::disconnect:
491 {
492 _disconnect = other._disconnect;
493
494 break;
495 }
496
497 case type::friends:
498 {
499 new(&_friends) std::set<user_id>(other._friends);
500
501 break;
502 }
503
504 case type::direct:
505 {
506 new(&_direct_message) direct_message(other._direct_message);
507
508 break;
509 }
510 }
511
512 return *this;
513 }
514
515 notification::~notification()
516 {
517 switch (_type)
518 {
519 case type::tweet:
520 {
521 _tweet.~tweet();
522
523 break;
524 }
525
526 case type::update_user:
527 case type::block:
528 case type::unblock:
529 case type::follow:
530 case type::followed:
531 case type::unfollow:
532 {
533 _user.~user();
534
535 break;
536 }
537
538 case type::favorite:
539 case type::favorited:
540 case type::unfavorite:
541 case type::unfavorited:
542 case type::quoted:
543 {
544 _user_and_tweet._user.~user();
545 _user_and_tweet._tweet.~tweet();
546
547 break;
548 }
549
550 case type::list_created:
551 case type::list_destroyed:
552 case type::list_updated:
553 {
554 _list.~list();
555
556 break;
557 }
558
559 case type::list_add:
560 case type::list_added:
561 case type::list_remove:
562 case type::list_removed:
563 case type::list_subscribe:
564 case type::list_subscribed:
565 case type::list_unsubscribe:
566 case type::list_unsubscribed:
567 {
568 _user_and_list._user.~user();
569 _user_and_list._list.~list();
570
571 break;
572 }
573
574 case type::stall:
575 case type::follow_limit:
576 {
577 using string_type = std::string;
578 _warning.~string_type();
579
580 break;
581 }
582
583 case type::withhold_status:
584 {
585 using list_type = std::vector<std::string>;
586 _withhold_status._countries.~list_type();
587
588 break;
589 }
590
591 case type::withhold_user:
592 {
593 using list_type = std::vector<std::string>;
594 _withhold_user._countries.~list_type();
595
596 break;
597 }
598
599 case type::friends:
600 {
601 using list_type = std::set<user_id>;
602 _friends.~list_type();
603
604 break;
605 }
606
607 case type::direct:
608 {
609 _direct_message.~direct_message();
610
611 break;
612 }
613 }
614 }
615
616 tweet notification::getTweet() const
617 {
618 switch (_type)
619 {
620 case type::tweet:
621 {
622 return _tweet;
623 }
624
625 case type::favorite:
626 case type::favorited:
627 case type::unfavorite:
628 case type::unfavorited:
629 case type::quoted:
630 {
631 return _user_and_tweet._tweet;
632 }
633
634 default:
635 {
636 assert(false);
637
638 return tweet();
639 }
640 }
641 }
642
643 user notification::getUser() const
644 {
645 switch (_type)
646 {
647 case type::update_user:
648 case type::block:
649 case type::unblock:
650 case type::follow:
651 case type::followed:
652 case type::unfollow:
653 {
654 return _user;
655 }
656
657 case type::favorite:
658 case type::favorited:
659 case type::unfavorite:
660 case type::unfavorited:
661 case type::quoted:
662 {
663 return _user_and_tweet._user;
664 }
665
666 case type::list_add:
667 case type::list_added:
668 case type::list_remove:
669 case type::list_removed:
670 case type::list_subscribe:
671 case type::list_subscribed:
672 case type::list_unsubscribe:
673 case type::list_unsubscribed:
674 {
675 return _user_and_list._user;
676 }
677
678 default:
679 {
680 assert(false);
681
682 return user();
683 }
684 }
685 }
686
687 list notification::getList() const
688 {
689 switch (_type)
690 {
691 case type::list_created:
692 case type::list_destroyed:
693 case type::list_updated:
694 {
695 return _list;
696 }
697
698 case type::list_add:
699 case type::list_added:
700 case type::list_remove:
701 case type::list_removed:
702 case type::list_subscribe:
703 case type::list_subscribed:
704 case type::list_unsubscribe:
705 case type::list_unsubscribed:
706 {
707 return _user_and_list._list;
708 }
709
710 default:
711 {
712 assert(false);
713
714 return list();
715 }
716 }
717 }
718
719 tweet_id notification::getTweetID() const
720 {
721 switch (_type)
722 {
723 case type::deletion:
724 case type::scrub_location:
725 {
726 return _user_id_and_tweet_id._tweet_id;
727 }
728
729 case type::withhold_status:
730 {
731 return _withhold_status._tweet_id;
732 }
733
734 default:
735 {
736 assert(false);
737
738 return 0;
739 }
740 }
741 }
742
743 user_id notification::getUserID() const
744 {
745 switch (_type)
746 {
747 case type::deletion:
748 case type::scrub_location:
749 {
750 return _user_id_and_tweet_id._user_id;
751 }
752
753 case type::withhold_status:
754 {
755 return _withhold_status._user_id;
756 }
757
758 case type::withhold_user:
759 {
760 return _withhold_user._user_id;
761 }
762
763 default:
764 {
765 assert(false);
766
767 return 0;
768 }
769 }
770 }
771
772 std::vector<std::string> notification::getCountries() const
773 {
774 switch (_type)
775 {
776 case type::withhold_status:
777 {
778 return _withhold_status._countries;
779 }
780
781 case type::withhold_user:
782 {
783 return _withhold_user._countries;
784 }
785
786 default:
787 {
788 assert(false);
789
790 return std::vector<std::string>();
791 }
792 }
793 }
794
795 disconnect_code notification::getDisconnectCode() const
796 {
797 assert(_type == type::disconnect);
798
799 return _disconnect;
800 }
801
802 std::set<user_id> notification::getFriends() const
803 {
804 assert(_type == type::friends);
805
806 return _friends;
807 }
808
809 direct_message notification::getDirectMessage() const
810 {
811 assert(_type == type::direct);
812
813 return _direct_message;
814 }
815
816 int notification::getLimit() const
817 {
818 assert(_type == type::limit);
819
820 return _limit;
821 }
822
823 std::string notification::getWarning() const
824 {
825 switch (_type)
826 {
827 case type::stall:
828 case type::follow_limit:
829 case type::unknown_warning:
830 {
831 return _warning;
832 }
833
834 default:
835 {
836 assert(false);
837
838 return "";
839 }
840 }
841 }
842
843 notification::operator bool() const
844 {
845 return _type != type::invalid;
846 }
847
848};