bigboard r7269 - in trunk: . bigboard



Author: marinaz
Date: Wed Mar 19 17:51:21 2008
New Revision: 7269
URL: http://svn.gnome.org/viewvc/bigboard?rev=7269&view=rev

Log:
Provide a GConf schema template for the accounts in /apps/bigboard/accounts directory. Associate new account entries with that schema.

Re-work the way we maintain accounts to sync the accounts in GConf with the ones provided by server for the account types that are provided by server. GConf preferences might indicate if the account is enabled or disabled, and should be synced with GConf sync. 

Add code to get Google accounts for the user from the server.

Use the weblogin driver to check if a password is available for a specified account, but no longer use it for supplying additional accounts. 


Modified:
   trunk/bigboard.schemas.in
   trunk/bigboard/accounts.py
   trunk/bigboard/accounts_dialog.py
   trunk/bigboard/google.py
   trunk/bigboard/google_stock.py

Modified: trunk/bigboard.schemas.in
==============================================================================
--- trunk/bigboard.schemas.in	(original)
+++ trunk/bigboard.schemas.in	Wed Mar 19 17:51:21 2008
@@ -83,5 +83,42 @@
                 <long>The orientation of the Bigboard panel. Possible values are "west" or "east". The key specifies which screen edge the panel is on.</long>
       </locale>
     </schema> 
+    <schema>
+      <key>/schemas/apps/bigboard/accounts/TEMPLATE/enabled</key>
+      <owner>bigboard</owner>
+      <type>bool</type>
+      <default>TRUE</default>
+      <locale name="C">
+		<short>Whether the account is enabled by the user to be utilized by bigboard stocks.</short>
+      </locale>
+    </schema>
+    <schema>
+      <key>/schemas/apps/bigboard/accounts/TEMPLATE/kind</key>
+      <owner>bigboard</owner>
+      <type>string</type>
+      <default></default>
+      <locale name="C">
+                <short>The type of the account.</short>
+      </locale>
+    </schema> 
+    <schema>
+      <key>/schemas/apps/bigboard/accounts/TEMPLATE/username</key>
+      <owner>bigboard</owner>
+      <type>string</type>
+      <default></default>
+      <locale name="C">
+                <short>The username for the account.</short>
+      </locale>
+    </schema> 
+    <schema>
+      <key>/schemas/apps/bigboard/accounts/TEMPLATE/url</key>
+      <owner>bigboard</owner>
+      <type>string</type>
+      <default></default>
+      <locale name="C">
+                <short>The domain for the account.</short>
+                <long>The domain for the account. If the account is identified by an e-mail address, the username would contain the part before the @ sign, and the url would contain the part after the @ sign.</long>
+      </locale>
+    </schema> 
   </schemalist>
 </gconfschemafile>

Modified: trunk/bigboard/accounts.py
==============================================================================
--- trunk/bigboard/accounts.py	(original)
+++ trunk/bigboard/accounts.py	Wed Mar 19 17:51:21 2008
@@ -1,6 +1,6 @@
 import sys, logging, base64
 
-import gobject, gconf, dbus
+import gobject, gconf, dbus, os, copy
 
 from ddm import DataModel
 import bigboard.globals as globals
@@ -11,15 +11,24 @@
 
 _logger = logging.getLogger("bigboard.Accounts")
 
+_accounts_schema_dir = "/schemas/apps/bigboard/accounts/TEMPLATE"
+
 class AccountKind(object):
-    def __init__(self, id):
+    def __init__(self, id, provided_by_server):
         super(AccountKind, self).__init__()        
         self.__id = id
+        self.__provided_by_server = provided_by_server
 
     def get_id(self):
         return self.__id
 
-KIND_GOOGLE = AccountKind("google")
+    def get_provided_by_server(self):
+        return self.__provided_by_server
+
+    def __str__(self):
+        return "<AccountKind:%s, provided_by_server:%s>" % (self.get_id(), self.get_provided_by_server())
+
+KIND_GOOGLE = AccountKind("google", True)
 
 def kind_from_string(s):
     for kind in [KIND_GOOGLE]:
