First untested version of blocking feature

This commit is contained in:
Jan Kaluza 2011-07-27 10:33:34 +02:00
parent 59236d962f
commit 8ee0310448
17 changed files with 335 additions and 6 deletions

View file

@ -485,6 +485,16 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
}
}
void handleBuddyBlockToggled(const std::string &user, const std::string &buddyName, bool blocked) {
PurpleAccount *account = m_sessions[user];
if (account) {
if (blocked)
purple_privacy_deny(account, buddyName.c_str(), FALSE, FALSE);
else
purple_privacy_allow(account, buddyName.c_str(), FALSE, FALSE);
}
}
void handleTypingRequest(const std::string &user, const std::string &buddyName) {
PurpleAccount *account = m_sessions[user];
if (account) {
@ -657,7 +667,8 @@ static void buddyListUpdate(PurpleBuddyList *list, PurpleBlistNode *node) {
std::string message;
getStatus(buddy, status, message);
np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy));
np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy),
purple_privacy_check(account, purple_buddy_get_name(buddy)) == false);
}
static void NodeRemoved(PurpleBlistNode *node, void *data) {

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2011 Jan Kaluza
* Licensed under the Simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#include <Swiften/Elements/BlockPayload.h>
namespace Swift {
// This payload is NOT part of ANY XEP and it is only
// libtransport related extension.
BlockPayload::BlockPayload() {
}
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2011 Jan Kaluza
* Licensed under the Simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#pragma once
#include <vector>
#include <string>
#include <boost/shared_ptr.hpp>
#include <Swiften/Elements/Payload.h>
// This payload is NOT part of ANY XEP and it is only
// libtransport related extension.
namespace Swift {
class BlockPayload : public Payload {
public:
typedef boost::shared_ptr<BlockPayload> ref;
public:
BlockPayload();
};
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2011 Jan Kaluza
* Licensed under the Simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#include <Swiften/Parser/PayloadParsers/BlockParser.h>
namespace Swift {
// This payload is NOT part of ANY XEP and it is only
// libtransport related extension.
BlockParser::BlockParser() /*: level_(0)*/ {
}
void BlockParser::handleStartElement(const std::string& /*element*/, const std::string& /*ns*/, const AttributeMap& /*attributes*/) {
}
void BlockParser::handleEndElement(const std::string&, const std::string&) {
}
void BlockParser::handleCharacterData(const std::string&) {
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2011 Jan Kaluza
* Licensed under the Simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#pragma once
#include <Swiften/Elements/BlockPayload.h>
#include <Swiften/Parser/GenericPayloadParser.h>
// This payload is NOT part of ANY XEP and it is only
// libtransport related extension.
namespace Swift {
class BlockParser : public GenericPayloadParser<BlockPayload> {
public:
BlockParser();
virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
virtual void handleEndElement(const std::string& element, const std::string&);
virtual void handleCharacterData(const std::string& data);
// private:
// int level_;
};
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2011 Jan Kaluza
* Licensed under the Simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#include <Swiften/Serializer/PayloadSerializers/BlockSerializer.h>
#include <boost/shared_ptr.hpp>
#include <Swiften/Serializer/XML/XMLTextNode.h>
#include <Swiften/Serializer/XML/XMLRawTextNode.h>
#include <Swiften/Serializer/XML/XMLElement.h>
namespace Swift {
// This payload is NOT part of ANY XEP and it is only
// libtransport related extension.
BlockSerializer::BlockSerializer() : GenericPayloadSerializer<BlockPayload>() {
}
std::string BlockSerializer::serializePayload(boost::shared_ptr<BlockPayload> attention) const {
XMLElement attentionElement("block", "urn:xmpp:block:0");
return attentionElement.serialize();
}
}

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2011 Jan Kaluza
* Licensed under the Simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#pragma once
#include <Swiften/Serializer/GenericPayloadSerializer.h>
#include <Swiften/Elements/BlockPayload.h>
// This payload is NOT part of ANY XEP and it is only
// libtransport related extension.
namespace Swift {
class BlockSerializer : public GenericPayloadSerializer<BlockPayload> {
public:
BlockSerializer();
virtual std::string serializePayload(boost::shared_ptr<BlockPayload>) const;
};
}

View file

@ -84,6 +84,14 @@ class Buddy {
/// Marks this buddy as offline.
void setOffline();
void setBlocked(bool block) {
m_blocked = block;
}
bool isBlocked() {
return m_blocked;
}
/// Returns true if this buddy is marked as available/online.
/// \return true if this buddy is marked as available/online.
@ -170,6 +178,7 @@ class Buddy {
long m_id;
bool m_online;
bool m_blocked;
std::string m_subscription;
Swift::Presence::ref m_lastPresence;
Swift::JID m_jid;

View file

@ -41,7 +41,8 @@ class NetworkPlugin {
virtual ~NetworkPlugin();
void handleBuddyChanged(const std::string &user, const std::string &buddyName, const std::string &alias,
const std::string &groups, int status, const std::string &statusMessage = "", const std::string &iconHash = ""
const std::string &groups, int status, const std::string &statusMessage = "", const std::string &iconHash = "",
bool blocked = false
);
void handleParticipantChanged(const std::string &user, const std::string &nickname, const std::string &room, int flags, int status = Swift::StatusShow::None, const std::string &statusMessage = "", const std::string &newname = "");
@ -78,6 +79,7 @@ class NetworkPlugin {
virtual void handleStatusChangeRequest(const std::string &/*user*/, int status, const std::string &statusMessage) {}
virtual void handleBuddyUpdatedRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*alias*/, const std::string &/*groups*/) {}
virtual void handleBuddyRemovedRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*groups*/) {}
virtual void handleBuddyBlockToggled(const std::string &/*user*/, const std::string &/*buddyName*/, bool /*blocked*/) {}
virtual void handleTypingRequest(const std::string &/*user*/, const std::string &/*buddyName*/) {}
virtual void handleTypedRequest(const std::string &/*user*/, const std::string &/*buddyName*/) {}

View file

@ -39,6 +39,7 @@ class Config;
class NetworkConversation;
class VCardResponder;
class RosterResponder;
class BlockResponder;
class NetworkPluginServer {
public:
@ -95,6 +96,8 @@ class NetworkPluginServer {
void handleBuddyRemoved(Buddy *buddy);
void handleBuddyAdded(Buddy *buddy, const Swift::RosterItemPayload &item);
void handleBlockToggled(Buddy *buddy);
void handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> vcard);
void handleVCardRequired(User *user, const std::string &name, unsigned int id);
@ -107,6 +110,7 @@ class NetworkPluginServer {
UserManager *m_userManager;
VCardResponder *m_vcardResponder;
RosterResponder *m_rosterResponder;
BlockResponder *m_blockResponder;
Config *m_config;
boost::shared_ptr<Swift::BoostConnectionServer> m_server;
std::list<Backend *> m_clients;

69
src/blockresponder.cpp Normal file
View file

@ -0,0 +1,69 @@
/**
* 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 "blockresponder.h"
#include <iostream>
#include <boost/bind.hpp>
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Elements/BlockPayload.h"
#include "Swiften/Swiften.h"
#include "transport/usermanager.h"
#include "transport/user.h"
#include "transport/buddy.h"
#include "transport/rostermanager.h"
#include "log4cxx/logger.h"
using namespace log4cxx;
using namespace Swift;
using namespace boost;
namespace Transport {
static LoggerPtr logger = Logger::getLogger("BlockResponder");
BlockResponder::BlockResponder(Swift::IQRouter *router, UserManager *userManager) : Swift::SetResponder<BlockPayload>(router) {
m_userManager = userManager;
}
BlockResponder::~BlockResponder() {
}
bool BlockResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::BlockPayload> info) {
User *user = m_userManager->getUser(from.toBare().toString());
if (!user) {
LOG4CXX_WARN(logger, from.toBare().toString() << ": User is not logged in");
return true;
}
Buddy *buddy = user->getRosterManager()->getBuddy(Buddy::JIDToLegacyName(to));
if (buddy) {
LOG4CXX_WARN(logger, from.toBare().toString() << ": Buddy " << Buddy::JIDToLegacyName(to) << " does not exist");
return true;
}
onBlockToggled(buddy);
return true;
}
}

46
src/blockresponder.h Normal file
View file

@ -0,0 +1,46 @@
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* 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
*/
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Queries/SetResponder.h"
#include "Swiften/Elements/BlockPayload.h"
namespace Transport {
class UserManager;
class Buddy;
class BlockResponder : public Swift::SetResponder<Swift::BlockPayload> {
public:
BlockResponder(Swift::IQRouter *router, UserManager *userManager);
~BlockResponder();
boost::signal<void (Buddy *)> onBlockToggled;
private:
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::BlockPayload> payload);
UserManager *m_userManager;
};
}

View file

@ -22,10 +22,11 @@
#include "transport/rostermanager.h"
#include "transport/user.h"
#include "transport/transport.h"
#include "Swiften/Elements/BlockPayload.h"
namespace Transport {
Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_online(false), m_subscription("ask"), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager){
Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_online(false), m_blocked(false), m_subscription("ask"), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager){
// m_rosterManager->setBuddy(this);
}
@ -112,6 +113,9 @@ Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new)
// if (features & 0/*TRANSPORT_FEATURE_AVATARS*/) {
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::VCardUpdate (getIconHash())));
// }
if (m_blocked) {
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::BlockPayload ()));
}
}
if (only_new) {

View file

@ -130,7 +130,7 @@ void NetworkPlugin::handleSubject(const std::string &user, const std::string &le
}
void NetworkPlugin::handleBuddyChanged(const std::string &user, const std::string &buddyName, const std::string &alias,
const std::string &groups, int status, const std::string &statusMessage, const std::string &iconHash) {
const std::string &groups, int status, const std::string &statusMessage, const std::string &iconHash, bool blocked) {
pbnetwork::Buddy buddy;
buddy.set_username(user);
buddy.set_buddyname(buddyName);
@ -139,6 +139,7 @@ void NetworkPlugin::handleBuddyChanged(const std::string &user, const std::strin
buddy.set_status(status);
buddy.set_statusmessage(statusMessage);
buddy.set_iconhash(iconHash);
buddy.set_blocked(blocked);
std::string message;
buddy.SerializeToString(&message);
@ -373,8 +374,12 @@ void NetworkPlugin::handleBuddyChangedPayload(const std::string &data) {
// TODO: ERROR
return;
}
handleBuddyUpdatedRequest(payload.username(), payload.buddyname(), payload.alias(), payload.groups());
if (payload.has_blocked()) {
handleBuddyBlockToggled(payload.username(), payload.buddyname(), payload.blocked());
}
else {
handleBuddyUpdatedRequest(payload.username(), payload.buddyname(), payload.alias(), payload.groups());
}
}
void NetworkPlugin::handleBuddyRemovedPayload(const std::string &data) {

View file

@ -30,6 +30,7 @@
#include "transport/conversation.h"
#include "transport/vcardresponder.h"
#include "transport/rosterresponder.h"
#include "blockresponder.h"
#include "Swiften/Swiften.h"
#include "Swiften/Server/ServerStanzaChannel.h"
#include "Swiften/Elements/StreamError.h"
@ -130,6 +131,7 @@ static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payloa
buddy->setGroups(groups);
buddy->setStatus(Swift::StatusShow((Swift::StatusShow::Type) payload.status()), payload.statusmessage());
buddy->setIconHash(payload.iconhash());
buddy->setBlocked(payload.blocked());
}
NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, UserManager *userManager) {
@ -155,6 +157,10 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U
m_rosterResponder->onBuddyUpdated.connect(boost::bind(&NetworkPluginServer::handleBuddyUpdated, this, _1, _2));
m_rosterResponder->start();
m_blockResponder = new BlockResponder(component->getIQRouter(), userManager);
m_blockResponder->onBlockToggled.connect(boost::bind(&NetworkPluginServer::handleBlockToggled, this, _1));
m_blockResponder->start();
m_server = Swift::BoostConnectionServer::create(Swift::HostAddress(CONFIG_STRING(m_config, "service.backend_host")), boost::lexical_cast<int>(CONFIG_STRING(m_config, "service.backend_port")), component->getNetworkFactories()->getIOServiceThread()->getIOService(), component->m_loop);
m_server->onNewConnection.connect(boost::bind(&NetworkPluginServer::handleNewClientConnection, this, _1));
m_server->start();
@ -173,6 +179,7 @@ NetworkPluginServer::~NetworkPluginServer() {
delete m_component->m_factory;
delete m_vcardResponder;
delete m_rosterResponder;
delete m_blockResponder;
}
void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Connection> c) {
@ -857,6 +864,30 @@ void NetworkPluginServer::handleBuddyAdded(Buddy *buddy, const Swift::RosterItem
handleBuddyUpdated(buddy, item);
}
void NetworkPluginServer::handleBlockToggled(Buddy *b) {
User *user = b->getRosterManager()->getUser();
pbnetwork::Buddy buddy;
buddy.set_username(user->getJID().toBare());
buddy.set_buddyname(b->getName());
buddy.set_alias(b->getAlias());
buddy.set_groups(b->getGroups().size() == 0 ? "" : b->getGroups()[0]);
buddy.set_status(Swift::StatusShow::None);
buddy.set_blocked(not b->isBlocked());
std::string message;
buddy.SerializeToString(&message);
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED);
Backend *c = (Backend *) user->getData();
if (!c) {
return;
}
send(c->connection, message);
}
void NetworkPluginServer::handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> v) {
pbnetwork::VCard vcard;
vcard.set_username(user->getJID().toBare());

View file

@ -30,6 +30,7 @@ message Buddy {
optional int32 status = 5;
optional string statusMessage = 6;
optional string iconHash = 7;
optional bool blocked = 8;
}
message ConversationMessage {

View file

@ -33,6 +33,8 @@
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
#include "Swiften/Parser/PayloadParsers/BlockParser.h"
#include "Swiften/Serializer/PayloadSerializers/BlockSerializer.h"
#include "log4cxx/logger.h"
#include "log4cxx/consoleappender.h"
#include "log4cxx/patternlayout.h"
@ -90,9 +92,11 @@ Component::Component(Swift::EventLoop *loop, Config *config, Factory *factory, T
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::BlockParser>("block", "urn:xmpp:block:0"));
m_server->addPayloadSerializer(new Swift::AttentionSerializer());
m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
m_server->addPayloadSerializer(new Swift::BlockSerializer());
m_server->onDataRead.connect(bind(&Component::handleDataRead, this, _1));
m_server->onDataWritten.connect(bind(&Component::handleDataWritten, this, _1));