Changeset - bdb8aed78f63
[Not reviewed]
backends/twitter/Requests/CreateFriendRequest.cpp
Show inline comments
 
#include "CreateFriendRequest.h"
 
DEFINE_LOGGER(logger, "CreateFriendRequest")
 

	
 
void CreateFriendRequest::run()
 
{
 
	LOG4CXX_INFO(logger, user << ": Sending follow request for " << frnd)
 
	LOG4CXX_INFO(logger, user << " - Sending follow request for " << frnd)
 
	replyMsg = "";
 
	success = twitObj->friendshipCreate(frnd, false);
 
	if(success) twitObj->getLastWebResponse(replyMsg);
 
	if(success) {
 
		twitObj->getLastWebResponse(replyMsg);
 

	
 
		LOG4CXX_INFO(logger, user << replyMsg)		
 

	
 
	   	friendInfo = getUser(replyMsg);
 
		if(friendInfo.getScreenName() == "") LOG4CXX_INFO(logger, user << " - Was unable to fetch user info for " << frnd);
 
	}
 
}
 

	
 
void CreateFriendRequest::finalize()
 
{
 
	if(!success) {
 
		std::string error;
 
		twitObj->getLastCurlError(error);
 
		LOG4CXX_ERROR(logger, user << " - Curl error: " << error)
 
		callBack(user, frnd, error);
 
		callBack(user, friendInfo, error);
 
	} else {
 
		std::string error;
 
		error = getErrorMessage(replyMsg);
 
		if(error.length()) {
 
			LOG4CXX_ERROR(logger, user << " - " << error)
 
			//LOG4CXX_ERROR(logger, user << " " << replyMsg)
 
		}
 
		else LOG4CXX_INFO(logger, user << ": Now following " << frnd)
 
		callBack(user, frnd, error);
 
		callBack(user, friendInfo, error);
 
	}
 
}
backends/twitter/Requests/CreateFriendRequest.h
Show inline comments
 
#ifndef CREATE_FRIEND
 
#define CREATE_FRIEND
 

	
 
#include "../ThreadPool.h"
 
#include "../TwitterResponseParser.h"
 
#include "../libtwitcurl/twitcurl.h"
 
#include "transport/logging.h"
 
#include <string>
 
#include <boost/function.hpp>
 
#include <iostream>
 
#include <vector>
 

	
 
using namespace Transport;
 

	
 
class CreateFriendRequest : public Thread
 
{
 
	twitCurl *twitObj;
 
	std::string user;
 
	std::string frnd;
 
	std::string replyMsg;
 
	boost::function< void (std::string&, std::string&, std::string&) > callBack;
 
	
 
	boost::function< void (std::string&, User&, std::string&) > callBack;
 
	User friendInfo;	
 
	bool success;
 

	
 
	public:
 
	CreateFriendRequest(twitCurl *obj, const std::string &_user, const std::string & _frnd,
 
			     		 boost::function< void (std::string&, std::string&, std::string&) >  cb) {
 
			     		 boost::function< void (std::string&, User&, std::string&) >  cb) {
 
		twitObj = obj->clone();
 
		user = _user;
 
		frnd = _frnd;
 
		callBack = cb;
 
	}
 

	
 
	~CreateFriendRequest() {
 
		delete twitObj;
 
	}
 

	
 
	void run();
 
	void finalize();
 
};
 

	
 
#endif
backends/twitter/Requests/DestroyFriendRequest.cpp
Show inline comments
 
#include "DestroyFriendRequest.h"
 
DEFINE_LOGGER(logger, "DestroyFriendRequest")
 

	
 
void DestroyFriendRequest::run()
 
{
 
	replyMsg = "";
 
	success = twitObj->friendshipDestroy(frnd, false);
 
	if(success) twitObj->getLastWebResponse(replyMsg);
 
	if(success) {
 
		twitObj->getLastWebResponse(replyMsg);
 
		
 
		LOG4CXX_INFO(logger, user << replyMsg)		
 
		
 

	
 
	   	friendInfo = getUser(replyMsg);
 
		if(friendInfo.getScreenName() == "") LOG4CXX_INFO(logger, user << " - Was unable to fetch user info for " << frnd);
 
	}
 
}
 

	
 
void DestroyFriendRequest::finalize()
 
{
 
	if(!success) {
 
		std::string error;
 
		twitObj->getLastCurlError(error);
 
		LOG4CXX_ERROR(logger, user << " Curl error: " << error)
 
		callBack(user, frnd, error);
 
		callBack(user, friendInfo, error);
 
	} else {
 
		std::string error;
 
		error = getErrorMessage(replyMsg);
 
		if(error.length()) LOG4CXX_ERROR(logger, user << " - " << error)
 
		callBack(user, frnd, error);
 
		callBack(user, friendInfo, error);
 
	}
 
}
backends/twitter/Requests/DestroyFriendRequest.h
Show inline comments
 
#ifndef DESTROY_FRIEND
 
#define DESTROY_FRIEND
 

	
 
#include "../ThreadPool.h"
 
#include "../TwitterResponseParser.h"
 
#include "../libtwitcurl/twitcurl.h"
 
#include "transport/logging.h"
 
#include <string>
 
#include <boost/function.hpp>
 
#include <iostream>
 
#include <vector>
 

	
 
using namespace Transport;
 

	
 
class DestroyFriendRequest : public Thread
 
{
 
	twitCurl *twitObj;
 
	std::string user;
 
	std::string frnd;
 
