Commit | Line | Data |
---|---|---|
0cc5f772 | 1 | # -*- encoding: utf-8 -*- |
d566e9c1 EMS |
2 | import re |
3 | from itertools import chain | |
0cc5f772 | 4 | from lxml import etree |
d566e9c1 EMS |
5 | from savoirs.globals import * |
6 | from savoirs.lib.utils import meta_set, smart_str | |
7 | from urllib import urlopen | |
8 | from urlparse import urljoin | |
9 | ||
10 | DC_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 | ||
27 | def 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 |