Ajout harvesters OAI
authorCyril Robert <Cyril Robert crobert@inverse.ca>
Mon, 1 Mar 2010 20:20:22 +0000 (15:20 -0500)
committerCyril Robert <Cyril Robert crobert@inverse.ca>
Mon, 1 Mar 2010 20:20:22 +0000 (15:20 -0500)
Apps/auf_sep/globals.py
Apps/auf_sep/harvest/harvesters/oai/__init__.py [new file with mode: 0644]
Apps/auf_sep/harvest/harvesters/oai/generic.py [new file with mode: 0644]
Apps/auf_sep/harvest/harvesters/pmb/export.py
Apps/auf_sep/harvest/harvesters/pmb/pmbclient.py
Apps/auf_sep/sep/utils.py [new file with mode: 0644]
Apps/auf_sep/storage/json.py

index 90c128d..724f51e 100644 (file)
@@ -3,26 +3,23 @@
 
 #####
 # Meta fields
-TITLE = 'title'
-CREATOR = 'creator'
-TOC = 'toc'
-ABSTRACT = 'abstract'
-PUBLISHER = 'publisher'
-CONTRIBUTOR = 'contributor'
-DATE_CREATION = 'creation'
-DATE_VALID = 'valid'
-DATE_AVAILABLE = 'available'
-DATE_ISSUED = 'issued'
-DATE_MODIFIED = 'modified'
-DATE_ACCEPTED = 'accepted'
-DATE_COPYRIGHTED = 'copyrighted'
-DATE_SUBMITTED = 'submitted'
-TYPE = 'type'
-FORMAT = 'format'
-MEDIUM = 'medium'
-IDENTIFIER = 'identifier'
-URI = 'uri'
-SOURCE = 'source'
-LANGUAGE = 'language'
-COVERAGE = 'coverage'
+TITLE           = 'title'       #X str
+ALT_TITLE       = 'alt_title'   #X str
+CREATOR         = 'creator'     #X str
+CONTRIBUTOR     = 'contributor' #X array (str)
+DESCRIPTION     = 'description' #  str
+ABSTRACT        = 'abstract'    #X str
+SUBJECT         = 'subject'     #X str
+PUBLISHER       = 'publisher'   #X str
+DATE_CREATION   = 'creation'    #  date
+DATE_ISSUED     = 'issued'      #X date
+DATE_MODIFIED   = 'modified'    #  date
+TYPE            = 'type'        #  str
+FORMAT          = 'format'      #  str
+IDENTIFIER      = 'identifier'  #X str (int?)
+ISBN            = 'isbn'        #X str
+URI             = 'uri'         #X str (url)
+SOURCE          = 'source'      #X str (url)
+LANGUAGE        = 'language'    #X str
+ORIG_LANG       = 'orig_lang'   #X str
 
