diff src/tools/memory.py @ 412:62b17854254e

database integration: first draft - using SQLite as backend /!\ Not finished yet, break execution. SàT CAN'T LAUNCH PROPERLY IN THE CURRENT STATE
author Goffi <goffi@goffi.org>
date Sun, 30 Oct 2011 23:13:40 +0100
parents 3ed53803b3b3
children dd4caab17008
line wrap: on
line diff
--- a/src/tools/memory.py	Sat Oct 08 21:03:02 2011 +0200
+++ b/src/tools/memory.py	Sun Oct 30 23:13:40 2011 +0100
@@ -27,16 +27,17 @@
 from ConfigParser import SafeConfigParser, NoOptionError, NoSectionError
 from xml.dom import minidom
 from logging import debug, info, warning, error
-import pdb
 from twisted.internet import defer
 from twisted.words.protocols.jabber import jid
 from sat.tools.xml_tools import paramsXml2xmlUI
 from sat.core.default_config import default_config
+from sat.tools.sqlite import SqliteStorage
 
 SAVEFILE_PARAM_XML="/param" #xml parameters template
 SAVEFILE_PARAM_DATA="/param" #individual & general parameters; _ind and _gen suffixes will be added
 SAVEFILE_HISTORY="/history"
 SAVEFILE_PRIVATE="/private"  #file used to store misc values (mainly for plugins)
+SAVEFILE_DATABASE="/sat.db"
 
 class Param():
     """This class manage parameters with xml"""
@@ -75,26 +76,20 @@
         """Load parameters template from file"""
         self.dom = minidom.parse(file)
     
-    def load_data(self, file):
-        """Load parameters data from file"""
-        file_ind = file + '_ind'
-        file_gen = file + '_gen'
-
-        if os.path.exists(file_gen):
-            try:
-                with open(file_gen, 'r') as file_gen_pickle:
-                    self.params_gen=pickle.load(file_gen_pickle)
-                debug(_("general params data loaded"))
-            except:
-                error (_("Can't load general params data !"))
+    def loadGenData(self, storage):
+        """Load general parameters data from storage
+        @param storage: xxxStorage object instance
+        @return: deferred triggered once params are loaded"""
+        return storage.loadGenParams(self.params_gen)
         
-        if os.path.exists(file_ind):
-            try:
-                with open(file_ind, 'r') as file_ind_pickle:
-                    self.params=pickle.load(file_ind_pickle)
-                debug(_("individual params data loaded"))
-            except:
-                error (_("Can't load individual params data !"))
+    def loadIndData(self, storage, profile):
+        """Load individual parameters
+        set self.params cache
+        @param storage: xxxStorage object instance
+        @param profile: profile to load (*must exist*)
+        @return: deferred triggered once params are loaded"""
+        self.params[profile] = {}
+        return storage.loadIndParams(self.params, profile)
     
     def save_xml(self, file):
         """Save parameters template to xml file"""
@@ -124,28 +119,25 @@
         host.set_const('savefile_param_data', SAVEFILE_PARAM_DATA)
         host.registerGeneralCB("registerNewAccount", host.registerNewAccountCB)
 
-    def getProfilesList(self):
-        return self.params.keys()
-
     def createProfile(self, name):
         """Create a new profile
         @param name: Name of the profile"""
-        if self.params.has_key(name):
+        if self.storage.hasProfile(name):
             info (_('The profile name already exists'))
-            return 1
+            return True
         if not self.host.trigger.point("ProfileCreation", name):
-            return 0
+            return False
         self.params[name]={}
-        return 0
+        return False
 
     def deleteProfile(self, name):
         """Delete an existing profile
         @param name: Name of the profile"""
-        if not self.params.has_key(name):
+        if not self.storage.hasProfile(name):
             error (_('Trying to delete an unknown profile'))
-            return 1
+            return True
         del self.params[name]
