diff --git a/backends/twitter/TwitterResponseParser.cpp b/backends/twitter/TwitterResponseParser.cpp index 44fc4eca..77e8e8b1 100644 --- a/backends/twitter/TwitterResponseParser.cpp +++ b/backends/twitter/TwitterResponseParser.cpp @@ -20,13 +20,18 @@ template std::string stringOf(T object) { return (os.str()); } -static std::string unescape(std::string data) { +static std::string unescape(std::string data, std::vector urls) { using boost::algorithm::replace_all; replace_all(data, "&", "&"); replace_all(data, """, "\""); replace_all(data, "'", "\'"); replace_all(data, "<", "<"); replace_all(data, ">", ">"); + + for (std::vector::size_type i = 0; i < urls.size(); i++) { + replace_all(data, urls[i].getUrl(), urls[i].getExpandedUrl()); + } + return data; } @@ -53,7 +58,7 @@ EmbeddedStatus getEmbeddedStatus(const rapidjson::Value &element) } status.setCreationTime( toIsoTime ( std::string( element[TwitterReponseTypes::created_at.c_str()].GetString() ) ) ); status.setID( stringOf( element[TwitterReponseTypes::id.c_str()].GetInt64() ) ); - status.setTweet( unescape ( std::string( element[TwitterReponseTypes::text.c_str()].GetString() ) ) ); + status.setTweet( unescape ( std::string( element[TwitterReponseTypes::text.c_str()].GetString() ), getUrlEntities(element) ) ); status.setTruncated( element[TwitterReponseTypes::truncated.c_str()].GetBool()); status.setReplyToStatusID( element[TwitterReponseTypes::in_reply_to_status_id.c_str()].IsNull() ? "" : stringOf(element[TwitterReponseTypes::in_reply_to_status_id.c_str()].GetInt64()) ); @@ -88,10 +93,10 @@ User getUser(const rapidjson::Value &element) Status getStatus(const rapidjson::Value &element) { Status status; - + status.setCreationTime( toIsoTime ( std::string( element[TwitterReponseTypes::created_at.c_str()].GetString() ) ) ); status.setID( stringOf( element[TwitterReponseTypes::id.c_str()].GetInt64() )); - status.setTweet( unescape ( std::string( element[TwitterReponseTypes::text.c_str()].GetString() ) ) ); + status.setTweet( unescape ( std::string( element[TwitterReponseTypes::text.c_str()].GetString() ), getUrlEntities(element) ) ); status.setTruncated( element[TwitterReponseTypes::truncated.c_str()].GetBool()); status.setReplyToStatusID( element[TwitterReponseTypes::in_reply_to_status_id.c_str()].IsNull() ? "" : stringOf(element[TwitterReponseTypes::in_reply_to_status_id.c_str()].GetInt64()) ); @@ -105,11 +110,13 @@ Status getStatus(const rapidjson::Value &element) status.setRetweeted( element[TwitterReponseTypes::retweeted.c_str()].GetBool()); const rapidjson::Value &rt = element[TwitterReponseTypes::retweeted_status.c_str()]; if (rt.IsObject()) { - status.setTweet(unescape( std::string( rt[TwitterReponseTypes::text.c_str()].GetString()) + " (RT by @" + status.getUserData().getScreenName() + ")") ); + status.setTweet(unescape( std::string( rt[TwitterReponseTypes::text.c_str()].GetString()) + " (RT by @" + status.getUserData().getScreenName() + ")" + , getUrlEntities(element)) ); status.setRetweetID( stringOf(rt[TwitterReponseTypes::id.c_str()].GetInt64()) ); status.setCreationTime( toIsoTime ( std::string (rt[TwitterReponseTypes::created_at.c_str()].GetString() ) ) ); status.setUserData( getUser ( rt[TwitterReponseTypes::user.c_str()]) ); } + return status; } @@ -119,7 +126,7 @@ DirectMessage getDirectMessage(const rapidjson::Value &element) DM.setCreationTime( toIsoTime ( std::string( element[TwitterReponseTypes::created_at.c_str()].GetString() ) ) ); DM.setID( stringOf( element[TwitterReponseTypes::id.c_str()].GetInt64() ) ); - DM.setMessage( unescape ( std::string( element[TwitterReponseTypes::text.c_str()].GetString() ) ) ); + DM.setMessage( unescape ( std::string( element[TwitterReponseTypes::text.c_str()].GetString() ), getUrlEntities(element) ) ); DM.setSenderID( stringOf( element[TwitterReponseTypes::sender_id.c_str()].GetInt64()) ); DM.setRecipientID( stringOf( element[TwitterReponseTypes::recipient_id.c_str()].GetInt64() ) ); DM.setSenderScreenName( std::string( element[TwitterReponseTypes::sender_screen_name.c_str()].GetString() ) ); @@ -269,3 +276,23 @@ Error getErrorMessage(std::string &json) return resp; } + +std::vector getUrlEntities(const rapidjson::Value &element) +{ + + std::vector url_entities; + + const rapidjson::Value &entities = element["entities"]; + + if (entities.IsObject()) { + const rapidjson::Value &urls = entities["urls"]; + if (urls.IsArray()) { + for (rapidjson::SizeType i = 0; i < urls.Size(); i++) { + UrlEntity entity(urls[i]["url"].GetString(), urls[i]["expanded_url"].GetString()); + url_entities.push_back(entity); + } + } + } + + return url_entities; +} diff --git a/backends/twitter/TwitterResponseParser.h b/backends/twitter/TwitterResponseParser.h index 7ef187a8..79bc544e 100644 --- a/backends/twitter/TwitterResponseParser.h +++ b/backends/twitter/TwitterResponseParser.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace TwitterReponseTypes { @@ -211,6 +212,21 @@ class Error void setMessage(std::string &_message) {message = _message;} }; +class UrlEntity +{ + std::string url; + std::string expanded_url; +public: + UrlEntity(std::string _url, std::string _expanded) + { + url = _url; + expanded_url = _expanded; + } + std::string getUrl() {return url;} + std::string getExpandedUrl() {return expanded_url;} + +}; + std::vector getTimeline(std::string &xml); std::vector getDirectMessages(std::string &xml); std::vector getIDs(std::string &xml); @@ -218,6 +234,7 @@ std::vector getUsers(std::string &xml); User getUser(std::string &xml); Error getErrorMessage(std::string &xml); +std::vector getUrlEntities(const rapidjson::Value &element); Status getStatus(const rapidjson::Value &element); DirectMessage getDirectMessage(const rapidjson::Value &element); User getUser(const rapidjson::Value &element);