9 from org.bleb.wimpworks import WimpWorks
10 from org.maemo.hermes.gui.contactview import ContactView
11 from org.maemo.hermes.gui.mapcontact import MapContact
12 from org.maemo.hermes.gui.accountsdialogue import AccountsDialogue
13 from org.bleb.wimpworks import HildonMainScreenLayout
14 from org.maemo.hermes.engine.syncjob import SyncJob
15 from org.maemo.hermes.engine.hermes import Hermes
17 class HermesGUI(WimpWorks):
18 """Provides the GUI for Hermes, allowing the syncing of Facebook and
19 Twitter friends' information with the Evolution contacts' database.
21 Copyright (c) Andrew Flegg <andrew@bleb.org> 2009.
22 Released under the Artistic Licence."""
25 # -----------------------------------------------------------------------
26 def __init__(self, providers = None):
27 gettext.install('hermes','/opt/hermes/share/locale/')
28 WimpWorks.__init__(self, 'Hermes', version = '0.9.0', dbus_name = 'org.maemo.hermes')
29 self.set_background('background.png')
31 layout = HildonMainScreenLayout(offset = 0.8, container = self)
32 layout.add_button('Retrieve', _("Get contacts' missing info"))
33 layout.add_button('Refresh', _("Update contacts' info"))
35 self.add_menu_action("Accounts")
38 self.providers = providers
39 self.progressnote = None
40 connection = conic.Connection()
41 gobject.timeout_add(100, connection.request_connection, conic.CONNECT_FLAG_NONE)
44 # -----------------------------------------------------------------------
45 def do_retrieve(self, widget):
46 self.sync(widget, False)
49 # -----------------------------------------------------------------------
50 def do_refresh(self, widget):
51 self.sync(widget, True)
54 # -----------------------------------------------------------------------
55 def do_accounts(self, widget = None):
56 dialog = AccountsDialogue(self.main_window, self.providers)
60 # -----------------------------------------------------------------------
61 def sync(self, widget, force, main = True):
63 for provider in self.providers:
64 if self.gconf.get_bool('/apps/maemo/hermes/use_%s' % (provider.get_id())):
65 enabled.append(provider)
67 if main and len(enabled) == 0:
68 saved = self.do_accounts()
69 if saved == gtk.RESPONSE_DELETE_EVENT:
72 print "doing sync", main
75 self.main_window.set_property('sensitive', False)
76 thread.start_new_thread(self.sync, (widget, force, False))
79 self.progress('', 0, 0)
81 for provider in enabled:
82 services.append(provider.service(self))
84 hermes = Hermes(services, self.progress)
86 gobject.idle_add(self.open_summary, hermes)
88 except urllib2.HTTPError, e:
91 gobject.idle_add(self.report_error, _('Authentication problem. Check credentials.'), True)
93 gobject.idle_add(self.report_error, _('Network connection error. Check connectivity.'))
95 except urllib2.URLError, e:
97 gobject.idle_add(self.report_error, _('Network connection error. Check connectivity.'))
100 traceback.print_exc()
101 gobject.idle_add(self.report_error, _('Something went wrong: ') + e.message)
104 # -----------------------------------------------------------------------
105 def open_summary(self, fb2c):
106 gobject.idle_add(self.main_window.set_property, 'sensitive', True)
108 dialog = gtk.Dialog(_('Summary'), self.main_window)
109 dialog.add_button(_('Done'), gtk.RESPONSE_OK)
111 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
112 title = _('Updated %d contacts') % (len(fb2c.updated)))
113 button.connect('clicked', self.show_contacts, fb2c, fb2c.updated)
114 button.set_property('sensitive', len(fb2c.updated) > 0)
115 dialog.vbox.add(button)
117 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
118 title = _('Matched %d contacts') % (len(fb2c.matched)))
119 button.connect('clicked', self.show_contacts, fb2c, fb2c.matched)
120 button.set_property('sensitive', len(fb2c.matched) > 0)
121 dialog.vbox.add(button)
123 button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
124 title = _('%d contacts unmatched') % (len(fb2c.unmatched)))
125 button.connect('clicked', self.show_contacts, fb2c, fb2c.unmatched)
126 button.set_property('sensitive', len(fb2c.unmatched) > 0)
127 dialog.vbox.add(button)
134 # -----------------------------------------------------------------------
135 def show_contacts(self, widget, fb2c, contacts):
136 view = ContactView(contacts)
138 dialog = gtk.Dialog(_('Contacts'), self.main_window)
139 view.connect('contact-activated', self.map_contact, fb2c)
140 dialog.vbox.add(view)
147 # -----------------------------------------------------------------------
148 def map_contact(self, widget, contact, fb2c):
149 view = MapContact(fb2c.friends, contact)
151 dialog = gtk.Dialog(contact.get_name(), self.main_window)
152 dialog.add_button(_('Update'), gtk.RESPONSE_OK)
153 dialog.vbox.add(view)
156 result = dialog.run()
158 if result == gtk.RESPONSE_OK:
159 friend = view.get_selected_friend()
161 if friend.get_contact() == contact:
162 hildon.hildon_banner_show_information(self.main_window, '', _("Removing existing mappings is not yet supported"))
163 elif view.contact_mapped:
164 fb2c.update_contact(contact, friend, True, True)
165 widget.add_mapping(friend.get_source())
167 fb2c.update_contact(contact, friend, False, True)
168 widget.add_mapping(friend.get_source())
171 # -----------------------------------------------------------------------
172 def need_auth(self, main = False):
173 """Part of the GUI callback API."""
176 hildon.hildon_banner_show_information(self.main_window, '', _("Need to authenticate via browser"))
178 gobject.idle_add(self.need_auth, True)
181 # -----------------------------------------------------------------------
182 def block_for_auth(self, prompt = False, main = False, lock = None):
183 """Part of the GUI callback API."""
186 note = gtk.Dialog(_('Service authorisation'), self.main_window)
187 note.add_button(_("Validate"), gtk.RESPONSE_OK)
189 input = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
190 input.set_property('is-focus', False)
191 note.set_title(_("Verification code from web browser"))
194 note.vbox.add(gtk.Label(_("\nPress 'Validate' once account has\nbeen authorised in web browser.\n")))
200 if prompt and result == gtk.RESPONSE_OK:
201 print input.get_text()
202 return input.get_text()
208 lock = thread.allocate_lock()
210 gobject.idle_add(self.block_for_auth, prompt, True, lock)
215 # -----------------------------------------------------------------------
216 def progress(self, msg, i, j, main = False):
217 """Part of the GUI callback API."""
221 self.progressbar = gtk.ProgressBar()
222 self.progressnote = gtk.Dialog(_("Initialising connections"), self.main_window)
223 self.progressnote.vbox.add(self.progressbar)
224 hildon.hildon_gtk_window_set_progress_indicator(self.progressnote, 1)
226 self.progressnote.show_all()
229 self.progressnote.set_title(_(msg))
230 hildon.hildon_gtk_window_set_progress_indicator(self.progressnote, 0)
232 self.progressbar.set_fraction(float(i) / float(j))
235 self.progressnote.destroy()
239 gobject.idle_add(self.progress, msg, i, j, True)
242 # -----------------------------------------------------------------------
243 def report_error(self, e, prefs = False):
244 if self.progressnote:
245 self.main_window.set_property('sensitive', True)
246 self.progressnote.destroy()
248 hildon.hildon_banner_show_information(self.main_window, '', e)