ajout des listsets provenant des sites et liaison avec les records
authorolivier larcheveque <olivier.larcheveque@u-ol.(none)>
Mon, 20 Sep 2010 20:15:51 +0000 (16:15 -0400)
committerolivier larcheveque <olivier.larcheveque@u-ol.(none)>
Mon, 20 Sep 2010 20:15:51 +0000 (16:15 -0400)
auf_savoirs_en_partage/savoirs/admin.py
auf_savoirs_en_partage/savoirs/lib/harvest.py
auf_savoirs_en_partage/savoirs/lib/harvesters/oai/generic.py
auf_savoirs_en_partage/savoirs/lib/sep.py
auf_savoirs_en_partage/savoirs/models.py

index a3f8804..eeb2051 100644 (file)
@@ -2,7 +2,7 @@
 import re
 from django.contrib import admin
 from django.utils.safestring import mark_safe
-from models import SourceActualite, Actualite, Discipline, Evenement, Record, HarvestLog
+from models import SourceActualite, Actualite, Discipline, Evenement, Record, ListSet, HarvestLog
 from savoirs.globals import META
 from savoirs.lib.backend import Backend
 
@@ -29,9 +29,16 @@ class ReadOnlyWidget(forms.Widget):
         else:
             output = unicode(self.original_value)
 
+        # pour les relations
+        try:
+            output = ", ".join([ls.name for ls in self.original_value.get_query_set()])
+        except:
+            pass
+
         is_url = re.match('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', output)
         if is_url:
             output = "<a target='_blank' href='%s'>%s</a>" % (output, output)
+
         return mark_safe(output)
 
     def value_from_datadict(self, data, files, name):
@@ -70,6 +77,7 @@ class RecordAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
         'type',
         'format',
         'language',
+        'listsets',
         'disciplines',
         'thematiques',
         ]
