Add preferences UI for Facebook. Tidy up lose ends related to this;
[hermes] / package / src / org / maemo / hermes / engine / facebook / provider.py
1 from facebook import Facebook, FacebookError
2 import gnome.gconf
3 import gtk, hildon
4 import org.maemo.hermes.engine.provider
5 import org.maemo.hermes.engine.facebook.service
6
7 class Provider(org.maemo.hermes.engine.provider.Provider):
8     """Facebook provider for Hermes. 
9
10        This requires two gconf paths to contain Facebook application keys:
11            /apps/maemo/hermes/facebook_app
12            /apps/maemo/hermes/facebook_secret
13        
14        Copyright (c) Andrew Flegg <andrew@bleb.org> 2010.
15        Released under the Artistic Licence."""
16
17     # -----------------------------------------------------------------------
18     def __init__(self):
19         """Initialise the provider, and ensure the environment is going to work."""
20
21         self._gc = gnome.gconf.client_get_default()
22         if (self._gc.get_string('/desktop/gnome/url-handlers/http/command') == 'epiphany %s'):
23             raise Exception('Browser in gconf invalid (see NB#136012). Installation error.')
24
25         key_app    = self._gc.get_string('/apps/maemo/hermes/facebook_app')
26         key_secret = self._gc.get_string('/apps/maemo/hermes/facebook_secret')
27         if key_app is None or key_secret is None:
28             raise Exception('No Facebook application keys found. Installation error.')
29         
30         self.fb = Facebook(key_app, key_secret)
31         self.fb.desktop = True
32
33         if self.fb.session_key is None:
34             self.fb.session_key = self._gc.get_string('/apps/maemo/hermes/facebook_session_key')
35             self.fb.secret = self._gc.get_string('/apps/maemo/hermes/facebook_secret_key')
36             self.fb.uid = self._gc.get_string('/apps/maemo/hermes/facebook_uid')
37
38
39     # -----------------------------------------------------------------------
40     def get_name(self):
41         """Return the display name of this service. An icon, of with the lower-case,
42            all-alphabetic version of this name is expected to be provided."""
43            
44         return 'Facebook'
45
46     
47     # -----------------------------------------------------------------------
48     def get_account_detail(self):
49         """Return the email address associated with the user, if available."""
50         
51 #        if self.fb.users.getLoggedInUser() and self.fb.session_key:
52 #            info = self.fb.users.getInfo([self.fb.uid], ['name'])
53 #            return info['name']
54 #        else:
55         return '---'
56     
57     
58     # -----------------------------------------------------------------------
59     def has_preferences(self):
60         """Whether or not this provider has any preferences. If it does not,
61            open_preferences must NOT be called; as the behaviour is undetermined."""
62            
63         return True
64     
65     
66     # -----------------------------------------------------------------------
67     def open_preferences(self, parent):
68         """Open the preferences for this provider as a child of the 'parent' widget."""
69
70         dialog = gtk.Dialog(self.get_name(), parent)
71         dialog.add_button(_('Clear'), gtk.RESPONSE_OK)
72         dialog.add_button(_('Disable'), gtk.RESPONSE_NO)
73         dialog.add_button(_('Enable'), gtk.RESPONSE_YES)
74         
75         dialog.vbox.add(gtk.Label(_('Note: authentication via web page')))
76         
77         checkbox = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
78         checkbox.set_label(_('Create birthday-only contacts'))
79         checkbox.set_active(self._gc.get_bool('/apps/maemo/hermes/facebook_birthday_only'))
80         dialog.vbox.add(checkbox)
81         dialog.vbox.add(gtk.Label(''))
82         
83         while True:
84             dialog.show_all()
85             result = dialog.run()
86             dialog.hide()
87             if result == gtk.RESPONSE_CANCEL:
88                 return None
89             elif result == gtk.RESPONSE_OK:
90                 self._gc.set_string('/apps/maemo/hermes/facebook_session_key', '')
91                 self._gc.set_string('/apps/maemo/hermes/facebook_secret_key', '')
92                 self._gc.set_string('/apps/maemo/hermes/facebook_uid', '')
93             else:
94                 break
95     
96         self._gc.set_bool('/apps/maemo/hermes/facebook_birthday_only', checkbox.get_active())
97         return result == gtk.RESPONSE_YES
98         
99     
100     # -----------------------------------------------------------------------
101     def service(self, gui_callback):
102         """Return a service instance."""
103         
104         self._gui = gui_callback
105         
106         # Check the available session is still valid...
107         while True:
108             try:
109                 if self.fb.users.getLoggedInUser() and self.fb.session_key:
110                     break
111             except FacebookError:
112                 pass
113             self._do_fb_login()
114
115         return org.maemo.hermes.engine.facebook.service.Service(self.fb)
116
117
118     # -----------------------------------------------------------------------
119     def _do_fb_login(self):
120         """Perform authentication against Facebook and store the result in gconf
121              for later use. Uses the 'need_auth' and 'block_for_auth' methods on
122              the callback class. The former allows a message to warn the user
123              about what is about to happen to be shown; the second is to wait
124              for the user to confirm they have logged in."""
125         self.fb.session_key = None
126         self.fb.secret = None
127         self.fb.uid = None
128         
129         if self._gui:
130             self._gui.need_auth()
131             
132         self.fb.auth.createToken()
133         self.fb.login()
134         
135         if self._gui:
136             self._gui.block_for_auth()
137           
138         session = self.fb.auth.getSession()
139         self._gc.set_string('/apps/maemo/hermes/facebook_session_key', session['session_key'])
140         self._gc.set_string('/apps/maemo/hermes/facebook_secret_key', session['secret'])
141         self._gc.set_string('/apps/maemo/hermes/facebook_uid', str(session['uid']))