Corrections pour thread-safety SEP, correction script sigma
authorCyril Robert <Cyril Robert crobert@inverse.ca>
Tue, 2 Mar 2010 16:45:02 +0000 (11:45 -0500)
committerCyril Robert <Cyril Robert crobert@inverse.ca>
Tue, 2 Mar 2010 16:45:02 +0000 (11:45 -0500)
Apps/auf_savoirs_backend/sep/io.py
Apps/auf_savoirs_backend/storage/json.py
Scripts/SigmaCopyUsers/copy_users.py

index b4862aa..3485697 100644 (file)
@@ -8,7 +8,7 @@ from globals import *
 
 class SEP:
     backend = None
-    required_methods = ['open', 'close', 'add', 'delete', 'search', 'update']
+    required_methods = ['add', 'delete', 'search', 'update']
 
     def __init__ (self):
         # Charge le backend de stockage
@@ -16,26 +16,13 @@ class SEP:
         __import__ (module)
         backend_module = sys.modules[module]
         self.backend = backend_module.Backend (conf.BACKEND['options'])
-
-        # Vérifier qu'il répond à l'API
-        available = dir (self.backend)
-        for method in self.required_methods:
-            if not method in available:
-                msg = "Backend incomplet\nManque %s\nexiste %s" \
-                        % (method, available)
-                raise Exception(msg)
-
-        # Charge
-        self.backend.open ()
-
-
+    
     def __del__ (self):
-        self.backend.close ()
-
+        del(self.backend)
 
 #############
 # API public
-    def search (self, q = None):
+    def search (self, q = {}):
         return self.backend.search (q)
 
     def get (self, id):
index 366b462..f3a46b3 100644 (file)
@@ -1,7 +1,6 @@
 # -*- encoding: utf-8 -*-
-import os
+import os, sys, thread, time
 import simplejson as json
-import sys
 sys.path.append ("../")
 from globals import *
 
@@ -32,108 +31,174 @@ class File:
 
 
 class Backend:
-    options = {}
-    data = {}
-    needs_write = False
-    remove = []
-    last_index = 0
-
-    def __init__ (self, options):
-        self.options = options
-        # juste pour lancer une exception si jamais on a pas le path
-        p = self.options['path']
-
-    def open (self):
-        p = self.options['path']
-        ip = os.path.join (p, INDEX_NAME)
-
-        if not os.path.exists (p):
-            os.makedirs (p)
-
-        elif os.path.exists (ip):
-            index = File (ip, 'r').read ()
-            for id in index:
-                fp = os.path.join (p, DATA_FMT % id)
-                meta = File (fp, 'r').read ()
-                meta['needs_write'] = False
-                self.data[id] = meta
-                if id > self.last_index:
-                    self.last_index = id
-
-    def close (self):
-        if self.needs_write:
+    class __impl:
+        """Classe interne, pour singleton"""
+        options = {}
+        data = {}
+        needs_write = False
+        remove = []
+        last_index = 0
+        __locked = False
+        __reading = 0
+
+        def __init__ (self, options):
+            self.options = options
+            # juste pour lancer une exception si jamais on a pas le path
             p = self.options['path']
-            
-            # Enleve les vieux trucs
-            if len (self.remove) > 0:
-                for id in self.remove:
-                    fp = os.path.join (p, DATA_FMT % id)
-                    os.remove (fp)
+            ip = os.path.join(p, INDEX_NAME)
 
-            # Ecrit l'index
-            File(os.path.join(p, INDEX_NAME), 'w').write(self.data.keys ())
+            if not os.path.exists (p):
+                os.makedirs (p)
 
-            # Ecrit les données
-            for id in self.data.keys ():
-                record = self.data[id]
-                if record['needs_write']:
-                    del (record['needs_write'])
+            elif os.path.exists (ip):
+                index = File (ip, 'r').read ()
+                for id in index:
                     fp = os.path.join (p, DATA_FMT % id)
