Add v0.0.1 of Hermes from source tarball
[hermes] / package / src / gui.py
1 #!/usr/bin/env python
2
3 import gtk, gobject
4 import gnome.gconf
5 import hildon, osso
6 import time
7 import thread
8 from hermes import Hermes
9
10 gobject.threads_init()
11
12 class HermesGUI:
13   """Provides the GUI for Hermes, allowing the syncing of Facebook and
14      Twitter friends' information with the Evolution contacts' database.
15        
16      Copyright (c) Andrew Flegg <andrew@bleb.org> 2009.
17      Released under the Artistic Licence."""
18
19
20   # -----------------------------------------------------------------------
21   def __init__(self):
22     """Constructor. Initialises the gconf connection."""
23     self.gc = gnome.gconf.client_get_default()
24
25
26   # -----------------------------------------------------------------------
27   def doSync(self, widget, force, main = True):
28     if main and not self.get_use_facebook() and not self.get_use_twitter():
29       saved = self.open_prefs()
30       if saved == gtk.RESPONSE_DELETE_EVENT:
31         return
32
33     if main:
34       self.window.set_property('sensitive', False)
35       thread.start_new_thread(self.doSync, (widget, force, False))
36     else:
37       try:
38         fb2c = Hermes(self,
39                       twitter = (self.get_use_twitter() and self.get_twitter_credentials()) or None,
40                       facebook = self.get_use_facebook())
41         fb2c.load_friends()
42         fb2c.sync_contacts(resync = force)
43         gobject.idle_add(hildon.hildon_banner_show_information, self.window, '', "Updated %d contacts" % (len(fb2c.updated)))
44         gobject.idle_add(self.window.set_property, 'sensitive', True)
45       except Exception, e:
46         print e
47         gobject.idle_add(self.report_error, 'Something went wrong: ' + e.message)
48
49
50   # -----------------------------------------------------------------------
51   def open_prefs(self, widget = None):
52     dialog = gtk.Dialog('Accounts', self.window)
53     dialog.add_button('Save', gtk.RESPONSE_OK)
54
55     use_facebook = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
56     use_facebook.set_label('Use Facebook')
57     use_facebook.set_active(self.get_use_facebook())
58     dialog.vbox.add(use_facebook)
59
60     use_twitter = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
61     use_twitter.set_label('Use Twitter')
62     use_twitter.set_active(self.get_use_twitter())
63     dialog.vbox.add(use_twitter)
64
65     tw_indent = gtk.HBox()
66     tw_user = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
67     tw_user.set_property('hildon-input-mode', gtk.HILDON_GTK_INPUT_MODE_FULL)
68     tw_user.set_placeholder("Username")
69     tw_user.set_property('is-focus', False)
70     tw_user.set_text(self.get_twitter_credentials()[0])
71     self.sync_edit(use_twitter, tw_user)
72     use_twitter.connect('toggled', self.sync_edit, tw_user)
73     tw_indent.pack_start(tw_user, padding=48)
74     dialog.vbox.add(tw_indent)
75
76     tw_indent = gtk.HBox()
77     tw_pass = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
78     tw_pass.set_placeholder("Password")
79     tw_pass.set_property('hildon-input-mode', gtk.HILDON_GTK_INPUT_MODE_FULL |
80                                               gtk.HILDON_GTK_INPUT_MODE_INVISIBLE)
81     tw_pass.set_text(self.get_twitter_credentials()[1])
82     self.sync_edit(use_twitter, tw_pass)
83     use_twitter.connect('toggled', self.sync_edit, tw_pass)
84     tw_indent.pack_start(tw_pass, padding=48)
85     dialog.vbox.add(tw_indent)
86
87     dialog.show_all()
88     result = dialog.run()
89     dialog.hide()
90     if result == gtk.RESPONSE_OK:
91       self.set_use_facebook(use_facebook.get_active())
92       self.set_use_twitter(use_twitter.get_active(), tw_user.get_text(), tw_pass.get_text())
93
94     return result
95     
96     
97   # -----------------------------------------------------------------------
98   def sync_edit(self, use_twitter, edit):
99     edit.set_property('sensitive', use_twitter.get_active())
100
101
102   # -----------------------------------------------------------------------
103   def need_auth(self, main = False):
104     if main:
105       hildon.hildon_banner_show_information(self.window, '', "Need to authenticate with Facebook")
106     else:
107       gobject.idle_add(self.need_auth, True)
108     
109
110   # -----------------------------------------------------------------------
111   def block_for_auth(self, main = False, lock = None):
112     if main:
113       note = gtk.Dialog('Facebook authorisation', self.window)
114       note.add_button("Validate", gtk.RESPONSE_OK)
115       note.vbox.add(gtk.Label("\nPress 'Validate' once Facebook has\nbeen authenticated in web browser.\n"))
116
117       note.show_all()
118       result = note.run()
119       note.hide()
120       lock.release()
121       
122     else:
123       time.sleep(2)
124       lock = thread.allocate_lock()
125       lock.acquire()
126       gobject.idle_add(self.block_for_auth, True, lock)
127       lock.acquire()
128       lock.release()
129
130
131   # -----------------------------------------------------------------------
132   def progress(self, i, j, main = False):
133     if main:
134       if i == 0:
135         self.progressbar = gtk.ProgressBar()
136         self.progressnote = gtk.Dialog("Fetching friends' info", self.window)
137         self.progressnote.vbox.add(self.progressbar)
138         hildon.hildon_gtk_window_set_progress_indicator(self.progressnote, 1)
139         
140         self.progressnote.show_all()
141         
142       elif i < j:
143         if i == 1:
144           self.progressnote.set_title("Updating contacts")
145           hildon.hildon_gtk_window_set_progress_indicator(self.progressnote, 0)
146           
147         self.progressbar.set_fraction(float(i) / float(j))
148         
149       else:
150         self.progressnote.destroy()
151         
152       print i,j
153     else:
154       gobject.idle_add(self.progress, i, j, True)
155
156
157   # -----------------------------------------------------------------------
158   def report_error(self, e):
159     hildon.hildon_banner_show_information(self.window, '', e)
160
161
162   # -----------------------------------------------------------------------
163   def main(self):
164     # -- Window and app...
165     #
166     self.app = hildon.Program()
167     self.window = hildon.Window()
168     gtk.set_application_name('Hermes')
169     osso_context = osso.Context('org.maemo.hermes', '0.0.1', False)
170     self.app.add_window(self.window)
171
172     self.window.connect("delete-event", gtk.main_quit)
173
174     # -- Main window buttons...
175     #
176     box = gtk.HButtonBox()
177     self.window.add(box)
178     
179     box.set_property('layout-style', gtk.BUTTONBOX_SPREAD)
180     button = hildon.Button(gtk.HILDON_SIZE_THUMB_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
181                            title = 'Retrieve', value = "Get contacts' missing info")
182     button.set_property('width-request', 250)
183     button.connect('clicked', self.doSync, False)
184     box.add(button)
185
186     button = hildon.Button(gtk.HILDON_SIZE_THUMB_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL,
187                            title = 'Update', value = "Update contacts' info")
188     button.set_property('width-request', 250)
189     button.connect('clicked', self.doSync, True)
190     box.add(button)
191     
192     # -- Application menu...
193     #
194     menu = hildon.AppMenu()
195     button = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
196     button.set_label("Accounts")
197     button.connect("clicked", self.open_prefs)
198     menu.append(button)
199     menu.show_all()
200     self.window.set_app_menu(menu)
201   
202     self.window.show_all()
203     gtk.main()
204
205
206   def get_use_facebook(self):
207     return self.gc.get_bool("/apps/maemo/hermes/use_facebook")
208
209
210   def set_use_facebook(self, value):
211     self.gc.set_bool("/apps/maemo/hermes/use_facebook", value)
212
213
214   def get_use_twitter(self):
215     return self.gc.get_bool("/apps/maemo/hermes/use_twitter")
216
217
218   def set_use_twitter(self, value, user, password):
219     self.gc.set_bool("/apps/maemo/hermes/use_twitter", value)
220     self.gc.set_string("/apps/maemo/hermes/twitter_user", user)
221     self.gc.set_string("/apps/maemo/hermes/twitter_pwd", password)
222     
223   
224   def get_twitter_credentials(self):
225     return (self.gc.get_string("/apps/maemo/hermes/twitter_user") or '',
226             self.gc.get_string("/apps/maemo/hermes/twitter_pwd") or '')
227
228
229 # -------------------------------------------------------------------------
230 if __name__ == '__main__':
231   HermesGUI().main()
232