	std::string replyMsg;
 
	boost::function< void (std::string&, std::string&, std::string&) > callBack;
 
	boost::function< void (std::string&, User&, std::string&) > callBack;
 
	User friendInfo;	
 
	bool success;
 

	
 
	public:
 
	DestroyFriendRequest(twitCurl *obj, const std::string &_user, const std::string & _frnd,
 
			     		 boost::function< void (std::string&, std::string&, std::string&) >  cb) {
 
			     		 boost::function< void (std::string&, User&, std::string&) >  cb) {
 
		twitObj = obj->clone();
 
		user = _user;
 
		frnd = _frnd;
 
		callBack = cb;
 
	}
 

	
 
	~DestroyFriendRequest() {
 
		delete twitObj;
 
	}
 

	
 
	void run();
 
	void finalize();
 
};
 

	
 
#endif
backends/twitter/Requests/ProfileImageRequest.cpp
Show inline comments
 
new file 100644
 
#include "ProfileImageRequest.h"
 
DEFINE_LOGGER(logger, "ProfileImageRequest")
 

	
 
int ProfileImageRequest::curlCallback(char* data, size_t size, size_t nmemb, ProfileImageRequest* obj)
 
{
 
    int writtenSize = 0;
 
    if(obj && data) {
 
       obj->callbackdata.append(data, size*nmemb);
 
	   writtenSize = (int)(size*nmemb);
 
    }
 
    return writtenSize;
 
}
 

	
 
bool ProfileImageRequest::fetchImage()
 
{
 
	LOG4CXX_INFO(logger, user << " - Fetching  profile image");
 

	
 
	curl_easy_setopt(curlhandle, CURLOPT_CUSTOMREQUEST, NULL);
 
    curl_easy_setopt(curlhandle, CURLOPT_ENCODING, "");
 
    
 
	img = "";
 
	callbackdata = "";
 
    memset(curl_errorbuffer, 0, 1024);
 
	
 
	curl_easy_setopt(curlhandle, CURLOPT_ERRORBUFFER, curl_errorbuffer);
 
	curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, curlCallback);
 
	curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, this);
 
    	
 
	/* Set http request and url */
 
    curl_easy_setopt(curlhandle, CURLOPT_HTTPGET, 1);
 
    curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1);
 
    curl_easy_setopt(curlhandle, CURLOPT_URL, url.c_str());
 
    
 
    /* Send http request and return status*/
 
    return (CURLE_OK == curl_easy_perform(curlhandle));
 
}
 

	
 

	
 
void ProfileImageRequest::run() 
 
{	
 
	if(curlhandle == NULL) {
 
		error = "Failed to init CURL!";
 
		success = false;
 
		return;
 
	}
 
	success = fetchImage();
 
	if(!success) error.assign(curl_errorbuffer);
 
}
 

	
 
void ProfileImageRequest::finalize()
 
{
 
	if(!success) {
 
		LOG4CXX_ERROR(logger,  user << " - " << error)
 
		img = "";
 
		callBack(user, buddy, img, reqID, error);
 
	} else {
 
		//std::string error = getErrorMessage(replyMsg);
 
		//if(error.length()) LOG4CXX_ERROR(logger,  user << " - " << error)
 
		LOG4CXX_INFO(logger, user << " - " << callbackdata);
 
		img = callbackdata;
 
		callBack(user, buddy, img, reqID, error);	
 
	} 
 
}
backends/twitter/Requests/ProfileImageRequest.h
Show inline comments
 
new file 100644
 
#ifndef PROFILEIMAGE_H
 
#define PROFILEIMAGE_H
 

	
 
#include "../ThreadPool.h"
 
#include "../libtwitcurl/curl/curl.h"
 
#include "../TwitterResponseParser.h"
 
#include "transport/logging.h"
 
#include "transport/config.h"
 
#include <string>
 
#include <boost/signals.hpp>
 
#include <boost/function.hpp>
 
#include <boost/bind.hpp>
 
#include <iostream>
 
#include <sstream>
 

	
 
using namespace Transport;
 
using namespace boost::program_options;
 

	
 
class ProfileImageRequest : public Thread
 
{
 
	std::string user;
 
	std::string buddy;
 
	std::string url;
 
	std::string img;
 
	unsigned int reqID;
 
	boost::function< void (std::string&, std::string&, std::string&, int, std::string&) > callBack;
 

	
 

	
 
	bool success;
 
	CURL *curlhandle;
 
	
 
	std::string error;
 
	std::string callbackdata;
 
	char curl_errorbuffer[1024];
 
	bool fetchImage();
 
    static int curlCallback( char* data, size_t size, size_t nmemb, ProfileImageRequest *obj);
 

	
 
	public:
 
