From bb4afb3c6acf993ba5ece5ff71b4711028cb2aab Mon Sep 17 00:00:00 2001 From: Fredrik Wendt Date: Sun, 6 Jun 2010 23:29:26 +0100 Subject: [PATCH] mostly cleanup, minor adds, pseudo code in gtkui.py --- package/src/org/maemo/hermes/engine/friend.py | 4 ++ .../org/maemo/hermes/engine/gravatar/provider.py | 4 ++ .../org/maemo/hermes/engine/gravatar/service.py | 1 + .../src/org/maemo/hermes/engine/linkedin/api.py | 69 ++++++++++++++------ package/src/org/maemo/hermes/engine/syncjob.py | 40 ++++++++++-- package/src/org/maemo/hermes/gui/gtkui.py | 11 ++++ package/test/test_gravatar.py | 4 +- package/test/test_syncjob.py | 4 +- 8 files changed, 107 insertions(+), 30 deletions(-) diff --git a/package/src/org/maemo/hermes/engine/friend.py b/package/src/org/maemo/hermes/engine/friend.py index fadd586..954f4f5 100644 --- a/package/src/org/maemo/hermes/engine/friend.py +++ b/package/src/org/maemo/hermes/engine/friend.py @@ -28,6 +28,10 @@ class Friend(): def get_urls(self): try: return self._multi_attributes['url'] except: return [] + + def get_photo_url(self): + try: return self._attributes['photo-url'] + except: return None def add_url(self, url): self._add('url', url) diff --git a/package/src/org/maemo/hermes/engine/gravatar/provider.py b/package/src/org/maemo/hermes/engine/gravatar/provider.py index 4627c28..8ef1908 100644 --- a/package/src/org/maemo/hermes/engine/gravatar/provider.py +++ b/package/src/org/maemo/hermes/engine/gravatar/provider.py @@ -37,4 +37,8 @@ class Provider(org.maemo.hermes.engine.provider.Provider): api_email = self._gconf.get_string('/apps/maemo/hermes/gravatar_email') api_key = self._gconf.get_string('/apps/maemo/hermes/gravatar_key') + # FIXME: put this in postinst + api_email = 'maemohermes@wendt.se' + api_key = 'b14ec179822b' + return org.maemo.hermes.engine.gravatar.service.Service(api_email, api_key) diff --git a/package/src/org/maemo/hermes/engine/gravatar/service.py b/package/src/org/maemo/hermes/engine/gravatar/service.py index cccc676..cf11f09 100644 --- a/package/src/org/maemo/hermes/engine/gravatar/service.py +++ b/package/src/org/maemo/hermes/engine/gravatar/service.py @@ -117,6 +117,7 @@ class Service(org.maemo.hermes.engine.service.Service): # ----------------------------------------------------------------------- def _set_hash_information(self, hash_info): self._hash_has_gravatar = hash_info + print hash_info self._empty_cache = False diff --git a/package/src/org/maemo/hermes/engine/linkedin/api.py b/package/src/org/maemo/hermes/engine/linkedin/api.py index 8775493..5f2fd96 100644 --- a/package/src/org/maemo/hermes/engine/linkedin/api.py +++ b/package/src/org/maemo/hermes/engine/linkedin/api.py @@ -30,29 +30,36 @@ class LinkedInApi(): self._gc = gnome.gconf.client_get_default() # -- Check the environment is going to work... - # + # FIXME: duplication if (self._gc.get_string('/desktop/gnome/url-handlers/http/command') == 'epiphany %s'): raise Exception('Browser in gconf invalid (see NB#136012). Installation error.') api_key = self._gc.get_string('/apps/maemo/hermes/linkedin_api_key') secret_key = self._gc.get_string('/apps/maemo/hermes/linkedin_key_secret') - # FIXME: remove this + # FIXME: move this to gconf and postinst api_key = '1et4G-VtmtqNfY7gF8PHtxMOf0KNWl9ericlTEtdKJeoA4ubk4wEQwf8lSL8AnYE' secret_key = 'uk--OtmWcxER-Yh6Py5p0VeLPNlDJSMaXj1xfHILoFzrK7fM9eepNo5RbwGdkRo_' if api_key is None or secret_key is None: raise Exception('No LinkedIn application keys found. Installation error.') - self.api_key = api_key - self.secret_key = secret_key - - # FIXME: move this - token_str = "oauth_token_secret=60f817af-6437-4015-962f-cc3aefee0264&oauth_token=f89c2b7b-1c12-4f83-a469-838e78901716" - self.access_token = oauth.OAuthToken.from_string(token_str) + self.access_token = self._get_access_token_from_gconf() self.consumer = oauth.OAuthConsumer(api_key, secret_key) self.sig_method = oauth.OAuthSignatureMethod_HMAC_SHA1() + + # IMPROVEMENT: verify that the access_token is valid for at least another hour + self._verify_access_token() + + + def authenticate(self, need_auth, block_for_auth): + need_auth() + token = self._get_request_token() + url = self._get_authorize_url(token) + verifier = block_for_auth(url) + self._verify_verifier(verifier) + # ----------------------------------------------------------------------- def get_friends(self): @@ -63,8 +70,34 @@ class LinkedInApi(): friends = self._parse_dom(dom) return friends + + + # ----------------------------------------------------------------------- + def _verify_verifier(self, verifier): + try: + self.access_token = self._get_access_token(self.request_token, verifier) + self._store_access_token_in_gconf() + except: + raise Exception("authorization failed, try again") + + + # ----------------------------------------------------------------------- + def _verify_access_token(self): + return True + # ----------------------------------------------------------------------- + def _store_access_token_in_gconf(self, token_str): + self._gc.set_string('/apps/maemo/hermes/linkedin_access_token', token_str) + + + # ----------------------------------------------------------------------- + def _get_access_token_from_gconf(self): + token_str = self._gc.get_string('/apps/maemo/hermes/linkedin_access_token') + return oauth.OAuthToken.from_string(token_str) + + + # ----------------------------------------------------------------------- def _make_api_request(self, url): print "_make_api_request", url oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, token=self.access_token, http_url=url) @@ -126,7 +159,8 @@ class LinkedInApi(): # ----------------------------------------------------------------------- def _get_access_token(self, token, verifier): - """user provides the verifier, which was displayed in the browser window""" + """If the verifier (which was displayed in the browser window) is valid, + then an access token is returned which should be used to access data on the service.""" oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, token=token, verifier=verifier, http_url=self.ACCESS_TOKEN_URL) oauth_request.sign_request(self.sig_method, self.consumer, token) @@ -134,7 +168,9 @@ class LinkedInApi(): connection = httplib.HTTPSConnection(self.LI_SERVER) connection.request(oauth_request.http_method, self.ACCESS_TOKEN_URL, headers=oauth_request.to_header()) response = connection.getresponse() - return oauth.OAuthToken.from_string(response.read()) + token_str = response.read() + self._store_access_token_in_gconf(token_str) + return oauth.OAuthToken.from_string(token_str) # ----------------------------------------------------------------------- @@ -146,11 +182,11 @@ class LinkedInApi(): # ----------------------------------------------------------------------- - def _get_request_token(self, callback): + def _get_request_token(self): """Get a request token from LinkedIn""" oauth_consumer_key = self.api_key - oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, callback=callback, http_url=self.REQUEST_TOKEN_URL) + oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, callback="oob", http_url=self.REQUEST_TOKEN_URL) oauth_request.sign_request(self.sig_method, self.consumer, None) connection = httplib.HTTPSConnection(self.LI_SERVER) @@ -160,12 +196,3 @@ class LinkedInApi(): token = oauth.OAuthToken.from_string(response) return token - - # ----------------------------------------------------------------------- - def _do_li_login(self): - """Perform authentication against LinkedIn and store the result in gconf - for later use. Uses the 'need_auth' and 'block_for_auth' methods on - the callback class. The former allows a message to warn the user - about what is about to happen to be shown; the second is to wait - for the user to confirm they have logged in.""" - # FIXME diff --git a/package/src/org/maemo/hermes/engine/syncjob.py b/package/src/org/maemo/hermes/engine/syncjob.py index 19ee3c8..4c3429f 100644 --- a/package/src/org/maemo/hermes/engine/syncjob.py +++ b/package/src/org/maemo/hermes/engine/syncjob.py @@ -1,26 +1,54 @@ #!/usr/bin/env python -class Syncjob(): +class SyncJob(): - def __init__(self, services, originalContacts): + def __init__(self, services, original_contacts, progress_callback): self._services = services - self._originalContacts = originalContacts + self._original_contacts = original_contacts + def run(self): self._pre_process_contacts() self._process_friends() self._process_contacts() + + + def create_contact_for_friend(self, friend): + """Creates a contact for the friend: + FIXME: if we do it NOW, then that contact can be re-used and mapped to other unmatched friends + FIXME: should this really take place here ...""" + + pass + + + def register_match(self, contact, friend): + """Makes sure that when save is clicked,""" + + def get_unmatched_friends(self): + pass + + + def get_updated_contacts(self): + pass + + + def get_matched_contacts(self): + pass + + def _pre_process_contacts(self): - for contact in self._originalContacts: + for contact in self._original_contacts: for service in self._services: service.pre_process_contact(contact) + def _process_friends(self): for service in self._services: service.process_friends() + def _process_contacts(self): - for contact in self._originalContacts: + for contact in self._original_contacts: for service in self._services: - service.process_contact(contact) + service.process_contact(contact) diff --git a/package/src/org/maemo/hermes/gui/gtkui.py b/package/src/org/maemo/hermes/gui/gtkui.py index c1a605c..79b9fa4 100644 --- a/package/src/org/maemo/hermes/gui/gtkui.py +++ b/package/src/org/maemo/hermes/gui/gtkui.py @@ -10,6 +10,7 @@ from org.maemo.hermes.gui.contactview import ContactView from org.maemo.hermes.gui.mapcontact import MapContact from org.maemo.hermes.gui.accountsdialogue import AccountsDialogue from org.bleb.wimpworks import HildonMainScreenLayout +from org.maemo.hermes.engine.syncjob import SyncJob #from hermes import Hermes ### FIXME This needs to be new class HermesGUI(WimpWorks): @@ -75,6 +76,16 @@ class HermesGUI(WimpWorks): services.append(provider.service(self)) print services + class FakeContact(): + def get_name(self): + return "Fredrik Wendt" + def get_emails(self): + return ["fredrik@wendt.se","maemohermes@wendt.se"] + self._sync_job = SyncJob(services, [FakeContact()], self.progress) + self._sync_job.run() + self._sync_job.get_unmatched_friends() + self._sync_job.get_updated_contacts() + self._sync_job.get_matched_contacts() raise Exception("TODO - implement syncing") except urllib2.HTTPError, e: diff --git a/package/test/test_gravatar.py b/package/test/test_gravatar.py index db9704f..077145b 100644 --- a/package/test/test_gravatar.py +++ b/package/test/test_gravatar.py @@ -28,7 +28,9 @@ class TestGravatarService(unittest.TestCase): assert len(contacts) == 1 assert self.missing_contact not in contacts.keys() assert self.existing_contact in contacts.keys() - assert friends[0].get_name() == self.existing_contact.get_name() + friend = friends[0] + assert friend.get_name() == self.existing_contact.get_name() + print friend.get_photo_url() def test_that_a_person_with_two_addresses_and_one_gravatar_works(self): diff --git a/package/test/test_syncjob.py b/package/test/test_syncjob.py index 4b2246d..ebf7b5d 100644 --- a/package/test/test_syncjob.py +++ b/package/test/test_syncjob.py @@ -1,5 +1,5 @@ import unittest -from org.maemo.hermes.engine.syncjob import Syncjob +from org.maemo.hermes.engine.syncjob import SyncJob class FakeContact(): def __init__(self): @@ -26,7 +26,7 @@ class TestSyncJob(unittest.TestCase): self.services = [self.service] self.contact = FakeContact() self.contacts = [self.contact] - self.testee = Syncjob(self.services, self.contacts) + self.testee = SyncJob(self.services, self.contacts) def test_main_flow(self): self.testee.run() -- 1.7.9.5