From 975742531dce89ba77d6c337da16ca710bba8a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sat, 12 Mar 2011 13:37:23 +0100 Subject: Cache vcard photo hashes. 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 +#include +#include #include +#include +#include +#include #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("jid")); + std::string hash(v.second.get("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 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 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 #include +#include +#include #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 PhotoHashMap; + mutable PhotoHashMap photoHashes; }; } -- cgit v0.10.2-6-g49f6