	ProfileImageRequest(Config *config, const std::string &_user, const std::string &_buddy, const std::string &_url, unsigned int _reqID,
 
			     boost::function< void (std::string&, std::string&, std::string&, int, std::string&) >  cb) {
 
		
 
		curlhandle = curl_easy_init();
 
		curl_easy_setopt(curlhandle, CURLOPT_PROXY, NULL);
 
		curl_easy_setopt(curlhandle, CURLOPT_PROXYUSERPWD, NULL);
 
		curl_easy_setopt(curlhandle, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
 

	
 
		/************ Set proxy if available *****************************************/
 
		if(CONFIG_HAS_KEY(config,"proxy.server")) {
 
			std::string ip = CONFIG_STRING(config,"proxy.server");
 

	
 
			std::ostringstream out; 
 
			out << CONFIG_INT(config,"proxy.port");
 
			std::string port = out.str();
 

	
 
			std::string puser = CONFIG_STRING(config,"proxy.user");
 
			std::string ppasswd = CONFIG_STRING(config,"proxy.password");
 
	
 
			if(ip != "localhost" && port != "0") {
 
				/* Set proxy details in cURL */
 
				std::string proxyIpPort = ip + ":" + port;
 
				curl_easy_setopt(curlhandle, CURLOPT_PROXY, proxyIpPort.c_str());
 

	
 
				/* Prepare username and password for proxy server */
 
				if(puser.length() && ppasswd.length()) {
 
					std::string proxyUserPass = puser + ":" + ppasswd;
 
					curl_easy_setopt(curlhandle, CURLOPT_PROXYUSERPWD, proxyUserPass.c_str());
 
				}
 
			}
 
		}
 
		/*****************************************************************************/
 

	
 
		user = _user;
 
		buddy = _buddy;
 
		url = _url;
 
		reqID = _reqID;
 
		callBack = cb;
 
	}
 

	
 
	~ProfileImageRequest() {
 
		if(curlhandle) {
 
			curl_easy_cleanup(curlhandle);
 
			curlhandle = NULL;
 
		}
 
	}
 

	
 
	void run();
 
	void finalize();
 
};
 
#endif
backends/twitter/TwitterPlugin.cpp
Show inline comments
 
#include "TwitterPlugin.h"
 
#include "Requests/StatusUpdateRequest.h"
 
#include "Requests/DirectMessageRequest.h"
 
#include "Requests/TimelineRequest.h"
 
#include "Requests/FetchFriends.h"
 
#include "Requests/HelpMessageRequest.h"
 
#include "Requests/PINExchangeProcess.h"
 
#include "Requests/OAuthFlow.h"
 
#include "Requests/CreateFriendRequest.h"
 
#include "Requests/DestroyFriendRequest.h"
 
#include "Requests/RetweetRequest.h"
 
#include "Requests/ProfileImageRequest.h"
 

	
 
DEFINE_LOGGER(logger, "Twitter Backend");
 

	
 
TwitterPlugin *np = NULL;
 
Swift::SimpleEventLoop *loop_; // Event Loop
 

	
 
#define abs(x) ((x)<0?-(x):(x))
 
static int cmp(std::string a, std::string b)
 
{
 
	int diff = abs((int)a.size() - (int)b.size());
 
	if(a.size() < b.size()) a = std::string(diff,'0') + a;
 
	else b = std::string(diff,'0') + b;
 
	
 
	if(a == b) return 0;
 
	if(a < b) return -1;
 
	return 1;
 
}
 

	
 

	
 
TwitterPlugin::TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port) : NetworkPlugin() 
 
{
 
	this->config = config;
 
	this->storagebackend = storagebackend;
 

	
 
@@ -118,49 +119,48 @@ void TwitterPlugin::handleLoginRequest(const std::string &user, const std::strin
 
	handleBuddyChanged(user, adminLegacyName, adminAlias, std::vector<std::string>(), pbnetwork::STATUS_ONLINE);
 
	nickName[user] = "";
 
	//setTwitterMode(user, 0);
 
	
 
	LOG4CXX_INFO(logger, "Querying database for usersettings of " << user)
 
	
 
	std::string key, secret;
 
	getUserOAuthKeyAndSecret(user, key, secret);
 

	
 
	if(key == "" || secret == "") {			
 
		LOG4CXX_INFO(logger, "Intiating OAuth Flow for user " << user)
 
		setTwitterMode(user, 0);
 
		tp->runAsThread(new OAuthFlow(np, sessions[user], user, sessions[user]->getTwitterUsername()));
 
	} else {
 
		LOG4CXX_INFO(logger, user << " is already registerd. Using the stored oauth key and secret")
 
		LOG4CXX_INFO(logger, key << " " << secret)	
 
		pinExchangeComplete(user, key, secret);
 
	}
 
}
 

	
 
// User logging out
 
void TwitterPlugin::handleLogoutRequest(const std::string &user, const std::string &legacyName) 
 
{
 
	if(onlineUsers.count(user)) {
 
		clearRoster(user);
 
		delete sessions[user];
 
		sessions[user] = NULL;
 
		connectionState[user] = DISCONNECTED;
 
		onlineUsers.erase(user);
 
	}
 
}
 

	
 
void TwitterPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password)
 
{
 
	if(room == adminChatRoom) {
 
		
 
		LOG4CXX_INFO(logger, "Received Join Twitter room request for " << user)
 

	
 
		setTwitterMode(user, 2);
 
			
 
		handleParticipantChanged(user, adminNickName, room, 0, pbnetwork::STATUS_ONLINE);
 

	
 
		nickName[user] = nickname;
 

	
 
		handleMessage(user, adminChatRoom, "Connected to Twitter Room! Populating your followers list", adminNickName);
 
		
 
		tp->runAsThread(new FetchFriends(sessions[user], user,
 
										 boost::bind(&TwitterPlugin::populateRoster, this, _1, _2, _3)));
 
	} else {
 
@@ -270,48 +270,62 @@ void TwitterPlugin::handleMessageSendRequest(const std::string &user, const std:
 
}
 

	
 
void TwitterPlugin::handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) 
 
{
 
	if(connectionState[user] != CONNECTED) {
 
		LOG4CXX_ERROR(logger, user << " is not connected to twitter!")
 
		return;
 
	}
 

	
 
	LOG4CXX_INFO(logger, user << " Adding Twitter contact " << buddyName)
 
	tp->runAsThread(new CreateFriendRequest(sessions[user], user, buddyName, 
 
											boost::bind(&TwitterPlugin::createFriendResponse, this, _1, _2, _3)));
 
}
 

	
 
void TwitterPlugin::handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) 
 
