From 3e40b302af0e2abde3c002c7f25ec5276f68f230 Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Fri, 3 Oct 2014 15:48:37 +0200
Subject: Update vCard cache on 'Show Profile' if cached vCard is older than 5
 minutes.

Store last write time in memory in VCardStorage. VCardManager::getVCardAndRequestWhenNeeded
will check an optional parameter and the last write time to determine if the
cached vCard is fresh enough.

Test-Information:

ALl unit tests still run fine and tested that it fetches the vCard again when you
open the 'Show Profile' dialog after 5 minutes.

Change-Id: I27d7f931188a43aa090348014bcdbdf6d534c5a0

diff --git a/Swift/Controllers/ShowProfileController.cpp b/Swift/Controllers/ShowProfileController.cpp
index 15b7b26..d13e5a1 100644
--- a/Swift/Controllers/ShowProfileController.cpp
+++ b/Swift/Controllers/ShowProfileController.cpp
@@ -4,9 +4,16 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
+/*
+ * Copyright (c) 2014 Kevin Smith and Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
 #include "ShowProfileController.h"
 
 #include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 
 #include <Swiften/Base/foreach.h>
 #include <Swiften/VCards/VCardManager.h>
@@ -44,7 +51,7 @@ void ShowProfileController::handleUIEvent(UIEvent::ref event) {
 		newProfileWindow->setJID(showProfileEvent->getJID());
 		newProfileWindow->onWindowAboutToBeClosed.connect(boost::bind(&ShowProfileController::handleProfileWindowAboutToBeClosed, this, _1));
 		openedProfileWindows[showProfileEvent->getJID()] = newProfileWindow;
-		VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(showProfileEvent->getJID());
+		VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(showProfileEvent->getJID(), boost::posix_time::minutes(5));
 		if (vcard) {
 			newProfileWindow->setVCard(vcard);
 		} else {
diff --git a/Swift/Controllers/Storages/VCardFileStorage.cpp b/Swift/Controllers/Storages/VCardFileStorage.cpp
index b22e235..876d642 100644
--- a/Swift/Controllers/Storages/VCardFileStorage.cpp
+++ b/Swift/Controllers/Storages/VCardFileStorage.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -58,7 +58,17 @@ boost::shared_ptr<VCard> VCardFileStorage::getVCard(const JID& jid) const {
 	return result;
 }
 
+boost::posix_time::ptime VCardFileStorage::getVCardWriteTime(const JID& jid) const {
+	if (vcardWriteTimes.find(jid) == vcardWriteTimes.end()) {
+		return boost::posix_time::ptime();
+	}
+	else {
+		return vcardWriteTimes.at(jid);
+	}
+}
+
 void VCardFileStorage::setVCard(const JID& jid, VCard::ref v) {
+	vcardWriteTimes[jid] = boost::posix_time::second_clock::universal_time();
 	VCardPersister().savePayload(v, getVCardPath(jid));
 	getAndUpdatePhotoHash(jid, v);
 }
diff --git a/Swift/Controllers/Storages/VCardFileStorage.h b/Swift/Controllers/Storages/VCardFileStorage.h
index 2c3af3d..8ba001e 100644
--- a/Swift/Controllers/Storages/VCardFileStorage.h
+++ b/Swift/Controllers/Storages/VCardFileStorage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -21,6 +21,7 @@ namespace Swift {
 			VCardFileStorage(boost::filesystem::path dir, CryptoProvider* crypto);
 
 			virtual VCard::ref getVCard(const JID& jid) const;
+			virtual boost::posix_time::ptime getVCardWriteTime(const JID& jid) const;
 			virtual void setVCard(const JID& jid, VCard::ref v);
 
 			virtual std::string getPhotoHash(const JID&) const;
@@ -37,5 +38,6 @@ namespace Swift {
 			boost::filesystem::path cacheFile;
 			typedef std::map<JID, std::string> PhotoHashMap;
 			mutable PhotoHashMap photoHashes;
+			std::map<JID, boost::posix_time::ptime> vcardWriteTimes;
 	};
 }
diff --git a/Swiften/VCards/VCardManager.cpp b/Swiften/VCards/VCardManager.cpp
index 52447a1..5a65dcd 100644
--- a/Swiften/VCards/VCardManager.cpp
+++ b/Swiften/VCards/VCardManager.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -8,6 +8,7 @@
 
 #include <boost/bind.hpp>
 
+#include <Swiften/Base/Log.h>
 #include <Swiften/JID/JID.h>
 #include <Swiften/VCards/VCardStorage.h>
 #include <Swiften/VCards/GetVCardRequest.h>
@@ -25,9 +26,11 @@ VCard::ref VCardManager::getVCard(const JID& jid) const {
 	return storage->getVCard(jid);
 }
 
-VCard::ref VCardManager::getVCardAndRequestWhenNeeded(const JID& jid) {
+VCard::ref VCardManager::getVCardAndRequestWhenNeeded(const JID& jid, const boost::posix_time::time_duration& allowedAge) {
 	VCard::ref vcard = storage->getVCard(jid);
-	if (!vcard) {
+	boost::posix_time::ptime vcardFetchedTime = storage->getVCardWriteTime(jid);
+	bool vcardTooOld = vcard && (vcardFetchedTime.is_special() || ((boost::posix_time::second_clock::universal_time() - vcardFetchedTime) > allowedAge));
+	if (!vcard || vcardTooOld) {
 		requestVCard(jid);
 	}
 	return vcard;
diff --git a/Swiften/VCards/VCardManager.h b/Swiften/VCards/VCardManager.h
index b7e3c32..78e0f3e 100644
--- a/Swiften/VCards/VCardManager.h
+++ b/Swiften/VCards/VCardManager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -8,6 +8,8 @@
 
 #include <set>
 
+#include <boost/date_time/posix_time/posix_time.hpp>
+
 #include <Swiften/Base/API.h>
 #include <Swiften/JID/JID.h>
 #include <Swiften/Elements/VCard.h>
@@ -26,7 +28,7 @@ namespace Swift {
 			~VCardManager();
 
 			VCard::ref getVCard(const JID& jid) const;
-			VCard::ref getVCardAndRequestWhenNeeded(const JID& jid);
+			VCard::ref getVCardAndRequestWhenNeeded(const JID& jid, const boost::posix_time::time_duration& allowedAge = boost::posix_time::time_duration(boost::date_time::pos_infin));
 			void requestVCard(const JID& jid);
 			void requestOwnVCard();
 
diff --git a/Swiften/VCards/VCardMemoryStorage.h b/Swiften/VCards/VCardMemoryStorage.h
index 86ae1b2..f538fc1 100644
--- a/Swiften/VCards/VCardMemoryStorage.h
+++ b/Swiften/VCards/VCardMemoryStorage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -7,6 +7,7 @@
 #pragma once
 
 #include <boost/shared_ptr.hpp>
+
 #include <map>
 
 #include <Swiften/JID/JID.h>
@@ -27,12 +28,24 @@ namespace Swift {
 				}
 			}
 
+			virtual boost::posix_time::ptime getVCardWriteTime(const JID& jid) const {
+				if (vcardWriteTimes.find(jid) == vcardWriteTimes.end()) {
+					return boost::posix_time::ptime();
+				}
+				else {
+					return vcardWriteTimes.at(jid);
+				}
+			}
+
 			virtual void setVCard(const JID& jid, VCard::ref v) {
 				vcards[jid] = v;
+				vcardWriteTimes[jid] = boost::posix_time::second_clock::universal_time();
 			}
 
 		private:
 			typedef std::map<JID, VCard::ref> VCardMap;
+			typedef std::map<JID, boost::posix_time::ptime> VCardWriteTimeMap;
 			VCardMap vcards;
+			VCardWriteTimeMap vcardWriteTimes;
 	};
 }
diff --git a/Swiften/VCards/VCardStorage.h b/Swiften/VCards/VCardStorage.h
index 924204c..e6c84f4 100644
--- a/Swiften/VCards/VCardStorage.h
+++ b/Swiften/VCards/VCardStorage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -7,7 +7,9 @@
 #pragma once
 
 #include <string>
+
 #include <boost/shared_ptr.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 
 #include <Swiften/Base/API.h>
 #include <Swiften/Elements/VCard.h>
@@ -22,6 +24,7 @@ namespace Swift {
 			virtual ~VCardStorage();
 
 			virtual VCard::ref getVCard(const JID& jid) const = 0;
+			virtual boost::posix_time::ptime getVCardWriteTime(const JID& jid) const = 0;
 			virtual void setVCard(const JID&, VCard::ref) = 0;
 
 			virtual std::string getPhotoHash(const JID&) const;
-- 
cgit v0.10.2-6-g49f6