From 042c12c31cda77b3d57ed41d5c121a2b4383e69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Tue, 24 Aug 2010 09:26:43 +0200 Subject: Split out VCardUpdateAvatarManager from AvatarManager. diff --git a/Swiften/Avatars/AvatarManager.cpp b/Swiften/Avatars/AvatarManager.cpp index 33b1bee..909b07c 100644 --- a/Swiften/Avatars/AvatarManager.cpp +++ b/Swiften/Avatars/AvatarManager.cpp @@ -8,92 +8,25 @@ #include -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Elements/VCardUpdate.h" -#include "Swiften/Queries/Requests/GetVCardRequest.h" -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/StringCodecs/Hexify.h" -#include "Swiften/Avatars/AvatarStorage.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/VCards/VCardManager.h" +#include "Swiften/Avatars/VCardUpdateAvatarManager.h" namespace Swift { -AvatarManager::AvatarManager(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, MUCRegistry* mucRegistry) : vcardManager_(vcardManager), stanzaChannel_(stanzaChannel), avatarStorage_(avatarStorage), mucRegistry_(mucRegistry) { - stanzaChannel->onPresenceReceived.connect(boost::bind(&AvatarManager::handlePresenceReceived, this, _1)); - vcardManager_->onVCardChanged.connect(boost::bind(&AvatarManager::handleVCardChanged, this, _1, _2)); +AvatarManager::AvatarManager(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, MUCRegistry* mucRegistry) { + vcardUpdateAvatarManager = new VCardUpdateAvatarManager(vcardManager, stanzaChannel, avatarStorage, mucRegistry); + vcardUpdateAvatarManager->onAvatarChanged.connect(boost::ref(onAvatarChanged)); } AvatarManager::~AvatarManager() { - + delete vcardUpdateAvatarManager; } void AvatarManager::setMUCRegistry(MUCRegistry* mucRegistry) { - mucRegistry_ = mucRegistry; -} - -void AvatarManager::handlePresenceReceived(boost::shared_ptr presence) { - boost::shared_ptr update = presence->getPayload(); - if (!update || presence->getPayload()) { - return; - } - JID from = getAvatarJID(presence->getFrom()); - if (getAvatarHash(from) == update->getPhotoHash()) { - return; - } - if (avatarStorage_->hasAvatar(update->getPhotoHash())) { - setAvatarHash(from, update->getPhotoHash()); - } - else { - vcardManager_->requestVCard(from); - } -} - -void AvatarManager::handleVCardChanged(const JID& from, VCard::ref vCard) { - if (!vCard) { - std::cerr << "Warning: " << from << ": null vcard payload" << std::endl; - return; - } - - String hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto())); - avatarStorage_->addAvatar(hash, vCard->getPhoto()); - setAvatarHash(from, hash); -} - -void AvatarManager::setAvatarHash(const JID& from, const String& hash) { - avatarHashes_[from] = hash; - onAvatarChanged(from, hash); -} - -/* -void AvatarManager::setAvatar(const JID& jid, const ByteArray& avatar) { - String hash = Hexify::hexify(SHA1::getHash(avatar)); - avatarStorage_->addAvatar(hash, avatar); - setAvatarHash(getAvatarJID(jid), hash); -} -*/ - -String AvatarManager::getAvatarHash(const JID& jid) const { - std::map::const_iterator i = avatarHashes_.find(getAvatarJID(jid)); - if (i != avatarHashes_.end()) { - return i->second; - } - else { - return ""; - } + vcardUpdateAvatarManager->setMUCRegistry(mucRegistry); } boost::filesystem::path AvatarManager::getAvatarPath(const JID& jid) const { - String hash = getAvatarHash(jid); - if (!hash.isEmpty()) { - return avatarStorage_->getAvatarPath(hash); - } - return boost::filesystem::path(); -} - -JID AvatarManager::getAvatarJID(const JID& jid) const { - JID bareFrom = jid.toBare(); - return (mucRegistry_ && mucRegistry_->isMUC(bareFrom)) ? jid : bareFrom; + return vcardUpdateAvatarManager->getAvatarPath(jid); } diff --git a/Swiften/Avatars/AvatarManager.h b/Swiften/Avatars/AvatarManager.h index 543d167..d3d593d 100644 --- a/Swiften/Avatars/AvatarManager.h +++ b/Swiften/Avatars/AvatarManager.h @@ -22,6 +22,7 @@ namespace Swift { class AvatarStorage; class StanzaChannel; class VCardManager; + class VCardUpdateAvatarManager; class AvatarManager { public: @@ -32,23 +33,10 @@ namespace Swift { virtual boost::filesystem::path getAvatarPath(const JID&) const; -// virtual void setAvatar(const JID&, const ByteArray& avatar);*/ - public: boost::signal onAvatarChanged; private: - void handlePresenceReceived(boost::shared_ptr); - void handleVCardChanged(const JID& from, VCard::ref); - void setAvatarHash(const JID& from, const String& hash); - JID getAvatarJID(const JID& o) const; - String getAvatarHash(const JID&) const; - - private: - VCardManager* vcardManager_; - StanzaChannel* stanzaChannel_; - AvatarStorage* avatarStorage_; - MUCRegistry* mucRegistry_; - std::map avatarHashes_; + VCardUpdateAvatarManager* vcardUpdateAvatarManager; }; } diff --git a/Swiften/Avatars/AvatarMemoryStorage.h b/Swiften/Avatars/AvatarMemoryStorage.h index f60f603..13fbd9b 100644 --- a/Swiften/Avatars/AvatarMemoryStorage.h +++ b/Swiften/Avatars/AvatarMemoryStorage.h @@ -22,7 +22,7 @@ namespace Swift { return i == avatars.end() ? ByteArray() : i->second; } - virtual boost::filesystem::path getAvatarPath(const String& hash) const { + virtual boost::filesystem::path getAvatarPath(const String& /*hash*/) const { return boost::filesystem::path(); } diff --git a/Swiften/Avatars/UnitTest/AvatarManagerTest.cpp b/Swiften/Avatars/UnitTest/AvatarManagerTest.cpp deleted file mode 100644 index 858d257..0000000 --- a/Swiften/Avatars/UnitTest/AvatarManagerTest.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include -#include -#include - -#include "Swiften/Elements/VCardUpdate.h" -#include "Swiften/Avatars/AvatarManager.h" -#include "Swiften/Avatars/AvatarMemoryStorage.h" -#include "Swiften/VCards/VCardMemoryStorage.h" -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/StringCodecs/SHA1.h" -#include "Swiften/StringCodecs/Hexify.h" - -using namespace Swift; - -class AvatarManagerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(AvatarManagerTest); - CPPUNIT_TEST(testUpdate_NewHashNewVCardRequestsVCard); - CPPUNIT_TEST(testUpdate_NewHashStoresAvatarAndEmitsNotificationOnVCardReceive); - CPPUNIT_TEST(testUpdate_KnownHash); - CPPUNIT_TEST(testUpdate_KnownHashFromDifferentUserDoesNotRequestVCardButTriggersNotification); - /*& - CPPUNIT_TEST(testUpdate_UpdateNewHashAlreadyHaveAvatar); - CPPUNIT_TEST(testUpdate_UpdateNewHashFromMUC); - CPPUNIT_TEST(testUpdate_UpdateSameHash);*/ - //CPPUNIT_TEST(testUpdate_UpdateWithError); - /* - CPPUNIT_TEST(testUpdate_UpdateNewHashSameThanOtherUser); - CPPUNIT_TEST(testReceiveVCard); - CPPUNIT_TEST(testGetAvatarPath); - CPPUNIT_TEST(testGetAvatarPathFromMUC);*/ - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - ownJID = JID("foo@fum.com/bum"); - stanzaChannel = new DummyStanzaChannel(); - iqRouter = new IQRouter(stanzaChannel); - mucRegistry = new DummyMUCRegistry(); - avatarStorage = new AvatarMemoryStorage(); - vcardStorage = new VCardMemoryStorage(); - vcardManager = new VCardManager(ownJID, iqRouter, vcardStorage); - avatar1 = ByteArray("abcdefg"); - avatar1Hash = Hexify::hexify(SHA1::getHash(avatar1)); - user1 = JID("user1@bar.com/bla"); - user2 = JID("user2@foo.com/baz"); - } - - void tearDown() { - delete vcardManager; - delete vcardStorage; - delete avatarStorage; - delete mucRegistry; - delete iqRouter; - delete stanzaChannel; - } - - void testUpdate_NewHashNewVCardRequestsVCard() { - std::auto_ptr testling = createManager(); - stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); - - CPPUNIT_ASSERT_EQUAL(1, static_cast(stanzaChannel->sentStanzas.size())); - CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex(0, user1.toBare(), IQ::Get)); - } - - void testUpdate_NewHashStoresAvatarAndEmitsNotificationOnVCardReceive() { - std::auto_ptr testling = createManager(); - stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); - stanzaChannel->onIQReceived(createVCardResult(avatar1)); - - CPPUNIT_ASSERT_EQUAL(1, static_cast(changes.size())); - CPPUNIT_ASSERT_EQUAL(user1.toBare(), changes[0].first); - CPPUNIT_ASSERT_EQUAL(avatar1Hash, changes[0].second); - CPPUNIT_ASSERT(avatarStorage->hasAvatar(avatar1Hash)); - CPPUNIT_ASSERT_EQUAL(avatar1, avatarStorage->getAvatar(avatar1Hash)); - } - - void testUpdate_KnownHash() { - std::auto_ptr testling = createManager(); - stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); - stanzaChannel->onIQReceived(createVCardResult(avatar1)); - changes.clear(); - stanzaChannel->sentStanzas.clear(); - - stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); - - CPPUNIT_ASSERT_EQUAL(0, static_cast(stanzaChannel->sentStanzas.size())); - CPPUNIT_ASSERT_EQUAL(0, static_cast(changes.size())); - } - - void testUpdate_KnownHashFromDifferentUserDoesNotRequestVCardButTriggersNotification() { - std::auto_ptr testling = createManager(); - stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); - stanzaChannel->onIQReceived(createVCardResult(avatar1)); - changes.clear(); - stanzaChannel->sentStanzas.clear(); - - stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user2, avatar1Hash)); - - CPPUNIT_ASSERT_EQUAL(0, static_cast(stanzaChannel->sentStanzas.size())); - CPPUNIT_ASSERT_EQUAL(1, static_cast(changes.size())); - CPPUNIT_ASSERT_EQUAL(user2.toBare(), changes[0].first); - CPPUNIT_ASSERT_EQUAL(avatar1Hash, changes[0].second); - } - -/* - void testUpdate_UpdateNewHashFromMUC() { - std::auto_ptr testling = createManager(); - } - - */ - - /*void testUpdate_UpdateWithError() { - std::auto_ptr testling = createManager(); - boost::shared_ptr update = createPresenceWithPhotoHash(); - update->addPayload(boost::shared_ptr(new ErrorPayload())); - stanzaChannel_->onPresenceReceived(update); - - CPPUNIT_ASSERT_EQUAL(0, static_cast(stanzaChannel_->sentStanzas.size())); - }*/ - - - private: - std::auto_ptr createManager() { - std::auto_ptr result(new AvatarManager(vcardManager, stanzaChannel, avatarStorage, mucRegistry)); - result->onAvatarChanged.connect(boost::bind(&AvatarManagerTest::handleAvatarChanged, this, _1, _2)); - return result; - } - - boost::shared_ptr createPresenceWithPhotoHash(const JID& jid, const String& hash) { - boost::shared_ptr presence(new Presence()); - presence->setFrom(jid); - presence->addPayload(boost::shared_ptr(new VCardUpdate(hash))); - return presence; - } - - IQ::ref createVCardResult(const ByteArray& avatar) { - VCard::ref vcard(new VCard()); - vcard->setPhoto(avatar); - return IQ::createResult(JID("baz@fum.com"), stanzaChannel->sentStanzas[0]->getID(), vcard); - } - - void handleAvatarChanged(const JID& jid, const String& hash) { - changes.push_back(std::pair(jid, hash)); - } - - private: - struct DummyMUCRegistry : public MUCRegistry { - bool isMUC(const JID& jid) const { return std::find(mucs_.begin(), mucs_.end(), jid) != mucs_.end(); } - std::vector mucs_; - }; - - JID ownJID; - DummyStanzaChannel* stanzaChannel; - IQRouter* iqRouter; - DummyMUCRegistry* mucRegistry; - AvatarMemoryStorage* avatarStorage; - VCardManager* vcardManager; - VCardMemoryStorage* vcardStorage; - ByteArray avatar1; - String avatar1Hash; - std::vector > changes; - JID user1; - JID user2; -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(AvatarManagerTest); diff --git a/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp b/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp new file mode 100644 index 0000000..e3d9c58 --- /dev/null +++ b/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include +#include +#include + +#include "Swiften/Elements/VCardUpdate.h" +#include "Swiften/Avatars/VCardUpdateAvatarManager.h" +#include "Swiften/Avatars/AvatarMemoryStorage.h" +#include "Swiften/VCards/VCardMemoryStorage.h" +#include "Swiften/VCards/VCardManager.h" +#include "Swiften/MUC/MUCRegistry.h" +#include "Swiften/Queries/IQRouter.h" +#include "Swiften/Client/DummyStanzaChannel.h" +#include "Swiften/StringCodecs/SHA1.h" +#include "Swiften/StringCodecs/Hexify.h" + +using namespace Swift; + +class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(VCardUpdateAvatarManagerTest); + CPPUNIT_TEST(testUpdate_NewHashNewVCardRequestsVCard); + CPPUNIT_TEST(testUpdate_NewHashStoresAvatarAndEmitsNotificationOnVCardReceive); + CPPUNIT_TEST(testUpdate_KnownHash); + CPPUNIT_TEST(testUpdate_KnownHashFromDifferentUserDoesNotRequestVCardButTriggersNotification); + /*& + CPPUNIT_TEST(testUpdate_UpdateNewHashAlreadyHaveAvatar); + CPPUNIT_TEST(testUpdate_UpdateNewHashFromMUC); + CPPUNIT_TEST(testUpdate_UpdateSameHash);*/ + //CPPUNIT_TEST(testUpdate_UpdateWithError); + /* + CPPUNIT_TEST(testUpdate_UpdateNewHashSameThanOtherUser); + CPPUNIT_TEST(testReceiveVCard); + CPPUNIT_TEST(testGetAvatarPath); + CPPUNIT_TEST(testGetAvatarPathFromMUC);*/ + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + ownJID = JID("foo@fum.com/bum"); + stanzaChannel = new DummyStanzaChannel(); + iqRouter = new IQRouter(stanzaChannel); + mucRegistry = new DummyMUCRegistry(); + avatarStorage = new AvatarMemoryStorage(); + vcardStorage = new VCardMemoryStorage(); + vcardManager = new VCardManager(ownJID, iqRouter, vcardStorage); + avatar1 = ByteArray("abcdefg"); + avatar1Hash = Hexify::hexify(SHA1::getHash(avatar1)); + user1 = JID("user1@bar.com/bla"); + user2 = JID("user2@foo.com/baz"); + } + + void tearDown() { + delete vcardManager; + delete vcardStorage; + delete avatarStorage; + delete mucRegistry; + delete iqRouter; + delete stanzaChannel; + } + + void testUpdate_NewHashNewVCardRequestsVCard() { + std::auto_ptr testling = createManager(); + stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); + + CPPUNIT_ASSERT_EQUAL(1, static_cast(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex(0, user1.toBare(), IQ::Get)); + } + + void testUpdate_NewHashStoresAvatarAndEmitsNotificationOnVCardReceive() { + std::auto_ptr testling = createManager(); + stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); + stanzaChannel->onIQReceived(createVCardResult(avatar1)); + + CPPUNIT_ASSERT_EQUAL(1, static_cast(changes.size())); + CPPUNIT_ASSERT_EQUAL(user1.toBare(), changes[0].first); + CPPUNIT_ASSERT_EQUAL(avatar1Hash, changes[0].second); + CPPUNIT_ASSERT(avatarStorage->hasAvatar(avatar1Hash)); + CPPUNIT_ASSERT_EQUAL(avatar1, avatarStorage->getAvatar(avatar1Hash)); + } + + void testUpdate_KnownHash() { + std::auto_ptr testling = createManager(); + stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); + stanzaChannel->onIQReceived(createVCardResult(avatar1)); + changes.clear(); + stanzaChannel->sentStanzas.clear(); + + stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); + + CPPUNIT_ASSERT_EQUAL(0, static_cast(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast(changes.size())); + } + + void testUpdate_KnownHashFromDifferentUserDoesNotRequestVCardButTriggersNotification() { + std::auto_ptr testling = createManager(); + stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash)); + stanzaChannel->onIQReceived(createVCardResult(avatar1)); + changes.clear(); + stanzaChannel->sentStanzas.clear(); + + stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user2, avatar1Hash)); + + CPPUNIT_ASSERT_EQUAL(0, static_cast(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast(changes.size())); + CPPUNIT_ASSERT_EQUAL(user2.toBare(), changes[0].first); + CPPUNIT_ASSERT_EQUAL(avatar1Hash, changes[0].second); + } + +/* + void testUpdate_UpdateNewHashFromMUC() { + std::auto_ptr testling = createManager(); + } + + */ + + /*void testUpdate_UpdateWithError() { + std::auto_ptr testling = createManager(); + boost::shared_ptr update = createPresenceWithPhotoHash(); + update->addPayload(boost::shared_ptr(new ErrorPayload())); + stanzaChannel_->onPresenceReceived(update); + + CPPUNIT_ASSERT_EQUAL(0, static_cast(stanzaChannel_->sentStanzas.size())); + }*/ + + + private: + std::auto_ptr createManager() { + std::auto_ptr result(new VCardUpdateAvatarManager(vcardManager, stanzaChannel, avatarStorage, mucRegistry)); + result->onAvatarChanged.connect(boost::bind(&VCardUpdateAvatarManagerTest::handleAvatarChanged, this, _1, _2)); + return result; + } + + boost::shared_ptr createPresenceWithPhotoHash(const JID& jid, const String& hash) { + boost::shared_ptr presence(new Presence()); + presence->setFrom(jid); + presence->addPayload(boost::shared_ptr(new VCardUpdate(hash))); + return presence; + } + + IQ::ref createVCardResult(const ByteArray& avatar) { + VCard::ref vcard(new VCard()); + vcard->setPhoto(avatar); + return IQ::createResult(JID("baz@fum.com"), stanzaChannel->sentStanzas[0]->getID(), vcard); + } + + void handleAvatarChanged(const JID& jid, const String& hash) { + changes.push_back(std::pair(jid, hash)); + } + + private: + struct DummyMUCRegistry : public MUCRegistry { + bool isMUC(const JID& jid) const { return std::find(mucs_.begin(), mucs_.end(), jid) != mucs_.end(); } + std::vector mucs_; + }; + + JID ownJID; + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + DummyMUCRegistry* mucRegistry; + AvatarMemoryStorage* avatarStorage; + VCardManager* vcardManager; + VCardMemoryStorage* vcardStorage; + ByteArray avatar1; + String avatar1Hash; + std::vector > changes; + JID user1; + JID user2; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(VCardUpdateAvatarManagerTest); diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.cpp b/Swiften/Avatars/VCardUpdateAvatarManager.cpp new file mode 100644 index 0000000..c7f1637 --- /dev/null +++ b/Swiften/Avatars/VCardUpdateAvatarManager.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/Avatars/VCardUpdateAvatarManager.h" + +#include + +#include "Swiften/Client/StanzaChannel.h" +#include "Swiften/Elements/VCardUpdate.h" +#include "Swiften/Queries/Requests/GetVCardRequest.h" +#include "Swiften/StringCodecs/SHA1.h" +#include "Swiften/StringCodecs/Hexify.h" +#include "Swiften/Avatars/AvatarStorage.h" +#include "Swiften/MUC/MUCRegistry.h" +#include "Swiften/VCards/VCardManager.h" + +namespace Swift { + +VCardUpdateAvatarManager::VCardUpdateAvatarManager(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, MUCRegistry* mucRegistry) : vcardManager_(vcardManager), stanzaChannel_(stanzaChannel), avatarStorage_(avatarStorage), mucRegistry_(mucRegistry) { + stanzaChannel->onPresenceReceived.connect(boost::bind(&VCardUpdateAvatarManager::handlePresenceReceived, this, _1)); + vcardManager_->onVCardChanged.connect(boost::bind(&VCardUpdateAvatarManager::handleVCardChanged, this, _1, _2)); +} + +VCardUpdateAvatarManager::~VCardUpdateAvatarManager() { + +} + +void VCardUpdateAvatarManager::setMUCRegistry(MUCRegistry* mucRegistry) { + mucRegistry_ = mucRegistry; +} + +void VCardUpdateAvatarManager::handlePresenceReceived(boost::shared_ptr presence) { + boost::shared_ptr update = presence->getPayload(); + if (!update || presence->getPayload()) { + return; + } + JID from = getAvatarJID(presence->getFrom()); + if (getAvatarHash(from) == update->getPhotoHash()) { + return; + } + if (avatarStorage_->hasAvatar(update->getPhotoHash())) { + setAvatarHash(from, update->getPhotoHash()); + } + else { + vcardManager_->requestVCard(from); + } +} + +void VCardUpdateAvatarManager::handleVCardChanged(const JID& from, VCard::ref vCard) { + if (!vCard) { + std::cerr << "Warning: " << from << ": null vcard payload" << std::endl; + return; + } + + String hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto())); + avatarStorage_->addAvatar(hash, vCard->getPhoto()); + setAvatarHash(from, hash); +} + +void VCardUpdateAvatarManager::setAvatarHash(const JID& from, const String& hash) { + avatarHashes_[from] = hash; + onAvatarChanged(from, hash); +} + +/* +void VCardUpdateAvatarManager::setAvatar(const JID& jid, const ByteArray& avatar) { + String hash = Hexify::hexify(SHA1::getHash(avatar)); + avatarStorage_->addAvatar(hash, avatar); + setAvatarHash(getAvatarJID(jid), hash); +} +*/ + +String VCardUpdateAvatarManager::getAvatarHash(const JID& jid) const { + std::map::const_iterator i = avatarHashes_.find(getAvatarJID(jid)); + if (i != avatarHashes_.end()) { + return i->second; + } + else { + return ""; + } +} + +boost::filesystem::path VCardUpdateAvatarManager::getAvatarPath(const JID& jid) const { + String hash = getAvatarHash(jid); + if (!hash.isEmpty()) { + return avatarStorage_->getAvatarPath(hash); + } + return boost::filesystem::path(); +} + +JID VCardUpdateAvatarManager::getAvatarJID(const JID& jid) const { + JID bareFrom = jid.toBare(); + return (mucRegistry_ && mucRegistry_->isMUC(bareFrom)) ? jid : bareFrom; +} + + +} diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.h b/Swiften/Avatars/VCardUpdateAvatarManager.h new file mode 100644 index 0000000..b7ef34b --- /dev/null +++ b/Swiften/Avatars/VCardUpdateAvatarManager.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include +#include +#include +#include + +#include "Swiften/Base/boost_bsignals.h" +#include "Swiften/JID/JID.h" +#include "Swiften/Elements/Presence.h" +#include "Swiften/Elements/VCard.h" +#include "Swiften/Elements/ErrorPayload.h" + +namespace Swift { + class MUCRegistry; + class AvatarStorage; + class StanzaChannel; + class VCardManager; + + class VCardUpdateAvatarManager { + public: + VCardUpdateAvatarManager(VCardManager*, StanzaChannel*, AvatarStorage*, MUCRegistry* = NULL); + virtual ~VCardUpdateAvatarManager(); + + virtual void setMUCRegistry(MUCRegistry*); + + virtual boost::filesystem::path getAvatarPath(const JID&) const; + + public: + boost::signal onAvatarChanged; + + private: + void handlePresenceReceived(boost::shared_ptr); + void handleVCardChanged(const JID& from, VCard::ref); + void setAvatarHash(const JID& from, const String& hash); + JID getAvatarJID(const JID& o) const; + String getAvatarHash(const JID&) const; + + private: + VCardManager* vcardManager_; + StanzaChannel* stanzaChannel_; + AvatarStorage* avatarStorage_; + MUCRegistry* mucRegistry_; + std::map avatarHashes_; + }; +} diff --git a/Swiften/SConscript b/Swiften/SConscript index 6e2628a..bd54e7c 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -25,6 +25,7 @@ if env["SCONS_STAGE"] == "build" : myenv.MergeFlags(myenv["OPENSSL_FLAGS"]) sources = [ "Avatars/AvatarFileStorage.cpp", + "Avatars/VCardUpdateAvatarManager.cpp", "Avatars/AvatarManager.cpp", "Avatars/AvatarStorage.cpp", "Chat/ChatStateTracker.cpp", @@ -140,7 +141,7 @@ if env["SCONS_STAGE"] == "build" : env.Append(UNITTEST_SOURCES = [ File("Application/UnitTest/ApplicationPathProviderTest.cpp"), - File("Avatars/UnitTest/AvatarManagerTest.cpp"), + File("Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp"), File("Base/UnitTest/IDGeneratorTest.cpp"), File("Base/UnitTest/StringTest.cpp"), File("Base/UnitTest/ByteArrayTest.cpp"), -- cgit v0.10.2-6-g49f6