{
 
	if(connectionState[user] != CONNECTED) {
 
		LOG4CXX_ERROR(logger, user << " is not connected to twitter!")
 
		return;
 
	}
 
	tp->runAsThread(new DestroyFriendRequest(sessions[user], user, buddyName, 
 
											 boost::bind(&TwitterPlugin::deleteFriendResponse, this, _1, _2, _3)));
 
}
 

	
 
void TwitterPlugin::handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id)
 
{
 
	LOG4CXX_INFO(logger, user << " - VCardRequest for " << legacyName << ", " << imgURL[legacyName])
 
	if(connectionState[user] != CONNECTED) {
 
		LOG4CXX_ERROR(logger, user << " is not connected to twitter!")
 
		return;
 
	}
 

	
 
	if(getTwitterMode(user) != SINGLECONTACT && buddies[user].count(legacyName) && imgURL[legacyName].length()) {
 
		LOG4CXX_INFO(logger, user << " - Initiating VCard request for " << legacyName);
 
		tp->runAsThread(new ProfileImageRequest(config, user, legacyName, imgURL[legacyName], id,
 
										        boost::bind(&TwitterPlugin::profileImageResponse, this, _1, _2, _3, _4, _5)));
 
	}
 
}
 

	
 
void TwitterPlugin::pollForTweets()
 
{
 
	boost::mutex::scoped_lock lock(userlock);
 
	std::set<std::string>::iterator it = onlineUsers.begin();
 
	while(it != onlineUsers.end()) {
 
		std::string user = *it;
 
		tp->runAsThread(new TimelineRequest(sessions[user], user, "", mostRecentTweetID[user],
 
											boost::bind(&TwitterPlugin::displayTweets, this, _1, _2, _3, _4)));
 
		it++;
 
	}
 
	tweet_timer->start();
 
}
 

	
 
void TwitterPlugin::pollForDirectMessages()
 
{
 
	boost::mutex::scoped_lock lock(userlock);
 
	std::set<std::string>::iterator it = onlineUsers.begin();
 
	while(it != onlineUsers.end()) {
 
		std::string user = *it;
 
		tp->runAsThread(new DirectMessageRequest(sessions[user], user, "", mostRecentDirectMessageID[user],
 
											boost::bind(&TwitterPlugin::directMessageResponse, this, _1, _2, _3, _4)));
 
		it++;
 
	}
 
@@ -489,66 +503,66 @@ std::string TwitterPlugin::getMostRecentDMID(const std::string user)
 

	
 
/************************************** Twitter response functions **********************************/
 
void TwitterPlugin::statusUpdateResponse(std::string &user, std::string &errMsg)
 
{
 
	if(errMsg.length()) {
 
		handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
							errMsg, twitterMode[user] == CHATROOM ? adminNickName : "");
 
	} else {
 
		handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
							"Status Update successful", twitterMode[user] == CHATROOM ? adminNickName : "");
 
	}
 
}
 

	
 
void TwitterPlugin::helpMessageResponse(std::string &user, std::string &msg)
 
{
 
	handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
						msg, twitterMode[user] == CHATROOM ? adminNickName : "");
 
}
 

	
 
void TwitterPlugin::clearRoster(const std::string user)
 
{
 
	if(buddies[user].size() == 0) return;
 
	std::set<std::string>::iterator it = buddies[user].begin();
 
	while(it != buddies[user].end()) {
 
		handleBuddyChanged(user, *it, *it, std::vector<std::string>(), pbnetwork::STATUS_NONE);
 
		//handleBuddyChanged(user, *it, *it, std::vector<std::string>(), pbnetwork::STATUS_NONE);
 
		handleBuddyRemoved(user, *it);
 
		it++;
 
	}
 
	buddies[user].clear();
 
}
 

	
 
void TwitterPlugin::populateRoster(std::string &user, std::vector<User> &friends, std::string &errMsg) 
 
{
 
	if(errMsg.length() == 0) 
 
	{
 
		for(int i=0 ; i<friends.size() ; i++) {
 
			if(twitterMode[user] == MULTIPLECONTACT)
 
				handleBuddyChanged(user, friends[i].getScreenName(), friends[i].getScreenName(), std::vector<std::string>(), pbnetwork::STATUS_ONLINE);
 
			else if(twitterMode[user] == CHATROOM) {
 
			else if(twitterMode[user] == CHATROOM)
 
				handleParticipantChanged(user, friends[i].getScreenName(), adminChatRoom, 0, pbnetwork::STATUS_ONLINE);
 
			buddies[user].insert(friends[i].getScreenName());
 
			}
 
			imgURL[friends[i].getScreenName()] = friends[i].getProfileImgURL();
 
		}
 
	} else handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
							   std::string("Error populating roster - ") + errMsg, twitterMode[user] == CHATROOM ? adminNickName : "");	
 

	
 
	if(twitterMode[user] == CHATROOM) handleParticipantChanged(user, nickName[user], adminChatRoom, 0, pbnetwork::STATUS_ONLINE);
 
}
 

	
 
