12 from hermes import Hermes
14 gobject.threads_init()
17 """Provides the GUI for Hermes, allowing the syncing of Facebook and
18 Twitter friends' information with the Evolution contacts' database.
20 Copyright (c) Andrew Flegg <andrew@bleb.org> 2009.
21 Released under the Artistic Licence."""
24 # -----------------------------------------------------------------------
26 """Constructor. Initialises the gconf connection."""
27 self.gc = gnome.gconf.client_get_default()
30 # -----------------------------------------------------------------------
31 def doSync(self, widget, force, main = True):
32 if main and not self.get_use_facebook() and not self.get_use_twitter():
33 saved = self.open_prefs()
34 if saved == gtk.RESPONSE_DELETE_EVENT:
38 self.window.set_property('sensitive', False)
39 thread.start_new_thread(self.doSync, (widget, force, False))
43 twitter = (self.get_use_twitter() and self.get_twitter_credentials()) or None,
44 facebook = self.get_use_facebook(),
45 empty = self.get_create_empty())
47 fb2c.sync_contacts(resync = force)
48 gobject.idle_add(self.open_summary, fb2c)
50 except urllib2.HTTPError, e:
53 gobject.idle_add(self.report_error, 'Authentication problem. Check credentials.', True)
55 gobject.idle_add(self.report_error, 'Network connection error. Check connectivity.')
57 except urllib2.URLError, e:
59 gobject.idle_add(self.report_error, 'Network connection error. Check connectivity.')
63 gobject.idle_add(self.report_error, 'Something went wrong: ' + e.message)
66 # -----------------------------------------------------------------------
67 def open_summary(self, fb2c):
68 gobject.idle_add(self.window.set_property, 'sensitive', True)
70 dialog = gtk.Dialog('Summary', self.window)
71 dialog.add_button('Done', gtk.RESPONSE_OK)
73 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
74 title = 'Updated %d contacts' % (len(fb2c.updated)))
75 button.connect('clicked', self.show_contacts, fb2c.updated)
76 button.set_property('sensitive', len(fb2c.updated) > 0)
77 dialog.vbox.add(button)
79 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
80 title = 'Matched %d contacts' % (len(fb2c.matched)))
81 button.connect('clicked', self.show_contacts, fb2c.matched)
82 button.set_property('sensitive', len(fb2c.matched) > 0)
83 dialog.vbox.add(button)
85 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
86 title = '%d contacts unmatched' % (len(fb2c.unmatched)))
87 button.connect('clicked', self.show_contacts, fb2c.unmatched)
88 button.set_property('sensitive', len(fb2c.unmatched) > 0)
89 dialog.vbox.add(button)
96 # -----------------------------------------------------------------------
97 def show_contacts(self, widget, contacts):
98 view = contactview.ContactView(contacts)
100 dialog = gtk.Dialog('Contacts', self.window)
101 #view.connect('contact-activated', self.map_contact)
102 dialog.vbox.add(view)
109 # -----------------------------------------------------------------------
110 def map_contact(self, widget, contact):
111 print widget, contact
114 # -----------------------------------------------------------------------
115 def open_prefs(self, widget = None):
116 dialog = gtk.Dialog('Accounts', self.window)
117 dialog.add_button('Save', gtk.RESPONSE_OK)
119 #pa = hildon.PannableArea()
121 content = dialog.vbox
122 #content = gtk.VBox()
124 #pa.set_size_request(600, 380)
126 use_facebook = self.new_checkbox('Use Facebook', content)
127 use_facebook.set_active(self.get_use_facebook())
129 indent = self.new_indent(content)
130 fb_msg = self.add_linked(indent, use_facebook, gtk.Label('Note: authentication via web page'))
131 fb_msg.set_property('justify', gtk.JUSTIFY_LEFT)
133 fb_empty = self.add_linked(indent, use_facebook, self.new_checkbox('Create birthday-only contacts'))
134 fb_empty.set_active(self.get_create_empty())
136 use_twitter = self.new_checkbox('Use Twitter', content)
137 use_twitter.set_active(self.get_use_twitter())
139 indent = self.new_indent(content)
140 tw_user = self.add_linked(indent, use_twitter, self.new_input('Twitter username'))
141 tw_user.set_text(self.get_twitter_credentials()[0])
143 tw_pass = self.add_linked(indent, use_twitter, self.new_input('Twitter password'))
144 tw_pass.set_property('hildon-input-mode', gtk.HILDON_GTK_INPUT_MODE_FULL |
145 gtk.HILDON_GTK_INPUT_MODE_INVISIBLE)
146 tw_pass.set_text(self.get_twitter_credentials()[1])
149 result = dialog.run()
151 if result == gtk.RESPONSE_OK:
152 self.set_use_facebook(use_facebook.get_active())
153 self.set_create_empty(fb_empty.get_active())
154 self.set_use_twitter(use_twitter.get_active(), tw_user.get_text(), tw_pass.get_text())
158 # -----------------------------------------------------------------------
159 def new_checkbox(self, label, box = None):
160 checkbox = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
161 checkbox.set_label(label)
167 # -----------------------------------------------------------------------
168 def new_indent(self, box):
171 outer.pack_start(indent, padding=48)
176 # -----------------------------------------------------------------------
177 def new_input(self, text, box = None):
178 input = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
179 input.set_property('hildon-input-mode', gtk.HILDON_GTK_INPUT_MODE_FULL)
180 input.set_placeholder(text)
181 input.set_property('is-focus', False)
187 # -----------------------------------------------------------------------
188 def add_linked(self, box, ctrl, to_add):
190 self.sync_edit(ctrl, to_add)
191 ctrl.connect('toggled', self.sync_edit, to_add)
195 # -----------------------------------------------------------------------
196 def sync_edit(self, use_twitter, edit):
197 edit.set_property('sensitive', use_twitter.get_active())
200 # -----------------------------------------------------------------------
201 def need_auth(self, main = False):
203 hildon.hildon_banner_show_information(self.window, '', "Need to authenticate with Facebook")
205 gobject.idle_add(self.need_auth, True)
208 # -----------------------------------------------------------------------
209 def block_for_auth(self, main = False, lock = None):
211 note = gtk.Dialog('Facebook authorisation', self.window)
212 note.add_button("Validate", gtk.RESPONSE_OK)
213 note.vbox.add(gtk.Label("\nPress 'Validate' once Facebook has\nbeen authenticated in web browser.\n"))
222 lock = thread.allocate_lock()
224 gobject.idle_add(self.block_for_auth, True, lock)
229 # -----------------------------------------------------------------------
230 def progress(self, i, j, main = False):
233 self.progressbar = gtk.ProgressBar()
234 self.progressnote = gtk.Dialog("Fetching friends' info", self.window)
235 self.progressnote.vbox.add(self.progressbar)
236 hildon.hildon_gtk_window_set_progress_indicator(self.progressnote, 1)
238 self.progressnote.show_all()
242 self.progressnote.set_title("Updating contacts")
243 hildon.hildon_gtk_window_set_progress_indicator(self.progressnote, 0)
245 self.progressbar.set_fraction(float(i) / float(j))
248 self.progressnote.destroy()
252 gobject.idle_add(self.progress, i, j, True)
255 # -----------------------------------------------------------------------
256 def report_error(self, e, prefs = False):
257 if self.progressnote:
258 self.window.set_property('sensitive', True)
259 self.progressnote.destroy()
261 hildon.hildon_banner_show_information(self.window, '', e)
266 # -----------------------------------------------------------------------
267 def take_screenshot(self, event = None, data = None):
268 self.window.disconnect(self.expose_hid)
269 if not os.path.isfile("/home/user/.cache/launch/org.maemo.hermes.pvr"):
270 gobject.timeout_add(80, hildon.hildon_gtk_window_take_screenshot, self.window, True)
273 # -----------------------------------------------------------------------
275 # -- Window and app...
277 self.app = hildon.Program()
278 self.window = hildon.Window()
279 gtk.set_application_name('Hermes')
280 self.osso_context = osso.Context('org.maemo.hermes', '0.0.5', False)
281 self.app.add_window(self.window)
283 self.window.connect("delete-event", gtk.main_quit)
284 self.expose_hid = self.window.connect('expose-event', self.take_screenshot)
286 # -- Main window buttons...
288 self.background, mask = gtk.gdk.pixbuf_new_from_file('/opt/hermes/share/background.png').render_pixmap_and_mask()
289 self.window.realize()
290 self.window.window.set_back_pixmap(self.background, False)
291 alignment = gtk.Alignment(xalign=0.5, yalign=0.8, xscale=0.8)
292 box = gtk.HButtonBox()
294 self.window.add(alignment)
296 box.set_property('layout-style', gtk.BUTTONBOX_SPREAD)
297 button = hildon.Button(gtk.HILDON_SIZE_THUMB_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
298 title = 'Retrieve', value = "Get contacts' missing info")
299 button.set_property('width-request', 250)
300 button.connect('clicked', self.doSync, False)
303 button = hildon.Button(gtk.HILDON_SIZE_THUMB_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
304 title = 'Update', value = "Update contacts' info")
305 button.set_property('width-request', 250)
306 button.connect('clicked', self.doSync, True)
309 # -- Application menu...
311 menu = hildon.AppMenu()
312 button = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
313 button.set_label("Accounts")
314 button.connect("clicked", self.open_prefs)
317 self.window.set_app_menu(menu)
319 self.window.show_all()
323 def get_use_facebook(self):
324 return self.gc.get_bool("/apps/maemo/hermes/use_facebook")
327 def set_use_facebook(self, value):
328 self.gc.set_bool("/apps/maemo/hermes/use_facebook", value)
330 def get_create_empty(self):
331 return self.gc.get_bool("/apps/maemo/hermes/create_empty")
334 def set_create_empty(self, value):
335 self.gc.set_bool("/apps/maemo/hermes/create_empty", value)
338 def get_use_twitter(self):
339 return self.gc.get_bool("/apps/maemo/hermes/use_twitter")
342 def set_use_twitter(self, value, user, password):
343 self.gc.set_bool("/apps/maemo/hermes/use_twitter", value)
344 self.gc.set_string("/apps/maemo/hermes/twitter_user", user)
345 self.gc.set_string("/apps/maemo/hermes/twitter_pwd", password)
348 def get_twitter_credentials(self):
349 return (self.gc.get_string("/apps/maemo/hermes/twitter_user") or '',
350 self.gc.get_string("/apps/maemo/hermes/twitter_pwd") or '')
353 # -------------------------------------------------------------------------
354 if __name__ == '__main__':