diff options
| author | Remko Tronçon <git@el-tramo.be> | 2011-03-12 12:37:23 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2011-03-12 12:37:23 (GMT) | 
| commit | 975742531dce89ba77d6c337da16ca710bba8a66 (patch) | |
| tree | 0ccaf5c34a0479ec7724225f040ee0b0232ca2d3 | |
| parent | 1e2722460b9a67713484903bf6382d08f7e09278 (diff) | |
| download | swift-975742531dce89ba77d6c337da16ca710bba8a66.zip swift-975742531dce89ba77d6c337da16ca710bba8a66.tar.bz2 | |
Cache vcard photo hashes.
| -rw-r--r-- | Swiften/VCards/VCardFileStorage.cpp | 72 | ||||
| -rw-r--r-- | Swiften/VCards/VCardFileStorage.h | 10 | 
2 files changed, 82 insertions, 0 deletions
| diff --git a/Swiften/VCards/VCardFileStorage.cpp b/Swiften/VCards/VCardFileStorage.cpp index 63652ad..3f84678 100644 --- a/Swiften/VCards/VCardFileStorage.cpp +++ b/Swiften/VCards/VCardFileStorage.cpp @@ -7,8 +7,13 @@  #include "Swiften/VCards/VCardFileStorage.h"  #include <boost/filesystem/fstream.hpp> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/xml_parser.hpp>  #include <Swiften/Base/String.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Base/foreach.h>  #include "Swiften/JID/JID.h"  #include "Swiften/Base/ByteArray.h"  #include "Swiften/Elements/VCard.h" @@ -19,6 +24,28 @@  namespace Swift {  VCardFileStorage::VCardFileStorage(boost::filesystem::path dir) : vcardsPath(dir) { +	cacheFile = vcardsPath / "vcards.xml"; +	if (boost::filesystem::exists(cacheFile)) { +		boost::property_tree::ptree tree; +		try { +			boost::property_tree::xml_parser::read_xml(cacheFile.string(), tree); +		} +		catch (const boost::property_tree::xml_parser::xml_parser_error& e) { +			std::cerr << "Error reading vcards file: " << e.filename() << ":" << e.line() << ": " << e.message() << std::endl; +		} +		foreach(const boost::property_tree::ptree::value_type &v, tree.get_child("vcards")) { +			try { +				JID jid(v.second.get<std::string>("jid")); +				std::string hash(v.second.get<std::string>("phash")); +				if (jid.isValid()) { +					photoHashes.insert(std::make_pair(jid, hash)); +				} +			} +			catch (const boost::property_tree::ptree_error& e) { +				std::cerr << "Invalid vcard value: " << e.what() << std::endl; +			} +		} +	}  }  boost::shared_ptr<VCard> VCardFileStorage::getVCard(const JID& jid) const { @@ -50,6 +77,7 @@ void VCardFileStorage::setVCard(const JID& jid, VCard::ref v) {  	boost::filesystem::ofstream file(getVCardPath(jid));  	file << VCardSerializer().serializePayload(v);  	file.close(); +	getAndUpdatePhotoHash(jid, v);  }  boost::filesystem::path VCardFileStorage::getVCardPath(const JID& jid) const { @@ -58,4 +86,48 @@ boost::filesystem::path VCardFileStorage::getVCardPath(const JID& jid) const {  	return boost::filesystem::path(vcardsPath / (file + ".xml"));  } +std::string VCardFileStorage::getPhotoHash(const JID& jid) const { +	PhotoHashMap::const_iterator i = photoHashes.find(jid); +	if (i != photoHashes.end()) { +		return i->second; +	} +	else { +		VCard::ref vCard = getVCard(jid); +		return getAndUpdatePhotoHash(jid, vCard); +	} +} + +std::string VCardFileStorage::getAndUpdatePhotoHash(const JID& jid, VCard::ref vCard) const { +	std::string hash; +	if (vCard && !vCard->getPhoto().isEmpty()) { +		hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto())); +	} +	std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash)); +	if (r.second) { +		savePhotoHashes(); +	} +	else if (r.first->second != hash) { +		r.first->second = hash; +		savePhotoHashes(); +	} +	return hash; +} + +void VCardFileStorage::savePhotoHashes() const { +	boost::property_tree::ptree tree; +	for (PhotoHashMap::const_iterator i = photoHashes.begin(); i != photoHashes.end(); ++i) { +		boost::property_tree::ptree entry; +		entry.put("jid", i->first.toString()); +		entry.put("phash", i->second); +		tree.add_child("vcards.vcard", entry); +	} +	try { +		boost::property_tree::xml_parser::write_xml(cacheFile.string(), tree); +	} +	catch (const boost::property_tree::xml_parser::xml_parser_error& e) { +		std::cerr << "Error writing vcards file: " << e.filename() << ": " << e.message() << std::endl; +	} +} + +  } diff --git a/Swiften/VCards/VCardFileStorage.h b/Swiften/VCards/VCardFileStorage.h index 5f8cb1a..26bf4b2 100644 --- a/Swiften/VCards/VCardFileStorage.h +++ b/Swiften/VCards/VCardFileStorage.h @@ -8,6 +8,8 @@  #include <boost/shared_ptr.hpp>  #include <boost/filesystem.hpp> +#include <string> +#include <map>  #include "Swiften/VCards/VCardStorage.h" @@ -19,10 +21,18 @@ namespace Swift {  			virtual VCard::ref getVCard(const JID& jid) const;  			virtual void setVCard(const JID& jid, VCard::ref v); +			virtual std::string getPhotoHash(const JID&) const; +  		private:  			boost::filesystem::path getVCardPath(const JID&) const; +			std::string getAndUpdatePhotoHash(const JID& jid, VCard::ref vcard) const; +			void savePhotoHashes() const; +  		private:  			boost::filesystem::path vcardsPath; +			boost::filesystem::path cacheFile; +			typedef std::map<JID, std::string> PhotoHashMap; +			mutable PhotoHashMap photoHashes;  	};  } | 
 Swift
 Swift