void TwitterPlugin::displayFriendlist(std::string &user, std::vector<User> &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, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
							userlist, twitterMode[user] == CHATROOM ? adminNickName : "");	
 
	} else handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName, 
 
							   errMsg, twitterMode[user] == CHATROOM ? adminNickName : "");	
 
 
 
}
 

	
 
void TwitterPlugin::displayTweets(std::string &user, std::string &userRequested, std::vector<Status> &tweets , std::string &errMsg)
 
@@ -608,79 +622,97 @@ void TwitterPlugin::directMessageResponse(std::string &user, std::string &userna
 

	
 
		if(msglist.length()) handleMessage(user, adminLegacyName, msglist, "");	
 
		updateLastDMID(user, maxID);
 

	
 
	} else {
 
		
 
		std::string msgID = getMostRecentDMID(user);
 
		std::string maxID = msgID;
 

	
 
		for(int i=0 ; i < messages.size() ; i++) {
 
			if(cmp(msgID, messages[i].getID()) == -1) {
 
				if(twitterMode[user] == MULTIPLECONTACT)
 
					handleMessage(user, messages[i].getSenderData().getScreenName(), messages[i].getMessage(), "");
 
				else
 
					handleMessage(user, adminChatRoom, messages[i].getMessage() + " - <Direct Message>", messages[i].getSenderData().getScreenName());
 
				if(cmp(maxID, messages[i].getID()) == -1) maxID = messages[i].getID();
 
			}
 
		}	
 
		
 
		if(maxID == getMostRecentDMID(user)) LOG4CXX_INFO(logger, "No new direct messages for " << user)
 
		updateLastDMID(user, maxID);
 
	}
 
}
 

	
 
void TwitterPlugin::createFriendResponse(std::string &user, std::string &frnd, std::string &errMsg)
 
void TwitterPlugin::createFriendResponse(std::string &user, User &frnd, std::string &errMsg)
 
{
 
	if(errMsg.length()) {
 
		handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
							errMsg, twitterMode[user] == CHATROOM ? adminNickName : "");
 
		return;
 
	}
 

	
 
	handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
						std::string("You are now following ") + frnd, twitterMode[user] == CHATROOM ? adminNickName : "");
 
						std::string("You are now following ") + frnd.getScreenName(), twitterMode[user] == CHATROOM ? adminNickName : "");
 
	
 
	//buddies[user].insert(frnd);
 
	buddies[user].insert(frnd.getScreenName());
 
	imgURL[frnd.getScreenName()] = frnd.getProfileImgURL();
 
	LOG4CXX_INFO(logger, user << " - " << frnd.getScreenName() << ", " << imgURL[frnd.getScreenName()])
 
	//handleBuddyChanged(user, frnd, frnd, std::vector<std::string>(), pbnetwork::STATUS_NONE);
 

	
 
	if(twitterMode[user] == MULTIPLECONTACT) {
 
		handleBuddyChanged(user, frnd, frnd, std::vector<std::string>(), pbnetwork::STATUS_ONLINE);
 
		handleBuddyChanged(user, frnd.getScreenName(), frnd.getScreenName(), std::vector<std::string>(), pbnetwork::STATUS_ONLINE);
 
	} else if(twitterMode[user] == CHATROOM) {
 
		buddies[user].insert(frnd);
 
		handleParticipantChanged(user, frnd, adminChatRoom, 0, pbnetwork::STATUS_ONLINE);
 
		//buddies[user].insert(frnd);
 
		handleParticipantChanged(user, frnd.getScreenName(), adminChatRoom, 0, pbnetwork::STATUS_ONLINE);
 
	}
 
}
 

	
 
void TwitterPlugin::deleteFriendResponse(std::string &user, std::string &frnd, std::string &errMsg)
 
void TwitterPlugin::deleteFriendResponse(std::string &user, User &frnd, std::string &errMsg)
 
{
 
	if(errMsg.length()) {
 
		handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName, 
 
							errMsg, twitterMode[user] == CHATROOM ? adminNickName : "");
 
		return;
 
	} 
 
	
 
	handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
						std::string("You are not following ") + frnd + " anymore", twitterMode[user] == CHATROOM ? adminNickName : "");
 
						std::string("You are not following ") + frnd.getScreenName() + " anymore", twitterMode[user] == CHATROOM ? adminNickName : "");
 
	
 
	if (twitterMode[user] == CHATROOM) {
 
		handleParticipantChanged(user, frnd, adminLegacyName, 0, pbnetwork::STATUS_NONE);
 
		buddies[user].erase(frnd);
 
	}
 
		handleParticipantChanged(user, frnd.getScreenName(), adminLegacyName, 0, pbnetwork::STATUS_NONE);
 
		//buddies[user].erase(frnd);
 
	}
 

	
 
	LOG4CXX_INFO(logger, user << " - " << frnd.getScreenName() << ", " << imgURL[frnd.getScreenName()])
 
	
 
	buddies[user].erase(frnd.getScreenName());
 
	imgURL[frnd.getScreenName()] = "";
 

	
 
	//handleBuddyRemoved(user, frnd);
 
	if(twitterMode[user] == MULTIPLECONTACT) {
 
		handleBuddyRemoved(user, frnd);
 
		handleBuddyRemoved(user, frnd.getScreenName());
 
	} 
 
}
 

	
 

	
 
void TwitterPlugin::RetweetResponse(std::string &user, std::string &errMsg)
 
