Changeset - 18a72df6850b
[Not reviewed]
0 7 0
HanzZ - 15 years ago 2011-03-30 21:23:39
hanzz.k@gmail.com
Working presence forwarding
7 files changed with 107 insertions and 8 deletions:
0 comments (0 inline, 0 general)
include/transport/abstractbuddy.h
Show inline comments
 
@@ -38,92 +38,94 @@ typedef enum { 	BUDDY_NO_FLAG = 0,
 
/// Represents one legacy network Buddy.
 
class AbstractBuddy {
 
	public:
 
		/// Constructor.
 
		AbstractBuddy(RosterManager *rosterManager, long id);
 

	
 
		/// Destructor
 
		virtual ~AbstractBuddy();
 
		
 
		/// Sets unique ID used to identify this buddy by StorageBackend. This is set
 
		/// by RosterStorage class once the buddy is stored into database or when the
 
		/// buddy is loaded from database.
 
		/// You should not need to set this ID manually.
 
		/// \param id ID
 
		void setID(long id);
 

	
 
		/// Returns unique ID used to identify this buddy by StorageBackend.
 
		/// \see AbstractBuddy::setID(long)
 
		/// \return ID
 
		long getID();
 

	
 
		/// Returns full JID of this buddy.
 
		/// \param hostname hostname used as domain in returned JID
 
		/// \return full JID of this buddy
 
		const Swift::JID &getJID(const std::string &hostname);
 
		const Swift::JID &getJID();
 

	
 
		/// Generates whole Presennce stanza with current status/show for this buddy.
 
		/// Presence stanza does not containt "to" attribute, it has to be added manually.
 
		/// \param features features used in returned stanza
 
		/// \param only_new if True, this function returns Presence stanza only if it's different
 
		/// than the previously generated one.
 
		/// \return Presence stanza or NULL.
 
		Swift::Presence::ref generatePresenceStanza(int features, bool only_new = false);
 

	
 
		/// Marks this buddy as available.
 
		void setOnline();
 

	
 
		/// Marks this buddy as offline.
 
		void setOffline();
 

	
 
		/// Returns true if this buddy is marked as available/online.
 
		/// \return true if this buddy is marked as available/online.
 
		bool isOnline();
 

	
 
		/// Sets current subscription.
 
		/// \param subscription "to", "from", "both", "ask"
 
		void setSubscription(const std::string &subscription);
 

	
 
		/// Returns current subscription
 
		/// \return subscription "to", "from", "both", "ask"
 
		const std::string &getSubscription();
 

	
 
		/// Sets this buddy's flags.
 
		/// \param flags flags
 
		void setFlags(BuddyFlag flags);
 

	
 
		/// Returns this buddy's flags.
 
		/// \param flags flags
 
		BuddyFlag getFlags();
 

	
 
		/// Returns RosterManager associated with this buddy
 
		/// \return rosterManager
 
		RosterManager *getRosterManager() { return m_rosterManager; }
 

	
 
		/// Returns legacy network username which does not contain unsafe characters,
 
		/// so it can be used in JIDs.
 
		std::string getSafeName();
 

	
 
		void buddyChanged();
 

	
 
		/// Returns legacy network username of this buddy. (for example UIN for ICQ,
 
		/// JID for Jabber, ...).
 
		/// \return legacy network username
 
		virtual std::string getName() = 0;
 

	
 
		/// Returns alias (nickname) of this buddy.
 
		/// \return alias (nickname)
 
		virtual std::string getAlias() = 0;
 

	
 
		/// Returns list of groups this buddy is in.
 
		/// \return groups
 
		virtual std::vector<std::string> getGroups() = 0;
 

	
 
		/// Returns current legacy network status and statuMessage of this buddy.
 
		/// \param status current status/show is stored here
 
		/// \param statusMessage current status message is stored here
 
		/// \return true if status was stored successfully
 
		virtual bool getStatus(Swift::StatusShow &status, std::string &statusMessage) = 0;
 

	
 
		/// Returns SHA-1 hash of buddy icon (avatar) or empty string if there is no avatar
 
		/// for this buddy.
 
		/// \return avatar hash or empty string.
 
		virtual std::string getIconHash() = 0;
 

	
include/transport/rostermanager.h
Show inline comments
 
@@ -48,31 +48,34 @@ class RosterManager {
 
		/// are sent to XMPP user (subscribe presences, Roster Item Exchange stanza or
 
		/// the buddy is added to server-side roster using remote-roster protoXEP).
 
		/// \param buddy AbstractBuddy
 
		void setBuddy(AbstractBuddy *buddy);
 

	
 
		/// Deassociates the buddy with this roster.
 
		/// \param buddy AbstractBuddy.
 
		void unsetBuddy(AbstractBuddy *buddy);
 

	
 
		/// Returns user associated with this roster.
 
		/// \return User
 
		User *getUser() { return m_user; }
 

	
 
		/// Called when new AbstractBuddy is added to this roster.
 
		/// \param buddy newly added AbstractBuddy
 
		boost::signal<void (AbstractBuddy *buddy)> onBuddySet;
 

	
 
		/// Called when AbstractBuddy has been removed from this roster.
 
		/// \param buddy removed AbstractBuddy
 
		boost::signal<void (AbstractBuddy *buddy)> onBuddyUnset;
 

	
 
	private:
 
		void setBuddyCallback(AbstractBuddy *buddy);
 

	
 
		void sendBuddyRosterPush(AbstractBuddy *buddy);
 
		void handleBuddyRosterPushResponse(Swift::ErrorPayload::ref error, const std::string &key);
 

	
 
		std::map<std::string, AbstractBuddy *> m_buddies;
 
		Component *m_component;
 
		User *m_user;
 
		Swift::Timer::ref m_setBuddyTimer;
 
};
 

	
 
}
include/transport/transport.h
Show inline comments
 
@@ -52,48 +52,50 @@ namespace Transport {
 
	/// Represents one transport instance.
 

	
 
	/// It's used to connect
 
	/// the Jabber server and provides transaction layer between Jabber server
 
	/// and other classes.
 
	class Component {
 
		public:
 
			/// Creates new Component instance.
 
			/// \param loop main event loop 
 
			/// \param config cofiguration, this class uses following Config values:
 
			/// 	- service.jid
 
			/// 	- service.password
 
			/// 	- service.server
 
			/// 	- service.port
 
			Component(Swift::EventLoop *loop, Config *config);
 

	
 
			/// Component destructor.
 
			~Component();
 

	
 
			/// Returns Swift::Component associated with this Transport::Component.
 
			/// You can use it to send presences and other stanzas.
 
			/// \return Swift::Component associated with this Transport::Component
 
			Swift::StanzaChannel *getStanzaChannel();
 

	
 
			Swift::IQRouter *getIQRouter() { return m_iqRouter; }
 

	
 
			/// Returns Swift::PresenceOracle associated with this Transport::Component.
 
			/// You can use it to check current resource connected for particular user.
 
			/// \return Swift::PresenceOracle associated with this Transport::Component
 
			Swift::PresenceOracle *getPresenceOracle();
 

	
 
			bool inServerMode() { return m_server != NULL; }
 
			const std::string &getUserRegistryPassword(const std::string &barejid);
 

	
 
			/// Connects the Jabber server.
 
			/// \see Component()
 
			void connect();
 

	
 
			/// Sets disco#info features which are sent as answer to
 
			/// disco#info IQ-get. This sets features of transport contact (For example "j2j.domain.tld").
 
			/// \param features list of features as sent in disco#info response
 
			void setTransportFeatures(std::list<std::string> &features);
 

	
 
			/// Sets disco#info features which are sent as answer to
 
			/// disco#info IQ-get. This sets features of legacy network buddies (For example "me\40gmail.com@j2j.domain.tld").
 
			/// \param features list of features as sent in disco#info response
 
			void setBuddyFeatures(std::list<std::string> &features);
 

	
 
			/// Returns Jabber ID of this transport.
 
			/// \return Jabber ID of this transport
spectrum/src/main.cpp
Show inline comments
 
@@ -50,48 +50,81 @@ static void buddyListNewNode(PurpleBlistNode *node) {
 

	
 
	if (!user)
 
		return;
 

	
 
	SpectrumBuddy *s_buddy = NULL;
 
	GSList *list = purple_find_buddies(account, purple_buddy_get_name(buddy));
 
	while (list) {
 
		PurpleBuddy *b = (PurpleBuddy *) list->data;
 
		if (b->node.ui_data)
 
			s_buddy = (SpectrumBuddy *) b->node.ui_data;
 
		list = g_slist_delete_link(list, list);
 
	}
 

	
 
	if (s_buddy) {
 
		buddy->node.ui_data = s_buddy;
 
		s_buddy->addBuddy(buddy);
 
	}
 
	else {
 
		buddy->node.ui_data = (void *) new SpectrumBuddy(user->getRosterManager(), -1, buddy);
 
		SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
		s_buddy->setFlags(BUDDY_JID_ESCAPING);
 
	}
 
}
 

	
 
static void buddyStatusChanged(PurpleBuddy *buddy, PurpleStatus *status, PurpleStatus *old_status) {
 
	SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 
	User *user = (User *) account->ui_data;
 

	
 
	if (!user || !s_buddy)
 
		return;
 

	
 
	s_buddy->buddyChanged();
 
}
 

	
 
static void buddySignedOn(PurpleBuddy *buddy) {
 
	SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 
	User *user = (User *) account->ui_data;
 

	
 
	if (!user || !s_buddy)
 
		return;
 

	
 
	s_buddy->buddyChanged();
 
}
 

	
 
static void buddySignedOff(PurpleBuddy *buddy) {
 
	SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 
	User *user = (User *) account->ui_data;
 

	
 
	if (!user || !s_buddy)
 
		return;
 

	
 
	s_buddy->buddyChanged();
 
}
 

	
 
static void NodeRemoved(PurpleBlistNode *node, void *data) {
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
		return;
 
	PurpleBuddy *buddy = (PurpleBuddy *) node;
 
	
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 
	User *user = (User *) account->ui_data;
 
	if (buddy->node.ui_data) {
 
		SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
		s_buddy->removeBuddy(buddy);
 
		buddy->node.ui_data = NULL;
 
		if (s_buddy->getBuddiesCount() == 0) {
 
			delete s_buddy;
 
		}
 
	}
 
}
 

	
 
static PurpleBlistUiOps blistUiOps =
 
{
 
	NULL,
 
	buddyListNewNode,
 
	NULL,
 
	NULL, // buddyListUpdate,
 
	NULL, //NodeRemoved,
 
@@ -184,51 +217,51 @@ static bool initPurple(Config &cfg) {
 
		/* Good default preferences */
 
		/* The combination of these two settings mean that libpurple will never
 
		 * (of its own accord) set all the user accounts idle.
 
		 */
 
		purple_prefs_set_bool("/purple/away/away_when_idle", false);
 
		/*
 
		 * This must be set to something not "none" for idle reporting to work
 
		 * for, e.g., the OSCAR prpl. We don't implement the UI ops, so this is
 
		 * okay for now.
 
		 */
 
		purple_prefs_set_string("/purple/away/idle_reporting", "system");
 

	
 
		/* Disable all logging */
 
		purple_prefs_set_bool("/purple/logging/log_ims", false);
 
		purple_prefs_set_bool("/purple/logging/log_chats", false);
 
		purple_prefs_set_bool("/purple/logging/log_system", false);
 

	
 

	
 
// 		purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", &conversation_handle, PURPLE_CALLBACK(newMessageReceived), NULL);
 
// 		purple_signal_connect(purple_conversations_get_handle(), "buddy-typing", &conversation_handle, PURPLE_CALLBACK(buddyTyping), NULL);
 
// 		purple_signal_connect(purple_conversations_get_handle(), "buddy-typed", &conversation_handle, PURPLE_CALLBACK(buddyTyped), NULL);
 
// 		purple_signal_connect(purple_conversations_get_handle(), "buddy-typing-stopped", &conversation_handle, PURPLE_CALLBACK(buddyTypingStopped), NULL);
 
// 		purple_signal_connect(purple_connections_get_handle(), "signed-on", &conn_handle,PURPLE_CALLBACK(signed_on), NULL);
 
// 		purple_signal_connect(purple_blist_get_handle(), "buddy-removed", &blist_handle,PURPLE_CALLBACK(buddyRemoved), NULL);
 
// 		purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", &blist_handle,PURPLE_CALLBACK(buddySignedOn), NULL);
 
// 		purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", &blist_handle,PURPLE_CALLBACK(buddySignedOff), NULL);
 
// 		purple_signal_connect(purple_blist_get_handle(), "buddy-status-changed", &blist_handle,PURPLE_CALLBACK(buddyStatusChanged), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", &blist_handle,PURPLE_CALLBACK(buddySignedOn), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", &blist_handle,PURPLE_CALLBACK(buddySignedOff), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "buddy-status-changed", &blist_handle,PURPLE_CALLBACK(buddyStatusChanged), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "blist-node-removed", &blist_handle,PURPLE_CALLBACK(NodeRemoved), NULL);
 
// 		purple_signal_connect(purple_conversations_get_handle(), "chat-topic-changed", &conversation_handle, PURPLE_CALLBACK(conv_chat_topic_changed), NULL);
 
// 
 
// 		purple_commands_init();
 

	
 
	}
 
	return ret;
 
}
 

	
 
static void handleUserReadyToConnect(User *user) {
 
	PurpleAccount *account = (PurpleAccount *) user->getData();
 
	purple_account_set_enabled(account, "spectrum", TRUE);
 
	
 
	const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AVAILABLE);
 
	if (status_type != NULL) {
 
		purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, NULL);
 
	}
 
}
 

	
 
static void handleUserCreated(User *user, UserManager *userManager, Config *config) {
 
	UserInfo userInfo = user->getUserInfo();
 
	PurpleAccount *account = NULL;
 
	const char *protocol = CONFIG_STRING(config, "service.protocol").c_str();
 
	if (purple_accounts_find(userInfo.uin.c_str(), protocol) != NULL){
spectrum/src/spectrumbuddy.cpp
Show inline comments
 
@@ -34,49 +34,73 @@ std::string SpectrumBuddy::getAlias() {
 
	std::string alias;
 
	if (purple_buddy_get_server_alias(m_buddy))
 
		alias = (std::string) purple_buddy_get_server_alias(m_buddy);
 
	else
 
		alias = (std::string) purple_buddy_get_alias(m_buddy);
 
	return alias;
 
}
 

	
 
std::string SpectrumBuddy::getName() {
 
	std::string name(purple_buddy_get_name(m_buddy));
 
	if (name.empty()) {
 
		Log("SpectrumBuddy::getName", "Name is EMPTY!");
 
	}
 
	return name;
 
}
 

	
 
bool SpectrumBuddy::getStatus(Swift::StatusShow &status, std::string &statusMessage) {
 
	PurplePresence *pres = purple_buddy_get_presence(m_buddy);
 
	if (pres == NULL)
 
		return false;
 
	PurpleStatus *stat = purple_presence_get_active_status(pres);
 
	if (stat == NULL)
 
		return false;
 
	int st = purple_status_type_get_primitive(purple_status_get_type(stat));
 
	// TODO: populate status
 

	
 
	switch(st) {
 
		case PURPLE_STATUS_AVAILABLE: {
 
			break;
 
		}
 
		case PURPLE_STATUS_AWAY: {
 
			status = Swift::StatusShow::Away;
 
			break;
 
		}
 
		case PURPLE_STATUS_UNAVAILABLE: {
 
			status = Swift::StatusShow::DND;
 
			break;
 
		}
 
		case PURPLE_STATUS_EXTENDED_AWAY: {
 
			status = Swift::StatusShow::XA;
 
			break;
 
		}
 
		case PURPLE_STATUS_OFFLINE: {
 
			status = Swift::StatusShow::None;
 
			break;
 
		}
 
		default:
 
			break;
 
	}
 

	
 
	const char *message = purple_status_get_attr_string(stat, "message");
 

	
 
	if (message != NULL) {
 
		char *stripped = purple_markup_strip_html(message);
 
		statusMessage = std::string(stripped);
 
		g_free(stripped);
 
	}
 
	else
 
		statusMessage = "";
 
	return true;
 
}
 

	
 
std::string SpectrumBuddy::getIconHash() {
 
	char *avatarHash = NULL;
 
	PurpleBuddyIcon *icon = purple_buddy_icons_find(purple_buddy_get_account(m_buddy), purple_buddy_get_name(m_buddy));
 
	if (icon) {
 
		avatarHash = purple_buddy_icon_get_full_path(icon);
 
		Log(getName(), "avatarHash");
 
	}
 

	
 
	if (avatarHash) {
 
		Log(getName(), "Got avatar hash");
 
		// Check if it's patched libpurple which saves icons to directories
 
		char *hash = strrchr(avatarHash,'/');
src/abstractbuddy.cpp
Show inline comments
 
@@ -35,87 +35,88 @@ AbstractBuddy::~AbstractBuddy() {
 

	
 
void AbstractBuddy::generateJID() {
 
	m_jid = Swift::JID();
 
	m_jid = Swift::JID(getSafeName(), m_rosterManager->getUser()->getComponent()->getJID().toString(), "bot");
 
}
 

	
 
void AbstractBuddy::setID(long id) {
 
	m_id = id;
 
}
 

	
 
long AbstractBuddy::getID() {
 
	return m_id;
 
}
 

	
 
void AbstractBuddy::setFlags(BuddyFlag flags) {
 
	m_flags = flags;
 

	
 
	generateJID();
 
}
 

	
 
BuddyFlag AbstractBuddy::getFlags() {
 
	return m_flags;
 
}
 

	
 
const Swift::JID &AbstractBuddy::getJID(const std::string &hostname) {
 
const Swift::JID &AbstractBuddy::getJID() {
 
	if (!m_jid.isValid()) {
 
		generateJID();
 
	}
 
	return m_jid;
 
}
 

	
 
void AbstractBuddy::setOnline() {
 
	m_online = true;
 
}
 

	
 
void AbstractBuddy::setOffline() {
 
	m_online = false;
 
	m_lastPresence = Swift::Presence::ref();
 
}
 

	
 
bool AbstractBuddy::isOnline() {
 
	return m_online;
 
}
 

	
 
void AbstractBuddy::setSubscription(const std::string &subscription) {
 
	m_subscription = subscription;
 
}
 

	
 
const std::string &AbstractBuddy::getSubscription() {
 
	return m_subscription;
 
}
 

	
 
Swift::Presence::ref AbstractBuddy::generatePresenceStanza(int features, bool only_new) {
 
	std::string alias = getAlias();
 
	std::string name = getSafeName();
 

	
 
	Swift::StatusShow s;
 
	std::string statusMessage;
 
	if (!getStatus(s, statusMessage))
 
		return Swift::Presence::ref();
 

	
 
	Swift::Presence::ref presence = Swift::Presence::create();
 
// 	presence->setFrom(getJID());
 
 	presence->setFrom(m_jid);
 
	presence->setTo(m_rosterManager->getUser()->getJID().toBare());
 
	presence->setType(Swift::Presence::Available);
 

	
 
	if (!statusMessage.empty())
 
		presence->setStatus(statusMessage);
 

	
 
	if (s.getType() == Swift::StatusShow::None)
 
		presence->setType(Swift::Presence::Unavailable);
 
	presence->setShow(s.getType());
 

	
 
	if (presence->getType() != Swift::Presence::Unavailable) {
 
		// caps
 
// 		presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::CapsInfo (CONFIG().caps)));
 

	
 
		if (features & 0/*TRANSPORT_FEATURE_AVATARS*/) {
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::VCardUpdate (getIconHash())));
 
		}
 
	}
 

	
 
	if (only_new) {
 
		if (m_lastPresence)
 
			m_lastPresence->setTo(Swift::JID(""));
 
		if (m_lastPresence == presence) {
 
			return Swift::Presence::ref();
 
		}
 
@@ -124,25 +125,32 @@ Swift::Presence::ref AbstractBuddy::generatePresenceStanza(int features, bool on
 

	
 
	return presence;
 
}
 

	
 
std::string AbstractBuddy::getSafeName() {
 
	if (m_jid.isValid()) {
 
		return m_jid.getNode();
 
	}
 
	std::string name = getName();
 
// 	Transport::instance()->protocol()->prepareUsername(name, purple_buddy_get_account(m_buddy));
 
	if (getFlags() & BUDDY_JID_ESCAPING) {
 
		name = Swift::JID::getEscapedNode(name);
 
	}
 
	else {
 
		if (name.find_last_of("@") != std::string::npos) {
 
			name.replace(name.find_last_of("@"), 1, "%");
 
		}
 
	}
 
// 	if (name.empty()) {
 
// 		Log("SpectrumBuddy::getSafeName", "Name is EMPTY! Previous was " << getName() << ".");
 
// 	}
 
	return name;
 
}
 

	
 
void AbstractBuddy::buddyChanged() {
 
	Swift::Presence::ref presence = generatePresenceStanza(255);
 
	if (presence) {
 
		m_rosterManager->getUser()->getComponent()->getStanzaChannel()->sendPresence(presence);
 
	}
 
}
 

	
 
}
src/rostermanager.cpp
Show inline comments
 
@@ -2,58 +2,85 @@
 
 * XMPP - libpurple transport
 
 *
 
 * Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
 
 *
 
 * This program is free software; you can redistribute it and/or modify
 
 * it under the terms of the GNU General Public License as published by
 
 * the Free Software Foundation; either version 2 of the License, or
 
 * (at your option) any later version.
 
 *
 
 * This program is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 
 */
 

	
 
#include "transport/rostermanager.h"
 
#include "transport/abstractbuddy.h"
 
#include "transport/usermanager.h"
 
#include "transport/abstractbuddy.h"
 
#include "transport/user.h"
 
#include "Swiften/Roster/SetRosterRequest.h"
 
#include "Swiften/Elements/RosterPayload.h"
 
#include "Swiften/Elements/RosterItemPayload.h"
 

	
 
namespace Transport {
 

	
 
RosterManager::RosterManager(User *user, Component *component){
 
	m_user = user;
 
	m_component = component;
 
	m_setBuddyTimer = m_component->getFactories()->getTimerFactory()->createTimer(10);
 
	m_setBuddyTimer = m_component->getFactories()->getTimerFactory()->createTimer(1000);
 
}
 

	
 
RosterManager::~RosterManager() {
 
}
 

	
 
void RosterManager::setBuddy(AbstractBuddy *buddy) {
 
	m_setBuddyTimer->onTick.connect(boost::bind(&RosterManager::setBuddyCallback, this, buddy));
 
	m_setBuddyTimer->start();
 
}
 

	
 
void RosterManager::sendBuddyRosterPush(AbstractBuddy *buddy) {
 
	Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
 
	Swift::RosterItemPayload item;
 
	item.setJID(buddy->getJID().toBare());
 
	item.setName(buddy->getAlias());
 
	item.setGroups(buddy->getGroups());
 

	
 
	payload->addItem(item);
 

	
 
	Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, m_component->getIQRouter(), m_user->getJID().toBare());
 
	request->onResponse.connect(boost::bind(&RosterManager::handleBuddyRosterPushResponse, this, _1, buddy->getSafeName()));
 
	request->send();
 
}
 

	
 
void RosterManager::setBuddyCallback(AbstractBuddy *buddy) {
 
	m_setBuddyTimer->onTick.disconnect(boost::bind(&RosterManager::setBuddyCallback, this, buddy));
 

	
 
	m_buddies[buddy->getSafeName()] = buddy;
 
	onBuddySet(buddy);
 

	
 
	if (m_component->inServerMode()) {
 
		sendBuddyRosterPush(buddy);
 
	}
 

	
 
	if (m_setBuddyTimer->onTick.empty()) {
 
		m_setBuddyTimer->stop();
 
	}
 
}
 

	
 
void RosterManager::unsetBuddy(AbstractBuddy *buddy) {
 
	m_buddies.erase(buddy->getSafeName());
 
	onBuddyUnset(buddy);
 
}
 

	
 
void RosterManager::handleBuddyRosterPushResponse(Swift::ErrorPayload::ref error, const std::string &key) {
 
	if (m_buddies[key] != NULL) {
 
		m_buddies[key]->buddyChanged();
 
	}
 
}
 

	
 
}
 
\ No newline at end of file
0 comments (0 inline, 0 general)