Nouvelle méthode de moisson pour les Lodel.
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / lib / harvesters / lodel / html.py
CommitLineData
0cc5f772 1# -*- encoding: utf-8 -*-
d566e9c1
EMS
2import re
3from itertools import chain
0cc5f772 4from lxml import etree
d566e9c1
EMS
5from savoirs.globals import *
6from savoirs.lib.utils import meta_set, smart_str
7from urllib import urlopen
8from urlparse import urljoin
9
10DC_MAP = {'DC.Title': [TITLE,],
11 'DCTERMS.alternative': [ALT_TITLE,],
12 'DC.Creator': [CREATOR,],
13 'DC.Contributor': [CONTRIBUTOR,],
14 'DC.Description': [DESCRIPTION,],
15 'DCTERMS.abstract': [ABSTRACT,],
16 'DC.Subject': [SUBJECT,],
17 'DC.Publisher': [PUBLISHER,],
18 'DCTERMS.issued': [DATE_ISSUED,],
19 'DCTERMS.modified': [DATE_MODIFIED,],
20 'DC.Type': [TYPE,],
21 'DC.Format': [FORMAT,],
22 'DC.Identifier': [URI,],
23 #'DC.Source': [SOURCE,], # ignoré, source pointe vers la recine du site
24 'DC.Language': [LANGUAGE,],
25 }
26
27def harvest(options):
0cc5f772
CR
28 """Méthode de moissonage pour systèmes Lodel < 0.8. Lodel, avant la version
29 0.8 n'offre pas de système d'exportation de données, autre que la
30 présentation des information OAI (Dublin Core) dans les tags *meta* des
31 pages des articles. On n'a pas non plus de facon d'obtenir la liste des
32 items existant dans l'instance.
33
34 La méthode adoptée est d'y aller en *brute-force*, on cherche tout ce qui a
35 un *id* entre 0 et 100000, et on s'arrete si on a 200 erreurs consécutives.
36
37 *options*
38 *options* est un dictionnaire, et doit contenir au moins les attributs
39 suivants:
40
41 *url*
42 Racine de l'instance de Lodel.
43
44 La méthode retourne une liste d'éléments correspondant au format de
45 metadonnées.
46 """
d566e9c1
EMS
47 BASE_URL = options['url']
48
49 def get_page(path):
50 try:
51 url = urljoin(BASE_URL, path)
52 print "Récupération de la page:", url
53 f = urlopen(url)
54 page = f.read()
55 f.close()
56 return page
57 except:
58 print "Erreur: impossible de récupérer la page:", url
59 return ''
60
61 SOMMAIRE_ID_RE = re.compile(r'sommaire\.php\?id=(\d+)')
62 def get_sommaire_ids(path):
63 return SOMMAIRE_ID_RE.findall(get_page(path))
64
65 AUTEUR_ID_RE = re.compile(r'personne\.php\?id=(\d+)')
66 def get_auteur_ids(path):
67 return AUTEUR_ID_RE.findall(get_page(path))
68
69 ENTREE_TYPE_RE = re.compile(r'entrees\.php\?type=(\w+)')
70 def get_entree_types(path):
71 return ENTREE_TYPE_RE.findall(get_page(path))
72
73 ENTREE_ID_RE = re.compile(r'entree\.php\?id=(\d+)')
74 def get_entree_ids(path):
75 return ENTREE_ID_RE.findall(get_page(path))
76
77 DOCUMENT_ID_RE = re.compile(r'document\.php\?id=(\d+)')
78 def get_document_ids(path):
79 return DOCUMENT_ID_RE.findall(get_page(path))
0cc5f772 80
d566e9c1
EMS
81 def get_meta(path):
82 page = get_page(path)
83 if not page:
84 return None
85 tree = etree.HTML(page)
86 meta = { IDENTIFIER: urljoin(BASE_URL, path) }
87 fields = tree.findall(".//meta")
88 for field in fields:
89 if field.attrib.get('lang', 'fr') == 'fr': # ignore en
90 match = DC_MAP.get(field.attrib.get('name'))
91 if match is not None:
92 for k in match:
93 meta_set(meta, k, smart_str(field.attrib.get('content')))
94 if meta.get("uri") is not None:
95 return meta
0cc5f772 96
d566e9c1
EMS
97 nodes = []
98 sommaire_ids = set(chain(get_sommaire_ids('/'), get_sommaire_ids('/index.php?format=numero')))
99 auteur_ids = get_auteur_ids('/personnes.php?type=auteur')
100
101 entree_types = get_entree_types('/')
102 entree_ids = set()
103 for type in entree_types:
104 entree_ids.update(get_entree_ids('/entrees.php?type=%s' % type))
105
106 document_ids = set()
107 for id in sommaire_ids:
108 path = '/sommaire.php?id=%s' % id
109 meta = get_meta(path)
110 if meta:
111 nodes.append(meta)
112 document_ids.update(get_document_ids(path))
113 for id in auteur_ids:
114 document_ids.update(get_document_ids('/personne.php?id=%s&type=auteur' % id))
115 for id in entree_ids:
116 document_ids.update(get_document_ids('/entree.php?id=%s' % id))
117
118 for id in document_ids:
119 meta = get_meta('/document.php?id=%s' % id)
120 if meta:
121 nodes.append(meta)
0cc5f772 122 return nodes