Changeset - 8761e976aeca
[Not reviewed]
0 7 0
HanzZ - 13 years ago 2012-12-21 11:20:05
hanzz.k@gmail.com
Cache messages also when you leave room but do not disconnect
7 files changed with 105 insertions and 4 deletions:
0 comments (0 inline, 0 general)
backends/libcommuni/session.cpp
Show inline comments
 
@@ -114,12 +114,15 @@ void MyIrcSession::on_parted(IrcMessage *message) {
 

	
 
void MyIrcSession::on_quit(IrcMessage *message) {
 
	IrcQuitMessage *m = (IrcQuitMessage *) message;
 
	for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
 
		bool op = 0;
 
		std::string nickname = TO_UTF8(m->sender().name());
 
		if (!hasIRCBuddy(it->second->getChannel(), nickname)) {
 
			continue;
 
		}
 
		op = correctNickname(nickname);
 
		removeIRCBuddy(it->second->getChannel(), nickname);
 
		LOG4CXX_INFO(logger, user << ": " << nickname << " quit " << it->second->getChannel() + suffix);
 
		np->handleParticipantChanged(user, nickname, it->second->getChannel() + suffix, op, pbnetwork::STATUS_NONE, TO_UTF8(m->reason()));
 
	}
 
}
include/transport/conversation.h
Show inline comments
 
@@ -137,13 +137,13 @@ class Conversation {
 
		}
 

	
 
		void destroyRoom();
 

	
 
		void sendParticipants(const Swift::JID &to);
 

	
 
		void sendCachedMessages(const Swift::JID &to);
 
		void sendCachedMessages(const Swift::JID &to = Swift::JID());
 

	
 
	private:
 
		Swift::Presence::ref generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname = "");
 

	
 
	private:
 
		ConversationManager *m_conversationManager;
include/transport/conversationmanager.h
Show inline comments
 
