Aller chercher un peu plus d'articles dans 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)
d566e9c1
EMS
52 f = urlopen(url)
53 page = f.read()
54 f.close()
55 return page
56 except:
57 print "Erreur: impossible de récupérer la page:", url
58 return ''
59
60 SOMMAIRE_ID_RE = re.compile(r'sommaire\.php\?id=(\d+)')
61 def get_sommaire_ids(path):
62 return SOMMAIRE_ID_RE.findall(get_page(path))
63
64 AUTEUR_ID_RE = re.compile(r'personne\.php\?id=(\d+)')
65 def get_auteur_ids(path):
66 return AUTEUR_ID_RE.findall(get_page(path))
67
68 ENTREE_TYPE_RE = re.compile(r'entrees\.php\?type=(\w+)')
69 def get_entree_types(path):
70 return ENTREE_TYPE_RE.findall(get_page(path))
71
72 ENTREE_ID_RE = re.compile(r'entree\.php\?id=(\d+)')
73 def get_entree_ids(path):
74 return ENTREE_ID_RE.findall(get_page(path))
75
76 DOCUMENT_ID_RE = re.compile(r'document\.php\?id=(\d+)')
77 def get_document_ids(path):
78 return DOCUMENT_ID_RE.findall(get_page(path))
0cc5f772 79
d566e9c1
EMS
80 def get_meta(path):
81 page = get_page(path)
82 if not page:
83 return None
84 tree = etree.HTML(page)
85 meta = { IDENTIFIER: urljoin(BASE_URL, path) }
86 fields = tree.findall(".//meta")
87 for field in fields:
88 if field.attrib.get('lang', 'fr') == 'fr': # ignore en
89 match = DC_MAP.get(field.attrib.get('name'))
90 if match is not None:
91 for k in match:
92 meta_set(meta, k, smart_str(field.attrib.get('content')))
93 if meta.get("uri") is not None:
94 return meta
0cc5f772 95
d566e9c1 96 nodes = []
9203dda6
EMS
97 meta = get_meta('/')
98 if meta:
99 nodes.append(meta)
100
101 sommaire_ids = set(chain(get_sommaire_ids('/'), get_sommaire_ids('/index.php?format=numero'),
102 get_sommaire_ids('/index.php?format=numeros')))
d566e9c1
EMS
103 auteur_ids = get_auteur_ids('/personnes.php?type=auteur')
104
105 entree_types = get_entree_types('/')
106 entree_ids = set()
107 for type in entree_types:
108 entree_ids.update(get_entree_ids('/entrees.php?type=%s' % type))
109
110 document_ids = set()
111 for id in sommaire_ids:
112 path = '/sommaire.php?id=%s' % id
113 meta = get_meta(path)
114 if meta:
115 nodes.append(meta)
116 document_ids.update(get_document_ids(path))
117 for id in auteur_ids:
118 document_ids.update(get_document_ids('/personne.php?id=%s&type=auteur' % id))
119 for id in entree_ids:
120 document_ids.update(get_document_ids('/entree.php?id=%s' % id))
121
122 for id in document_ids:
123 meta = get_meta('/document.php?id=%s' % id)
124 if meta:
125 nodes.append(meta)
0cc5f772 126 return nodes