diff --git a/backends/twitter/TwitterPlugin.cpp b/backends/twitter/TwitterPlugin.cpp index 54190e74..74c859a0 100644 --- a/backends/twitter/TwitterPlugin.cpp +++ b/backends/twitter/TwitterPlugin.cpp @@ -17,7 +17,17 @@ TwitterPlugin *np = NULL; Swift::SimpleEventLoop *loop_; // Event Loop #define abs(x) ((x)<0?-(x):(x)) -#define SHA(x) (Swift::byteArrayToString(Swift::SHA1::getHash(Swift::createByteArray((x))))) +#define SHA(x) (convertToChars(Swift::byteArrayToString(Swift::SHA1::getHash(Swift::createByteArray((x)))))) + +static std::string convertToChars(std::string s) +{ + std::string ret = ""; + std::string tab[] = {"0","1","2","3","4","5","6","7", + "8","9","A","B","C","D","E","F"}; + for(int i = 0 ; i < s.size() ; i++) + ret = tab[s[i]>>4&15] + tab[s[i]&15] + ret; + return ret; +} //Compares two +ve intergers 'a' and 'b' represented as strings static int cmp(std::string a, std::string b) @@ -534,11 +544,17 @@ void TwitterPlugin::populateRoster(std::string &user, std::vector &friends userdb[user].buddiesInfo[friends[i].getScreenName()] = friends[i]; userdb[user].buddiesImgs[friends[i].getScreenName()] = friendAvatars[i]; - if(userdb[user].twitterMode == MULTIPLECONTACT) - handleBuddyChanged(user, friends[i].getScreenName(), friends[i].getScreenName(), std::vector(), - pbnetwork::STATUS_ONLINE, "", SHA(friendAvatars[i])); + if(userdb[user].twitterMode == MULTIPLECONTACT) { + std::string lastTweet = friends[i].getLastStatus().getTweet(); + handleBuddyChanged(user, friends[i].getScreenName(), friends[i].getUserName(), std::vector(), + pbnetwork::STATUS_ONLINE, lastTweet, SHA(friendAvatars[i])); + } else if(userdb[user].twitterMode == CHATROOM) handleParticipantChanged(user, friends[i].getScreenName(), adminChatRoom, 0, pbnetwork::STATUS_ONLINE); + + /*handleMessage(user, userdb[user].twitterMode == CHATROOM ? adminChatRoom : adminLegacyName, + friends[i].getScreenName() + " - " + friends[i].getLastStatus().getTweet(), + userdb[user].twitterMode == CHATROOM ? adminNickName : "");*/ } } else handleMessage(user, userdb[user].twitterMode == CHATROOM ? adminChatRoom : adminLegacyName, std::string("Error populating roster - ") + errMsg, userdb[user].twitterMode == CHATROOM ? adminNickName : ""); @@ -565,17 +581,32 @@ void TwitterPlugin::displayFriendlist(std::string &user, std::vector &frie void TwitterPlugin::displayTweets(std::string &user, std::string &userRequested, std::vector &tweets , std::string &errMsg) { if(errMsg.length() == 0) { + std::string timeline = ""; + std::map lastTweet; + std::map::iterator it; for(int i=0 ; isecond; + handleBuddyChanged(user, tweets[t].getUserData().getScreenName(), tweets[t].getUserData().getUserName(), + std::vector(), pbnetwork::STATUS_ONLINE, tweets[t].getTweet()); + } + } if((userRequested == "" || userRequested == user) && tweets.size()) { std::string tweetID = getMostRecentTweetID(user); @@ -657,7 +688,7 @@ void TwitterPlugin::createFriendResponse(std::string &user, User &frnd, std::str LOG4CXX_INFO(logger, user << " - " << frnd.getScreenName() << ", " << frnd.getProfileImgURL()) if(userdb[user].twitterMode == MULTIPLECONTACT) { - handleBuddyChanged(user, frnd.getScreenName(), frnd.getScreenName(), std::vector(), pbnetwork::STATUS_ONLINE, "", SHA(img)); + handleBuddyChanged(user, frnd.getScreenName(), frnd.getUserName(), std::vector(), pbnetwork::STATUS_ONLINE, "", SHA(img)); } else if(userdb[user].twitterMode == CHATROOM) { handleParticipantChanged(user, frnd.getScreenName(), adminChatRoom, 0, pbnetwork::STATUS_ONLINE); } diff --git a/backends/twitter/TwitterResponseParser.cpp b/backends/twitter/TwitterResponseParser.cpp index 33e2f27c..cc334d37 100644 --- a/backends/twitter/TwitterResponseParser.cpp +++ b/backends/twitter/TwitterResponseParser.cpp @@ -11,6 +11,27 @@ static std::string tolowercase(std::string inp) return out; } +EmbeddedStatus getEmbeddedStatus(const Swift::ParserElement::ref &element, const std::string xmlns) +{ + EmbeddedStatus status; + if(element->getName() != TwitterReponseTypes::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.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; +} + User getUser(const Swift::ParserElement::ref &element, const std::string xmlns) { User user; @@ -26,6 +47,8 @@ User getUser(const Swift::ParserElement::ref &element, const std::string xmlns) 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()) ); + if(element->getChild(TwitterReponseTypes::status, xmlns)) + user.setLastStatus(getEmbeddedStatus(element->getChild(TwitterReponseTypes::status, xmlns), xmlns)); return user; } diff --git a/backends/twitter/TwitterResponseParser.h b/backends/twitter/TwitterResponseParser.h index c1f1f8fc..70d525ac 100644 --- a/backends/twitter/TwitterResponseParser.h +++ b/backends/twitter/TwitterResponseParser.h @@ -37,6 +37,49 @@ namespace TwitterReponseTypes const std::string profile_image_url = "profile_image_url"; }; +//Class representing an embedded status object within other objects such as the User object. +//Note: Not possible to user Status due to circular dependency +class EmbeddedStatus +{ + 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; + unsigned int retweet_count; + bool favorited; + bool retweeted; + + public: + EmbeddedStatus():created_at(""),ID(""),text(""),truncated(false),in_reply_to_status_id(""), + in_reply_to_user_id(""),in_reply_to_screen_name(""),retweet_count(0), + favorited(false),retweeted(0){} + + std::string getCreationTime() {return created_at;} + std::string getID() {return ID;} + std::string getTweet() {return text;} + bool isTruncated() {return truncated;} + std::string getReplyToStatusID() {return in_reply_to_status_id;} + std::string getReplyToUserID() {return in_reply_to_user_id;} + std::string getReplyToScreenName() {return in_reply_to_screen_name;} + unsigned int getRetweetCount() {return retweet_count;} + bool isFavorited() {return favorited;} + bool isRetweeted() {return retweeted;} + + void setCreationTime(std::string _created) {created_at = _created;} + void setID(std::string _id) {ID = _id;} + void setTweet(std::string _text) {text = _text;} + void setTruncated(bool val) {truncated = val;} + void setReplyToStatusID(std::string _id) {in_reply_to_status_id = _id;} + void setReplyToUserID(std::string _id) {in_reply_to_user_id = _id;} + void setReplyToScreenName(std::string _name) {in_reply_to_screen_name = _name;} + void setRetweetCount(unsigned int rc) {retweet_count = rc;} + void setFavorited(bool val) {favorited = val;} + void setRetweeted(bool val) {retweeted = val;} +}; + //Class holding user data class User { @@ -45,6 +88,7 @@ class User std::string screen_name; std::string profile_image_url; unsigned int statuses_count; + EmbeddedStatus last_status; public: User():ID(""),name(""),screen_name(""),statuses_count(0){} @@ -54,6 +98,7 @@ class User std::string getScreenName() {return screen_name;} std::string getProfileImgURL() {return profile_image_url;} unsigned int getNumberOfTweets() {return statuses_count;} + EmbeddedStatus getLastStatus() {return last_status;} void setUserID(std::string _id) {ID = _id;} @@ -61,8 +106,10 @@ class User 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;} + void setLastStatus(EmbeddedStatus _last_status) {last_status = _last_status;} }; + //Class representing a status (tweet) class Status {