From cc57105f29b4095daad03273bc1a882368e75664 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Thu, 30 Aug 2018 19:22:20 -0400 Subject: Removed stream functionality The Twitter streaming API has officially sunset, so the stream functionality can no longer be used. Because of this, there is no need to keep it in the codebase. refs #3 --- src/notification.cpp | 1212 -------------------------------------------------- src/notification.h | 192 -------- src/stream.cpp | 295 ------------ src/stream.h | 71 --- src/twitter.h | 2 - 5 files changed, 1772 deletions(-) delete mode 100644 src/notification.cpp delete mode 100644 src/notification.h delete mode 100644 src/stream.cpp delete mode 100644 src/stream.h (limited to 'src') diff --git a/src/notification.cpp b/src/notification.cpp deleted file mode 100644 index 0d09fcf..0000000 --- a/src/notification.cpp +++ /dev/null @@ -1,1212 +0,0 @@ -#include "notification.h" -#include -#include -#include -#include "codes.h" -#include "client.h" - -namespace twitter { - - notification::type notification::getType() const - { - return _type; - } - - notification::notification(const user& current_user, std::string data) - { - nlohmann::json json; - - try - { - json = nlohmann::json::parse(data); - } catch (const std::invalid_argument& error) - { - std::throw_with_nested(invalid_response(data)); - } - - try - { - if (!json["event"].is_null()) - { - std::string event = json["event"]; - user source(json["source"].dump()); - user target(json["target"].dump()); - - if (event == "user_update") - { - _type = type::update_user; - - new(&_user) user(source); - } else if (event == "block") - { - _type = type::block; - - new(&_user) user(target); - } else if (event == "unblock") - { - _type = type::unblock; - - new(&_user) user(target); - } else if (event == "favorite") - { - new(&_user_and_tweet._tweet) tweet(json["target_object"].dump()); - - if (current_user == source) - { - _type = type::favorite; - - new(&_user_and_tweet._user) user(target); - } else { - _type = type::favorited; - - new(&_user_and_tweet._user) user(source); - } - } else if (event == "unfavorite") - { - new(&_user_and_tweet._tweet) tweet(json["target_object"].dump()); - - if (current_user == source) - { - _type = type::unfavorite; - - new(&_user_and_tweet._user) user(target); - } else { - _type = type::unfavorited; - - new(&_user_and_tweet._user) user(source); - } - } else if (event == "follow") - { - if (current_user == source) - { - _type = type::follow; - - new(&_user) user(target); - } else { - _type = type::followed; - - new(&_user) user(source); - } - } else if (event == "unfollow") - { - _type = type::unfollow; - - new(&_user) user(target); - } else if (event == "list_created") - { - _type = type::list_created; - - new(&_list) list(json["target_object"].dump()); - } else if (event == "list_destroyed") - { - _type = type::list_destroyed; - - new(&_list) list(json["target_object"].dump()); - } else if (event == "list_updated") - { - _type = type::list_updated; - - new(&_list) list(json["target_object"].dump()); - } else if (event == "list_member_added") - { - new(&_user_and_list._list) list(json["target_object"].dump()); - - if (current_user == source) - { - _type = type::list_add; - - new(&_user_and_list._user) user(target); - } else { - _type = type::list_added; - - new(&_user_and_list._user) user(source); - } - } else if (event == "list_member_removed") - { - new(&_user_and_list._list) list(json["target_object"].dump()); - - if (current_user == source) - { - _type = type::list_remove; - - new(&_user_and_list._user) user(target); - } else { - _type = type::list_removed; - - new(&_user_and_list._user) user(source); - } - } else if (event == "list_member_subscribe") - { - new(&_user_and_list._list) list(json["target_object"].dump()); - - if (current_user == source) - { - _type = type::list_subscribe; - - new(&_user_and_list._user) user(target); - } else { - _type = type::list_subscribed; - - new(&_user_and_list._user) user(source); - } - } else if (event == "list_member_unsubscribe") - { - new(&_user_and_list._list) list(json["target_object"].dump()); - - if (current_user == source) - { - _type = type::list_unsubscribe; - - new(&_user_and_list._user) user(target); - } else { - _type = type::list_unsubscribed; - - new(&_user_and_list._user) user(source); - } - } else if (event == "quoted_tweet") - { - _type = type::quoted; - - new(&_user_and_tweet._user) user(source); - new(&_user_and_tweet._tweet) tweet(json["target_object"].dump()); - } else { - _type = type::unknown; - } - } else if (!json["warning"].is_null()) - { - new(&_warning) std::string(json["warning"]["message"].get()); - - auto warning_code = json["warning"]["code"].get(); - if (warning_code == "FALLING_BEHIND") - { - _type = type::stall; - } else if (warning_code == "FOLLOWS_OVER_LIMIT") - { - _type = type::follow_limit; - } else { - _type = type::unknown_warning; - } - } else if (!json["delete"].is_null()) - { - _type = type::deletion; - - _user_id_and_tweet_id._tweet_id = json["delete"]["status"]["id"].get(); - _user_id_and_tweet_id._user_id = json["delete"]["status"]["user_id"].get(); - } else if (!json["scrub_geo"].is_null()) - { - _type = type::scrub_location; - - _user_id_and_tweet_id._tweet_id = json["scrub_geo"]["up_to_status_id"].get(); - _user_id_and_tweet_id._user_id = json["scrub_geo"]["user_id"].get(); - } else if (!json["limit"].is_null()) - { - _type = type::limit; - - _limit = json["limit"]["track"].get(); - } else if (!json["status_withheld"].is_null()) - { - _type = type::withhold_status; - - _withhold_status._user_id = json["status_withheld"]["user_id"].get(); - _withhold_status._tweet_id = json["status_withheld"]["id"].get(); - - new(&_withhold_status._countries) std::vector(); - for (auto s : json["status_withheld"]["withheld_in_countries"]) - { - _withhold_status._countries.push_back(s); - } - } else if (!json["user_withheld"].is_null()) - { - _type = type::withhold_user; - - _withhold_user._user_id = json["user_withheld"]["id"].get(); - - new(&_withhold_user._countries) std::vector(); - for (auto s : json["user_withheld"]["withheld_in_countries"]) - { - _withhold_user._countries.push_back(s); - } - } else if (!json["disconnect"].is_null()) - { - _type = type::disconnect; - - switch (json["disconnect"]["code"].get()) - { - case 1: _disconnect = disconnect_code::shutdown; break; - case 2: _disconnect = disconnect_code::duplicate; break; - case 4: _disconnect = disconnect_code::stall; break; - case 5: _disconnect = disconnect_code::normal; break; - case 6: _disconnect = disconnect_code::token_revoked; break; - case 7: _disconnect = disconnect_code::admin_logout; break; - case 9: _disconnect = disconnect_code::limit; break; - case 10: _disconnect = disconnect_code::exception; break; - case 11: _disconnect = disconnect_code::broker; break; - case 12: _disconnect = disconnect_code::load; break; - default: _disconnect = disconnect_code::unknown; - } - } else if (!json["friends"].is_null()) - { - _type = type::friends; - - new(&_friends) std::set(std::begin(json["friends"]), std::end(json["friends"])); - } else if (!json["direct_message"].is_null()) - { - _type = type::direct; - - new(&_direct_message) direct_message(json["direct_message"].dump()); - } else { - _type = type::tweet; - - new(&_tweet) tweet(data); - } - } catch (const std::domain_error& error) - { - std::throw_with_nested(invalid_response(data)); - } - } - - notification::notification(const notification& other) - { - _type = other._type; - - switch (_type) - { - case type::tweet: - { - new(&_tweet) tweet(other._tweet); - - break; - } - - case type::update_user: - case type::block: - case type::unblock: - case type::follow: - case type::followed: - case type::unfollow: - { - new(&_user) user(other._user); - - break; - } - - case type::favorite: - case type::favorited: - case type::unfavorite: - case type::unfavorited: - case type::quoted: - { - new(&_user_and_tweet._user) user(other._user_and_tweet._user); - new(&_user_and_tweet._tweet) tweet(other._user_and_tweet._tweet); - - break; - } - - case type::list_created: - case type::list_destroyed: - case type::list_updated: - { - new(&_list) list(other._list); - - break; - } - - case type::list_add: - case type::list_added: - case type::list_remove: - case type::list_removed: - case type::list_subscribe: - case type::list_subscribed: - case type::list_unsubscribe: - case type::list_unsubscribed: - { - new(&_user_and_list._user) user(other._user_and_list._user); - new(&_user_and_list._list) list(other._user_and_list._list); - - break; - } - - case type::stall: - case type::follow_limit: - case type::unknown_warning: - { - new(&_warning) std::string(other._warning); - - break; - } - - case type::deletion: - case type::scrub_location: - { - _user_id_and_tweet_id._user_id = other._user_id_and_tweet_id._user_id; - _user_id_and_tweet_id._tweet_id = other._user_id_and_tweet_id._tweet_id; - - break; - } - - case type::limit: - { - _limit = other._limit; - - break; - } - - case type::withhold_status: - { - _withhold_status._user_id = other._withhold_status._user_id; - _withhold_status._tweet_id = other._withhold_status._tweet_id; - new(&_withhold_status._countries) std::vector(other._withhold_status._countries); - - break; - } - - case type::withhold_user: - { - _withhold_user._user_id = other._withhold_user._user_id; - new(&_withhold_user._countries) std::vector(other._withhold_user._countries); - - break; - } - - case type::disconnect: - { - _disconnect = other._disconnect; - - break; - } - - case type::friends: - { - new(&_friends) std::set(other._friends); - - break; - } - - case type::direct: - { - new(&_direct_message) direct_message(other._direct_message); - - break; - } - - case type::unknown: - case type::invalid: - { - break; - } - } - } - - notification::notification(notification&& other) : notification() - { - swap(*this, other); - } - - notification& notification::operator=(notification other) - { - swap(*this, other); - - return *this; - } - - notification::~notification() - { - switch (_type) - { - case type::tweet: - { - _tweet.~tweet(); - - break; - } - - case type::update_user: - case type::block: - case type::unblock: - case type::follow: - case type::followed: - case type::unfollow: - { - _user.~user(); - - break; - } - - case type::favorite: - case type::favorited: - case type::unfavorite: - case type::unfavorited: - case type::quoted: - { - _user_and_tweet._user.~user(); - _user_and_tweet._tweet.~tweet(); - - break; - } - - case type::list_created: - case type::list_destroyed: - case type::list_updated: - { - _list.~list(); - - break; - } - - case type::list_add: - case type::list_added: - case type::list_remove: - case type::list_removed: - case type::list_subscribe: - case type::list_subscribed: - case type::list_unsubscribe: - case type::list_unsubscribed: - { - _user_and_list._user.~user(); - _user_and_list._list.~list(); - - break; - } - - case type::stall: - case type::follow_limit: - case type::unknown_warning: - { - using string_type = std::string; - _warning.~string_type(); - - break; - } - - case type::withhold_status: - { - using list_type = std::vector; - _withhold_status._countries.~list_type(); - - break; - } - - case type::withhold_user: - { - using list_type = std::vector; - _withhold_user._countries.~list_type(); - - break; - } - - case type::friends: - { - using list_type = std::set; - _friends.~list_type(); - - break; - } - - case type::direct: - { - _direct_message.~direct_message(); - - break; - } - - case type::deletion: - case type::scrub_location: - case type::limit: - case type::disconnect: - case type::unknown: - case type::invalid: - { - break; - } - } - } - - void swap(notification& first, notification& second) - { - using type = notification::type; - - type tempType = first._type; - tweet tempTweet; - user tempUser; - list tempList; - std::string tempWarning; - user_id tempUserId; - tweet_id tempTweetId; - int tempLimit; - std::vector tempCountries; - disconnect_code tempDisconnectCode; - std::set tempFriends; - direct_message tempDirectMessage; - - switch (first._type) - { - case type::tweet: - { - tempTweet = std::move(first._tweet); - - break; - } - - case type::update_user: - case type::block: - case type::unblock: - case type::follow: - case type::followed: - case type::unfollow: - { - tempUser = std::move(first._user); - - break; - } - - case type::favorite: - case type::favorited: - case type::unfavorite: - case type::unfavorited: - case type::quoted: - { - tempTweet = std::move(first._user_and_tweet._tweet); - tempUser = std::move(first._user_and_tweet._user); - - break; - } - - case type::list_created: - case type::list_destroyed: - case type::list_updated: - { - tempList = std::move(first._list); - - break; - } - - case type::list_add: - case type::list_added: - case type::list_remove: - case type::list_removed: - case type::list_subscribe: - case type::list_subscribed: - case type::list_unsubscribe: - case type::list_unsubscribed: - { - tempList = std::move(first._user_and_list._list); - tempUser = std::move(first._user_and_list._user); - - break; - } - - case type::stall: - case type::follow_limit: - case type::unknown_warning: - { - tempWarning = std::move(first._warning); - - break; - } - - case type::deletion: - case type::scrub_location: - { - tempUserId = first._user_id_and_tweet_id._user_id; - tempTweetId = first._user_id_and_tweet_id._tweet_id; - - break; - } - - case type::limit: - { - tempLimit = first._limit; - - break; - } - - case type::withhold_status: - { - tempUserId = first._withhold_status._user_id; - tempTweetId = first._withhold_status._tweet_id; - tempCountries = std::move(first._withhold_status._countries); - - break; - } - - case type::withhold_user: - { - tempUserId = first._withhold_user._user_id; - tempCountries = std::move(first._withhold_user._countries); - - break; - } - - case type::disconnect: - { - tempDisconnectCode = first._disconnect; - - break; - } - - case type::friends: - { - tempFriends = std::move(first._friends); - - break; - } - - case type::direct: - { - tempDirectMessage = std::move(first._direct_message); - - break; - } - - case type::invalid: - case type::unknown: - { - break; - } - } - - first.~notification(); - - first._type = second._type; - - // Okay now you need to initialize the first with the data from the second - // And then destruct the second and initialize it with the data stored in temp - // This is hell - - switch (second._type) - { - case type::tweet: - { - new(&first._tweet) tweet(std::move(second._tweet)); - - break; - } - - case type::update_user: - case type::block: - case type::unblock: - case type::follow: - case type::followed: - case type::unfollow: - { - new(&first._user) user(std::move(second._user)); - - break; - } - - case type::favorite: - case type::favorited: - case type::unfavorite: - case type::unfavorited: - case type::quoted: - { - new(&first._user_and_tweet._user) user(std::move(second._user_and_tweet._user)); - new(&first._user_and_tweet._tweet) tweet(std::move(second._user_and_tweet._tweet)); - - break; - } - - case type::list_created: - case type::list_destroyed: - case type::list_updated: - { - new(&first._list) list(std::move(second._list)); - - break; - } - - case type::list_add: - case type::list_added: - case type::list_remove: - case type::list_removed: - case type::list_subscribe: - case type::list_subscribed: - case type::list_unsubscribe: - case type::list_unsubscribed: - { - new(&first._user_and_list._user) user(std::move(second._user_and_list._user)); - new(&first._user_and_list._list) list(std::move(second._user_and_list._list)); - - break; - } - - case type::stall: - case type::follow_limit: - case type::unknown_warning: - { - new(&first._warning) std::string(std::move(second._warning)); - - break; - } - - case type::deletion: - case type::scrub_location: - { - first._user_id_and_tweet_id._user_id = second._user_id_and_tweet_id._user_id; - first._user_id_and_tweet_id._tweet_id = second._user_id_and_tweet_id._tweet_id; - - break; - } - - case type::limit: - { - first._limit = second._limit; - - break; - } - - case type::withhold_status: - { - first._withhold_status._user_id = second._withhold_status._user_id; - first._withhold_status._tweet_id = second._withhold_status._tweet_id; - new(&first._withhold_status._countries) std::vector(std::move(second._withhold_status._countries)); - - break; - } - - case type::withhold_user: - { - first._withhold_user._user_id = second._withhold_user._user_id; - new(&first._withhold_user._countries) std::vector(std::move(second._withhold_user._countries)); - - break; - } - - case type::disconnect: - { - first._disconnect = second._disconnect; - - break; - } - - case type::friends: - { - new(&first._friends) std::set(std::move(second._friends)); - - break; - } - - case type::direct: - { - new(&first._direct_message) direct_message(std::move(second._direct_message)); - - break; - } - - case type::invalid: - case type::unknown: - { - break; - } - } - - // Now destruct the second and initialize it with data from the first - second.~notification(); - - second._type = tempType; - - switch (tempType) - { - case type::tweet: - { - new(&second._tweet) tweet(std::move(tempTweet)); - - break; - } - - case type::update_user: - case type::block: - case type::unblock: - case type::follow: - case type::followed: - case type::unfollow: - { - new(&second._user) user(std::move(tempUser)); - - break; - } - - case type::favorite: - case type::favorited: - case type::unfavorite: - case type::unfavorited: - case type::quoted: - { - new(&second._user_and_tweet._user) user(std::move(tempUser)); - new(&second._user_and_tweet._tweet) tweet(std::move(tempTweet)); - - break; - } - - case type::list_created: - case type::list_destroyed: - case type::list_updated: - { - new(&second._list) list(std::move(tempList)); - - break; - } - - case type::list_add: - case type::list_added: - case type::list_remove: - case type::list_removed: - case type::list_subscribe: - case type::list_subscribed: - case type::list_unsubscribe: - case type::list_unsubscribed: - { - new(&second._user_and_list._user) user(std::move(tempUser)); - new(&second._user_and_list._list) list(std::move(tempList)); - - break; - } - - case type::stall: - case type::follow_limit: - case type::unknown_warning: - { - new(&second._warning) std::string(std::move(tempWarning)); - - break; - } - - case type::deletion: - case type::scrub_location: - { - second._user_id_and_tweet_id._user_id = tempUserId; - second._user_id_and_tweet_id._tweet_id = tempTweetId; - - break; - } - - case type::limit: - { - second._limit = tempLimit; - - break; - } - - case type::withhold_status: - { - second._withhold_status._user_id = tempUserId; - second._withhold_status._tweet_id = tempTweetId; - new(&second._withhold_status._countries) std::vector(std::move(tempCountries)); - - break; - } - - case type::withhold_user: - { - second._withhold_user._user_id = tempUserId; - new(&second._withhold_user._countries) std::vector(std::move(tempCountries)); - - break; - } - - case type::disconnect: - { - second._disconnect = tempDisconnectCode; - - break; - } - - case type::friends: - { - new(&second._friends) std::set(std::move(tempFriends)); - - break; - } - - case type::direct: - { - new(&second._direct_message) direct_message(std::move(tempDirectMessage)); - - break; - } - - case type::invalid: - case type::unknown: - { - break; - } - } - } - - const tweet& notification::getTweet() const - { - switch (_type) - { - case type::tweet: - { - return _tweet; - } - - case type::favorite: - case type::favorited: - case type::unfavorite: - case type::unfavorited: - case type::quoted: - { - return _user_and_tweet._tweet; - } - - default: - { - assert(false); - } - } - } - - const user& notification::getUser() const - { - switch (_type) - { - case type::update_user: - case type::block: - case type::unblock: - case type::follow: - case type::followed: - case type::unfollow: - { - return _user; - } - - case type::favorite: - case type::favorited: - case type::unfavorite: - case type::unfavorited: - case type::quoted: - { - return _user_and_tweet._user; - } - - case type::list_add: - case type::list_added: - case type::list_remove: - case type::list_removed: - case type::list_subscribe: - case type::list_subscribed: - case type::list_unsubscribe: - case type::list_unsubscribed: - { - return _user_and_list._user; - } - - default: - { - assert(false); - } - } - } - - const list& notification::getList() const - { - switch (_type) - { - case type::list_created: - case type::list_destroyed: - case type::list_updated: - { - return _list; - } - - case type::list_add: - case type::list_added: - case type::list_remove: - case type::list_removed: - case type::list_subscribe: - case type::list_subscribed: - case type::list_unsubscribe: - case type::list_unsubscribed: - { - return _user_and_list._list; - } - - default: - { - assert(false); - } - } - } - - tweet_id notification::getTweetID() const - { - switch (_type) - { - case type::deletion: - case type::scrub_location: - { - return _user_id_and_tweet_id._tweet_id; - } - - case type::withhold_status: - { - return _withhold_status._tweet_id; - } - - default: - { - assert(false); - } - } - } - - void notification::setTweetID(tweet_id _arg) - { - switch (_type) - { - case type::deletion: - case type::scrub_location: - { - _user_id_and_tweet_id._tweet_id = _arg;; - } - - case type::withhold_status: - { - _withhold_status._tweet_id = _arg; - } - - default: - { - assert(false); - } - } - } - - user_id notification::getUserID() const - { - switch (_type) - { - case type::deletion: - case type::scrub_location: - { - return _user_id_and_tweet_id._user_id; - } - - case type::withhold_status: - { - return _withhold_status._user_id; - } - - case type::withhold_user: - { - return _withhold_user._user_id; - } - - default: - { - assert(false); - } - } - } - - void notification::setUserID(user_id _arg) - { - switch (_type) - { - case type::deletion: - case type::scrub_location: - { - _user_id_and_tweet_id._user_id = _arg; - } - - case type::withhold_status: - { - _withhold_status._user_id = _arg; - } - - case type::withhold_user: - { - _withhold_user._user_id = _arg; - } - - default: - { - assert(false); - } - } - } - - const std::vector& notification::getCountries() const - { - switch (_type) - { - case type::withhold_status: - { - return _withhold_status._countries; - } - - case type::withhold_user: - { - return _withhold_user._countries; - } - - default: - { - assert(false); - } - } - } - - disconnect_code notification::getDisconnectCode() const - { - assert(_type == type::disconnect); - - return _disconnect; - } - - void notification::setDisconnectCode(disconnect_code _arg) - { - assert(_type == type::disconnect); - - _disconnect = _arg; - } - - const std::set& notification::getFriends() const - { - assert(_type == type::friends); - - return _friends; - } - - const direct_message& notification::getDirectMessage() const - { - assert(_type == type::direct); - - return _direct_message; - } - - int notification::getLimit() const - { - assert(_type == type::limit); - - return _limit; - } - - void notification::setLimit(int _arg) - { - assert(_type == type::limit); - - _limit = _arg; - } - - const std::string& notification::getWarning() const - { - switch (_type) - { - case type::stall: - case type::follow_limit: - case type::unknown_warning: - { - return _warning; - } - - default: - { - assert(false); - } - } - } - -}; diff --git a/src/notification.h b/src/notification.h deleted file mode 100644 index ad649c3..0000000 --- a/src/notification.h +++ /dev/null @@ -1,192 +0,0 @@ -#ifndef NOTIFICATION_H_69AEF4CC -#define NOTIFICATION_H_69AEF4CC - -#include -#include -#include -#include "tweet.h" -#include "user.h" -#include "list.h" -#include "direct_message.h" - -namespace twitter { - - class client; - - enum class disconnect_code - { - shutdown, - duplicate, - stall, - normal, - token_revoked, - admin_logout, - limit, - exception, - broker, - load, - unknown - }; - - class notification { - public: - enum class type { - // Tweet object - tweet, - - // User object - update_user, - block, - unblock, - follow, - followed, - unfollow, - - // User and tweet - favorite, - favorited, - unfavorite, - unfavorited, - quoted, - - // List - list_created, - list_destroyed, - list_updated, - - // User and list - list_add, - list_added, - list_remove, - list_removed, - list_subscribe, - list_subscribed, - list_unsubscribe, - list_unsubscribed, - - // Warning - stall, - follow_limit, - unknown_warning, - - // User ID and tweet ID - deletion, - scrub_location, - - // Special - limit, - withhold_status, - withhold_user, - disconnect, - friends, - direct, - - // Nothing - unknown, - invalid - }; - - type getType() const; - - notification() {} - notification(const user& currentUser, std::string data); - - notification(const notification& other); - notification(notification&& other); - notification& operator=(notification other); - ~notification(); - - friend void swap(notification& first, notification& second); - - const tweet& getTweet() const; - tweet& getTweet() - { - return const_cast(static_cast(*this).getTweet()); - } - - const user& getUser() const; - user& getUser() - { - return const_cast(static_cast(*this).getUser()); - } - - const list& getList() const; - list& getList() - { - return const_cast(static_cast(*this).getList()); - } - - tweet_id getTweetID() const; - void setTweetID(tweet_id _arg); - - user_id getUserID() const; - void setUserID(user_id _arg); - - const std::vector& getCountries() const; - std::vector& getCountries() - { - return const_cast&>(static_cast(*this).getCountries()); - } - - disconnect_code getDisconnectCode() const; - void setDisconnectCode(disconnect_code _arg); - - const std::set& getFriends() const; - std::set& getFriends() - { - return const_cast&>(static_cast(*this).getFriends()); - } - - const direct_message& getDirectMessage() const; - direct_message& getDirectMessage() - { - return const_cast(static_cast(*this).getDirectMessage()); - } - - int getLimit() const; - void setLimit(int _arg); - - const std::string& getWarning() const; - std::string& getWarning() - { - return const_cast(static_cast(*this).getWarning()); - } - - private: - union { - tweet _tweet; - user _user; - list _list; - struct { - user _user; - tweet _tweet; - } _user_and_tweet; - struct { - user _user; - list _list; - } _user_and_list; - std::string _warning; - struct { - user_id _user_id; - tweet_id _tweet_id; - } _user_id_and_tweet_id; - int _limit; - struct { - user_id _user_id; - tweet_id _tweet_id; - std::vector _countries; - } _withhold_status; - struct { - user_id _user_id; - std::vector _countries; - } _withhold_user; - disconnect_code _disconnect; - std::set _friends; - direct_message _direct_message; - }; - type _type = type::invalid; - }; - -}; - -#endif /* end of include guard: NOTIFICATION_H_69AEF4CC */ diff --git a/src/stream.cpp b/src/stream.cpp deleted file mode 100644 index 86d177c..0000000 --- a/src/stream.cpp +++ /dev/null @@ -1,295 +0,0 @@ -#include "stream.h" -#include -#include -#include -#include "util.h" -#include "notification.h" -#include "request.h" - -namespace twitter { - - stream::stream( - const auth& tauth, - notify_callback callback, - bool with_followings, - bool receive_all_replies, - std::list track, - std::list locations) : - _auth(tauth), - _notify(callback), - _currentUser(get( - _auth, - "https://api.twitter.com/1.1/account/verify_credentials.json") - .perform()), - _thread(&stream::run, this, generateUrl(with_followings, receive_all_replies, track, locations)) - { - } - - stream::~stream() - { - if (_thread.joinable()) - { - _stop = true; - _thread.join(); - } - } - - std::string stream::generateUrl( - bool with_followings, - bool receive_all_replies, - std::list track, - std::list locations) - { - std::list arguments; - - if (receive_all_replies) - { - arguments.push_back("replies=all"); - } - - if (!with_followings) - { - arguments.push_back("with=user"); - } - - if (!track.empty()) - { - std::ostringstream trackstr; - trackstr << "track="; - - for (auto it = std::begin(track); it != std::end(track); it++) - { - if (it != std::begin(track)) - { - trackstr << ","; - } - - trackstr << OAuth::HttpEncodeQueryValue(*it); - } - - arguments.push_back(trackstr.str()); - } - - if (!locations.empty()) - { - std::ostringstream localstr; - localstr << "locations="; - - for (auto it = std::begin(locations); it != std::end(locations); it++) - { - if (it != std::begin(locations)) - { - localstr << ","; - } - - localstr << (double)it->getSouthWestLongitude() << ","; - localstr << (double)it->getSouthWestLatitude() << ","; - localstr << (double)it->getNorthEastLongitude() << ","; - localstr << (double)it->getNorthEastLatitude(); - } - - arguments.push_back(localstr.str()); - } - - std::ostringstream urlstr; - urlstr << "https://userstream.twitter.com/1.1/user.json"; - - if (!arguments.empty()) - { - urlstr << "?"; - urlstr << implode(std::begin(arguments), std::end(arguments), "&"); - } - - return urlstr.str(); - } - - void stream::run(std::string url) - { - _backoff_type = backoff::none; - _backoff_amount = std::chrono::milliseconds(0); - for (;;) - { - curl::curl_ios ios(this, [] (void* contents, size_t size, size_t nmemb, void* userp) { - return static_cast(userp)->write(static_cast(contents), size, nmemb); - }); - - curl::curl_easy conn(ios); - curl::curl_header headers; - std::string oauth_header; - - try - { - oauth_header = _auth.getClient().getFormattedHttpHeader(OAuth::Http::Get, url, ""); - - if (!oauth_header.empty()) - { - headers.add(oauth_header); - } - } catch (const OAuth::ParseError& error) - { - std::cout << "Error generating OAuth header:" << std::endl; - std::cout << error.what() << std::endl; - std::cout << "This is likely due to a malformed URL." << std::endl; - - assert(false); - } - - try - { - conn.add(nullptr); - conn.add(nullptr); - conn.add([] (void* cdata, curl_off_t, curl_off_t, curl_off_t, curl_off_t) { - return static_cast(cdata)->progress(); - }); - conn.add(this); - conn.add(0); - //conn.add(1); - //conn.add(my_trace); - conn.add(url.c_str()); - conn.add(headers.get()); - } catch (const curl::curl_exception& error) - { - error.print_traceback(); - - assert(false); - } - - bool failure = false; - try - { - conn.perform(); - } catch (const curl::curl_easy_exception& error) - { - failure = true; - if ((error.get_code() == CURLE_ABORTED_BY_CALLBACK) && _stop) - { - break; - } else { - if (_backoff_type == backoff::none) - { - _established = false; - _backoff_type = backoff::network; - _backoff_amount = std::chrono::milliseconds(0); - } - } - } - - if (!failure) - { - long response_code = conn.get_info().get(); - if (response_code == 420) - { - if (_backoff_type == backoff::none) - { - _established = false; - _backoff_type = backoff::rate_limit; - _backoff_amount = std::chrono::minutes(1); - } - } else if (response_code != 200) - { - if (_backoff_type == backoff::none) - { - _established = false; - _backoff_type = backoff::http; - _backoff_amount = std::chrono::seconds(5); - } - } else { - if (_backoff_type == backoff::none) - { - _established = false; - _backoff_type = backoff::network; - _backoff_amount = std::chrono::milliseconds(0); - } - } - } - - std::this_thread::sleep_for(_backoff_amount); - - switch (_backoff_type) - { - case backoff::network: - { - if (_backoff_amount < std::chrono::seconds(16)) - { - _backoff_amount += std::chrono::milliseconds(250); - } - - break; - } - - case backoff::http: - { - if (_backoff_amount < std::chrono::seconds(320)) - { - _backoff_amount *= 2; - } - - break; - } - - case backoff::rate_limit: - { - _backoff_amount *= 2; - - break; - } - - case backoff::none: - { - break; - } - } - } - } - - size_t stream::write(char* ptr, size_t size, size_t nmemb) - { - for (size_t i = 0; i < size*nmemb; i++) - { - if (ptr[i] == '\r') - { - i++; // Skip the \n - - if (!_buffer.empty()) - { - notification n(_currentUser, _buffer); - if (n.getType() == notification::type::friends) - { - _established = true; - _backoff_type = backoff::none; - _backoff_amount = std::chrono::milliseconds(0); - } - - _notify(std::move(n)); - - _buffer = ""; - } - } else { - _buffer.push_back(ptr[i]); - } - } - - time(&_last_write); - - return size*nmemb; - } - - int stream::progress() - { - if (_stop) - { - return 1; - } - - if (_established) - { - if (difftime(time(NULL), _last_write) >= 90) - { - return 1; - } - } - - return 0; - } - -} diff --git a/src/stream.h b/src/stream.h deleted file mode 100644 index f6ce91e..0000000 --- a/src/stream.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef STREAM_H_E9146952 -#define STREAM_H_E9146952 - -#include -#include -#include -#include -#include -#include "bounding_box.h" -#include "auth.h" -#include "user.h" - -namespace twitter { - - class notification; - - class - [[deprecated("The Twitter streaming API will sunset on August 16th, 2018")]] - stream { - public: - - typedef std::function notify_callback; - - stream( - const auth& tauth, - notify_callback callback, - bool with_followings = true, - bool receive_all_replies = false, - std::list track = {}, - std::list locations = {}); - - ~stream(); - - stream(const stream& other) = delete; - stream(stream&& other) = delete; - stream& operator=(const stream& other) = delete; - stream& operator=(stream&& other) = delete; - - private: - enum class backoff { - none, - network, - http, - rate_limit - }; - - static std::string generateUrl( - bool with_followings, - bool receive_all_replies, - std::list track, - std::list locations); - - void run(std::string url); - int progress(); - size_t write(char* ptr, size_t size, size_t nmemb); - - const auth& _auth; - notify_callback _notify; - bool _stop = false; - std::string _buffer; - time_t _last_write; - bool _established = false; - backoff _backoff_type = backoff::none; - std::chrono::milliseconds _backoff_amount; - user _currentUser; - std::thread _thread; - }; - -} - -#endif /* end of include guard: STREAM_H_E9146952 */ diff --git a/src/twitter.h b/src/twitter.h index a4f336e..382cdce 100644 --- a/src/twitter.h +++ b/src/twitter.h @@ -12,10 +12,8 @@ namespace twitter { #include "auth.h" #include "client.h" #include "timeline.h" -#include "stream.h" #include "tweet.h" #include "user.h" -#include "notification.h" #include "list.h" #include "direct_message.h" #include "configuration.h" -- cgit 1.4.1