X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fdc_glade.py;h=49b9bf862c86788b211c914a6355ca4943356255;hb=6ba7868eb3907585a6dce28e11511fad9008a17c;hp=99889c5cd6338ae5764dd226c6f8f83e5dc00d8f;hpb=ce1e43db7cf277d01f71c8e9599dbf1bb4c64883;p=gc-dialer diff --git a/src/dc_glade.py b/src/dc_glade.py index 99889c5..49b9bf8 100755 --- a/src/dc_glade.py +++ b/src/dc_glade.py @@ -29,7 +29,7 @@ import threading import base64 import ConfigParser import itertools -import warnings +import logging import gtk import gtk.glade @@ -42,7 +42,7 @@ import gtk_toolbox def getmtime_nothrow(path): try: return os.path.getmtime(path) - except StandardError: + except Exception: return 0 @@ -130,7 +130,8 @@ class Dialcentral(object): self._window.connect("key-press-event", self._on_key_press) self._window.connect("window-state-event", self._on_window_state_change) else: - pass # warnings.warn("No Hildon", UserWarning, 2) + logging.warning("No hildonization support") + hildonize.set_application_title(self._window, "%s" % constants.__pretty_app_name__) @@ -158,8 +159,8 @@ class Dialcentral(object): """ If something can be done after the UI loads, push it here so it's not blocking the UI """ + # Barebones UI handlers try: - # Barebones UI handlers import null_backend import null_views @@ -176,11 +177,15 @@ class Dialcentral(object): self._recentViews[self._selectedBackendId].enable() self._messagesViews[self._selectedBackendId].enable() self._contactsViews[self._selectedBackendId].enable() + except Exception, e: + with gtk_toolbox.gtk_lock(): + self._errorDisplay.push_exception() - # Setup maemo specifics + # Setup maemo specifics + try: try: import osso - except ImportError: + except (ImportError, OSError): osso = None self._osso = None if osso is not None: @@ -188,25 +193,25 @@ class Dialcentral(object): device = osso.DeviceState(self._osso) device.set_device_state_callback(self._on_device_state_change, 0) else: - pass # warnings.warn("No OSSO", UserWarning, 2) + logging.warning("No device state support") try: import alarm_handler self._alarmHandler = alarm_handler.AlarmHandler() - except ImportError: + except (ImportError, OSError): alarm_handler = None except Exception: with gtk_toolbox.gtk_lock(): self._errorDisplay.push_exception() alarm_handler = None + logging.warning("No notification support") if hildonize.IS_HILDON: import led_handler self._ledHandler = led_handler.LedHandler() - # Setup maemo specifics try: import conic - except ImportError: + except (ImportError, OSError): conic = None self._connection = None if conic is not None: @@ -214,9 +219,13 @@ class Dialcentral(object): self._connection.connect("connection-event", self._on_connection_change, constants.__app_magic__) self._connection.request_connection(conic.CONNECT_FLAG_NONE) else: - pass # warnings.warn("No Internet Connectivity API ", UserWarning) + logging.warning("No connection support") + except Exception, e: + with gtk_toolbox.gtk_lock(): + self._errorDisplay.push_exception() - # Setup costly backends + # Setup costly backends + try: import gv_backend import file_backend import gv_views @@ -226,18 +235,13 @@ class Dialcentral(object): except OSError, e: if e.errno != 17: raise - gcCookiePath = os.path.join(constants._data_path_, "gc_cookies.txt") gvCookiePath = os.path.join(constants._data_path_, "gv_cookies.txt") - self._defaultBackendId = self._guess_preferred_backend(( - (self.GV_BACKEND, gvCookiePath), - )) self._phoneBackends.update({ self.GV_BACKEND: gv_backend.GVDialer(gvCookiePath), }) with gtk_toolbox.gtk_lock(): unifiedDialpad = gv_views.Dialpad(self._widgetTree, self._errorDisplay) - unifiedDialpad.set_number("") self._dialpads.update({ self.GV_BACKEND: unifiedDialpad, }) @@ -265,24 +269,25 @@ class Dialcentral(object): fsContactsPath = os.path.join(constants._data_path_, "contacts") fileBackend = file_backend.FilesystemAddressBookFactory(fsContactsPath) - for backendId in (self.GV_BACKEND, ): - self._dialpads[backendId].number_selected = self._select_action - self._recentViews[backendId].number_selected = self._select_action - self._messagesViews[backendId].number_selected = self._select_action - self._contactsViews[backendId].number_selected = self._select_action - - addressBooks = [ - self._phoneBackends[backendId], - fileBackend, - ] - mergedBook = gv_views.MergedAddressBook(addressBooks, gv_views.MergedAddressBook.advanced_lastname_sorter) - self._contactsViews[backendId].append(mergedBook) - self._contactsViews[backendId].extend(addressBooks) - self._contactsViews[backendId].open_addressbook(*self._contactsViews[backendId].get_addressbooks().next()[0][0:2]) + + self._dialpads[self.GV_BACKEND].number_selected = self._select_action + self._recentViews[self.GV_BACKEND].number_selected = self._select_action + self._messagesViews[self.GV_BACKEND].number_selected = self._select_action + self._contactsViews[self.GV_BACKEND].number_selected = self._select_action + + addressBooks = [ + self._phoneBackends[self.GV_BACKEND], + fileBackend, + ] + mergedBook = gv_views.MergedAddressBook(addressBooks, gv_views.MergedAddressBook.advanced_lastname_sorter) + self._contactsViews[self.GV_BACKEND].append(mergedBook) + self._contactsViews[self.GV_BACKEND].extend(addressBooks) + self._contactsViews[self.GV_BACKEND].open_addressbook(*self._contactsViews[self.GV_BACKEND].get_addressbooks().next()[0][0:2]) callbackMapping = { "on_paste": self._on_paste, "on_refresh": self._on_menu_refresh, + "on_rotate": self._on_menu_rotate, "on_clearcookies_clicked": self._on_clearcookies_clicked, "on_notebook_switch_page": self._on_notebook_switch_page, "on_about_activate": self._on_about_activate, @@ -307,11 +312,11 @@ class Dialcentral(object): config.read(constants._user_settings_) with gtk_toolbox.gtk_lock(): self.load_settings(config) - - self._spawn_attempt_login(2) except Exception, e: with gtk_toolbox.gtk_lock(): self._errorDisplay.push_exception() + finally: + self._spawn_attempt_login(2) def attempt_login(self, numOfAttempts = 10, force = False): """ @@ -330,15 +335,15 @@ class Dialcentral(object): self.refresh_session() serviceId = self._defaultBackendId loggedIn = True - except StandardError, e: - warnings.warn('Session refresh failed with the following message "%s"' % e.message, UserWarning, 2) + except Exception, e: + logging.exception('Session refresh failed with the following message "%s"' % e.message) if not loggedIn: loggedIn, serviceId = self._login_by_user(numOfAttempts) with gtk_toolbox.gtk_lock(): self._change_loggedin_status(serviceId) - except StandardError, e: + except Exception, e: with gtk_toolbox.gtk_lock(): self._errorDisplay.push_exception() @@ -366,10 +371,7 @@ class Dialcentral(object): """ loggedIn = self._phoneBackends[self._defaultBackendId].is_authed() if loggedIn: - warnings.warn( - "Logged into %r through cookies" % self._phoneBackends[self._defaultBackendId], - UserWarning, 2 - ) + logging.info("Logged into %r through cookies" % self._phoneBackends[self._defaultBackendId]) return loggedIn def _login_by_settings(self): @@ -380,10 +382,7 @@ class Dialcentral(object): loggedIn = self._phoneBackends[self._defaultBackendId].login(username, password) if loggedIn: self._credentials = username, password - warnings.warn( - "Logged into %r through settings" % self._phoneBackends[self._defaultBackendId], - UserWarning, 2 - ) + logging.info("Logged into %r through settings" % self._phoneBackends[self._defaultBackendId]) return loggedIn def _login_by_user(self, numOfAttempts): @@ -391,27 +390,21 @@ class Dialcentral(object): @note This must be run outside of the UI lock """ loggedIn, (username, password) = False, self._credentials - tmpServiceId = self.NULL_BACKEND + tmpServiceId = self.GV_BACKEND for attemptCount in xrange(numOfAttempts): if loggedIn: break - availableServices = ( - (self.GV_BACKEND, "Google Voice"), - ) with gtk_toolbox.gtk_lock(): - credentials = self._credentialsDialog.request_credentials_from( - availableServices, defaultCredentials = self._credentials + credentials = self._credentialsDialog.request_credentials( + defaultCredentials = self._credentials ) - tmpServiceId, username, password = credentials + username, password = credentials loggedIn = self._phoneBackends[tmpServiceId].login(username, password) if loggedIn: serviceId = tmpServiceId self._credentials = username, password - warnings.warn( - "Logged into %r through user request" % self._phoneBackends[serviceId], - UserWarning, 2 - ) + logging.info("Logged into %r through user request" % self._phoneBackends[serviceId]) else: serviceId = self.NULL_BACKEND @@ -457,7 +450,7 @@ class Dialcentral(object): @note UI Thread """ try: - self._defaultBackendId = int(config.get(constants.__pretty_app_name__, "active")) + self._defaultBackendId = config.getint(constants.__pretty_app_name__, "active") blobs = ( config.get(constants.__pretty_app_name__, "bin_blob_%i" % i) for i in xrange(len(self._credentials)) @@ -470,21 +463,25 @@ class Dialcentral(object): if self._alarmHandler is not None: self._alarmHandler.load_settings(config, "alarm") + + previousOrientation = config.getint(constants.__pretty_app_name__, "orientation") + if previousOrientation == gtk.ORIENTATION_HORIZONTAL: + hildonize.window_to_landscape(self._window) + elif previousOrientation == gtk.ORIENTATION_VERTICAL: + hildonize.window_to_portrait(self._window) except ConfigParser.NoOptionError, e: - warnings.warn( + logging.exception( "Settings file %s is missing section %s" % ( constants._user_settings_, e.section, ), - stacklevel=2 ) except ConfigParser.NoSectionError, e: - warnings.warn( + logging.exception( "Settings file %s is missing section %s" % ( constants._user_settings_, e.section, ), - stacklevel=2 ) for backendId, view in itertools.chain( @@ -498,20 +495,18 @@ class Dialcentral(object): try: view.load_settings(config, sectionName) except ConfigParser.NoOptionError, e: - warnings.warn( + logging.exception( "Settings file %s is missing section %s" % ( constants._user_settings_, e.section, ), - stacklevel=2 ) except ConfigParser.NoSectionError, e: - warnings.warn( + logging.exception( "Settings file %s is missing section %s" % ( constants._user_settings_, e.section, ), - stacklevel=2 ) def save_settings(self, config): @@ -520,6 +515,7 @@ class Dialcentral(object): """ config.add_section(constants.__pretty_app_name__) config.set(constants.__pretty_app_name__, "active", str(self._selectedBackendId)) + config.set(constants.__pretty_app_name__, "orientation", str(int(gtk_toolbox.get_screen_orientation()))) for i, value in enumerate(self._credentials): blob = base64.b64encode(value) config.set(constants.__pretty_app_name__, "bin_blob_%i" % i, blob) @@ -538,14 +534,6 @@ class Dialcentral(object): config.add_section(sectionName) view.save_settings(config, sectionName) - def _guess_preferred_backend(self, backendAndCookiePaths): - modTimeAndPath = [ - (getmtime_nothrow(path), backendId, path) - for backendId, path in backendAndCookiePaths - ] - modTimeAndPath.sort() - return modTimeAndPath[-1][1] - def _save_settings(self): """ @note Thread Agnostic @@ -585,172 +573,220 @@ class Dialcentral(object): @note Hildon specific """ - if memory_low: - for backendId in self.BACKENDS: - self._phoneBackends[backendId].clear_caches() - self._contactsViews[self._selectedBackendId].clear_caches() - gc.collect() + try: + if memory_low: + for backendId in self.BACKENDS: + self._phoneBackends[backendId].clear_caches() + self._contactsViews[self._selectedBackendId].clear_caches() + gc.collect() - if save_unsaved_data or shutdown: - self._save_settings() + if save_unsaved_data or shutdown: + self._save_settings() + except Exception, e: + self._errorDisplay.push_exception() def _on_connection_change(self, connection, event, magicIdentifier): """ @note Hildon specific """ - import conic - - status = event.get_status() - error = event.get_error() - iap_id = event.get_iap_id() - bearer = event.get_bearer_type() - - if status == conic.STATUS_CONNECTED: - if self._initDone: - self._spawn_attempt_login(2) - elif status == conic.STATUS_DISCONNECTED: - if self._initDone: - self._defaultBackendId = self._selectedBackendId - self._change_loggedin_status(self.NULL_BACKEND) + try: + import conic + + status = event.get_status() + error = event.get_error() + iap_id = event.get_iap_id() + bearer = event.get_bearer_type() + + if status == conic.STATUS_CONNECTED: + if self._initDone: + self._spawn_attempt_login(2) + elif status == conic.STATUS_DISCONNECTED: + if self._initDone: + self._defaultBackendId = self._selectedBackendId + self._change_loggedin_status(self.NULL_BACKEND) + except Exception, e: + self._errorDisplay.push_exception() def _on_window_state_change(self, widget, event, *args): """ @note Hildon specific """ - if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN: - self._isFullScreen = True - else: - self._isFullScreen = False + try: + if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN: + self._isFullScreen = True + else: + self._isFullScreen = False + except Exception, e: + self._errorDisplay.push_exception() def _on_key_press(self, widget, event, *args): """ @note Hildon specific """ - if event.keyval == gtk.keysyms.F6: - if self._isFullScreen: - self._window.unfullscreen() - else: - self._window.fullscreen() + try: + if event.keyval == gtk.keysyms.F6: + if self._isFullScreen: + self._window.unfullscreen() + else: + self._window.fullscreen() + except Exception, e: + self._errorDisplay.push_exception() def _on_clearcookies_clicked(self, *args): - self._phoneBackends[self._selectedBackendId].logout() - self._accountViews[self._selectedBackendId].clear() - self._recentViews[self._selectedBackendId].clear() - self._messagesViews[self._selectedBackendId].clear() - self._contactsViews[self._selectedBackendId].clear() - self._change_loggedin_status(self.NULL_BACKEND) - - self._spawn_attempt_login(2, True) + try: + self._phoneBackends[self._selectedBackendId].logout() + self._accountViews[self._selectedBackendId].clear() + self._recentViews[self._selectedBackendId].clear() + self._messagesViews[self._selectedBackendId].clear() + self._contactsViews[self._selectedBackendId].clear() + self._change_loggedin_status(self.NULL_BACKEND) + + self._spawn_attempt_login(2, True) + except Exception, e: + self._errorDisplay.push_exception() def _on_notebook_switch_page(self, notebook, page, pageIndex): - self._reset_tab_refresh() - - didRecentUpdate = False - didMessagesUpdate = False - - if pageIndex == self.RECENT_TAB: - didRecentUpdate = self._recentViews[self._selectedBackendId].update() - elif pageIndex == self.MESSAGES_TAB: - didMessagesUpdate = self._messagesViews[self._selectedBackendId].update() - elif pageIndex == self.CONTACTS_TAB: - self._contactsViews[self._selectedBackendId].update() - elif pageIndex == self.ACCOUNT_TAB: - self._accountViews[self._selectedBackendId].update() - - if didRecentUpdate or didMessagesUpdate: - if self._ledHandler is not None: - self._ledHandler.off() + try: + self._reset_tab_refresh() + + didRecentUpdate = False + didMessagesUpdate = False + + if pageIndex == self.RECENT_TAB: + didRecentUpdate = self._recentViews[self._selectedBackendId].update() + elif pageIndex == self.MESSAGES_TAB: + didMessagesUpdate = self._messagesViews[self._selectedBackendId].update() + elif pageIndex == self.CONTACTS_TAB: + self._contactsViews[self._selectedBackendId].update() + elif pageIndex == self.ACCOUNT_TAB: + self._accountViews[self._selectedBackendId].update() + + if didRecentUpdate or didMessagesUpdate: + if self._ledHandler is not None: + self._ledHandler.off() + except Exception, e: + self._errorDisplay.push_exception() def _set_tab_refresh(self, *args): - pageIndex = self._notebook.get_current_page() - child = self._notebook.get_nth_page(pageIndex) - self._notebook.get_tab_label(child).set_text("Refresh?") + try: + pageIndex = self._notebook.get_current_page() + child = self._notebook.get_nth_page(pageIndex) + self._notebook.get_tab_label(child).set_text("Refresh?") + except Exception, e: + self._errorDisplay.push_exception() return False def _reset_tab_refresh(self, *args): - pageIndex = self._notebook.get_current_page() - child = self._notebook.get_nth_page(pageIndex) - self._notebook.get_tab_label(child).set_text(self._originalCurrentLabels[pageIndex]) + try: + pageIndex = self._notebook.get_current_page() + child = self._notebook.get_nth_page(pageIndex) + self._notebook.get_tab_label(child).set_text(self._originalCurrentLabels[pageIndex]) + except Exception, e: + self._errorDisplay.push_exception() return False def _on_tab_refresh(self, *args): - self._refresh_active_tab() - self._reset_tab_refresh() + try: + self._refresh_active_tab() + self._reset_tab_refresh() + except Exception, e: + self._errorDisplay.push_exception() return False def _on_sms_clicked(self, number, message): - assert number, "No number specified" - assert message, "Empty message" try: - loggedIn = self._phoneBackends[self._selectedBackendId].is_authed() - except StandardError, e: - loggedIn = False - self._errorDisplay.push_exception() - return + assert number, "No number specified" + assert message, "Empty message" + try: + loggedIn = self._phoneBackends[self._selectedBackendId].is_authed() + except Exception, e: + loggedIn = False + self._errorDisplay.push_exception() + return - if not loggedIn: - self._errorDisplay.push_message( - "Backend link with grandcentral is not working, please try again" - ) - return + if not loggedIn: + self._errorDisplay.push_message( + "Backend link with grandcentral is not working, please try again" + ) + return - dialed = False - try: - self._phoneBackends[self._selectedBackendId].send_sms(number, message) - dialed = True - except StandardError, e: - self._errorDisplay.push_exception() - except ValueError, e: - self._errorDisplay.push_exception() + dialed = False + try: + self._phoneBackends[self._selectedBackendId].send_sms(number, message) + dialed = True + except Exception, e: + self._errorDisplay.push_exception() - if dialed: - self._dialpads[self._selectedBackendId].clear() + if dialed: + self._dialpads[self._selectedBackendId].clear() + except Exception, e: + self._errorDisplay.push_exception() def _on_dial_clicked(self, number): - assert number, "No number to call" try: - loggedIn = self._phoneBackends[self._selectedBackendId].is_authed() - except StandardError, e: - loggedIn = False - self._errorDisplay.push_exception() - return + assert number, "No number to call" + try: + loggedIn = self._phoneBackends[self._selectedBackendId].is_authed() + except Exception, e: + loggedIn = False + self._errorDisplay.push_exception() + return - if not loggedIn: - self._errorDisplay.push_message( - "Backend link with grandcentral is not working, please try again" - ) - return + if not loggedIn: + self._errorDisplay.push_message( + "Backend link with grandcentral is not working, please try again" + ) + return - dialed = False - try: - assert self._phoneBackends[self._selectedBackendId].get_callback_number() != "", "No callback number specified" - self._phoneBackends[self._selectedBackendId].dial(number) - dialed = True - except StandardError, e: - self._errorDisplay.push_exception() - except ValueError, e: - self._errorDisplay.push_exception() + dialed = False + try: + assert self._phoneBackends[self._selectedBackendId].get_callback_number() != "", "No callback number specified" + self._phoneBackends[self._selectedBackendId].dial(number) + dialed = True + except Exception, e: + self._errorDisplay.push_exception() - if dialed: - self._dialpads[self._selectedBackendId].clear() + if dialed: + self._dialpads[self._selectedBackendId].clear() + except Exception, e: + self._errorDisplay.push_exception() def _on_menu_refresh(self, *args): - self._refresh_active_tab() + try: + self._refresh_active_tab() + except Exception, e: + self._errorDisplay.push_exception() + + def _on_menu_rotate(self, *args): + try: + orientation = gtk_toolbox.get_screen_orientation() + if orientation == gtk.ORIENTATION_HORIZONTAL: + hildonize.window_to_portrait(self._window) + elif orientation == gtk.ORIENTATION_VERTICAL: + hildonize.window_to_landscape(self._window) + except Exception, e: + self._errorDisplay.push_exception() def _on_paste(self, *args): - contents = self._clipboard.wait_for_text() - self._dialpads[self._selectedBackendId].set_number(contents) + try: + contents = self._clipboard.wait_for_text() + self._dialpads[self._selectedBackendId].set_number(contents) + except Exception, e: + self._errorDisplay.push_exception() def _on_about_activate(self, *args): - dlg = gtk.AboutDialog() - dlg.set_name(constants.__pretty_app_name__) - dlg.set_version(constants.__version__) - dlg.set_copyright("Copyright 2008 - LGPL") - dlg.set_comments("Dialcentral is a touch screen enhanced interface to your GoogleVoice/Grandcentral account. This application is not affiliated with Google in any way") - dlg.set_website("http://gc-dialer.garage.maemo.org/") - dlg.set_authors(["", "Eric Warnke ", "Ed Page "]) - dlg.run() - dlg.destroy() + try: + dlg = gtk.AboutDialog() + dlg.set_name(constants.__pretty_app_name__) + dlg.set_version("%s-%d" % (constants.__version__, constants.__build__)) + dlg.set_copyright("Copyright 2008 - LGPL") + dlg.set_comments("Dialcentral is a touch screen enhanced interface to your GoogleVoice/Grandcentral account. This application is not affiliated with Google in any way") + dlg.set_website("http://gc-dialer.garage.maemo.org/") + dlg.set_authors(["", "Eric Warnke ", "Ed Page "]) + dlg.run() + dlg.destroy() + except Exception, e: + self._errorDisplay.push_exception() def run_doctest(): @@ -782,21 +818,25 @@ class DummyOptions(object): if __name__ == "__main__": - if len(sys.argv) > 1: - try: - import optparse - except ImportError: - optparse = None - - if optparse is not None: - parser = optparse.OptionParser() - parser.add_option("-t", "--test", action="store_true", dest="test", help="Run tests") - (commandOptions, commandArgs) = parser.parse_args() - else: - commandOptions = DummyOptions() - commandArgs = [] + logging.basicConfig(level=logging.DEBUG) + try: + if len(sys.argv) > 1: + try: + import optparse + except ImportError: + optparse = None - if commandOptions.test: - run_doctest() - else: - run_dialpad() + if optparse is not None: + parser = optparse.OptionParser() + parser.add_option("-t", "--test", action="store_true", dest="test", help="Run tests") + (commandOptions, commandArgs) = parser.parse_args() + else: + commandOptions = DummyOptions() + commandArgs = [] + + if commandOptions.test: + run_doctest() + else: + run_dialpad() + finally: + logging.shutdown()