-        return 0
+        return False
 
     def getProfileName(self, profile_key):
         """return profile according to profile_key
@@ -159,10 +151,10 @@
             default = self.host.memory.getPrivate('Profile_default')
             if not default or not default in self.params:
                 info(_('No default profile, returning first one')) #TODO: manage real default profile
-                default = self.params.keys()[0]
+                default = self.getProfilesList()[0]
                 self.host.memory.setPrivate('Profile_default', default)
             return default #FIXME: temporary, must use real default value, and fallback to first one if it doesn't exists
-        if not self.params.has_key(profile_key):
+        if not self.storage.hasProfile(profile_key):
             info (_('Trying to access an unknown profile'))
             return ""
         return profile_key
@@ -396,6 +388,7 @@
         
         if node[0] == 'general':
             self.params_gen[(category, name)] = value
+            self.storage.setGenParam(category, name, value)
             for profile in self.getProfilesList():
                 if self.host.isConnected(profile):
                     self.host.bridge.paramUpdate(name, value, category, profile)
@@ -408,14 +401,18 @@
         if type=="button":
             print "clique",node.toxml()
         else:
-            self.params[profile][(category, name)] = value
-            self.host.bridge.paramUpdate(name, value, category, profile) #TODO: add profile in signal
+            if self.host.isConnected(profile): #key can not exists if profile is not connected
+                self.params[profile][(category, name)] = value
+            self.host.bridge.paramUpdate(name, value, category, profile)
+            self.storage.setIndParam(category, name, value, profile)
 
 class Memory:
     """This class manage all persistent informations"""
 
     def __init__(self, host):
         info (_("Memory manager init"))
+        self.initialized = defer.Deferred() 
+        init_defers = [] #list of deferred to wait before initialization is finished
         self.host = host
         self.contacts={}
         self.presenceStatus={}
@@ -429,7 +426,14 @@
         self.config = self.parseMainConf()
         host.set_const('savefile_history', SAVEFILE_HISTORY)
         host.set_const('savefile_private', SAVEFILE_PRIVATE)
-        self.load()
+        host.set_const('savefile_database', SAVEFILE_DATABASE)
+        database_file = os.path.expanduser(self.getConfig('','local_dir')+
+                                        self.host.get_const('savefile_database'))
+        self.loadFiles()
+        self.storage = SqliteStorage(database_file)
+        self.storage.initialized.addCallback(lambda ignore: self.load(init_defers))
+        
+        defer.DeferredList(init_defers).chainDeferred(self.initialized)
 
     def parseMainConf(self):
         """look for main .ini configuration file, and parse it"""
@@ -455,7 +459,8 @@
 
         return os.path.expanduser(_value) if name.endswith('_path') or name.endswith('_dir') else _value
 
-    def load(self):
+
+    def loadFiles(self):
         """Load parameters and all memory things from file/db"""
         param_file_xml = os.path.expanduser(self.getConfig('','local_dir')+
                                         self.host.get_const('savefile_param_xml'))
@@ -466,7 +471,7 @@
         private_file = os.path.expanduser(self.getConfig('','local_dir')+
                                         self.host.get_const('savefile_private'))
 
-        #parameters
+        #parameters template
         if os.path.exists(param_file_xml):
             try:
                 self.params.load_xml(param_file_xml)
@@ -478,12 +483,7 @@
             info (_("No params template, using default template"))
             self.params.load_default_params()
 
-        try:
-            self.params.load_data(param_file_data)
-            debug(_("params loaded"))
-        except:
-            error (_("Can't load params !"))
-
+        
         #history
         if os.path.exists(history_file):
             try:
@@ -502,6 +502,22 @@
             except:
                 error (_("Can't load private values !"))
 
+    def load(self, init_defers):
+        """Load parameters and all memory things from db
+        @param init_defers: list of deferred to wait before parameters are loaded"""
+        #parameters data
+        init_defers.append(self.params.loadGenData(self.storage))
+
+    def loadIndividualParams(self, profile_key):
+        """Load individual parameters for a profile
+        @param profile_key: %(doc_profile_key)s"""
+        profile = self.getProfileName(profile_key)
+        if not profile:
+            error (_('Trying to load parameters for a non-existant profile'))
+            raise Exception("Profile doesn't exist")
+        return self.params.loadIndParams(profile)
+
+
     def save(self):
         """Save parameters and all memory things to file/db"""
         #TODO: need to encrypt files (at least passwords !) and set permissions
@@ -525,7 +541,7 @@
         debug(_("private values saved"))
 
     def getProfilesList(self):
-        return self.params.getProfilesList()
+        return self.storage.getProfilesList()
 
 
     def getProfileName(self, profile_key):