@@ -56,12 +56,14 @@ class ConversationManager {
 
		/// Returns Conversation by its legacy network name (for example by UIN in case of ICQ).
 

	
 
		/// \param name legacy network name.
 
		/// \return Conversation or NULL.
 
		Conversation *getConversation(const std::string &name);
 

	
 
		void sendCachedChatMessages();
 

	
 
		/// Adds new Conversation to the manager.
 

	
 
		/// \param conv Conversation.
 
		void addConversation(Conversation *conv);
 

	
 
		/// Removes Conversation from the manager.
src/conversation.cpp
Show inline comments
 
@@ -124,13 +124,26 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
 
				message->setFrom(Swift::JID(n, m_conversationManager->getComponent()->getJID().toBare(), "user"));
 
			}
 
			else {
 
				message->setFrom(Swift::JID(m_room, m_conversationManager->getComponent()->getJID().toBare(), n));
 
			}
 
		}
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
 

	
 
		if (m_conversationManager->getComponent()->inServerMode() && m_conversationManager->getUser()->shouldCacheMessages()) {
 
			boost::posix_time::ptime timestamp = boost::posix_time::second_clock::universal_time();
 
			boost::shared_ptr<Swift::Delay> delay(boost::make_shared<Swift::Delay>());
 
			delay->setStamp(timestamp);
 
			message->addPayload(delay);
 
			m_cachedMessages.push_back(message);
 
			if (m_cachedMessages.size() > 100) {
 
				m_cachedMessages.pop_front();
 
			}
 
		}
 
		else {
 
			m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
 
		}
 
	}
 
	else {
 
		std::string legacyName = m_legacyName;
 
		if (legacyName.find_last_of("@") != std::string::npos) {
 
			legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
		}
 
@@ -139,13 +152,13 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
 
		if (n.empty()) {
 
			n = " ";
 
		}
 

	
 
		message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
 

	
 
		if (m_conversationManager->getUser()->shouldCacheMessages()) {
 
		if (m_jids.empty()) {
 
			boost::posix_time::ptime timestamp = boost::posix_time::second_clock::universal_time();
 
			boost::shared_ptr<Swift::Delay> delay(boost::make_shared<Swift::Delay>());
 
			delay->setStamp(timestamp);
 
			message->addPayload(delay);
 
			m_cachedMessages.push_back(message);
 
			if (m_cachedMessages.size() > 100) {
 
@@ -173,13 +186,18 @@ void Conversation::sendParticipants(const Swift::JID &to) {
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
 
	}
 
}
 

	
 
void Conversation::sendCachedMessages(const Swift::JID &to) {
 
	for (std::list<boost::shared_ptr<Swift::Message> >::const_iterator it = m_cachedMessages.begin(); it != m_cachedMessages.end(); it++) {
 
		(*it)->setTo(to);
 
		if (to.isValid()) {
 
			(*it)->setTo(to);
 
		}
 
		else {
 
			(*it)->setTo(m_jid.toBare());
 
		}
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(*it);
 
	}
 
	m_cachedMessages.clear();
 
}
 

	
 
Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
src/conversationmanager.cpp
Show inline comments
 
@@ -39,12 +39,21 @@ ConversationManager::ConversationManager(User *user, Component *component){
 
}
 

	
 
ConversationManager::~ConversationManager() {
 
	deleteAllConversations();
 
}
 

	
 
void ConversationManager::sendCachedChatMessages() {
 
	for (std::map<std::string, Conversation *>::const_iterator it = m_convs.begin(); it != m_convs.end(); it++) {
 
		if ((*it).second->isMUC()) {
 
			continue;
 
		}
 
		(*it).second->sendCachedMessages();
 
	}
 
}
 

	
 
void ConversationManager::deleteAllConversations() {
 
	while(!m_convs.empty()) {
 
		LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Removing conversation " << (*m_convs.begin()).first);
 
		(*m_convs.begin()).second->destroyRoom();
 
		delete (*m_convs.begin()).second;
 
		m_convs.erase(m_convs.begin());
src/tests/conversationmanager.cpp
Show inline comments
 
@@ -24,12 +24,13 @@ using namespace Transport;
 
class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST_SUITE(ConversationManagerTest);
 
	CPPUNIT_TEST(handleNormalMessages);
 
	CPPUNIT_TEST(handleNormalMessagesHeadline);
 
	CPPUNIT_TEST(handleGroupchatMessages);
 
	CPPUNIT_TEST(handleGroupchatMessagesBouncer);
 
	CPPUNIT_TEST(handleGroupchatMessagesBouncerLeave);
 
	CPPUNIT_TEST(handleGroupchatMessagesTwoResources);
 
	CPPUNIT_TEST(handleChatstateMessages);
 
	CPPUNIT_TEST(handleSubjectMessages);
 
	CPPUNIT_TEST(handleParticipantChanged);
 
	CPPUNIT_TEST(handleParticipantChangedTwoResources);
 
	CPPUNIT_TEST(handlePMFromXMPP);
 
@@ -352,12 +353,77 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getBody());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getFrom().toString());
 

	
 
	}
 

	
 
	void handleGroupchatMessagesBouncerLeave() {
 
		User *user = userManager->getUser("user@localhost");
 
		user->addUserSetting("stay_connected", "1");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		user->getConversationManager()->addConversation(conv);
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 

	
 
		CPPUNIT_ASSERT(!user->shouldCacheMessages());
 

	
 
		Swift::Presence::ref response3 = Swift::Presence::create();
 
		response3->setType(Swift::Presence::Unavailable);
 
		response3->setTo("#room@localhost/hanzz");
 
		response3->setFrom("user@localhost/resource");
 

	
 
		Swift::MUCPayload *payload3 = new Swift::MUCPayload();
 
		payload3->setPassword("password");
 
		response3->addPayload(boost::shared_ptr<Swift::Payload>(payload3));
 
		injectPresence(response3);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT(!user->shouldCacheMessages());
 

	
 
		// reset resources should not touch this resource
 
		user->getConversationManager()->resetResources();
 

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

	
 
		boost::shared_ptr<Swift::Message> msg2(new Swift::Message());
 
		msg2->setBody("hi there2!");
 
		conv->handleMessage(msg2, "anotheruser");
 

	
 
		loop->processEvents();
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 

	
 
		userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password"));
 
		userRegistry->onPasswordValid(Swift::JID("user@localhost/resource"));
 
		loop->processEvents();
 

	
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("#room@localhost/hanzz");
 
		response->setFrom("user@localhost/resource");
 

	
 
		Swift::MUCPayload *payload = new Swift::MUCPayload();
 
		payload->setPassword("password");
 
		response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
 
		injectPresence(response);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(4, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[2])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getBody());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getFrom().toString());
 

	
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[3])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getBody());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getFrom().toString());
 

	
 
	}
 

	
 
	void handleGroupchatMessagesTwoResources() {
 
		connectSecondResource();
 
		received2.clear();
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		user->getConversationManager()->addConversation(conv);
src/user.cpp
Show inline comments
 
@@ -183,12 +183,15 @@ void User::setConnected(bool connected) {
 
			handlePresence(presence, true);
 
		}
 
	}
 
}
 

	
 
void User::setCacheMessages(bool cacheMessages) {
 
	if (m_component->inServerMode() && !m_cacheMessages && cacheMessages) {
 
		m_conversationManager->sendCachedChatMessages();
 
	}
 
	m_cacheMessages = cacheMessages;
 
}
 

	
 
void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
 

	
 
	int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size();
0 comments (0 inline, 0 general)