@@ -109,6 +117,7 @@ class RecordAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
         et les champs en lecture seule uniquement."""
         self.search_fields = META.keys()
         self.readonly_fields = META.keys()
+        self.readonly_fields.append('listsets')
         super(RecordAdmin, self).__init__(*args, **kwargs) 
     
     def _uri(self, obj):
@@ -126,6 +135,14 @@ class RecordAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
 
 admin.site.register(Record, RecordAdmin)
 
+class ListSetAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
+    fields = ['spec', 'name', 'server', 'hidden' ]
+    list_display = fields
+    readonly_fields = ['spec', 'name', 'server',]
+    list_filter = ('server',)
+
+admin.site.register(ListSet, ListSetAdmin)
+
 class HarvestLogAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
     fields = ['context', 'name', 'added', 'updated', 'record']
     list_display = fields + ['date']
index be9b097..fc5b02b 100644 (file)
@@ -23,6 +23,8 @@ def import_all ():
     for name in resources.keys ():
         print "Import:", name
         options = RESOURCES[name]
+        options['server'] = name
+
         module = 'harvesters.%s.%s' \
                 % (options['type'], options['acces'])
         __import__ (module)
index 04356f3..d167527 100644 (file)
@@ -1,8 +1,10 @@
 # -*- encoding: utf-8 -*-
+import sys
 from lxml import etree
 from urlparse import urlparse, urljoin
 import sys, urllib, httplib, re, chardet
 
+from auf_savoirs_en_partage.savoirs.models import ListSet
 from auf_savoirs_en_partage.savoirs.globals import *
 from auf_savoirs_en_partage.savoirs.lib.utils \
         import safe_append, print_structure, meta_set
@@ -39,7 +41,7 @@ def connect(url):
 def find_location (url_str):
     url = urlparse(url_str)
 
-    possible = ("perl/oai2", "cgi/oai2", "cgi-bin/oaiserver", "oai/oai.php")
+    possible = ("perl/oai2", "cgi/oai2", "cgi-bin/oaiserver", "oai/oai.php", "oai/oai2.php")
     for test in possible:
         path = url.path + test
         handle = connect(url)
@@ -69,7 +71,28 @@ def load_xml (url):
     # Other crap
     content.replace("&", "&amp;")
     
-    return etree.XML (content.encode("utf-8"))
+    try:
+        return etree.XML (content.encode("utf-8"))
+    except:
+        print "Erreur parser"
+        print original
+        sys.exit()
+
+def store_listsets(options):
+    """interroge le serveur pour récupérer tous les listsets et les stocke en bd."""
+
+    oai2ns = "{http://www.openarchives.org/OAI/2.0/}"
+    url = find_location (options['url'])
+    root = load_xml (url.geturl() + "?verb=ListSets")
+    sets = root.findall (".//%sset" % oai2ns)
+    
+    listsets = [{'spec':e[0].text , 'name':e[1].text, 'server':options['server']} for e in sets]
+    for data in listsets:
+        ls, created = ListSet.objects.get_or_create(spec = data['spec'])
+        del data['spec']
+        for k,v in data.items():
+            setattr(ls, k, v)
+        ls.save()
 
 
 def harvest (options):
@@ -94,23 +117,28 @@ def harvest (options):
     oaidc  = "{http://www.openarchives.org/OAI/2.0/oai_dc/}dc"
     metans = "{http://purl.org/dc/elements/1.1/}"
 
+    # récupère les listsets du serveur
+    store_listsets(options)
+
     url = find_location (options['url'])
 
     records = []
     root = load_xml (url.geturl() + "?verb=ListRecords&metadataPrefix=oai_dc")
     records.extend (root.findall (".//%srecord" % oai2ns))
-    token = root.find (".//%sresumptionToken" % oai2ns)
+    token = root.find (".//%sresumptiontoken" % oai2ns)
+    print "total du serveur %s " % token.get("completeListSize")
 
     while token is not None:
         root = load_xml (url.geturl() + "?verb=ListRecords&resumptionToken=%s" % token.text)
         records.extend (root.findall (".//%srecord" % oai2ns))
-        token = root.find (".//%sresumptionToken" % oai2ns)
+        token = root.find (".//%sresumptiontoken" % oai2ns)
 
 
     nodes = []
     for record in records:
         meta = {}
         node = record.find (".//%sheader/%sdatestamp" % (oai2ns, oai2ns))
+
         meta[DATE_MODIFIED] = node.text
 
         dcnode = record.find (".//%s" % oaidc)
@@ -134,7 +162,11 @@ def harvest (options):
             if meta.get("uri") is None and meta.get("source") is not None:
                 meta['uri'] = meta['source']
 
+            # récupère les listsets associés
+            listsets = record.findall (".//%sheader/%ssetspec" % (oai2ns, oai2ns))
+            meta['listsets'] = [l.text for l in listsets]
+
             if meta.get("uri") is not None:
                 nodes.append (meta)
-
+    print "total récupérés %s" % len(nodes)       
     return nodes
index 5e1b797..0ec3925 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:
     """
@@ -53,10 +53,23 @@ class SEP:
                     meta[k] = self.encoder.decode(k, v)
         return meta
 
+    # 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 _save (self, metadata):
         r = Record ()
         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()
         r.save()
@@ -70,7 +83,11 @@ class SEP:
             return False
         
         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_update = datetime.datetime.today()
         r.save()
@@ -117,8 +134,8 @@ 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 id, (%s) AS score FROM savoirs_record \
+             WHERE (%s) HAVING score > 0 ORDER BY score DESC" % (m, m)
 
         from django.db import connection, transaction
         cursor = connection.cursor()
index 7589812..2f03507 100644 (file)
@@ -74,6 +74,12 @@ class Evenement(models.Model):
 
     objects = ActiveManager()
 
+class ListSet(models.Model):
+    spec = models.CharField(primary_key = True, max_length = 255)
+    name = models.CharField(max_length = 255)
+    server = models.CharField(max_length = 255)
+    hidden = models.BooleanField(default = False)
+
 class Record(models.Model):
     
     #fonctionnement interne
@@ -97,6 +103,8 @@ class Record(models.Model):
     format = models.TextField(null = True, blank = True)
     language = models.TextField(null = True, blank = True)
 
+    listsets = models.ManyToManyField(ListSet)
+
     #SEP 2 (aucune données récoltées)
     alt_title = models.TextField(null = True, blank = True)
     abstract = models.TextField(null = True, blank = True)
@@ -109,6 +117,7 @@ class Record(models.Model):
     disciplines = models.ManyToManyField(Discipline)
     thematiques = models.ManyToManyField(Thematique)
 
+
     def __unicode__(self):
         return "R[%s] %s" % (self.id, self.title)