{
 
	if(errMsg.length()) {
 
		handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
							errMsg, twitterMode[user] == CHATROOM ? adminNickName : "");
 
	} else {
 
		handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
							"Retweet successful", twitterMode[user] == CHATROOM ? adminNickName : "");
 
	}
 
}
 

	
 
void TwitterPlugin::profileImageResponse(std::string &user, std::string &buddy, std::string &img, unsigned int reqID, std::string &errMsg)
 
{
 
	if(errMsg.length()) {
 
		handleMessage(user, twitterMode[user] == CHATROOM ? adminChatRoom : adminLegacyName,
 
							errMsg, twitterMode[user] == CHATROOM ? adminNickName : "");
 
	} else {
 
		LOG4CXX_INFO(logger, user << " - Sending VCard for " << buddy)
 
		handleVCard(user, reqID, buddy, buddy, "", img);
 
	}
 
}
backends/twitter/TwitterPlugin.h
Show inline comments
 
@@ -56,94 +56,98 @@ class TwitterPlugin : public NetworkPlugin {
 
		~TwitterPlugin();
 

	
 
		// Send data to NetworkPlugin server
 
		void sendData(const std::string &string);
 

	
 
		// Receive date from the NetworkPlugin server and invoke the appropirate payload handler (implement in the NetworkPlugin class)
 
		void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data);
 
	
 
		// User trying to login into his twitter account
 
		void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
 
		
 
		// User logging out
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName);
 
		
 
		void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/);
 

	
 
		void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/);
 

	
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "");
 

	
 
		void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups);
 

	
 
		void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups);
 
		
 
		void handleVCardRequest(const std::string &/*user*/, const std::string &/*legacyName*/, unsigned int /*id*/);
 
		
 
		void pollForTweets();
 

	
 
		void pollForDirectMessages();
 
		
 
		bool getUserOAuthKeyAndSecret(const std::string user, std::string &key, std::string &secret);
 
		
 
		bool storeUserOAuthKeyAndSecret(const std::string user, const std::string OAuthKey, const std::string OAuthSecret);
 
		
 
		void initUserSession(const std::string user, const std::string password);
 
		
 
		void OAuthFlowComplete(const std::string user, twitCurl *obj);
 
		
 
		void pinExchangeComplete(const std::string user, const std::string OAuthAccessTokenKey, const std::string OAuthAccessTokenSecret);
 
		
 
		void updateLastTweetID(const std::string user, const std::string ID);
 

	
 
		std::string getMostRecentTweetID(const std::string user);
 

	
 
		void updateLastDMID(const std::string user, const std::string ID);
 
		
 
		std::string getMostRecentDMID(const std::string user);
 

	
 
		void clearRoster(const std::string user);
 

	
 
		int getTwitterMode(const std::string user);
 

	
 
		bool setTwitterMode(const std::string user, int m);
 

	
 
		/****************** Twitter Response handlers **************************************/
 
		void statusUpdateResponse(std::string &user, std::string &errMsg);
 
		void helpMessageResponse(std::string &user, std::string &msg);
 
		void populateRoster(std::string &user, std::vector<User> &friends, std::string &errMsg);
 
		void displayFriendlist(std::string &user, std::vector<User> &friends, std::string &errMsg);
 
		void displayTweets(std::string &user, std::string &userRequested, std::vector<Status> &tweets , std::string &errMsg);
 
		void directMessageResponse(std::string &user, std::string &username, std::vector<DirectMessage> &messages, std::string &errMsg);
 
		void createFriendResponse(std::string &user, std::string &frnd, std::string &errMsg);
 
		void deleteFriendResponse(std::string &user, std::string &frnd, std::string &errMsg);
 
		void createFriendResponse(std::string &user, User &frnd, std::string &errMsg);
 
		void deleteFriendResponse(std::string &user, User &frnd, std::string &errMsg);
 
		void RetweetResponse(std::string &user, std::string &errMsg);
 
		void profileImageResponse(std::string &user, std::string &buddy, std::string &img, unsigned int reqID, std::string &errMsg);
 
		/***********************************************************************************/
 

	
 
	private:
 
		enum status {NEW, WAITING_FOR_PIN, CONNECTED, DISCONNECTED};
 
		enum mode {SINGLECONTACT, MULTIPLECONTACT, CHATROOM};
 

	
 
		Config *config;
 
		std::string adminLegacyName;
 
		std::string adminChatRoom;
 
		std::string adminNickName;
 
		std::string adminAlias;
 

	
 
		std::string consumerKey;
 
		std::string consumerSecret;
 
		std::string OAUTH_KEY;
 
		std::string OAUTH_SECRET;
 
		std::string MODE;
 

	
 
		boost::mutex dblock, userlock;
 

	
 
		ThreadPool *tp;
 
		std::map<std::string, twitCurl*> sessions;		
 
		std::map<std::string, status> connectionState;
 
		std::map<std::string, std::string> mostRecentTweetID;
 
		std::map<std::string, std::string> mostRecentDirectMessageID;
 
		std::set<std::string> onlineUsers;
 
		std::map<std::string,std::string> nickName;
 
		std::map<std::string, std::set<std::string> > buddies;
 
		std::map<std::string, std::string> imgURL;
 
		std::map<std::string, mode> twitterMode;
 
};
 

	
 
#endif
backends/twitter/TwitterResponseParser.cpp
Show inline comments
 
#include "TwitterResponseParser.h"
 
#include "transport/logging.h"
 
#include <cctype>
 

	
 
