retourne dans les recherches les résultats qui nont pas de listset
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / lib / sep.py
index 89a97a4..7a6aae3 100644 (file)
@@ -1,7 +1,7 @@
 # -*- encoding: utf-8 -*-
 import simplejson, re, datetime, operator, hashlib
 from savoirs.globals import *
-from savoirs.models import Record
+from savoirs.models import Record, ListSet
 
 class SEPEncoder:
     """
@@ -9,27 +9,39 @@ class SEPEncoder:
     """
     separator = ", "
 
+    def propre(self, str):
+        """Retoune une chaîne de caractère propre utf-8
+        Elle permet de corrgier les problèmes d'encodage."""
+        if str is None:
+            return u""
+        
+        if str.__class__.__name__ == 'str':
+            str = str.decode('utf-8')
+        
+        return str.replace(u"\x92", u"´")
+
     def encode(self, field, data):
+        """Encode la structure de donnée moissonnée pour la BD"""
         if field in META.keys() and META[field]['type'] == 'array': 
             return self.separator.join(data)
         else:
             return data
 
     def decode(self, field, data):
+        """Décode la structure provenant de la BD"""
         if field in META.keys() and META[field]['type'] == 'array': 
             return data.split(self.separator)
         else:
             return data
     
-    #def migrate(self,):
-    #    for r in Record.objects.all():
-    #        for f in META.keys():
-    #            json = getattr(r, f)
-    #            if json is not None:
-    #                normal = simplejson.loads(json)
-    #                new = self.encode(f, normal)
-    #                setattr(r, f, new)
-    #        r.save()
+    def menage(self,):
+        """Applique sur tous les records, la fonction de corrections
+        de string sur les données moissonnées"""
+        for r in Record.objects.all():
+            for k in META.keys ():
+                v = getattr (r, k)
+                setattr (r, k, self.propre(v))
+            r.save()
 
 class SEP:
     """
@@ -45,7 +57,7 @@ class SEP:
     def _load (self, id):
         """Recupérer la structure de métadonnées pour un record selon un `id`."""
         r = Record.objects.get(id = id)
-        meta = {}
+        meta = {'id' : id}
         for k in META.keys ():
             if hasattr (r, k):
                 v = getattr (r, k)
@@ -53,13 +65,37 @@ class SEP:
                     meta[k] = self.encoder.decode(k, v)
         return meta
 
-    def _save (self, metadata):
-        r = Record ()
+    # traitement spécial pour certaines clef de la structure
+    def listsets(self, record, value):
+        
+        # doit avoir un id pour créer les relations multivaluées
+        record.save()
+
+        for set in  [ls for ls in ListSet.objects.all() if ls.spec in value]:
+            record.listsets.add(set)
+    
+    def _update_record(self, r, metadata):
         for k in metadata.keys ():
-            setattr (r, k, self.encoder.encode(k, metadata[k]))
+            if hasattr(self, k):
+                method = getattr(self, k)
+                method(r, metadata[k])
+            else:
+                setattr (r, k, self.encoder.encode(k, metadata[k]))
+
         r.last_checksum = hashlib.md5(str(metadata)).hexdigest()
         r.last_update = datetime.datetime.today()
+
+        # stocke des chaînes de caractères propre en BD en provenance
+        # des données moissonnées
+        for k in META.keys ():
+            v = getattr (r, k)
+            setattr (r, k, self.encoder.propre(v))
+        
         r.save()
+
+    def _save (self, metadata):
+        r = Record ()
+        self._update_record(r, metadata)
         return r.id
 
     def _modify (self, id, metadata):
@@ -68,12 +104,9 @@ class SEP:
         # test si le fichier a été modifié
         if hashlib.md5(str(metadata)).hexdigest() == r.last_checksum:
             return False
-        
-        for k in metadata.keys ():
-            setattr (r, k, self.encoder.encode(k, metadata[k]))
 
-        r.last_update = datetime.datetime.today()
-        r.save()
+        self._update_record(r, metadata)
+
         return True
 
     def _combine (self, result_lists, op):
@@ -117,9 +150,13 @@ class SEP:
             matches.append ("MATCH(`%s`) AGAINST ('%s'%s)" % (k, " ".join(words), suffix))
         m = "+".join (matches)
 
-        q = "SELECT id, (" + m + ") AS score FROM savoirs_record WHERE (" \
-                + m + ") HAVING score > 0 ORDER BY score DESC"
-
+        q = "SELECT r.id, (%s) AS score FROM savoirs_record AS r \
+             LEFT JOIN savoirs_record_listsets AS rl ON r.id = rl.record_id \
+             LEFT JOIN savoirs_listset AS l ON rl.listset_id = l.spec \
+             WHERE (%s) AND r.validated = 1 AND l.validated = 1 \
+             GROUP BY r.id \
+             HAVING score > 0 ORDER BY score DESC" % (m, m)
+        print q
         from django.db import connection, transaction
         cursor = connection.cursor()
         cursor.execute(q)
@@ -192,11 +229,11 @@ class SEP:
 
         if len (q) > 0:
             # Recherche "simple"
-            ww = q.get ("q", "").strip()[1:-1]
+            ww = q.get ("q", "").strip()
             if len (ww) > 0:
                 s = self._text_search (ww)
                 if len(s) > 0:
-                    rc.append (s)
+                    rc.extend(s)
             # Recherche URL
             elif q.get (URI) is not None:
                 s = []
@@ -206,10 +243,10 @@ class SEP:
                 except: pass
             # Recherche avancée
             else:
-                creator = q.get ("creator", "")[1:-1]
-                title = q.get ("title", "")[1:-1]
-                description = q.get ("description", "")[1:-1]
-                subject = q.get ("subject", "")[1:-1]
+                creator = q.get ("creator", "")
+                title = q.get ("title", "")
+                description = q.get ("description", "")
+                subject = q.get ("subject", "")
 
                 if len (creator) > 0:
                     sets.append (self._text_search (creator, [CREATOR, CONTRIBUTOR]))
@@ -227,5 +264,4 @@ class SEP:
 
         else:
             rc = self.ids()
-
         return rc