From 5b13c80ee9ea6722590b195fb04b9f5f4eb1f06b Mon Sep 17 00:00:00 2001 From: Sarang Bharadwaj Date: Sun, 10 Jun 2012 21:39:29 +0530 Subject: [PATCH] Populating user's roster --- backends/twitter/Requests/FetchFriends.cpp | 52 +++++-------- backends/twitter/Requests/FetchFriends.h | 14 ++-- backends/twitter/Requests/TimelineRequest.cpp | 50 +++++-------- backends/twitter/Requests/TimelineRequest.h | 12 +-- backends/twitter/TwitterPlugin.cpp | 75 +++++++++++++++++-- backends/twitter/TwitterPlugin.h | 10 ++- src/config.cpp | 1 + 7 files changed, 131 insertions(+), 83 deletions(-) diff --git a/backends/twitter/Requests/FetchFriends.cpp b/backends/twitter/Requests/FetchFriends.cpp index 34afc100..6f703007 100644 --- a/backends/twitter/Requests/FetchFriends.cpp +++ b/backends/twitter/Requests/FetchFriends.cpp @@ -4,45 +4,31 @@ DEFINE_LOGGER(logger, "FetchFriends") void FetchFriends::run() { replyMsg = ""; - if( twitObj->friendsIdsGet(twitObj->getTwitterUsername())) { - - while(replyMsg.length() == 0) { - twitObj->getLastWebResponse( replyMsg ); - } - LOG4CXX_INFO(logger, user << " - " << replyMsg.length() << " " << replyMsg << "\n" ); + success = twitObj->friendsIdsGet(twitObj->getTwitterUsername()); + if(!success) return; - std::vector IDs = getIDs( replyMsg ); - - twitObj->userLookup(IDs, true); - twitObj->getLastWebResponse( replyMsg ); + twitObj->getLastWebResponse( replyMsg ); + LOG4CXX_INFO(logger, user << " - " << replyMsg.length() << " " << replyMsg << "\n" ); + std::vector IDs = getIDs( replyMsg ); + + success = twitObj->userLookup(IDs, true); + if(!success) return; - LOG4CXX_INFO(logger, user << " - UserLookUp web response - " << replyMsg.length() << " " << replyMsg << "\n" ); - - std::vector users = getUsers( replyMsg ); - - userlist = "\n***************USER LIST****************\n"; - for(int i=0 ; i < users.size() ; i++) { - userlist += "*)" + users[i].getUserName() + " (" + users[i].getScreenName() + ")\n"; - } - userlist += "***************************************\n"; - - } + twitObj->getLastWebResponse( replyMsg ); + LOG4CXX_INFO(logger, user << " - UserLookUp web response - " << replyMsg.length() << " " << replyMsg << "\n" ); + friends = getUsers( replyMsg ); } void FetchFriends::finalize() { - if(replyMsg != "" ) { - std::string error = getErrorMessage(replyMsg); - if(error.length()) { - np->handleMessage(user, "twitter-account", error); - LOG4CXX_INFO(logger, user << ": " << error); - } else { - LOG4CXX_INFO(logger, user << ": " << userlist); - np->handleMessage(user, "twitter-account", userlist); - } - } else { + if(!success) { twitObj->getLastCurlError( replyMsg ); - LOG4CXX_INFO(logger, user << " - friendsIdsGet error - " << replyMsg ); - } + LOG4CXX_ERROR(logger, user << " - " << replyMsg) + callBack(user, friends, replyMsg); + } else { + std::string error = getErrorMessage(replyMsg); + if(error.length()) LOG4CXX_ERROR(logger, user << " - " << error) + callBack(user, friends, error); + } } diff --git a/backends/twitter/Requests/FetchFriends.h b/backends/twitter/Requests/FetchFriends.h index dbd5bf8f..ee2e4062 100644 --- a/backends/twitter/Requests/FetchFriends.h +++ b/backends/twitter/Requests/FetchFriends.h @@ -4,9 +4,11 @@ #include "../ThreadPool.h" #include "../libtwitcurl/twitcurl.h" #include "../TwitterResponseParser.h" -#include "transport/networkplugin.h" #include "transport/logging.h" #include +#include +#include +#include #include using namespace Transport; @@ -16,14 +18,16 @@ class FetchFriends : public Thread twitCurl *twitObj; std::string user; std::string replyMsg; - std::string userlist; - NetworkPlugin *np; + std::vector friends; + bool success; + boost::function< void (std::string, std::vector &, std::string) > callBack; public: - FetchFriends(NetworkPlugin *_np, twitCurl *obj, const std::string &_user) { + FetchFriends(twitCurl *obj, const std::string &_user, + boost::function< void (std::string, std::vector &, std::string) > cb) { twitObj = obj->clone(); - np = _np; user = _user; + callBack = cb; } ~FetchFriends() { diff --git a/backends/twitter/Requests/TimelineRequest.cpp b/backends/twitter/Requests/TimelineRequest.cpp index f8c15d14..19a3a367 100644 --- a/backends/twitter/Requests/TimelineRequest.cpp +++ b/backends/twitter/Requests/TimelineRequest.cpp @@ -2,47 +2,31 @@ DEFINE_LOGGER(logger, "TimelineRequest") void TimelineRequest::run() { - + LOG4CXX_INFO(logger, "Sending timeline request for user " << userRequested) + if(userRequested != "") success = twitObj->timelineUserGet(false, false, 20, userRequested, false); else success = twitObj->timelineHomeGet(since_id); + if(!success) return; + replyMsg = ""; - if(success) { - LOG4CXX_INFO(logger, "Sending timeline request for user " << user) + + twitObj->getLastWebResponse( replyMsg ); - while(replyMsg.length() == 0) { - twitObj->getLastWebResponse( replyMsg ); - } - - LOG4CXX_INFO(logger, user << " - " << replyMsg.length() << " " << replyMsg << "\n" ); - - std::vector tweets = getTimeline(replyMsg); - timeline = ""; - - if(tweets.size() && (since_id == "" || - (since_id != "" && tweets[0].getID() != np->getMostRecentTweetID(user)) )) { - for(int i=0 ; iupdateUsersLastTweetID(user, tweets[0].getID()); - } - } + LOG4CXX_INFO(logger, user << " - " << replyMsg.length() << " " << replyMsg << "\n" ); + + tweets = getTimeline(replyMsg); } void TimelineRequest::finalize() { - if(success && timeline != "") { - std::string error = getErrorMessage(replyMsg); - if(error.length()) { - np->handleMessage(user, "twitter-account", error); - LOG4CXX_INFO(logger, user << ": " << error); - } else { - LOG4CXX_INFO(logger, user << "'s timeline\n" << replyMsg); - np->handleMessage(user, "twitter-account", timeline); //send timeline - } - } - else { + if(!success) { twitObj->getLastCurlError( replyMsg ); - LOG4CXX_ERROR(logger, user << " - " << replyMsg ); - } + LOG4CXX_ERROR(logger, user << " - " << replyMsg) + callBack(user, userRequested, tweets, replyMsg); + } else { + std::string error = getErrorMessage(replyMsg); + if(error.length()) LOG4CXX_ERROR(logger, user << " - " << error) + callBack(user, userRequested, tweets, error); + } } diff --git a/backends/twitter/Requests/TimelineRequest.h b/backends/twitter/Requests/TimelineRequest.h index 464ce613..de39aa52 100644 --- a/backends/twitter/Requests/TimelineRequest.h +++ b/backends/twitter/Requests/TimelineRequest.h @@ -4,11 +4,10 @@ #include "../ThreadPool.h" #include "../libtwitcurl/twitcurl.h" #include "../TwitterResponseParser.h" -#include "transport/networkplugin.h" -#include "../TwitterPlugin.h" #include "transport/logging.h" #include #include +#include using namespace Transport; @@ -18,18 +17,19 @@ class TimelineRequest : public Thread std::string user; std::string userRequested; std::string replyMsg; - std::string timeline; std::string since_id; - TwitterPlugin *np; bool success; + boost::function< void (std::string&, std::string&, std::vector &, std::string&) > callBack; + std::vector tweets; public: - TimelineRequest(TwitterPlugin *_np, twitCurl *obj, const std::string &_user, const std::string &_user2, const std::string &_since_id) { + TimelineRequest(twitCurl *obj, const std::string &_user, const std::string &_user2, const std::string &_since_id, + boost::function< void (std::string&, std::string&, std::vector &, std::string&) > cb) { twitObj = obj->clone(); - np = _np; user = _user; userRequested = _user2; since_id = _since_id; + callBack = cb; } ~TimelineRequest() { diff --git a/backends/twitter/TwitterPlugin.cpp b/backends/twitter/TwitterPlugin.cpp index 4915a4a3..20ba95cc 100644 --- a/backends/twitter/TwitterPlugin.cpp +++ b/backends/twitter/TwitterPlugin.cpp @@ -21,6 +21,13 @@ TwitterPlugin::TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, Stora LOG4CXX_ERROR(logger, "Couldn't find consumer key and/or secret. Please check config file."); exit(0); } + + twitterMode = SINGLECONTACT; + if(CONFIG_HAS_KEY(config, "twitter.mode") == false) { + LOG4CXX_INFO(logger, "Using default single contact mode!"); + } else twitterMode = (mode)CONFIG_INT(config, "twitter.mode"); + + consumerKey = CONFIG_STRING(config, "twitter.consumer_key"); consumerSecret = CONFIG_STRING(config, "twitter.consumer_secret"); OAUTH_KEY = "oauth_key"; @@ -108,7 +115,7 @@ void TwitterPlugin::handleMessageSendRequest(const std::string &user, const std: if(legacyName == "twitter-account") { - char ch; + //char ch; std::string cmd = "", data = ""; int i; @@ -125,8 +132,10 @@ void TwitterPlugin::handleMessageSendRequest(const std::string &user, const std: tp->runAsThread(new DirectMessageRequest(np, sessions[user], user, username, data)); } else if(cmd == "#status") tp->runAsThread(new StatusUpdateRequest(np, sessions[user], user, data)); - else if(cmd == "#timeline") tp->runAsThread(new TimelineRequest(np, sessions[user], user, data, "")); - else if(cmd == "#friends") tp->runAsThread(new FetchFriends(np, sessions[user], user)); + else if(cmd == "#timeline") tp->runAsThread(new TimelineRequest(sessions[user], user, data, "", + boost::bind(&TwitterPlugin::displayTweets, this, _1, _2, _3, _4))); + else if(cmd == "#friends") tp->runAsThread(new FetchFriends(sessions[user], user, + boost::bind(&TwitterPlugin::displayFriendlist, this, _1, _2, _3))); else handleMessage(user, "twitter-account", "Unknown command! Type #help for a list of available commands."); } } @@ -149,7 +158,8 @@ void TwitterPlugin::pollForTweets() std::set::iterator it = onlineUsers.begin(); while(it != onlineUsers.end()) { std::string user = *it; - tp->runAsThread(new TimelineRequest(np, sessions[user], user, "", mostRecentTweetID[user])); + tp->runAsThread(new TimelineRequest(sessions[user], user, "", mostRecentTweetID[user], + boost::bind(&TwitterPlugin::displayTweets, this, _1, _2, _3, _4))); it++; } m_timer->start(); @@ -240,6 +250,12 @@ void TwitterPlugin::pinExchangeComplete(const std::string user, const std::strin sessions[user]->getOAuth().setOAuthTokenKey( OAuthAccessTokenKey ); sessions[user]->getOAuth().setOAuthTokenSecret( OAuthAccessTokenSecret ); connectionState[user] = CONNECTED; + + if(twitterMode == MULTIPLECONTACT) { + tp->runAsThread(new FetchFriends(sessions[user], user, + boost::bind(&TwitterPlugin::populateRoster, this, _1, _2, _3))); + } + onlineUsers.insert(user); mostRecentTweetID[user] = ""; } @@ -253,5 +269,54 @@ void TwitterPlugin::updateUsersLastTweetID(const std::string user, const std::st std::string TwitterPlugin::getMostRecentTweetID(const std::string user) { boost::mutex::scoped_lock lock(userlock); - return mostRecentTweetID[user]; + std::string ID = "-1"; + if(onlineUsers.count(user)) ID = mostRecentTweetID[user]; + return ID; } + +/************************************** Twitter response functions **********************************/ + +void TwitterPlugin::populateRoster(std::string &user, std::vector &friends, std::string &errMsg) +{ + if(errMsg.length() == 0) + { + for(int i=0 ; i(), pbnetwork::STATUS_ONLINE); + } + } else handleMessage(user, "twitter-account", std::string("Error populating roster - ") + errMsg); +} + +void TwitterPlugin::displayFriendlist(std::string &user, std::vector &friends, std::string &errMsg) +{ + if(errMsg.length() == 0) + { + std::string userlist = "\n***************USER LIST****************\n"; + for(int i=0 ; i < friends.size() ; i++) { + userlist += " - " + friends[i].getUserName() + " (" + friends[i].getScreenName() + ")\n"; + } + userlist += "***************************************\n"; + handleMessage(user, "twitter-account", userlist); + } else handleMessage(user, "twitter-account", errMsg); + +} + +void TwitterPlugin::displayTweets(std::string &user, std::string &userRequested, std::vector &tweets , std::string &errMsg) +{ + if(errMsg.length() == 0) { + std::string timeline = ""; + + for(int i=0 ; i &friends, std::string &errMsg); + void displayFriendlist(std::string &user, std::vector &friends, std::string &errMsg); + void displayTweets(std::string &user, std::string &userRequested, std::vector &tweets , std::string &errMsg); + /***********************************************************************************/ + private: enum status {NEW, WAITING_FOR_PIN, CONNECTED, DISCONNECTED}; - + enum mode {SINGLECONTACT, MULTIPLECONTACT, CHATROOM}; + Config *config; std::string consumerKey; @@ -105,6 +112,7 @@ class TwitterPlugin : public NetworkPlugin { std::map connectionState; std::map mostRecentTweetID; std::set onlineUsers; + mode twitterMode; }; #endif diff --git a/src/config.cpp b/src/config.cpp index e0b7b64a..f17efb70 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -122,6 +122,7 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description ("backend.no_vcard_fetch", value()->default_value(false), "True if VCards for buddies should not be fetched. Only avatars will be forwarded.") ("twitter.consumer_key", value()->default_value(""), "Twitter APP Consumer Key.") ("twitter.consumer_secret", value()->default_value(""), "Twitter APP Consumer Secret") + ("twitter.mode", value()->default_value(0), "Twitter mode") ("proxy.server", value()->default_value("localhost"), "Proxy IP.") ("proxy.user", value()->default_value(""), "Proxy user.") ("proxy.password", value()->default_value(""), "Proxy Password.")