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.
_image_url_base = "http://www.gravatar.com/avatar.php?"
# -----------------------------------------------------------------------
- def __init__(self):
- """Initialise the Gravatar service"""
+ def __init__(self, api_email, api_key):
+ """Initialise the Gravatar service
- self._gc = gnome.gconf.client_get_default()
+ api_email is the email address to use when talking to the backend.
+ api_key is the "secrect" key used when talking to the backend
+ """
+ self._api_email = api_email
+ self._api_key = api_key
+ if self._api_key is None or self._api_email is None:
+ raise Exception('No Gravatar application keys found. Installation error.')
+
self._address_to_contact = {}
- self._hash_to_address= {}
+ 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._friends_by_contact = {}
+ self._contacts_by_friend = {}
+
self._api_url = 'https://secure.gravatar.com/xmlrpc?user=' + hashlib.md5(self._api_email).hexdigest()
# -----------------------------------------------------------------------
- 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():
# -----------------------------------------------------------------------
- def process_contact(self, contact, friend):
- """On first call (with a contact missing a photo), go get gravatar existense data from the service."""
+ def process_contact(self, contact):
+ """On first call (with a contact missing a photo), go get data from Gravatar's servers."""
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]):
+ if (self._hash_has_gravatar.has_key(hash) and self._hash_has_gravatar[hash]):
+ friend = self._create_friend(contact.get_name())
friend.set_photo_url(self._get_url_for_email_hash(hash))
+ self._register_match(contact, friend)
+
+
+ # -----------------------------------------------------------------------
+ def process_friends(self):
+ self._lookup_addresses()
# -----------------------------------------------------------------------
- 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."""
+ def get_friends(self):
+ return self._contacts_by_friend.keys()
- 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)
+
+ def get_contacts_with_match(self):
+ """Returns a dict with Contact objects as keys and Friend objects as values"""
+ return self._friends_by_contact
+
+
+ def get_unmatched_friends(self):
+ """Will always return None - Gravatar only reacts on e-mail address input."""
+ return None
+
+
+
+
+ # -----------------------------------------------------------------------
+ def _register_match(self, contact, friend):
+ self._friends_by_contact[contact] = friend
+ self._contacts_by_friend[friend] = contact
# -----------------------------------------------------------------------
# FIXME
"""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)
+ addresses = self._address_to_contact.keys()
+ if len(addresses) == 0:
+ self._set_hash_information({})
+ else:
+ args = { "apikey" : self._api_key}
+ hashes = self._construct_hashes(addresses)
+ args["hashes"] = list(hashes)
+ url = self._api_url
+ self._set_hash_information(self._get_hash_info_from_server(args, url))
+
+
+ # -----------------------------------------------------------------------
+ def _get_hash_info_from_server(self, args, url):
+ """Makes the actual XML-RPC call - override this for testing"""
+
+ service = xmlrpclib.ServerProxy(url)
+ return service.grav.exists(args)
+
+
+ # -----------------------------------------------------------------------
+ def _set_hash_information(self, hash_info):
+ self._hash_has_gravatar = hash_info
self._empty_cache = False
-
+
# -----------------------------------------------------------------------
def _get_url_for_email_hash(self, hash, default="404", size="128"):
# -----------------------------------------------------------------------
def _get_hash_for_address(self, address):
- return hashlib.md5(address.lower()).hexdigest()
\ No newline at end of file
+ return hashlib.md5(address.lower()).hexdigest()