Log In
New Account
  
Home My Page Project Cloud Code Snippets Project Openings Hermes
Summary Lists News SCM
6f94c8647fc40176dbe3c4ef2db0de7a086699a0
1 import os.path
2 import evolution
3 from facebook import Facebook, FacebookError
4 import twitter
5 import gnome.gconf
6 from contacts import ContactStore
7 import names
9 class Hermes:
10   """Encapsulate the process of syncing Facebook friends' information with the
11      Evolution contacts' database. This should be used as follows:
12      
13        * Initialise, passing in a callback (methods: need_auth(),
14          block_for_auth(), use_twitter(), use_facebook()).
15        * Call load_friends().
16        * Call sync_contacts().
17        * Retrieve information on changes effected.
18        
19      This requires two gconf paths to contain Facebook application keys:
20          /apps/maemo/hermes/key_app
21          /apps/maemo/hermes/key_secret
22        
23      Copyright (c) Andrew Flegg <andrew@bleb.org> 2009.
24      Released under the Artistic Licence."""
27   # -----------------------------------------------------------------------
28   def __init__(self, callback, twitter = None, facebook = False):
29     """Constructor. Passed a callback which must implement three informational
30        methods:
31        
32          need_auth() - called to indicate a login is about to occur. The user
33                        should be informed.
34                        
35          block_for_auth() - prompt the user to take some action once they have
36                             successfully logged in to Facebook.
37                           
38          progress(i, j) - the application is currently processing friend 'i' of
39                           'j'. Should be used to provide the user a progress bar.
40                           
41       Other parameters:
42          twitter - a username/password tuple or None if Twitter should not be
43                    used. Defaults to None.
44                    
45          facebook - boolean indicating if Facebook should be used. Defaults to
46                     False.
47                           """
49     self.gc       = gnome.gconf.client_get_default()
50     self.callback = callback
51     self.twitter  = twitter
52     self.facebook = facebook
54     # -- Check the environment is going to work...
55     #
56     if (self.gc.get_string('/desktop/gnome/url-handlers/http/command') == 'epiphany %s'):
57       raise Exception('Browser in gconf invalid (see NB#136012). Installation error.')
59     # -- Get private keys for this app...
60     #
61     key_app    = self.gc.get_string('/apps/maemo/hermes/key_app')
62     key_secret = self.gc.get_string('/apps/maemo/hermes/key_secret')
63     if (key_app is None or key_secret is None):
64       raise Exception('No Facebook application keys found. Installation error.')
66     self.fb = Facebook(key_app, key_secret)
67     self.fb.desktop = True
70   # -----------------------------------------------------------------------
71   def do_fb_login(self):
72     """Perform authentication against Facebook and store the result in gconf
73          for later use. Uses the 'need_auth' and 'block_for_auth' methods on
74          the callback class. The former allows a message to warn the user
75          about what is about to happen to be shown; the second is to wait
76          for the user to confirm they have logged in."""
77     self.fb.session_key = None
78     self.fb.secret = None
79     self.fb.uid = None
80     
81     self.callback.need_auth()
82     self.fb.auth.createToken()
83     self.fb.login()
84     self.callback.block_for_auth()
85     session = self.fb.auth.getSession()
87     self.gc.set_string('/apps/maemo/hermes/session_key', session['session_key'])
88     self.gc.set_string('/apps/maemo/hermes/secret_key', session['secret'])
89     self.gc.set_int('/apps/maemo/hermes/uid', session['uid'])
92   # -----------------------------------------------------------------------
93   def load_friends(self):
94     """Load information on the authenticated user's friends. If no user is
95        currently authenticated, prompts for a login."""
97     self.friends = {}
98     self.blocked_pictures = []
99     
100     # -- Get a user session and retrieve Facebook friends...
101     #
102     if self.facebook:
103       if self.fb.session_key is None:
104         self.fb.session_key = self.gc.get_string('/apps/maemo/hermes/session_key')
105         self.fb.secret = self.gc.get_string('/apps/maemo/hermes/secret_key')
106         self.fb.uid = self.gc.get_int('/apps/maemo/hermes/uid')
108       # Check the available session is still valid...
109       while True:
110         try:
111           if self.fb.users.getLoggedInUser() and self.fb.session_key:
112             break
113         except FacebookError:
114           pass
115         self.do_fb_login()
117       self.callback.progress(0, 0)
118       # Get the list of friends...
119       attrs = ['uid', 'name', 'pic_big', 'birthday_date']
120       for friend in self.fb.users.getInfo(self.fb.friends.get(), attrs):
121         friend['pic'] = friend[attrs[2]]
122         self.friends[friend['name']] = friend
123         if not friend['pic']:
124           self.blocked_pictures.append(friend)
125           
126     # -- Retrieve following information from Twitter...
127     #
128     if self.twitter is not None:
129       (user, passwd) = self.twitter
130       api = twitter.Api(username=user, password=passwd)
131       users = api.GetFriends()
132       for friend in api.GetFriends():
133         self.friends[friend.name] = {'name': friend.name, 'pic': friend.profile_image_url, 'birthday_date': None}
134   
135   
136   # -----------------------------------------------------------------------
137   def sync_contacts(self, resync = False):
138     """Synchronise Facebook profiles to contact database. If resync is false,
139        no existing information will be overwritten."""
141     # -- Find addresses...
142     #
143     print "+++ Syncing contacts..."
144     addresses = evolution.ebook.open_addressbook('default')
145     print "+++ Addressbook opened..."
146     store = ContactStore(addresses)
147     print "+++ Contact store created..."
148     self.updated = []
149     contacts = addresses.get_all_contacts()
150     current = 0
151     maximum = len(contacts)
152     for contact in contacts:
153       current += 1
154       self.callback.progress(current, maximum)
155       for name in names.variants(contact.get_name()):
156         if name in self.friends:
157           friend = self.friends[name]
158       
159           if friend['pic'] and (resync or contact.get_property('photo') is None):
160             print "Picture for %s is [%s]" % (name, friend['pic'])
161             store.set_photo(contact, friend['pic'])
162             self.updated.append(contact)
163         
164           if friend['birthday_date'] and (resync or contact.get_property('birth-date') is None):
165             print "Birthday for %s is [%s]" % (name, friend['birthday_date'])
166     
167           break  
169     store.close()

Terms of Use    Privacy Policy    Contribution Guidelines    Feedback

Powered By GForge Collaborative Development Environment