class PreferencesWindow: ## CONSTRUCTOR ## def __init__(self): self.conf = Configuration() self.win = gtk.Window() self.win.set_title("Google Voice Notifer Preferences") main_box = gtk.VBox() self.win.add(main_box) prefs_table = gtk.Table(rows=3, columns=2) main_box.add(prefs_table) uname_lbl = gtk.Label("Username:"******"Password: "******"Update interval: ") prefs_table.attach(update_lbl, 0, 1, 2, 3) self.uname_ety = gtk.Entry() prefs_table.attach(self.uname_ety, 1, 2, 0, 1) self.passwd_ety = gtk.Entry() self.passwd_ety.set_visibility(False) prefs_table.attach(self.passwd_ety, 1, 2, 1, 2) self.update_ety = gtk.Entry() # TODO: make spinbox prefs_table.attach(self.update_ety, 1, 2, 2, 3) btn_box = gtk.HBox() main_box.add(btn_box) self.ok_btn = gtk.Button("OK") self.cancel_btn = gtk.Button("Cancel") btn_box.add(self.ok_btn) btn_box.add(self.cancel_btn) self.ok_btn.connect("activate", self.on_ok_btn_activate) self.cancel_btn.connect("activate", self.on_cancel_btn_activate) ## PUBLIC METHODS ## def show(self): self.uname_ety.set_text(self.conf.get_username() or "") self.passwd_ety.set_text(self.conf.get_password() or "") self.update_ety.set_text(str(self.conf.get_updateinterval())) # TODO: don't show or reset if already here. self.win.show_all() ## EVENT HANDLERS ## def on_ok_btn_activate(self, button, data=None): self.conf.set_username(self.uname_ety.get_text()) self.conf.set_password(self.passwd_ety.get_text()) self.conf.set_updateinterval(int(self.update_ety.get_text())) # FIXME: not going away! self.win.hide_all() self.win.destroy() def on_cancel_btn_activate(self, button, data=None): # FIXME: not going away! self.win.hide_all() self.win.destroy()
class Notifier(): already_notified = [] def main(self): # Start update loop and run it once manually. self.update_from_gv() self.update_loop_source = gobject.timeout_add(self.conf.get_updateinterval(), self.update_from_gv) # Enter the main loop. gtk.main() def __init__(self): # Load configuration stuff. self.conf = Configuration() # Config the status icon. self.statusicon = gtk.StatusIcon() # TODO: set better icon. self.statusicon.set_from_stock("gtk-directory") # Make a menu for popping up later. self.popup_menu = self.make_menu() # Setup GV client. # TODO: allow first-time setup. username = self.conf.get_username() password = self.conf.get_password() self.gv = GoogleVoice(username, password) self.gv.login() # Connect event handlers. self.statusicon.connect("activate", self.on_status_activate) self.statusicon.connect("popup-menu", self.on_status_popup) def make_menu(self): menu = gtk.Menu() self.agr = gtk.AccelGroup() #self.add_accel_group(self.agr) pref_item = self.make_menu_item(menu, self.on_pref_item_activate, accel_key="P", icon=gtk.STOCK_PREFERENCES) quit_item = self.make_menu_item(menu, self.on_quit_item_activate, accel_key="Q", icon=gtk.STOCK_QUIT) return menu def make_menu_item(self, formenu, activate_cb, label=None, icon=None, accel_key=None, accel_grp=None): if icon: agr = accel_grp or self.agr item = gtk.ImageMenuItem(icon, agr) k, m = gtk.accelerator_parse(accel_key) item.add_accelerator("activate", agr, k, m, gtk.ACCEL_VISIBLE) elif label: item = gtk.MenuItem(label) else: # TODO: throw error return item.connect("activate", activate_cb) formenu.append(item) item.show() return item def update_from_gv(self): try: self.gv.update() self.make_notifications() except (TooManyFailuresError): sys.stderr.write( 'Too many failures updating inbox. Waiting before next round of attempts.\n') self.display_error() return True # Make GTK run the update function again. def display_error(self): print('FIXME/TODO: implement display_error()!') def make_notifications(self): unread = self.gv.get_unread_msgs() unread_cnt = len(unread) if unread_cnt != self.gv.get_unread_msgs_count(): print('[Warning] sanity check failed: unread_cnt != self.gv.get_unread_msgs_count()') self.statusicon.set_tooltip("%d unread messages." % unread_cnt) self.statusicon.set_blinking(unread_cnt > 0) # TODO: change to a different icon instead! for msg in unread: if msg.id not in self.already_notified: # TODO: what if icon is remote? self.already_notified.append(msg.id) n = pynotify.Notification("New Google Voice Message", msg.markup(), msg.icon()) n.attach_to_status_icon(self.statusicon) n.set_urgency(pynotify.URGENCY_NORMAL) n.set_timeout(3000) n.show() ## EVENT HANDLERS ## def on_status_activate(self, icon, user_data=None): pass def on_status_popup(self, icon, button, activate_time, user_data=None): self.popup_menu.popup(None, None, None, button, activate_time, None) def on_pref_item_activate(self, item, user_data=None): # Load the preferences window. prefs_win = PreferencesWindow() prefs_win.show() def on_quit_item_activate(self, item, user_data=None): gtk.main_quit()