diff options
author | Tobias Markmann <tm@ayena.de> | 2013-04-30 20:10:12 (GMT) |
---|---|---|
committer | Swift Review <review@swift.im> | 2013-10-01 14:48:44 (GMT) |
commit | fd47dd7d5cec5155b9985959d2f0e0f3b386cd98 (patch) | |
tree | d4da57ce3f1c90f56701cab8757d75e089473c9e /Swiften | |
parent | a3781c5b770c03ff32c5cf8f1280b21c2a8e2626 (diff) | |
download | swift-contrib-fd47dd7d5cec5155b9985959d2f0e0f3b386cd98.zip swift-contrib-fd47dd7d5cec5155b9985959d2f0e0f3b386cd98.tar.bz2 |
Adding support for impromptu MUCs.
Change-Id: I363e9d740bbec311454827645f4ea6df8bb60bed
License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.
Diffstat (limited to 'Swiften')
-rw-r--r-- | Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp | 50 | ||||
-rw-r--r-- | Swiften/Disco/DiscoServiceWalker.cpp | 1 | ||||
-rw-r--r-- | Swiften/Disco/DiscoServiceWalker.h | 3 | ||||
-rw-r--r-- | Swiften/Elements/MUCInvitationPayload.h | 11 | ||||
-rw-r--r-- | Swiften/MUC/MUC.cpp | 22 | ||||
-rw-r--r-- | Swiften/MUC/MUC.h | 13 | ||||
-rw-r--r-- | Swiften/Parser/PayloadParsers/MUCInvitationPayloadParser.cpp | 1 | ||||
-rw-r--r-- | Swiften/Serializer/PayloadSerializers/MUCInvitationPayloadSerializer.cpp | 3 |
8 files changed, 55 insertions, 49 deletions
diff --git a/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp b/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp index dd76fb6..97edc73 100644 --- a/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp +++ b/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp @@ -13,15 +13,15 @@ #include <Swiften/Elements/VCard.h> #include <Swiften/Avatars/VCardAvatarManager.h> +#include <Swiften/VCards/VCardMemoryStorage.h> #include <Swiften/Avatars/AvatarMemoryStorage.h> #include <Swiften/VCards/VCardManager.h> -#include <Swiften/VCards/VCardStorage.h> #include <Swiften/MUC/MUCRegistry.h> #include <Swiften/Queries/IQRouter.h> #include <Swiften/Client/DummyStanzaChannel.h> -#include <Swiften/StringCodecs/Hexify.h> #include <Swiften/Crypto/CryptoProvider.h> #include <Swiften/Crypto/PlatformCryptoProvider.h> +#include <Swiften/StringCodecs/Hexify.h> using namespace Swift; @@ -36,45 +36,6 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE_END(); public: - class TestVCardStorage : public VCardStorage { - public: - TestVCardStorage(CryptoProvider* crypto) : VCardStorage(crypto), crypto(crypto) {} - - virtual VCard::ref getVCard(const JID& jid) const { - VCardMap::const_iterator i = vcards.find(jid); - if (i != vcards.end()) { - return i->second; - } - else { - return VCard::ref(); - } - } - - virtual void setVCard(const JID& jid, VCard::ref v) { - vcards[jid] = v; - } - - std::string getPhotoHash(const JID& jid) const { - if (photoHashes.find(jid) != photoHashes.end()) { - return photoHashes.find(jid)->second; - } - VCard::ref vCard = getVCard(jid); - if (vCard && !vCard->getPhoto().empty()) { - return Hexify::hexify(crypto->getSHA1Hash(vCard->getPhoto())); - } - else { - return ""; - } - } - - std::map<JID, std::string> photoHashes; - - private: - typedef std::map<JID, VCard::ref> VCardMap; - VCardMap vcards; - CryptoProvider* crypto; - }; - void setUp() { crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); ownJID = JID("foo@fum.com/bum"); @@ -83,7 +44,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { iqRouter = new IQRouter(stanzaChannel); mucRegistry = new DummyMUCRegistry(); avatarStorage = new AvatarMemoryStorage(); - vcardStorage = new TestVCardStorage(crypto.get()); + vcardStorage = new VCardMemoryStorage(crypto.get()); vcardManager = new VCardManager(ownJID, iqRouter, vcardStorage); avatar1 = createByteArray("abcdefg"); avatar1Hash = Hexify::hexify(crypto->getSHA1Hash(avatar1)); @@ -140,8 +101,9 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { void testGetAvatarHashKnownAvatarUnknownVCard() { boost::shared_ptr<VCardAvatarManager> testling = createManager(); - vcardStorage->photoHashes[user1.toBare()] = avatar1Hash; + avatarStorage->setAvatarForJID(user1, avatar1Hash); + std::string result = testling->getAvatarHash(user1); CPPUNIT_ASSERT_EQUAL(std::string(), result); @@ -196,7 +158,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture { DummyMUCRegistry* mucRegistry; AvatarMemoryStorage* avatarStorage; VCardManager* vcardManager; - TestVCardStorage* vcardStorage; + VCardMemoryStorage* vcardStorage; ByteArray avatar1; std::string avatar1Hash; std::vector<JID> changes; diff --git a/Swiften/Disco/DiscoServiceWalker.cpp b/Swiften/Disco/DiscoServiceWalker.cpp index c8c3e1b..0f27111 100644 --- a/Swiften/Disco/DiscoServiceWalker.cpp +++ b/Swiften/Disco/DiscoServiceWalker.cpp @@ -35,6 +35,7 @@ void DiscoServiceWalker::endWalk() { request->onResponse.disconnect(boost::bind(&DiscoServiceWalker::handleDiscoItemsResponse, this, _1, _2, request)); } active_ = false; + onWalkAborted(); } } diff --git a/Swiften/Disco/DiscoServiceWalker.h b/Swiften/Disco/DiscoServiceWalker.h index 1853b57..ea55a78 100644 --- a/Swiften/Disco/DiscoServiceWalker.h +++ b/Swiften/Disco/DiscoServiceWalker.h @@ -49,6 +49,9 @@ namespace Swift { /** Emitted for each service found. */ boost::signal<void(const JID&, boost::shared_ptr<DiscoInfo>)> onServiceFound; + /** Emitted when walking is aborted. */ + boost::signal<void()> onWalkAborted; + /** Emitted when walking is complete.*/ boost::signal<void()> onWalkComplete; diff --git a/Swiften/Elements/MUCInvitationPayload.h b/Swiften/Elements/MUCInvitationPayload.h index ebae61a..290c585 100644 --- a/Swiften/Elements/MUCInvitationPayload.h +++ b/Swiften/Elements/MUCInvitationPayload.h @@ -15,7 +15,7 @@ namespace Swift { class MUCInvitationPayload : public Payload { public: typedef boost::shared_ptr<MUCInvitationPayload> ref; - MUCInvitationPayload() : continuation_(false) { + MUCInvitationPayload() : continuation_(false), impromptu_(false) { } void setIsContinuation(bool b) { @@ -26,6 +26,14 @@ namespace Swift { return continuation_; } + void setIsImpromptu(bool b) { + impromptu_ = b; + } + + bool getIsImpromptu() const { + return impromptu_; + } + void setJID(const JID& jid) { jid_ = jid; } @@ -60,6 +68,7 @@ namespace Swift { private: bool continuation_; + bool impromptu_; JID jid_; std::string password_; std::string reason_; diff --git a/Swiften/MUC/MUC.cpp b/Swiften/MUC/MUC.cpp index a52f552..ff26c86 100644 --- a/Swiften/MUC/MUC.cpp +++ b/Swiften/MUC/MUC.cpp @@ -29,7 +29,7 @@ namespace Swift { typedef std::pair<std::string, MUCOccupant> StringMUCOccupantPair; -MUC::MUC(StanzaChannel* stanzaChannel, IQRouter* iqRouter, DirectedPresenceSender* presenceSender, const JID &muc, MUCRegistry* mucRegistry) : ownMUCJID(muc), stanzaChannel(stanzaChannel), iqRouter_(iqRouter), presenceSender(presenceSender), mucRegistry(mucRegistry), createAsReservedIfNew(false), unlocking(false) { +MUC::MUC(StanzaChannel* stanzaChannel, IQRouter* iqRouter, DirectedPresenceSender* presenceSender, const JID &muc, MUCRegistry* mucRegistry) : ownMUCJID(muc), stanzaChannel(stanzaChannel), iqRouter_(iqRouter), presenceSender(presenceSender), mucRegistry(mucRegistry), createAsReservedIfNew(false), unlocking(false), isUnlocked_(false) { scopedConnection_ = stanzaChannel->onPresenceReceived.connect(boost::bind(&MUC::handleIncomingPresence, this, _1)); } @@ -58,6 +58,10 @@ void MUC::joinWithContextSince(const std::string &nick, const boost::posix_time: internalJoin(nick); } +std::map<std::string, MUCOccupant> MUC::getOccupants() const { + return occupants; +} + void MUC::internalJoin(const std::string &nick) { //TODO: history request joinComplete_ = false; @@ -97,6 +101,7 @@ void MUC::handleUserLeft(LeavingType type) { occupants.clear(); joinComplete_ = false; joinSucceeded_ = false; + isUnlocked_ = false; presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); } @@ -170,8 +175,9 @@ void MUC::handleIncomingPresence(Presence::ref presence) { std::map<std::string,MUCOccupant>::iterator i = occupants.find(nick); if (i != occupants.end()) { //TODO: part type - onOccupantLeft(i->second, type, ""); occupants.erase(i); + MUCOccupant occupant = i->second; + onOccupantLeft(occupant, type, ""); } } } @@ -200,6 +206,7 @@ void MUC::handleIncomingPresence(Presence::ref presence) { onOccupantPresenceChange(presence); } if (mucPayload && !joinComplete_) { + bool isLocked = false; foreach (MUCUserPayload::StatusCode status, mucPayload->getStatusCodes()) { if (status.code == 110) { /* Simply knowing this is your presence is enough, 210 doesn't seem to be necessary. */ @@ -212,6 +219,7 @@ void MUC::handleIncomingPresence(Presence::ref presence) { onJoinComplete(getOwnNick()); } if (status.code == 201) { + isLocked = true; /* Room is created and locked */ /* Currently deal with this by making an instant room */ if (ownMUCJID != presence->getFrom()) { @@ -233,6 +241,10 @@ void MUC::handleIncomingPresence(Presence::ref presence) { } } } + if (!isLocked && !isUnlocked_ && (presence->getFrom() == ownMUCJID)) { + isUnlocked_ = true; + onUnlocked(); + } } } @@ -243,6 +255,8 @@ void MUC::handleCreationConfigResponse(MUCOwnerPayload::ref /*unused*/, ErrorPay onJoinFailed(error); } else { onJoinComplete(getOwnNick()); /* Previously, this wasn't needed here, as the presence duplication bug caused an emit elsewhere. */ + isUnlocked_ = true; + onUnlocked(); } } @@ -386,13 +400,15 @@ void MUC::destroyRoom() { request->send(); } -void MUC::invitePerson(const JID& person, const std::string& reason) { +void MUC::invitePerson(const JID& person, const std::string& reason, bool isImpromptu, bool isReuseChat) { Message::ref message = boost::make_shared<Message>(); message->setTo(person); message->setType(Message::Normal); MUCInvitationPayload::ref invite = boost::make_shared<MUCInvitationPayload>(); invite->setReason(reason); invite->setJID(ownMUCJID.toBare()); + invite->setIsImpromptu(isImpromptu); + invite->setIsContinuation(isReuseChat); message->addPayload(invite); stanzaChannel->sendMessage(message); } diff --git a/Swiften/MUC/MUC.h b/Swiften/MUC/MUC.h index 85f4564..6a0ab75 100644 --- a/Swiften/MUC/MUC.h +++ b/Swiften/MUC/MUC.h @@ -45,11 +45,20 @@ namespace Swift { return ownMUCJID.toBare(); } + /** + * Returns if the room is unlocked and other people can join the room. + * @return True if joinable by others; false otherwise. + */ + bool isUnlocked() const { + return isUnlocked_; + } + void joinAs(const std::string &nick); void joinWithContextSince(const std::string &nick, const boost::posix_time::ptime& since); /*void queryRoomInfo(); */ /*void queryRoomItems(); */ std::string getCurrentNick(); + std::map<std::string, MUCOccupant> getOccupants() const; void part(); void handleIncomingMessage(Message::ref message); /** Expose public so it can be called when e.g. user goes offline */ @@ -67,7 +76,7 @@ namespace Swift { void cancelConfigureRoom(); void destroyRoom(); /** Send an invite for the person to join the MUC */ - void invitePerson(const JID& person, const std::string& reason = ""); + void invitePerson(const JID& person, const std::string& reason = "", bool isImpromptu = false, bool isReuseChat = false); void setCreateAsReservedIfNew() {createAsReservedIfNew = true;} void setPassword(const boost::optional<std::string>& password); @@ -85,6 +94,7 @@ namespace Swift { boost::signal<void (const MUCOccupant&, LeavingType, const std::string& /*reason*/)> onOccupantLeft; boost::signal<void (Form::ref)> onConfigurationFormReceived; boost::signal<void (MUCOccupant::Affiliation, const std::vector<JID>&)> onAffiliationListReceived; + boost::signal<void ()> onUnlocked; /* boost::signal<void (const MUCInfo&)> onInfoResult; */ /* boost::signal<void (const blah&)> onItemsResult; */ @@ -121,6 +131,7 @@ namespace Swift { boost::posix_time::ptime joinSince_; bool createAsReservedIfNew; bool unlocking; + bool isUnlocked_; boost::optional<std::string> password; }; } diff --git a/Swiften/Parser/PayloadParsers/MUCInvitationPayloadParser.cpp b/Swiften/Parser/PayloadParsers/MUCInvitationPayloadParser.cpp index fa95af7..c1cf33d 100644 --- a/Swiften/Parser/PayloadParsers/MUCInvitationPayloadParser.cpp +++ b/Swiften/Parser/PayloadParsers/MUCInvitationPayloadParser.cpp @@ -17,6 +17,7 @@ void MUCInvitationPayloadParser::handleTree(ParserElement::ref root) { invite->setPassword(root->getAttributes().getAttribute("password")); invite->setReason(root->getAttributes().getAttribute("reason")); invite->setThread(root->getAttributes().getAttribute("thread")); + invite->setIsImpromptu(root->getChild("impromptu", "http://swift.im/impromptu") ? true : false); } } diff --git a/Swiften/Serializer/PayloadSerializers/MUCInvitationPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/MUCInvitationPayloadSerializer.cpp index 24e30e6..26df08c 100644 --- a/Swiften/Serializer/PayloadSerializers/MUCInvitationPayloadSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/MUCInvitationPayloadSerializer.cpp @@ -37,6 +37,9 @@ std::string MUCInvitationPayloadSerializer::serializePayload(boost::shared_ptr<M if (!payload->getThread().empty()) { mucElement.setAttribute("thread", payload->getThread()); } + if (payload->getIsImpromptu()) { + mucElement.addNode(boost::make_shared<XMLElement>("impromptu", "http://swift.im/impromptu")); + } return mucElement.serialize(); } |