@@ -53,10 +62,10 @@
     def get_username_as_google_email(self):
         if self.__username == '':
             return self.__username
-        elif '@' not in self.__username:
+        elif not self.__url or self.__url == '':
             return self.__username + '@gmail.com'
         else:
-            return self.__username
+            return self.__username + '@' + self.__url
 
     def get_password(self):
         return self.__password
@@ -71,7 +80,19 @@
         return self.__gconf_dir
 
     def _set_gconf_dir(self, gconf_dir):
-        self.__gconf_dir = gconf_dir
+        if self.__gconf_dir != gconf_dir:
+            self.__gconf_dir = gconf_dir
+            self.emit('changed')              
+
+    def _set_enabled(self, enabled):
+        if self.__enabled != enabled:  
+            self.__enabled = enabled
+            self.emit('changed')              
+
+    def _set_password(self, password):
+        if self.__password != password:
+            self.__password = password
+            self.emit('changed') 
 
     def _update_from_origin(self, new_props):
         """This is the only way to modify an Account object. It should be invoked only on change notification or refreshed data from the original origin of the account."""
@@ -89,6 +110,30 @@
         if changed:
             self.emit('changed')
 
+
+    def __str__(self):
+        return "<Account userame:%s, url:%s, kind:%s, gconf_dir:%s, enabled:%s>" % (self.get_username(), self.get_url(), str(self.get_kind()), self._get_gconf_dir(), self.get_enabled())
+
+def associate_schema(schema_dir, new_dir):
+    """
+
+    This function is used when dynamically creating a directory in
+    GConf that should be associated with a fixed schema.
+
+    schema_dir -- the directory where the schema is stored
+    new_dir -- the directory to associate the schema with
+
+    """
+    
+    client = gconf.client_get_default()
+    engine = gconf.engine_get_default()
+    _logger.debug("associating schema schema_dir %s" % schema_dir)
+    for entry in client.all_entries(schema_dir):
+        _logger.debug("entry key %s" % entry.get_key())
+        # There is a schema for each individual key, 
+        key = os.path.join(new_dir, os.path.basename(entry.get_key()))
+        engine.associate_schema(key, entry.get_key())
+
 class Accounts(gobject.GObject):
     __gsignals__ = {
         "account-added" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)), 
@@ -98,13 +143,16 @@
     def __init__(self, *args, **kwargs):
         super(Accounts, self).__init__(*args, **kwargs)
 
+        self.__received_response_from_server = False
+
+        self.__model = globals.get_data_model()
+        self.__model.add_ready_handler(self.__on_ready)
+
+        self.__server_accounts = set()
         self.__gconf_accounts = set()
         self.__weblogin_accounts = set()
         self.__enabled_accounts = set()
 