-                    File (fp, 'w').write (record)
-
-    def add (self, metadata):
-        self.last_index += 1
-        metadata['needs_write'] = True
-        self.data[self.last_index] = metadata
-        self.needs_write = True
-        return self.last_index
-
-    def delete (self, id):
-        self.needs_write = True
-        del (self.data[id])
-        self.remove.append (id)
-
-    def update (self, id, metadata):
-        metadata['needs_write'] = True
-        self.needs_write = True
-        for k in metadata.keys():
-            self.data[id][k] = metadata[k]
-
-    def get (self, id):
-        rc = None
-        if id in self.data.keys ():
-            rc = self.data[id]
-        return rc
-
-    def filter_string_contains (self, set, q, key):
-        rc = []
-        words = q.get (key)
-        if words:
-            for k in set:
-                if self.data[k][key].encode("utf-8").find (words) > -1:
-                    rc.append (k)
-        else:
-            rc = set
-        return rc
-
-    def filter_string_equals (self, set, q, key):
-        rc = []
-        string = q.get (key)
-        if string:
-            for k in set:
-                if self.data[k][key].encode("utf-8") == string:
-                    rc.append (k)
-        else:
-            rc = set
-        return rc
-
-    def search (self, q):
-        rc = self.data.keys ()
-
-        # Très incomplet
-        rc = self.filter_string_equals (rc, q, URI)
-        rc = self.filter_string_contains (rc, q, TITLE)
-        rc = self.filter_string_contains (rc, q, DESCRIPTION)
-
-        return rc
+                    meta = File (fp, 'r').read ()
+                    meta['needs_write'] = False
+                    self.data[id] = meta
+                    if id > self.last_index:
+                        self.last_index = id
+
+        def __del__ (self):
+            if self.needs_write:
+                p = self.options['path']
+            
+                # Enleve les vieux trucs
+                if len (self.remove) > 0:
+                    for id in self.remove:
+                        fp = os.path.join (p, DATA_FMT % id)
+                        os.remove (fp)
+
+                # Ecrit l'index
+                File(os.path.join(p, INDEX_NAME), 'w').write(self.data.keys ())
+
+                # Ecrit les données
+                for id in self.data.keys ():
+                    record = self.data[id]
+                    if record['needs_write']:
+                        del (record['needs_write'])
+                        fp = os.path.join (p, DATA_FMT % id)
+                        File (fp, 'w').write (record)
+
+        def __wait_lock (self):
+            while self.__locked:
+                time.sleep (1)
+        def __wait_rlock (self):
+            while self.__reading > 0:
+                time.sleep (1)
+
+        def __rlock (self):
+            self.__wait_lock ()
+            #print "Lock read"
+            self.__reading += 1
+        def __runlock (self):
+            #print "Unlock read"
+            self.__reading -= 1
+
+        def __wlock (self):
+            self.__wait_rlock ()
+            self.__wait_lock ()
+            #print "Lock write"
+            self.__locked = True
+
+        def __wunlock (self):
+            #print "Unlock write"
+            self.__locked = False
+
+
+        def add (self, metadata):
+            self.__wlock ()
+            self.last_index += 1
+            metadata['needs_write'] = True
+            self.data[self.last_index] = metadata
+            self.needs_write = True
+            self.__wunlock ()
+            return self.last_index
+
+        def delete (self, id):
+            self.__wlock ()
+            self.needs_write = True
+            del (self.data[id])
+            self.remove.append (id)
+            self.__wunlock ()
+
+        def update (self, id, metadata):
+            self.__wlock ()
+            metadata['needs_write'] = True
+            self.needs_write = True
+            for k in metadata.keys():
+                self.data[id][k] = metadata[k]
+            self.__wunlock ()
+
+        def get (self, id):
+            self.__rlock ()
+            rc = None
+            if id in self.data.keys ():
+                rc = self.data[id]
+            self.__runlock ()
+            return rc
+
+        def filter_string_contains (self, set, q, key):
+            rc = []
+            words = q.get (key)
+            if words:
+                for k in set:
+                    str = self.data[k].get(key, "").encode("utf-8")
+                    if str.find (words) > -1:
+                        rc.append (k)
+            else:
+                rc = set
+            return rc
+
+        def filter_string_equals (self, set, q, key):
+            rc = []
+            string = q.get (key)
+            if string:
+                for k in set:
+                    str = self.data[k].get(key, "").encode("utf-8")
+                    if str == string:
+                        rc.append (k)
+            else:
+                rc = set
+            return rc
+
+        def search (self, q):
+            self.__rlock ()
+            rc = self.data.keys ()
+
+            # Très incomplet
+            rc = self.filter_string_equals (rc, q, URI)
+            rc = self.filter_string_contains (rc, q, TITLE)
+            rc = self.filter_string_contains (rc, q, DESCRIPTION)
+
+            self.__runlock ()
+            return rc
+
+
+    __instance = None
+    __usage = 0
+    __lock = thread.allocate_lock()
+
+    def __init__(self, options):
+        Backend.__lock.acquire ()
+        if Backend.__instance is None:
+            Backend.__instance = Backend.__impl(options)
+        Backend.__usage += 1
+        Backend.__lock.release ()
+        self.__dict__['_Backend__instance'] = Backend.__instance
+
+    def __del__ (self):
+        Backend.__usage -= 1
+        if Backend.__usage == 0:
+            del (Backend.__instance)
+
+    # Délégation
+    def __getattr__(self, attr):
+        return getattr(self.__instance, attr)
+    def __setattr__(self, attr, value):
+        return setattr(self.__instance, attr, value)
+
+
+
 
index 6173209..03316d4 100755 (executable)
@@ -39,6 +39,7 @@ if __name__ == "__main__":
     print len (rows), "utilisateurs"
     for row in rows:
         (utilisateur, prenom, nom, email, habilitation) = row
+        d.execute ("DELETE FROM `auth_user` WHERE username=%s", utilisateur)
         d.execute (
         """INSERT INTO `auth_user` (username, first_name, last_name, email, 
                                     password, is_staff, is_active, is_superuser, 
@@ -49,11 +50,16 @@ if __name__ == "__main__":
         d.execute ("""SELECT `id` FROM `auth_user` WHERE `username`=%s""", utilisateur)
         user_id = d.fetchone()[0]
 
+        print email
         d.execute ("""SELECT `id` FROM `ref_employe` WHERE `courriel`=%s""", email)
-        matricule = d.fetchone()[0]
-        
-        d.execute ("""INSERT INTO `www_aufuser` (user_ptr_id, employe_id) 
-                      VALUES (%s, %s)""", (user_id, matricule))
+        try:
+            matricule = d.fetchone()[0]
+            
+            d.execute ("DELETE FROM `www_aufuser` WHERE user_ptr_id=%s or employe_id=%s", (user_id, matricule))
+            d.execute ("""INSERT INTO `www_aufuser` (user_ptr_id, employe_id) 
+                          VALUES (%s, %s)""", (user_id, matricule))
+        except:
+            print email, "non ajoute"
 
         if re.match (r'AB\[\d+\]$', habilitation):
             bureau = re.search (r'\[(\d+)\]', habilitation).group(1)