diff --git a/libtransport/Buddy.cpp b/libtransport/Buddy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c877b6bb2c07ec6df317666bf84b068eedc9d957 --- /dev/null +++ b/libtransport/Buddy.cpp @@ -0,0 +1,217 @@ +/** + * XMPP - libpurple transport + * + * Copyright (C) 2009, Jan Kaluza + * + * 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/Buddy.h" +#include "transport/RosterManager.h" +#include "transport/User.h" +#include "transport/Transport.h" +#include "transport/UserManager.h" +#include "transport/Frontend.h" + +#include "Swiften/Elements/VCardUpdate.h" +#include "Swiften/Elements/Presence.h" + +#include +#include + +namespace Transport { + +Buddy::Buddy(RosterManager *rosterManager, long id, BuddyFlag flags) : m_id(id), m_flags(flags), m_rosterManager(rosterManager), + m_subscription(Ask) { +} + +Buddy::~Buddy() { +} + +void Buddy::sendPresence() { + std::vector &presences = generatePresenceStanzas(255); + BOOST_FOREACH(Swift::Presence::ref presence, presences) { + m_rosterManager->getUser()->getComponent()->getFrontend()->sendPresence(presence); + } +} + +void Buddy::generateJID() { + m_jid = Swift::JID(); + m_jid = Swift::JID(getSafeName(), m_rosterManager->getUser()->getComponent()->getJID().toString(), "bot"); +} + +void Buddy::setID(long id) { + m_id = id; +} + +long Buddy::getID() { + return m_id; +} + +void Buddy::setFlags(BuddyFlag flags) { + m_flags = flags; + + if (!getSafeName().empty()) { + try { + generateJID(); + } catch (...) { + } + } +} + +BuddyFlag Buddy::getFlags() { + return m_flags; +} + +const Swift::JID &Buddy::getJID() { + if (!m_jid.isValid() || m_jid.getNode().empty()) { + generateJID(); + } + return m_jid; +} + +void Buddy::setSubscription(Subscription subscription) { + m_subscription = subscription; +} + +Buddy::Subscription Buddy::getSubscription() { + return m_subscription; +} + +void Buddy::handleRawPresence(Swift::Presence::ref presence) { + for (std::vector::iterator it = m_presences.begin(); it != m_presences.end(); it++) { + if ((*it)->getFrom() == presence->getFrom()) { + m_presences.erase(it); + break; + } + } + + m_presences.push_back(presence); + m_rosterManager->getUser()->getComponent()->getFrontend()->sendPresence(presence); +} + +std::vector &Buddy::generatePresenceStanzas(int features, bool only_new) { + if (m_jid.getNode().empty()) { + generateJID(); + } + + Swift::StatusShow s; + std::string statusMessage; + if (!getStatus(s, statusMessage)) { + for (std::vector::iterator it = m_presences.begin(); it != m_presences.end(); it++) { + if ((*it)->getFrom() == m_jid) { + m_presences.erase(it); + break; + } + } + return m_presences; + } + + Swift::Presence::ref presence = Swift::Presence::create(); + presence->setTo(m_rosterManager->getUser()->getJID().toBare()); + presence->setFrom(m_jid); + 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 + + +// if (features & 0/*TRANSPORT_FEATURE_AVATARS*/) { + presence->addPayload(boost::shared_ptr(new Swift::VCardUpdate (getIconHash()))); +// } +// if (isBlocked()) { +// presence->addPayload(boost::shared_ptr(new Transport::BlockPayload ())); +// } + } + + BOOST_FOREACH(Swift::Presence::ref &p, m_presences) { + if (p->getFrom() == presence->getFrom()) { + p = presence; + return m_presences; + } + } + + m_presences.push_back(presence); + +// if (only_new) { +// if (m_lastPresence) +// m_lastPresence->setTo(Swift::JID("")); +// if (m_lastPresence == presence) { +// return Swift::Presence::ref(); +// } +// m_lastPresence = presence; +// } + + return m_presences; +} + +std::string Buddy::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, "%"); // OK + } + } +// if (name.empty()) { +// Log("SpectrumBuddy::getSafeName", "Name is EMPTY! Previous was " << getName() << "."); +// } + return name; +} + +void Buddy::handleVCardReceived(const std::string &id, Swift::VCard::ref vcard) { + m_rosterManager->getUser()->getComponent()->getFrontend()->sendVCard(vcard, m_rosterManager->getUser()->getJID()); +} + +std::string Buddy::JIDToLegacyName(const Swift::JID &jid) { + std::string name; + if (jid.getUnescapedNode() == jid.getNode()) { + name = jid.getNode(); + if (name.find_last_of("%") != std::string::npos) { + name.replace(name.find_last_of("%"), 1, "@"); // OK + } + } + else { + name = jid.getUnescapedNode(); + // Psi sucks... +// if (name.find_last_of("\\40") != std::string::npos) { +// name.replace(name.find_last_of("\\40"), 1, "@"); // OK +// } + } + return name; +} + +BuddyFlag Buddy::buddyFlagsFromJID(const Swift::JID &jid) { + if (jid.getUnescapedNode() == jid.getNode()) { + return BUDDY_NO_FLAG; + } + return BUDDY_JID_ESCAPING; +} + +}