--- /dev/null
+import urllib, hashlib, xmlrpclib
+import gnome.gconf
+import org.maemo.hermes.engine.service
+
+from org.maemo.hermes.engine.names import canonical
+
+class Service(org.maemo.hermes.engine.service.Service):
+ """Gravatar backend for Hermes.
+
+ Copyright (c) Fredrik Wendt <fredrik@wendt.se> 2010.
+ Released under the Artistic Licence."""
+
+ _image_url_base = "http://www.gravatar.com/avatar.php?"
+
+ # -----------------------------------------------------------------------
+ def __init__(self):
+ """Initialise the Gravatar service"""
+
+ self._gc = gnome.gconf.client_get_default()
+ self._address_to_contact = {}
+ self._hash_to_address= {}
+ self._hash_has_gravatar = {}
+ self._empty_cache = True
+
+ self._api_email = self._gc.get_string('/apps/maemo/hermes/gravatar_api_email')
+ self._api_key = self._gc.get_string('/apps/maemo/hermes/gravatar_api_key')
+ self._api_email = 'maemohermes@wendt.se'
+ self._api_key = 'b14ec179822b' # FIXME
+ if self._api_key is None or self._api_email is None:
+ raise Exception('No Gravatar application keys found. Installation error.')
+ self._api_url = 'https://secure.gravatar.com/xmlrpc?user=' + hashlib.md5(self._api_email).hexdigest()
+
+
+ # -----------------------------------------------------------------------
+ def get_name(self):
+ return "Gravatar"
+
+
+ # -----------------------------------------------------------------------
+ def get_friends(self):
+ """Returns 'None' since manual mapping is not supported."""
+
+ return None
+
+
+ # -----------------------------------------------------------------------
+ def pre_process_contact(self, contact):
+ """Extracts addresses from the contact."""
+ for address in contact.get_emails():
+ self._address_to_contact[address] = contact
+
+
+ # -----------------------------------------------------------------------
+ def process_contact(self, contact, friend):
+ """On first call (with a contact missing a photo), go get gravatar existense data from the service."""
+
+ if not self._has_photo(contact):
+ if self._empty_cache:
+ self._lookup_addresses()
+ for address in contact.get_emails():
+ hash = self._get_hash_for_address(address)
+ if (self._hash_has_gravatar[hash]):
+ friend.set_photo_url(self._get_url_for_email_hash(hash))
+
+
+ # -----------------------------------------------------------------------
+ def finalise(self, updated, overwrite=True):
+ """We could make a new pass over all updated contacts, in the event that another service
+ added a new e-mail address to a contact (still missing a photo) that has a gravatar setup."""
+
+ pass
+ # It's plausible that info@company.com addresses would be present for several
+ # contacts, but unlikely that there'd be a gravatar set up for such generic
+ # addresses - the point of gravatar is to make it more personal ...
+
+ # we only look at contacts that has no photo (unless
+# for contact in self._contacts:
+# if not overwrite or not self._has_photo(contact):
+# for address in contact.get_emails():
+# self._address_to_contact[address] = contact
+# self._lookup_addresses()
+# for hash in self._hash_has_gravatar:
+# if self._hash_has_gravatar[hash]:
+# address = self._hash_to_address[hash]
+# contact = self._address_to_contact[address]
+# if not self._has_photo(contact):
+# url = self._get_url_for_email_hash(hash)
+# contact.set_photo(url)
+# updated.add(contact)
+
+ # -----------------------------------------------------------------------
+ # FIXME
+ def _has_photo(self, contact):
+ return False
+
+
+ # -----------------------------------------------------------------------
+ def _lookup_addresses(self):
+ """Constructs hashes for address_to_contact, makes call to the Gravatar.com service and updates
+ self._hash_has_gravatar"""
+
+ args = { "apikey" : self._api_key}
+ args["hashes"] = list(self._construct_hashes(self._address_to_contact.keys()))
+ service = xmlrpclib.ServerProxy(self._api_url)
+ self._hash_has_gravatar = service.grav.exists(args)
+ self._empty_cache = False
+
+
+ # -----------------------------------------------------------------------
+ def _get_url_for_email_hash(self, hash, default="404", size="128"):
+ """Assembles the URL to a gravatar, based on a hash of an e-mail address"""
+
+ return self._image_url_base + urllib.urlencode({'gravatar_id':hash, 'd':default, 'size':size})
+
+
+ # -----------------------------------------------------------------------
+ def _construct_hashes(self, addresses):
+ """Creates hashes for all addresses specified, returning a set of hashes"""
+
+ result = set()
+ for address in addresses:
+ hash = self._get_hash_for_address(address)
+ self._hash_to_address[hash] = address
+ result.add(hash)
+
+ return result
+
+ # -----------------------------------------------------------------------
+ def _get_hash_for_address(self, address):
+ return hashlib.md5(address.lower()).hexdigest()
\ No newline at end of file