Changeset - 9469109d37e4
[Not reviewed]
0 2 1
HanzZ - 13 years ago 2012-11-28 18:52:58
hanzz.k@gmail.com
Unescape double-escaped messages from twitter
3 files changed with 65 insertions and 7 deletions:
0 comments (0 inline, 0 general)
backends/twitter/TwitterResponseParser.cpp
Show inline comments
 
#include "TwitterResponseParser.h"
 
#include "transport/logging.h"
 
#include "boost/algorithm/string.hpp"
 
#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;
 
}
 

	
 
static std::string unescape(std::string data) {
 
	using boost::algorithm::replace_all;
 
	replace_all(data, "&amp;",  "&");
 
	replace_all(data, "&quot;", "\"");
 
	replace_all(data, "&apos;", "\'");
 
	replace_all(data, "&lt;",   "<");
 
	replace_all(data, "&gt;",   ">");
 
	return data;
 
}
 

	
 
static std::string toIsoTime(std::string in) {
 
	time_t now = time(0);
 
	struct tm *mtime = gmtime(&now);
 
	strptime(in.c_str(), "%a %b %d %H:%M:%S %z %Y", mtime);
 
	char buf[80];
 
	strftime(buf, sizeof(buf), "%Y%m%dT%H%M%S", mtime);
 
@@ -28,13 +39,13 @@ EmbeddedStatus getEmbeddedStatus(const Swift::ParserElement::ref &element, const
 
		return status;
 
	}
 

	
 
	status.setCreationTime( toIsoTime(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.setTweet( unescape (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" );
 
@@ -69,13 +80,13 @@ Status getStatus(const Swift::ParserElement::ref &element, const std::string xml
 
		LOG4CXX_ERROR(logger, "Not a status element!")
 
		return status;
 
	}
 

	
 
	status.setCreationTime( toIsoTime ( 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.setTweet( unescape ( 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() ) );
 
@@ -91,13 +102,13 @@ DirectMessage getDirectMessage(const Swift::ParserElement::ref &element, const s
 
		LOG4CXX_ERROR(logger, "Not a direct_message element!")
 
		return DM;
 
	}
 

	
 
	DM.setCreationTime( toIsoTime ( std::string( element->getChild(TwitterReponseTypes::created_at, xmlns)->getText() ) ) );
 
	DM.setID( std::string( element->getChild(TwitterReponseTypes::id, xmlns)->getText() ) );
 
	DM.setMessage( std::string( element->getChild(TwitterReponseTypes::text, xmlns)->getText() ) );
 
	DM.setMessage( unescape ( std::string( element->getChild(TwitterReponseTypes::text, xmlns)->getText() ) ) );
 
	DM.setSenderID( std::string( element->getChild(TwitterReponseTypes::sender_id, xmlns)->getText() ) );
 
	DM.setRecipientID( std::string( element->getChild(TwitterReponseTypes::recipient_id, xmlns)->getText() ) );
 
	DM.setSenderScreenName( std::string( element->getChild(TwitterReponseTypes::sender_screen_name, xmlns)->getText() ) );
 
	DM.setRecipientScreenName( std::string( element->getChild(TwitterReponseTypes::recipient_screen_name, xmlns)->getText() ) );
 
	DM.setSenderData( getUser(element->getChild(TwitterReponseTypes::sender, xmlns), xmlns) );
 
	DM.setRecipientData( getUser(element->getChild(TwitterReponseTypes::recipient, xmlns), xmlns) );
src/tests/conversationmanager.cpp
Show inline comments
 
@@ -138,36 +138,36 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 

	
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "buddy1@test");
 
		user->getConversationManager()->addConversation(conv);
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 

	
 
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
		msg->setBody("hi there!");
 
		msg->setBody("hi there<>!");
 

	
 
		// Forward it
 
		conv->handleMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getBody());
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there<>!"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getBody());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("buddy1\\40test@localhost/bot"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getFrom().toString());
 
		
 
		received.clear();
 

	
 
		// send response
 
		msg->setFrom("user@localhost/resource");
 
		msg->setTo("buddy1\\40test@localhost/bot");
 
		msg->setBody("response!");
 
		msg->setBody("response<>!");
 
		injectMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
		CPPUNIT_ASSERT(m_msg);
 
		CPPUNIT_ASSERT_EQUAL(std::string("response!"), m_msg->getBody());
 
		CPPUNIT_ASSERT_EQUAL(std::string("response<>!"), m_msg->getBody());
 

	
 
		// send another message from legacy network, should be sent to user@localhost/resource now
 
		boost::shared_ptr<Swift::Message> msg2(new Swift::Message());
 
		msg2->setBody("hi there!");
 

	
 
		// Forward it
src/tests/stringtreeparser.cpp
Show inline comments
 
new file 100644
 
#include "transport/userregistry.h"
 
#include "transport/config.h"
 
#include "transport/storagebackend.h"
 
#include "transport/user.h"
 
#include "transport/transport.h"
 
#include "transport/storagebackend.h"
 
#include "transport/conversation.h"
 
#include "transport/usermanager.h"
 
#include "transport/localbuddy.h"
 
#include <cppunit/TestFixture.h>
 
#include <cppunit/extensions/HelperMacros.h>
 
#include <Swiften/Swiften.h>
 
#include <Swiften/EventLoop/DummyEventLoop.h>
 
#include <Swiften/Server/Server.h>
 
#include <Swiften/Parser/StringTreeParser.h>
 
#include <Swiften/Network/DummyNetworkFactories.h>
 
#include <Swiften/Network/DummyConnectionServer.h>
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Server/ServerFromClientSession.h"
 
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
 
#include "basictest.h"
 

	
 
#include "transport/util.h"
 

	
 
using namespace Transport;
 

	
 
class StringTreeParserTest : public CPPUNIT_NS :: TestFixture{
 
	CPPUNIT_TEST_SUITE(StringTreeParserTest);
 
	CPPUNIT_TEST(parseEscapedCharacters);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
		void setUp (void) {
 
		}
 

	
 
		void tearDown (void) {
 

	
 
		}
 

	
 
	void parseEscapedCharacters() {
 
		Swift::ParserElement::ref root = Swift::StringTreeParser::parse("<body>&lt;test&gt;</body>");
 
		CPPUNIT_ASSERT_EQUAL(std::string("<test>"), root->getText());
 
	}
 

	
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (StringTreeParserTest);
0 comments (0 inline, 0 general)