DEFINE_LOGGER(logger, "TwitterResponseParser")
 

	
 
static std::string tolowercase(std::string inp)
 
{
 
	std::string out = inp;
 
	for(int i=0 ; i<out.size() ; i++) out[i] = tolower(out[i]);
 
	return out;
 
}
 

	
 
User getUser(const Swift::ParserElement::ref &element, const std::string xmlns) 
 
{
 
	User user;
 
	if(element->getName() != TwitterReponseTypes::user 
 
	   && element->getName() != TwitterReponseTypes::sender
 
	   && element->getName() != TwitterReponseTypes::recipient) {
 
		LOG4CXX_ERROR(logger, "Not a user element!")
 
		return user;
 
	}
 

	
 
	user.setUserID( std::string( element->getChild(TwitterReponseTypes::id, xmlns)->getText() ) );
 
	user.setScreenName( std::string( element->getChild(TwitterReponseTypes::screen_name, xmlns)->getText() ) );
 
	user.setScreenName( tolowercase( std::string( element->getChild(TwitterReponseTypes::screen_name, xmlns)->getText() ) ) );
 
	user.setUserName( std::string( element->getChild(TwitterReponseTypes::name, xmlns)->getText() ) );
 
	user.setProfileImgURL( std::string( element->getChild(TwitterReponseTypes::profile_image_url, xmlns)->getText() ) );
 
	user.setNumberOfTweets( atoi(element->getChild(TwitterReponseTypes::statuses_count, xmlns)->getText().c_str()) );
 
	return user;
 
}
 

	
 
Status getStatus(const Swift::ParserElement::ref &element, const std::string xmlns) 
 
{
 
	Status status;
 
	if(element->getName() != "status") {
 
		LOG4CXX_ERROR(logger, "Not a status element!")
 
		return status;
 
	}
 

	
 
	status.setCreationTime( std::string( element->getChild(TwitterReponseTypes::created_at, xmlns)->getText() ) );
 
	status.setID( std::string( element->getChild(TwitterReponseTypes::id, xmlns)->getText() ) );
 
	status.setTweet( std::string( element->getChild(TwitterReponseTypes::text, xmlns)->getText() ) );
 
	status.setTruncated( std::string( element->getChild(TwitterReponseTypes::truncated, xmlns)->getText() )=="true" );
 
	status.setReplyToStatusID( std::string( element->getChild(TwitterReponseTypes::in_reply_to_status_id, xmlns)->getText() ) );
 
	status.setReplyToUserID( std::string( element->getChild(TwitterReponseTypes::in_reply_to_user_id, xmlns)->getText() ) );
 
	status.setReplyToScreenName( std::string( element->getChild(TwitterReponseTypes::in_reply_to_screen_name, xmlns)->getText() ) );
 
	status.setUserData( getUser(element->getChild(TwitterReponseTypes::user, xmlns), xmlns) );
 
	status.setRetweetCount( atoi( element->getChild(TwitterReponseTypes::retweet_count, xmlns)->getText().c_str() ) );
 
	status.setFavorited( std::string( element->getChild(TwitterReponseTypes::favorited, xmlns)->getText() )=="true" );
 
	status.setRetweeted( std::string( element->getChild(TwitterReponseTypes::retweeted, xmlns)->getText() )=="true" );
 
	return status;
 
@@ -116,48 +125,67 @@ std::vector<User> getUsers(std::string &xml)
 
{
 
	std::vector<User> users;
 
	Swift::ParserElement::ref rootElement = Swift::StringTreeParser::parse(xml);
 
	
 
	if(rootElement == NULL) {
 
		LOG4CXX_ERROR(logger, "Error while parsing XML")
 
		return users;
 
	}
 

	
 
	if(rootElement->getName() != TwitterReponseTypes::users) {
 
		LOG4CXX_ERROR(logger, "XML doesn't correspond to user list")
 
		return users;
 
	}
 

	
 
	const std::string xmlns = rootElement->getNamespace();
 
	const std::vector<Swift::ParserElement::ref> children = rootElement->getChildren(TwitterReponseTypes::user, xmlns);
 

	
 
	for(int i = 0 ; i < children.size() ; i++) {
 
		const Swift::ParserElement::ref user = children[i];
 
		users.push_back(getUser(user, xmlns));
 
	}
 
	return users;
 
}
 

	
 
User getUser(std::string &xml)
 
{
 
	User user;
 
	Swift::ParserElement::ref rootElement = Swift::StringTreeParser::parse(xml);
 
	
 
	if(rootElement == NULL) {
 
		LOG4CXX_ERROR(logger, "Error while parsing XML")
 
		return user;
 
	}
 

	
 
	if(rootElement->getName() != TwitterReponseTypes::user) {
 
		LOG4CXX_ERROR(logger, "XML doesn't correspond to user object")
 
		return user;
 
	}
 

	
 
	const std::string xmlns = rootElement->getNamespace();
 
	return user = getUser(rootElement, xmlns);
 
}
 

	
 
std::vector<std::string> getIDs(std::string &xml)
 
{
 
	std::vector<std::string> IDs;
 
	Swift::ParserElement::ref rootElement = Swift::StringTreeParser::parse(xml);
 

	
 
	if(rootElement == NULL) {
 
		LOG4CXX_ERROR(logger, "Error while parsing XML")
 
		return IDs;
 
	}
 

	
 
	if(rootElement->getName() != TwitterReponseTypes::id_list) {
 
		LOG4CXX_ERROR(logger, "XML doesn't correspond to id_list");
 
		return IDs;
 
	}
 

	
 
	const std::string xmlns = rootElement->getNamespace();
 
	const std::vector<Swift::ParserElement::ref> ids = rootElement->getChild(TwitterReponseTypes::ids, xmlns)->getChildren(TwitterReponseTypes::id, xmlns);
 
	
 
	for(int i=0 ; i<ids.size() ; i++) {
 
		IDs.push_back(std::string( ids[i]->getText() ));
 
	}
 
	return IDs;
 
}
 

	
backends/twitter/TwitterResponseParser.h
Show inline comments
 
@@ -13,70 +13,74 @@ namespace TwitterReponseTypes
 
	const std::string name = "name";
 
	const std::string screen_name = "screen_name";
 
	const std::string statuses_count = "statuses_count";
 
	const std::string created_at = "created_at";
 
	const std::string text = "text";
 
	const std::string truncated = "truncated";
 
	const std::string in_reply_to_status_id = "in_reply_to_user_id";
 
	const std::string in_reply_to_user_id = "in_reply_to_user_id";
 
	const std::string in_reply_to_screen_name = "in_reply_to_screen_name";
 
	const std::string retweet_count = "retweet_count";
 
	const std::string favorited = "favorited";
 
	const std::string retweeted = "retweeted";
 
	const std::string user = "user";
 
	const std::string users = "users";
 
	const std::string status = "status";
 
	const std::string error = "error";
 
	const std::string direct_message = "direct_message";
 
	const std::string directmessages = "direct-messages";
 
	const std::string sender_id = "sender_id";
 
	const std::string recipient_id = "recipient_id";
 
	const std::string sender_screen_name = "sender_screen_name";
 
	const std::string recipient_screen_name = "recipient_screen_name";
 
	const std::string sender = "sender";
 
   	const std::string recipient = "recipient";
 
	const std::string profile_image_url = "profile_image_url";
 
};
 

	
 