diff --git a/Apps/auf_sep/harvest/harvesters/oai/__init__.py b/Apps/auf_sep/harvest/harvesters/oai/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Apps/auf_sep/harvest/harvesters/oai/generic.py b/Apps/auf_sep/harvest/harvesters/oai/generic.py
new file mode 100644 (file)
index 0000000..51d735b
--- /dev/null
@@ -0,0 +1,111 @@
+# -*- encoding: utf-8 -*-
+from lxml import etree
+import sys, urllib, httplib, re
+
+sys.path.append ("../../../")
+from globals import *
+from sep.utils import safe_append, print_structure
+
+
+
+def find_location (server, port, base_url):
+    rc = None
+    possible = ("perl/oai2", "cgi/oai2", "cgi-bin/oaiserver")
+    for test in possible:
+        url = base_url + test
+        handle = httplib.HTTPConnection (server, port)
+        handle.request ("GET", url + "?verb=Identify")
+        r = handle.getresponse ()
+        if r.status == 200:
+            rc = "http://" + server + url
+            break
+    return rc
+
+def load_xml (url):
+    ud = urllib.urlopen (url)
+    content = ud.read ().decode('iso-8859-1')
+    # Greenstone crap
+    content = content.replace ("xmlns=\"http://www.openarchives.com/OAI/2.0\"",
+            "xmlns=\"http://www.openarchives.org/OAI/2.0/\"")
+    ud.close ()
+    root = etree.XML (content.encode("utf-8"))
+    return root
+
+
+def cleanup (node):
+    node.tag = re.sub (r'^\{[a-zA-Z0-9_:.-\/]+\}', '', node.tag)
+    return node
+
+
+def harvest (options):
+    oai2ns = "{http://www.openarchives.org/OAI/2.0/}"
+    oaidc  = "{http://www.openarchives.org/OAI/2.0/oai_dc/}dc"
+    metans = "{http://purl.org/dc/elements/1.1/}"
+
+    uri = find_location (options['server'], 
+            options['port'], 
+            options['base_url'])
+
+    records = []
+    root = load_xml (uri + "?verb=ListRecords&metadataPrefix=oai_dc")
+    #print_structure (root)
+    records.extend (root.findall (".//%srecord" % oai2ns))
+    token = root.find (".//%sresumptionToken" % oai2ns)
+
+    while token is not None:
+        root = load_xml (uri + "?verb=ListRecords&resumptionToken=%s" % token.text)
+        records.extend (root.findall (".//%srecord" % 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)
+        for c in dcnode.getchildren ():
+            if c.text:
+                c.text = c.text.strip ()
+            else:
+                c.text = ""
+
+            if c.tag == "%stitle" % metans:
+                meta[TITLE] = c.text
+
+            elif c.tag == "%screator" % metans:
+                meta[CREATOR] = c.text
+
+            elif c.tag == "%scontributor" % metans:
+                safe_append (meta, CONTRIBUTOR, c.text)
+
+            elif c.tag == "%ssubject" % metans:
+                safe_append (meta, SUBJECT, c.text)
+
+            elif c.tag == "%sdescription" % metans:
+                meta[DESCRIPTION] = c.text
+
+            elif c.tag == "%spublisher" % metans:
+                if len (c.text) > 0:
+                    meta[PUBLISHER] = c.text
+
+            elif c.tag == "%sdate" % metans:
+                meta[DATE_CREATION] = c.text
+
+            elif c.tag == "%stype" % metans:
+                safe_append (meta, TYPE, c.text)
+
+            elif c.tag == "%sidentifier" % metans:
+                meta[IDENTIFIER] = c.text
+                meta[URI] = c.text
+
+            elif c.tag == '%sformat' % metans:
+                safe_append (meta, FORMAT, c.text)
+
+            elif c.tag == '%srelation' % metans:
+                meta[SOURCE] = c.text
+
+        nodes.append (meta)
+
+    return nodes
index 6516dec..f91fbe1 100644 (file)
@@ -5,26 +5,22 @@ import sys, re
 
 sys.path.append ("../../../")
 from globals import *
+from sep.utils import safe_append, print_structure, find_text
 
-def print_structure(element, tab=""):
-    if element.text:
-        element.text = element.text.strip ()
-    if element.tail:
-        element.tail = element.tail.strip ()
-    print(u"%s<%s>: %s, %s, %s" % (tab, element.tag, element.text, 
-        element.tail, element.attrib))
-    for x in element.getchildren():
-        print_structure(x, tab+" ")
-
-
-def findtext (node, tag):
-    rc = ""
-    n = node.find (".//%s" % tag)
-    if n is not None:
-        rc = n.text
 
+def read_person (node):
+    rc = u"%s %s" % (find_text(node, "prenom"), 
+            find_text(node, "nom"))
+    dates = find_text(node, "dates")
+    if len (dates) > 0:
+        rc += " (%s)" % dates
     return rc
 
+def read_publisher (node):
+    return u"%s, %s" % (find_text(node, "nom"), 
+            find_text(node, "ville"))
+    
+
 
 def harvest (options):
     c = PmbClient ()
@@ -40,29 +36,53 @@ def harvest (options):
     params = {'export_type': '14', 'lender': 'x'}
     content = c.export (params, export_script)
 
-    root = etree.XML (content)
+    root = etree.XML (content.encode("utf-8"))
     article_nodes = root.findall (".//notice")
     nodes = []
     for node in article_nodes:
         meta = {}
         for c in node.getchildren ():
+            if c.text:
+                c.text = c.text.strip ()
+
             if c.tag == 'idNotice':
                 meta[IDENTIFIER] = c.text
+
             elif c.tag == 'zoneTitre':
-                meta[TITLE] = findtext (c, 'titrePrincipal')
+                for t in c.getchildren ():
+                    if t.tag == 'titrePrincipal':
+                        meta[TITLE] = t.text
+                    else:
+                        safe_append (meta, ALT_TITLE, t.text)
+
             elif c.tag == 'zoneAuteurPrincipal':
-                meta[CREATOR] = u"%s %s" % (findtext(c, "prenom"), 
-                        findtext(c, "nom"))
+                meta[CREATOR] = read_person (c)
+
             elif c.tag == 'zoneAuteursAutres':
-                meta[CONTRIBUTOR] = u"%s %s" % (findtext(c, "prenom"), 
-                        findtext(c, "nom"))
+                safe_append (meta, CONTRIBUTOR, read_person (c))
+
+            elif c.tag == 'zoneNotes':
+                meta[ABSTRACT] = find_text (c, "noteResume")
+
             elif c.tag == 'zoneEditeur':
-                meta[PUBLISHER] = u"%s, %s (%s)" % (findtext(c, "nom"), 
-                        findtext(c, "ville"), findtext(c, "annee"))
+                safe_append (meta, PUBLISHER, read_publisher (c))
+                meta[DATE_ISSUED] = find_text (c, "annee")
+
+            elif c.tag == 'prixISBN':
+                meta[ISBN] = find_text (c, "ISBN")
+
+            elif c.tag == 'zoneLiens':
+                meta[SOURCE] = find_text (c, "lien")
+
+            elif c.tag == 'zoneLangue':
+                for t in c.getchildren ():
+                    if t.tag == 'langueDocument':
+                        safe_append (meta, LANGUAGE, t.text)
+                    elif t.tag == 'langueOriginale':
+                        safe_append (meta, ORIG_LANG, t.text)
+
             elif c.tag == 'zoneCategories':
-                meta[COVERAGE] = findtext (c, "categorie")
-            #else:
-            #    print c.tag, "ignoré"
+                safe_append (meta, SUBJECT, find_text (c, "categorie"))
 
         meta[URI] = "http://%s%scatalog.php?id=%s" % \
                 (options['host'], options['base_url'], meta[IDENTIFIER])
index 05c1d63..a301da8 100644 (file)
@@ -119,4 +119,4 @@ class PmbClient:
         content = r.read ()
 
         # Saloperie de PMB force le retour en iso crap
-        return content.decode('iso-8859-1').encode('utf-8')
+        return content.decode('iso-8859-1')
diff --git a/Apps/auf_sep/sep/utils.py b/Apps/auf_sep/sep/utils.py
new file mode 100644 (file)
index 0000000..3413433
--- /dev/null
@@ -0,0 +1,27 @@
+# -*- encoding: utf-8 -*-
+
+
+def safe_append (dict, key, value):
+    try:
+        list = dict[key]
+    except:
+        dict[key] = []
+    dict[key].append (value)
+
+def print_structure(element, tab=""):
+    if element.text:
+        element.text = element.text.strip ()
+    if element.tail:
+        element.tail = element.tail.strip ()
+    line = u"%s<%s>: %s, %s, %s" % (tab, element.tag, element.text, 
+        element.tail, element.attrib)
+    print line.encode ("utf-8")
+    for x in element.getchildren():
+        print_structure(x, tab+" ")
+
+def find_text (node, tag):
+    rc = ""
+    n = node.find (".//%s" % tag)
+    if n is not None:
+        rc = n.text
+    return rc
index 327450e..f9be889 100644 (file)
@@ -96,8 +96,8 @@ class Backend:
     def update (self, id, metadata):
         metadata['needs_write'] = True
         self.needs_write = True
-        del(self.data[id])
-        self.data[id] = metadata
+        for k in metadata.keys():
+            self.data[id][k] = metadata[k]
 
     def get (self, id):
         rc = None