mostly cleanup, minor adds, pseudo code in gtkui.py
authorFredrik Wendt <fredrik@wendt.se>
Sun, 6 Jun 2010 22:29:26 +0000 (23:29 +0100)
committerFredrik Wendt <fredrik@wendt.se>
Sun, 6 Jun 2010 22:29:26 +0000 (23:29 +0100)
package/src/org/maemo/hermes/engine/friend.py
package/src/org/maemo/hermes/engine/gravatar/provider.py
package/src/org/maemo/hermes/engine/gravatar/service.py
package/src/org/maemo/hermes/engine/linkedin/api.py
package/src/org/maemo/hermes/engine/syncjob.py
package/src/org/maemo/hermes/gui/gtkui.py
package/test/test_gravatar.py
package/test/test_syncjob.py

index fadd586..954f4f5 100644 (file)
@@ -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)
index 4627c28..8ef1908 100644 (file)
@@ -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)
index cccc676..cf11f09 100644 (file)
@@ -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
         
 
index 8775493..5f2fd96 100644 (file)
@@ -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
index 19ee3c8..4c3429f 100644 (file)
@@ -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)
index c1a605c..79b9fa4 100644 (file)
@@ -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:
index db9704f..077145b 100644 (file)
@@ -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):
index 4b2246d..ebf7b5d 100644 (file)
@@ -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()