//Class holding user data
 
class User
 
{
 
	std::string ID;
 
	std::string name;
 
	std::string screen_name;
 
	std::string profile_image_url;
 
	unsigned int statuses_count;
 

	
 
	public:
 
	User():ID(""),name(""),screen_name(""),statuses_count(0){}
 

	
 
	std::string getUserID() {return ID;}
 
	std::string getUserName() {return name;}
 
	std::string getScreenName() {return screen_name;}
 
	std::string getProfileImgURL() {return profile_image_url;}
 
	unsigned int getNumberOfTweets() {return statuses_count;}
 
	
 
	
 
	void setUserID(std::string _id) {ID = _id;}
 
	void setUserName(std::string _name) {name = _name;}
 
	void setScreenName(std::string _screen) {screen_name = _screen;}
 
	void setProfileImgURL(std::string _url) {profile_image_url = _url;}
 
	void setNumberOfTweets(unsigned int sc) {statuses_count  = sc;}
 
};
 

	
 
//Class representing a status (tweet)
 
class Status
 
{
 
	std::string created_at;
 
	std::string ID;
 
	std::string text;
 
	bool truncated;
 
	std::string in_reply_to_status_id;
 
	std::string in_reply_to_user_id;
 
	std::string in_reply_to_screen_name;
 
	User user;
 
	unsigned int retweet_count;
 
	bool favorited;
 
	bool retweeted;
 

	
 
	public:
 
	Status():created_at(""),ID(""),text(""),truncated(false),in_reply_to_status_id(""),
 
	         in_reply_to_user_id(""),in_reply_to_screen_name(""),user(User()),retweet_count(0),
 
	         favorited(false),retweeted(0){}
 
	
 
	std::string getCreationTime() {return created_at;}
 
@@ -124,30 +128,31 @@ class DirectMessage
 
	std::string getID() {return ID;}
 
	std::string getMessage() {return text;}
 
	std::string getSenderID() {return sender_id;}
 
	std::string getRecipientID() {return recipient_id;}
 
	std::string getSenderScreenName() {return sender_screen_name;}
 
	std::string getRecipientScreenName() {return recipient_screen_name;}
 
	User getSenderData() {return sender;}
 
	User getRecipientData() {return recipient;}
 
	
 
	void setCreationTime(std::string _created) {created_at = _created;}
 
	void setID(std::string _id) {ID = _id;}
 
	void setMessage(std::string _text) {text = _text;}
 
	void setSenderID(std::string _id) {sender_id = _id;}
 
	void setRecipientID(std::string _id) {recipient_id = _id;}
 
	void setSenderScreenName(std::string _name) {sender_screen_name = _name;}
 
	void setRecipientScreenName(std::string _name) {recipient_screen_name = _name;}
 
	void setSenderData(User u) {sender = u;}
 
	void setRecipientData(User u) {recipient = u;}
 
};
 

	
 
std::vector<Status> getTimeline(std::string &xml);
 
std::vector<DirectMessage> getDirectMessages(std::string &xml);
 
std::vector<std::string> getIDs(std::string &xml);
 
std::vector<User> getUsers(std::string &xml);
 
User getUser(std::string &xml);
 
std::string getErrorMessage(std::string &xml);
 

	
 
Status getStatus(const Swift::ParserElement::ref &element, const std::string xmlns);
 
DirectMessage getDirectMessage(const Swift::ParserElement::ref &element, const std::string xmlns);
 
User getUser(const Swift::ParserElement::ref &element, const std::string xmlns);
 
#endif
0 comments (0 inline, 0 general)