Version stabilisee
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / lib / harvesters / lodel / html.py
CommitLineData
0cc5f772
CR
1# -*- encoding: utf-8 -*-
2from lxml import etree
3import sys, httplib, re, pprint, simplejson
4from urlparse import urlparse, urljoin
5
6from auf_savoirs_en_partage.savoirs.lib.backend.globals import *
7from auf_savoirs_en_partage.savoirs.lib.utils \
8 import safe_append, print_structure, meta_set, smart_str
9
10
11map = {'DC.Title': [TITLE,],
12 'DCTERMS.alternative': [ALT_TITLE,],
13 'DC.Creator': [CREATOR,],
14 'DC.Contributor': [CONTRIBUTOR,],
15 'DC.Description': [DESCRIPTION,],
16 'DCTERMS.abstract': [ABSTRACT,],
17 'DC.Subject': [SUBJECT,],
18 'DC.Publisher': [PUBLISHER,],
19 'DCTERMS.issued': [DATE_ISSUED,],
20 'DCTERMS.modified': [DATE_MODIFIED,],
21 'DC.Type': [TYPE,],
22 'DC.Format': [FORMAT,],
23 'DC.Identifier': [URI,],
24 #'DC.Source': [SOURCE,], # ignoré, source pointe vers la recine du site
25 'DC.Language': [LANGUAGE,],
26 }
27
28
29def load_html (host, base, id):
30 root = None
31 handle = httplib.HTTPConnection (host)
32 uri = base + "document.php?id=%d" % id
33 handle.request ("GET", uri)
34 r = handle.getresponse ()
35 if r.status == 302:
36 del (handle)
37 del (r)
38 handle = httplib.HTTPConnection (host)
39 uri = base + "sommaire.php?id=%d" % id
40 handle.request ("GET", uri)
41 r = handle.getresponse ()
42
43 if r.status == 200:
44 content = smart_str(r.read ())
45 handle.close ()
46 root = etree.HTML (content)
47
48 return ("http://" + host + uri, root)
49
50
51def harvest (options):
52 """Méthode de moissonage pour systèmes Lodel < 0.8. Lodel, avant la version
53 0.8 n'offre pas de système d'exportation de données, autre que la
54 présentation des information OAI (Dublin Core) dans les tags *meta* des
55 pages des articles. On n'a pas non plus de facon d'obtenir la liste des
56 items existant dans l'instance.
57
58 La méthode adoptée est d'y aller en *brute-force*, on cherche tout ce qui a
59 un *id* entre 0 et 100000, et on s'arrete si on a 200 erreurs consécutives.
60
61 *options*
62 *options* est un dictionnaire, et doit contenir au moins les attributs
63 suivants:
64
65 *url*
66 Racine de l'instance de Lodel.
67
68 La méthode retourne une liste d'éléments correspondant au format de
69 metadonnées.
70 """
71 url = urlparse(options['url'])
72
73
74 ## BRUTE FORCE POWER!
75 max_err = 5000
76 err_count = 0
77
78 nodes = []
79 for i in range(0, 50000):
80 (loc, root) = load_html (url.hostname, url.path, i)
81
82 if root is not None:
83 err_count = 0
84 meta = {IDENTIFIER: loc}
85 fields = root.findall (".//meta")
86 for field in fields:
87 if field.attrib.get('lang', 'fr') == 'fr': # ignore en
88 match = map.get (field.attrib.get('name'))
89 if match is not None:
90 for k in match:
91 meta_set (meta, k, smart_str(field.attrib.get('content')))
92
93 if meta.get("uri") is not None:
94 nodes.append (meta)
95 else:
96 err_count += 1
97
98 if err_count >= max_err:
99 print i, "erreurs:", err_count
100 break
101
102
103 return nodes