-        ## this is a hash from AccountKind to (username, password) from the weblogindriver
-        self.__weblogin_info = {}
-
         try:
             self.__weblogindriver_proxy = dbus.SessionBus().get_object('org.gnome.WebLoginDriver', '/weblogindriver')
             self.__weblogindriver_proxy.connect_to_signal("SignonChanged",
@@ -125,9 +173,15 @@
 
         self.__reload_from_gconf()
 
-    def __find_weblogin_account_by_kind(self, kind):
+        if self.__model.ready:
+            self.__on_ready()
+
+    def __find_weblogin_account(self, kind, username, url = None):
         for a in self.__weblogin_accounts:
-            if a.get_kind() == kind:
+            _logger.debug("comparing to a weblogin account %s" % a)
+            if a.get_kind() == kind and a.get_username() == username \
+               and (url == None or a.get_url() == url or 
+                    (a.get_kind() == KIND_GOOGLE and url == "gmail.com" and (a.get_url() == None or a.get_url() == ''))):
                 return a
 
         return None
@@ -139,6 +193,21 @@
 
         return None
 
+    def __get_gconf_accounts_by_kind(self, kind):
+        gconf_accounts_by_kind = set()
+        for a in self.__gconf_accounts:
+            if a.get_kind() == kind:
+                gconf_accounts_by_kind.add(a)
+        return gconf_accounts_by_kind 
+
+    def __get_server_accounts_by_kind(self, kind):
+        server_accounts_by_kind = set()
+        for a in self.__server_accounts:
+            if a.get_kind() == kind:
+                server_accounts_by_kind.add(a)
+        return server_accounts_by_kind 
+
+    @log_except(_logger)
     def __update_account(self, account):
 
         _logger.debug("Updating account %s" % (str(account)))
@@ -147,14 +216,18 @@
         ## making a new Account object)
 
         was_enabled = account in self.__enabled_accounts
-        if was_enabled != account.get_enabled():
-            raise Exception("account enabled state messed up")
 
-        fields = { }
+        fields = {}
 
-        ## first, look for the info from our local gconf storage
-        gconf_base = '/apps/bigboard/accounts'
         gconf_dir = account._get_gconf_dir()
+        if account.get_kind().get_provided_by_server() and (account in self.__server_accounts):
+            self.__ensure_account_in_gconf(account)
+        elif account.get_kind().get_provided_by_server() and (account not in self.__server_accounts) and self.__received_response_from_server:
+            #remove gconf dir if one exists, set enabled field to False
+            if gconf_dir:
+                self.__remove_gconf_dir(gconf_dir)  
+
+        ## first, look for the info from our local gconf storage
         if gconf_dir and gconf_dir in self.__gconf_info:
             gconf_info = self.__gconf_info[gconf_dir]
 
@@ -177,26 +250,19 @@
             ## we'd normally set enabled=False in gconf, which would
             ## persist across restarts.
             fields['enabled'] = False
-
             self.__gconf_accounts.remove(account)
 
+        ## after compositing all this information, update our account object
+        account._update_from_origin(fields)
+
         ## second, look at weblogin driver, though we don't want to prefer
         ## its password over keyring, so there's some trickiness
         weblogin_password = None
-        if account.get_kind() in self.__weblogin_info:
-            (username, weblogin_password) = self.__weblogin_info[account.get_kind()]
-            if 'username' not in fields:
-                fields['username'] = username
-
-            ## if account was not disabled explicitly by gconf, we enable it
-            if 'enabled' not in fields:
-                fields['enabled'] = True
-        else:
-            if account in self.__weblogin_accounts:
-                self.__weblogin_accounts.remove(account)
-
-        ## after compositing all this information, update our account object
-        account._update_from_origin(fields)
+        _logger.debug("will look for a weblogin account with kind %s username %s url %s" % (account.get_kind(), account.get_username(), account.get_url()))
+        weblogin_account = self.__find_weblogin_account(account.get_kind(), account.get_username(), account.get_url()) 
+        if weblogin_account:
+            _logger.debug("weblogin account found")
+            weblogin_password = weblogin_account.get_password()
 
         ## use updated information to find password
         fields = {}
@@ -229,19 +295,20 @@
             self.emit('account-removed', account)
         elif not was_enabled and account.get_enabled():
             self.__enabled_accounts.add(account)
-            self.emit('account-added', account)            
-
-    def __ensure_and_update_weblogin_by_kind(self, kind):
-        account = self.__find_weblogin_account_by_kind(kind)
-        added = False
-        if not account:
-            account = Account(kind, enabled=True)
-            self.__weblogin_accounts.add(account)
-            self.__enabled_accounts.add(account)
-        self.__update_account(account)
+            self.emit('account-added', account) 
+           
+    @log_except(_logger)
+    def __remove_gconf_dir(self, gconf_dir):
+        base_key = '/apps/bigboard/accounts/' + gconf_dir
+        success = self.__gconf.recursive_unset(base_key, gconf.UNSET_INCLUDING_SCHEMA_NAMES)
+        _logger.debug("removed gconf dir %s success %s" % (base_key, success))
+        self.__gconf.suggest_sync() 
+        if self.__gconf_info.has_key(gconf_dir):
+            del self.__gconf_info[gconf_dir]
 
-    def __try_ensure_and_update_account_for_gconf_dir(self, gconf_dir):
+    def __try_ensure_and_update_account_for_gconf_dir(self, gconf_dir):         
         account = self.__find_account_by_gconf_dir(gconf_dir)
+        _logger.debug("ensuring account for %s gconf key %s", account, gconf_dir);
         if account:
             self.__update_account(account)
             return
@@ -253,18 +320,20 @@
         gconf_info = self.__gconf_info[gconf_dir]
         if 'kind' not in gconf_info:
             _logger.error("gconf account has no kind setting")
+            self.__remove_gconf_dir(gconf_dir)
             return
         
         kind = kind_from_string(gconf_info['kind'])
         if not kind:
             _logger.error("unknown account kind in gconf")
+            self.__remove_gconf_dir(gconf_dir)
             return
 
-        account = self.__find_weblogin_account_by_kind(kind)
-        if account:
-            account._set_gconf_dir(gconf_dir)
-        else:
-            account = Account(kind, gconf_dir=gconf_dir, enabled=False)
+        # account = self.__find_weblogin_account_by_kind(kind)
+        # if account:
+        #    account._set_gconf_dir(gconf_dir)
+        # else:
+        account = Account(kind, gconf_dir=gconf_dir, enabled=False)
 
         self.__gconf_accounts.add(account)
         
@@ -273,7 +342,93 @@
     def __remove_dirname(self, gconf_key):
         i = gconf_key.rfind('/')
         return gconf_key[i+1:]
-            
+
+    def __on_ready(self):
+        if self.__model.self_resource != None:
+            _logger.debug("will get online desktop accounts")
+            query = self.__model.query_resource(self.__model.self_resource, "googleEnabledEmails +")
+            query.add_handler(self.__on_google_enabled_emails)
+            query.add_error_handler(self.__on_datamodel_error)        
+            query.execute()
+        
+    def __on_datamodel_error(self, code, str):
+        _logger.error("datamodel error %s: %s", code, str)        
+        
+    def __on_google_enabled_emails(self, myself):    
+        _logger.debug("received some google enabled emails")
+        myself.connect(self.__update_google_enabled_emails, 'googleEnabledEmails') 
+        self.__update_google_enabled_emails(myself)
+
+    def __update_google_enabled_emails(self, myself):
+        if not hasattr(myself, 'googleEnabledEmails'):
+            _logger.debug("No googleEnabledEmails in DDM identity")
+            self.__received_response_from_server = True
+            return
+
+        google_accounts = self.__get_server_accounts_by_kind(KIND_GOOGLE) 
+
+        if len(myself.googleEnabledEmails) == 0:
+            _logger.debug("DDM identity has 0 googleEnabledEmails")
+
+        for email in myself.googleEnabledEmails:                        
+            (username, url) = email.split('@', 1)
+            username = str(username)
+            url = str(url) 
+            _logger.debug("got a googleEnabledEmail %s username: %s url: %s", email, username, url)        
+              
+            # if acccount already in the list of server_accounts, don't do anything
+            # if it is new, add it, and update information for it
+            # if it is no longer reurned by the server, remove it and remove it from other
+            # lists, including gconf
+            account_found = False
+            for a in google_accounts:
+                if a.get_kind() == KIND_GOOGLE and a.get_username() == username and \
+                   (a.get_url() == url or a.get_url() == "gmail.com"):
+                   # we found it, we don't need to change anything about it
+                   account_found = True
+                   google_accounts.remove(a)
+                   break
+             
+            if not account_found:             
+                # TODO: decide if we want to check if account is among weblogin_accounts
+                account = Account(KIND_GOOGLE, username=username, url=url)   
+                self.__server_accounts.add(account)
+                # this will add the account to gconf and enabled accounts, and check if 
+                # we have a password for it
+                self.__update_account(account)
+
+        # clear out accounts that are no longer found in the list of accounts of this kind from the server
+        for a in google_accounts:
+            self.__server_accounts.remove(a)
+            # this should remove the account from gconf and gconf_accounts
+            self.__update_account(a)
+
+        self.__received_response_from_server = True
+
+        # make sure that all accounts in gconf correspond to the ones returned from the server;
+        # this will remove old accounts from gconf 
+        google_accounts_in_gconf = self.__get_gconf_accounts_by_kind(KIND_GOOGLE) 
+        _logger.debug("google_accounts_in_gconf size %d" % len(google_accounts_in_gconf))
+        for a in google_accounts_in_gconf:
+            self.__update_account(a)       
+             
+    def __get_gconf_info(self, gconf_dir):
+        base_key = "/apps/bigboard/accounts/" + gconf_dir
+        gconf_info = {}
+        def get_account_prop(gconf, gconf_info, base_key, prop):
+            try:
+                value = gconf.get_value(base_key + '/' + prop)
+            except ValueError:
+                value = None
+            if value:
+                gconf_info[prop] = value
+        get_account_prop(self.__gconf, gconf_info, base_key, 'kind')
+        get_account_prop(self.__gconf, gconf_info, base_key, 'username')
+        get_account_prop(self.__gconf, gconf_info, base_key, 'url')
+        get_account_prop(self.__gconf, gconf_info, base_key, 'enabled')      
+        return gconf_info
+
+    @log_except(_logger)            
     def __reload_from_gconf(self):
         gconf_dirs = self.__gconf.all_dirs('/apps/bigboard/accounts')
 
@@ -282,33 +437,31 @@
         new_gconf_infos = {}
         for gconf_dir in gconf_dirs:
             base_key = gconf_dir
-            gconf_dir = self.__remove_dirname(gconf_dir)
-            
-            gconf_info = {}
-            def get_account_prop(gconf, gconf_info, base_key, prop):
-                try:
-                    value = gconf.get_value(base_key + '/' + prop)
-                except ValueError:
-                    value = None
-                if value:
-                    gconf_info[prop] = value
-            get_account_prop(self.__gconf, gconf_info, base_key, 'kind')
-            get_account_prop(self.__gconf, gconf_info, base_key, 'username')
-            get_account_prop(self.__gconf, gconf_info, base_key, 'url')
-            get_account_prop(self.__gconf, gconf_info, base_key, 'enabled')            
+            gconf_dir = self.__remove_dirname(gconf_dir)            
+            new_gconf_infos[gconf_dir] = self.__get_gconf_info(gconf_dir)
 
-            new_gconf_infos[gconf_dir] = gconf_info
-            
+            # GConf might already have some settings that did not have a schema.
+            # This portion is only for bootstrapping these settings to have a schema.
+            # We check if one of the entries that must be there (username) has a schema,
+            # and associate a schema with the whole directory if it doesn't.
+            username_entry = self.__gconf.get_entry(base_key + '/username', '', True)
+            if username_entry and not username_entry.get_schema_name():
+                associate_schema(_accounts_schema_dir, base_key)              
+            elif not username_entry:
+                _logger.warn("We expected username entry to be in %s, but it was not found" % base_key)
+ 
         self.__gconf_info = new_gconf_infos
 
         ## create any new accounts
-        for gconf_dir in self.__gconf_info.keys():
+        gconf_info_keys = copy.copy(self.__gconf_info.keys())  
+        for gconf_dir in gconf_info_keys:
             self.__try_ensure_and_update_account_for_gconf_dir(gconf_dir)
 
         ## now update any old accounts that are no longer in gconf,
         ## which should result in enabled=False
         for a in self.__gconf_accounts:
             gconf_dir = a._get_gconf_dir()
+            _logger.debug("processing gconf account for %s" % gconf_dir)
             if gconf_dir and gconf_dir not in self.__gconf_info:
                 self.__update_account(a)
         
@@ -316,15 +469,27 @@
     def __on_gconf_change(self, *args):
         _logger.debug("gconf change notify for accounts")
         self.__reload_from_gconf()
-    
+
+    @log_except(_logger)
     def __check_signons(self, signons):
-        for signon in signons:
+        # this processes signons for a specific hostname
+        # TODO: extend this to store signons for different types of accounts once we are ready to support them;
+        #       make sure we store signon information for GAFYD accounts
+        for signon in signons: 
             if 'hint' not in signon: continue
             if signon['hint'] == 'GMail':
                 username = signon['username']
                 password = base64.b64decode(signon['password'])
-                self.__weblogin_info[KIND_GOOGLE] = (username, password)
-                self.__ensure_and_update_account_for_kind(KIND_GOOGLE)
+                _logger.debug("got signon information %s" % str(signon))                
+                account = self.__find_weblogin_account(KIND_GOOGLE, username)
+                _logger.debug("found weblogin account %s" % str(account))
+                if not account:
+                    account = Account(KIND_GOOGLE, enabled=False, username=str(username), password=password)
+                    self.__weblogin_accounts.add(account)
+                    self.__update_account(account)
+                elif password != account.get_password():
+                    account._set_password(password)
+                    self.__update_account(account)
             
     def __recheck_signons(self):
         self.__weblogindriver_proxy.GetSignons(reply_handler=self.__on_get_signons_reply,
@@ -338,6 +503,14 @@
 
     @log_except(_logger)
     def __on_signon_changed(self, signons):
+        # TODO: __on_signon_changed is called with all signons for a given hostname.
+        # However, we need the hostname to be passed in as an argument, since it is needed
+        # for the case when no more signons remain for a given hostname.
+        # We should make this change, but for now, we just never remove existing weblogin accounts.
+        # (The list will be re-created when the bigboard is restarted.) We will update a password
+        # for an existing weblogin account if the updated signon information is passed in here.
+        # Once we make this change, we'll need to make sure to associate the right hostnames with
+        # weblogin accounts, in case they don't match what we store in the url field.
         _logger.debug("signons changed: %s", signons)
         self.__check_signons(signons)
 
@@ -355,45 +528,32 @@
             else:
                 i = i + 1
 
-    def save_account_changes(self, account, new_properties):
-
-        _logger.debug("Saving new props for account %s: %s" % (str(account), str(new_properties.keys())))
-        set_password = False
-
-        ## special-case handling of password since it goes in the keyring
-        if 'password' in new_properties:
-            if 'username' in new_properties:
-                username = new_properties['username']
-            else:
-                username = account.get_username()
-
-            if 'url' in new_properties:
-                url = new_properties['url']
-            else:
-                url = account.get_url()
-
-            k = keyring.get_keyring()
-            
-            k.store_login(kind=account.get_kind().get_id(),
-                          username=username,
-                          url=url,
-                          password=new_properties['password'])
-
-            set_password = True
-
-        ## now do everything else by stuffing it in gconf
-            
+    # new_properties is optional, it should be passed in if there are changes
+    # to an existing account and we will update other data constructs that contain
+    # this account based on the information from gconf
+    def __ensure_account_in_gconf(self, account, new_properties={}):       
         gconf_dir = account._get_gconf_dir()
+        new_gconf_dir = False
+
+        # first see if an account with the same credentials exists in GConf
+        if not gconf_dir:
+            for a in self.__gconf_accounts:
+                if a.get_kind() == account.get_kind() and a.get_username() == account.get_username() and \
+                   a.get_url() == account.get_url():
+                    gconf_dir = a._get_gconf_dir()
+                    account._set_gconf_dir(gconf_dir)
+                    account._set_enabled(a.get_enabled())
+                    self.__gconf_accounts.remove(a)
+                    if a in self.__enabled_accounts:
+                        self.__enabled_accounts.remove(a)
+                        self.emit('account-removed', a)
+                    self.__gconf_accounts.add(account)
+                    break
+        
+        # create a new GConf dir if it is a completely new account    
         if not gconf_dir:
             gconf_dir = self.__find_unused_gconf_dir(account.get_kind())
-
-            ## associate the Account with this new gconf dir.
-            ## basically this means if a weblogindriver account
-            ## is modified, it becomes a gconf account also.
-            ## We would also do this on seeing a new gconf
-            ## dir appear in gconf spontaneously, but doing
-            ## it here ensures that we definitely attach
-            ## to the proper previous Account
+            new_gconf_dir = True
             account._set_gconf_dir(gconf_dir)
             self.__gconf_accounts.add(account)
             
@@ -411,17 +571,61 @@
             else:
                 _logger.error("prop %s with value %s has an unexpected type %s" % (prop, str(value), type(value)))
 
-        set_account_prop(self.__gconf, base_key, 'kind', account.get_kind())
+        if new_gconf_dir:
+            set_account_prop(self.__gconf, base_key, 'kind', account.get_kind())
 
         if 'username' in new_properties:
             set_account_prop(self.__gconf, base_key, 'username', new_properties['username'])
+        elif new_gconf_dir:
+            set_account_prop(self.__gconf, base_key, 'username', account.get_username())
+
         if 'url' in new_properties:
             set_account_prop(self.__gconf, base_key, 'url', new_properties['url'])
-
+        elif new_gconf_dir:
+            set_account_prop(self.__gconf, base_key, 'url', account.get_url())
+  
         ## enable it last, so we ignore the other settings until we do this
         if 'enabled' in new_properties:
             set_account_prop(self.__gconf, base_key, 'enabled', new_properties['enabled'])
+        elif new_gconf_dir:
+             set_account_prop(self.__gconf, base_key, 'enabled', account.get_enabled())
+
+        if new_gconf_dir:
+            associate_schema(_accounts_schema_dir, base_key)
+            self.__gconf_info[gconf_dir]=self.__get_gconf_info(gconf_dir)
+
+    def save_account_changes(self, account, new_properties):
+
+        _logger.debug("Saving new props for account %s: %s" % (str(account), str(new_properties.keys())))
+        set_password = False
+
+        ## special-case handling of password since it goes in the keyring
+        if 'password' in new_properties:
+            if 'username' in new_properties:
+                username = new_properties['username']
+            else:
+                username = account.get_username()
+
+            if 'url' in new_properties:
+                url = new_properties['url']
+            else:
+                url = account.get_url()
 
+            if not url:
+                url=''          
+
+            k = keyring.get_keyring()
+
+            k.store_login(kind=account.get_kind().get_id(),
+                          username=username,
+                          url=url,
+                          password=new_properties['password'])
+
+            set_password = True
+
+        ## now do everything else by stuffing it in gconf
+        self.__ensure_account_in_gconf(account, new_properties)
+      
         ## keyring doesn't have change notification so we have to do the work for it
         if set_password:
             ## this should notice a new password

Modified: trunk/bigboard/accounts_dialog.py
==============================================================================
--- trunk/bigboard/accounts_dialog.py	(original)
+++ trunk/bigboard/accounts_dialog.py	Wed Mar 19 17:51:21 2008
@@ -103,11 +103,14 @@
 
     def __on_account_added(self, accts, a):
         if a.get_kind() == accounts.KIND_GOOGLE and a not in self.__editors_by_account:
+            _logger.debug("account added %s" % a) 
             self.__editors_by_account[a] = AccountEditor(account=a)
             self.vbox.pack_end(self.__editors_by_account[a])            
 
     def __on_account_removed(self, accts, a):
+        _logger.debug("account removed %s" % a) 
         if a in self.__editors_by_account:
+            _logger.debug("will remove")
             editor = self.__editors_by_account[a]
             del self.__editors_by_account[a]
             editor.destroy() ## should remove it from vbox

Modified: trunk/bigboard/google.py
==============================================================================
--- trunk/bigboard/google.py	(original)
+++ trunk/bigboard/google.py	Wed Mar 19 17:51:21 2008
@@ -581,9 +581,14 @@
 
 def get_google_for_account(account):
     global __googles_by_account
+    if not __googles_by_account.has_key(account):
+        _logger.debug("calling refresh googles from get google for account")
+        __refresh_googles(accounts.get_accounts())
+
     return __googles_by_account[account]
 
 def __refresh_googles(a):
+    _logger.debug("refresh googles was called")
     global __googles_by_account    
     gaccounts = a.get_accounts_with_kind(accounts.KIND_GOOGLE)
     new_googles = {}
@@ -611,7 +616,7 @@
     if __initialized:
         return
     __initialized = True
-    
+    _logger.debug("THE google is being initialized")
     a = accounts.get_accounts()
     __refresh_googles(a)
     a.connect('account-added', __on_account_added)

Modified: trunk/bigboard/google_stock.py
==============================================================================
--- trunk/bigboard/google_stock.py	(original)
+++ trunk/bigboard/google_stock.py	Wed Mar 19 17:51:21 2008
@@ -4,6 +4,7 @@
 import bigboard.accounts as accounts
 import accounts_dialog
 import bigboard.libbig.gutil as gutil
+from bigboard.libbig.logutil import log_except
 
 _logger = logging.getLogger("bigboard.Google")
 
@@ -15,23 +16,24 @@
 class GoogleStock(object):
     def __init__(self, action_id, **kwargs):
         super(GoogleStock, self).__init__(**kwargs)
-
+        _logger.debug("in google stock init")
         # A dictionary of authenticated google accounts, with keys that are used
         # to identify those accounts within the stock.
         self.googles = set()
         self.__googles_by_account = {} ## map accounts.Account => google.Google
 
+        _logger.debug("in google stock init action_id is %s", str(action_id))         
         self.__action_id = action_id
 
         self.__connections = gutil.DisconnectSet()
-
         accts = accounts.get_accounts()
         for a in accts.get_accounts_with_kind(accounts.KIND_GOOGLE):
             self.__on_account_added(a)
         id = accts.connect('account-added', lambda accounts, account: self.__on_account_added(account))
         self.__connections.add(accts, id)
         id = accts.connect('account-removed', lambda accounts, account: self.__on_account_removed(account))
-        self.__connections.add(accts, id)        
+        self.__connections.add(accts, id)
+        _logger.debug("done with google stock init")        
 
     ## we can't just override _on_delisted() because of multiple inheritance,
     ## so our subclasses have to override it then call this
@@ -43,15 +45,17 @@
         for a in accts:
             self.__on_account_removed(a)
 
+    @log_except(_logger)
     def __on_account_added(self, acct):
+        _logger.debug("in __on_account_added for %s", str(acct))         
         gobj = google.get_google_for_account(acct)
         gobj.add_poll_action_func(self.__action_id, lambda gobj: self.update_google_data(gobj))
         self.googles.add(gobj)
         self.__googles_by_account[acct] = gobj
-
         ## update_google_data() should be called in the poll action
     
     def __on_account_removed(self, acct):
+        _logger.debug("in __on_account_removed for %s", str(acct))  
         ## we keep our own __googles_by_account because google.get_google_for_account()
         ## will have dropped the Google before this point
         gobj = self.__googles_by_account[acct]



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]