udata 10.3.1.dev34819__py2.py3-none-any.whl → 10.3.1.dev34843__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of udata might be problematic. Click here for more details.
- udata/harvest/backends/maaf.py +234 -0
- udata/harvest/backends/maaf.xsd +362 -0
- udata/static/chunks/{10.8ca60413647062717b1e.js → 10.471164b2a9fe15614797.js} +3 -3
- udata/static/chunks/{10.8ca60413647062717b1e.js.map → 10.471164b2a9fe15614797.js.map} +1 -1
- udata/static/chunks/{11.b6f741fcc366abfad9c4.js → 11.51d706fb9521c16976bc.js} +3 -3
- udata/static/chunks/{11.b6f741fcc366abfad9c4.js.map → 11.51d706fb9521c16976bc.js.map} +1 -1
- udata/static/chunks/{13.2d06442dd9a05d9777b5.js → 13.f29411b06be1883356a3.js} +2 -2
- udata/static/chunks/{13.2d06442dd9a05d9777b5.js.map → 13.f29411b06be1883356a3.js.map} +1 -1
- udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js → 17.3bd0340930d4a314ce9c.js} +2 -2
- udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js.map → 17.3bd0340930d4a314ce9c.js.map} +1 -1
- udata/static/chunks/{19.f03a102365af4315f9db.js → 19.8da42e8359d72afc2618.js} +3 -3
- udata/static/chunks/{19.f03a102365af4315f9db.js.map → 19.8da42e8359d72afc2618.js.map} +1 -1
- udata/static/chunks/{8.778091d55cd8ea39af6b.js → 8.54e44b102164ae5e7a67.js} +2 -2
- udata/static/chunks/{8.778091d55cd8ea39af6b.js.map → 8.54e44b102164ae5e7a67.js.map} +1 -1
- udata/static/chunks/{9.033d7e190ca9e226a5d0.js → 9.07515e5187f475bce828.js} +3 -3
- udata/static/chunks/{9.033d7e190ca9e226a5d0.js.map → 9.07515e5187f475bce828.js.map} +1 -1
- udata/static/common.js +1 -1
- udata/static/common.js.map +1 -1
- {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/METADATA +2 -1
- {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/RECORD +24 -22
- {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/entry_points.txt +1 -0
- {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/LICENSE +0 -0
- {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/WHEEL +0 -0
- {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
from collections import OrderedDict
|
|
5
|
+
from urllib.parse import urljoin
|
|
6
|
+
|
|
7
|
+
from lxml import etree, html
|
|
8
|
+
from voluptuous import All, Any, In, Length, Lower, Optional, Schema
|
|
9
|
+
|
|
10
|
+
from udata.harvest.backends import BaseBackend
|
|
11
|
+
from udata.harvest.filters import (
|
|
12
|
+
boolean,
|
|
13
|
+
email,
|
|
14
|
+
force_list,
|
|
15
|
+
is_url,
|
|
16
|
+
normalize_string,
|
|
17
|
+
taglist,
|
|
18
|
+
to_date,
|
|
19
|
+
)
|
|
20
|
+
from udata.harvest.models import HarvestItem
|
|
21
|
+
from udata.models import Checksum, License, Resource, SpatialCoverage, db
|
|
22
|
+
from udata.utils import get_by
|
|
23
|
+
|
|
24
|
+
log = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
GRANULARITIES = {
|
|
27
|
+
"commune": "fr/town",
|
|
28
|
+
"france": "country",
|
|
29
|
+
"pays": "country",
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
RE_NAME = re.compile(r"(\{(?P<url>.+)\})?(?P<name>.+)$")
|
|
33
|
+
|
|
34
|
+
ZONES = {
|
|
35
|
+
"country/fr": "country/fr",
|
|
36
|
+
"country/monde": "country-group/world",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
FREQUENCIES = {
|
|
41
|
+
"ponctuelle": "punctual",
|
|
42
|
+
"temps réel": "continuous",
|
|
43
|
+
"quotidienne": "daily",
|
|
44
|
+
"hebdomadaire": "weekly",
|
|
45
|
+
"bimensuelle": "semimonthly",
|
|
46
|
+
"mensuelle": "monthly",
|
|
47
|
+
"bimestrielle": "bimonthly",
|
|
48
|
+
"trimestrielle": "quarterly",
|
|
49
|
+
"semestrielle": "semiannual",
|
|
50
|
+
"annuelle": "annual",
|
|
51
|
+
"triennale": "triennial",
|
|
52
|
+
"quinquennale": "quinquennial",
|
|
53
|
+
"aucune": "unknown",
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
XSD_PATH = os.path.join(os.path.dirname(__file__), "maaf.xsd")
|
|
57
|
+
|
|
58
|
+
SSL_COMMENT = """
|
|
59
|
+
Le site exposant les données est protégé par un certificat délivré par
|
|
60
|
+
l'IGC/A (IGC officielle de l'État).
|
|
61
|
+
Une exception de sécurité peut apparaître si votre navigateur ne reconnait
|
|
62
|
+
pas cette autorité :
|
|
63
|
+
vous trouverez la procédure à suivre pour éviter une telle alerte
|
|
64
|
+
à l'adresse :
|
|
65
|
+
http://www.ssi.gouv.fr/fr/anssi/services-securises/igc-a/\
|
|
66
|
+
modalites-de-verification-du-certificat-de-l-igc-a-rsa-4096.html
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
schema = Schema(
|
|
70
|
+
{
|
|
71
|
+
Optional("digest"): All(str, Length(min=1)),
|
|
72
|
+
"metadata": {
|
|
73
|
+
"author": str,
|
|
74
|
+
"author_email": Any(All(str, email), None),
|
|
75
|
+
"extras": [{"key": str, "value": str}],
|
|
76
|
+
"frequency": All(Lower, In(FREQUENCIES.keys())),
|
|
77
|
+
"groups": Any(None, All(Lower, "agriculture et alimentation")),
|
|
78
|
+
"id": str,
|
|
79
|
+
"license_id": Any("fr-lo"),
|
|
80
|
+
"maintainer": Any(str, None),
|
|
81
|
+
"maintainer_email": Any(All(str, email), None),
|
|
82
|
+
"notes": All(str, normalize_string),
|
|
83
|
+
"organization": str,
|
|
84
|
+
"private": boolean,
|
|
85
|
+
"resources": All(
|
|
86
|
+
force_list,
|
|
87
|
+
[
|
|
88
|
+
{
|
|
89
|
+
"name": str,
|
|
90
|
+
"description": All(str, normalize_string),
|
|
91
|
+
"format": All(str, Lower, Any("cle", "csv", "pdf", "txt")),
|
|
92
|
+
Optional("last_modified"): All(str, to_date),
|
|
93
|
+
"url": All(str, is_url(full=True)),
|
|
94
|
+
}
|
|
95
|
+
],
|
|
96
|
+
),
|
|
97
|
+
"state": Any(str, None),
|
|
98
|
+
"supplier": str,
|
|
99
|
+
"tags": All(str, taglist),
|
|
100
|
+
"temporal_coverage_from": None,
|
|
101
|
+
"temporal_coverage_to": None,
|
|
102
|
+
"territorial_coverage": {
|
|
103
|
+
"territorial_coverage_code": All(str, Lower, In(ZONES.keys())),
|
|
104
|
+
"territorial_coverage_granularity": All(str, Lower, In(GRANULARITIES.keys())),
|
|
105
|
+
},
|
|
106
|
+
"title": str,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
required=True,
|
|
110
|
+
extra=True,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
LIST_KEYS = "extras", "resources"
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def extract(element):
|
|
118
|
+
lst = [r for r in map(dictize, element) if isinstance(r[0], str)]
|
|
119
|
+
for key in LIST_KEYS:
|
|
120
|
+
values = [v for k, v in [r for r in lst if r[0] == key]]
|
|
121
|
+
if values:
|
|
122
|
+
lst = [r for r in lst if r[0] != key] + [(key, values)]
|
|
123
|
+
return lst
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def dictize(element):
|
|
127
|
+
return element.tag, OrderedDict(extract(element)) or element.text
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class MaafBackend(BaseBackend):
|
|
131
|
+
display_name = "MAAF"
|
|
132
|
+
verify_ssl = False
|
|
133
|
+
|
|
134
|
+
def inner_harvest(self):
|
|
135
|
+
"""Parse the index pages HTML to find link to dataset descriptors"""
|
|
136
|
+
directories = [self.source.url]
|
|
137
|
+
while directories:
|
|
138
|
+
directory = directories.pop(0)
|
|
139
|
+
response = self.get(directory)
|
|
140
|
+
root = html.fromstring(response.text)
|
|
141
|
+
for link in root.xpath("//ul/li/a")[1:]: # Skip parent directory.
|
|
142
|
+
href = link.get("href")
|
|
143
|
+
if href.endswith("/"):
|
|
144
|
+
directories.append(urljoin(directory, href))
|
|
145
|
+
elif href.lower().endswith(".xml"):
|
|
146
|
+
# We use the URL as `remote_id` for now, we'll be replace at
|
|
147
|
+
# the beginning of the process
|
|
148
|
+
self.process_dataset(urljoin(directory, href))
|
|
149
|
+
if self.has_reached_max_items():
|
|
150
|
+
return
|
|
151
|
+
else:
|
|
152
|
+
log.debug("Skip %s", href)
|
|
153
|
+
|
|
154
|
+
def inner_process_dataset(self, item: HarvestItem):
|
|
155
|
+
response = self.get(item.remote_id)
|
|
156
|
+
xml = self.parse_xml(response.content)
|
|
157
|
+
metadata = xml["metadata"]
|
|
158
|
+
|
|
159
|
+
# Replace the `remote_id` from the URL to `id`.
|
|
160
|
+
item.remote_id = metadata["id"]
|
|
161
|
+
dataset = self.get_dataset(item.remote_id)
|
|
162
|
+
|
|
163
|
+
dataset.title = metadata["title"]
|
|
164
|
+
dataset.frequency = FREQUENCIES.get(metadata["frequency"], "unknown")
|
|
165
|
+
dataset.description = metadata["notes"]
|
|
166
|
+
dataset.private = metadata["private"]
|
|
167
|
+
dataset.tags = sorted(set(metadata["tags"]))
|
|
168
|
+
|
|
169
|
+
if metadata.get("license_id"):
|
|
170
|
+
dataset.license = License.objects.get(id=metadata["license_id"])
|
|
171
|
+
|
|
172
|
+
if metadata.get("temporal_coverage_from") and metadata.get("temporal_coverage_to"):
|
|
173
|
+
dataset.temporal_coverage = db.DateRange(
|
|
174
|
+
start=metadata["temporal_coverage_from"], end=metadata["temporal_coverage_to"]
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
if metadata.get("territorial_coverage_code") or metadata.get(
|
|
178
|
+
"territorial_coverage_granularity"
|
|
179
|
+
):
|
|
180
|
+
dataset.spatial = SpatialCoverage()
|
|
181
|
+
|
|
182
|
+
if metadata.get("territorial_coverage_granularity"):
|
|
183
|
+
dataset.spatial.granularity = GRANULARITIES.get(
|
|
184
|
+
metadata["territorial_coverage_granularity"]
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
if metadata.get("territorial_coverage_code"):
|
|
188
|
+
dataset.spatial.zones = [ZONES[metadata["territorial_coverage_code"]]]
|
|
189
|
+
|
|
190
|
+
dataset.resources = []
|
|
191
|
+
cle = get_by(metadata["resources"], "format", "cle")
|
|
192
|
+
for row in metadata["resources"]:
|
|
193
|
+
if row["format"] == "cle":
|
|
194
|
+
continue
|
|
195
|
+
else:
|
|
196
|
+
resource = Resource(
|
|
197
|
+
title=row["name"],
|
|
198
|
+
description=(row["description"] + "\n\n" + SSL_COMMENT).strip(),
|
|
199
|
+
filetype="remote",
|
|
200
|
+
url=row["url"],
|
|
201
|
+
format=row["format"],
|
|
202
|
+
)
|
|
203
|
+
if resource.format == "csv" and cle:
|
|
204
|
+
resource.checksum = Checksum(type="sha256", value=self.get(cle["url"]).text)
|
|
205
|
+
if row.get("last_modified"):
|
|
206
|
+
resource.last_modified_internal = row["last_modified"]
|
|
207
|
+
dataset.resources.append(resource)
|
|
208
|
+
|
|
209
|
+
if metadata.get("author"):
|
|
210
|
+
dataset.extras["author"] = metadata["author"]
|
|
211
|
+
if metadata.get("author_email"):
|
|
212
|
+
dataset.extras["author_email"] = metadata["author_email"]
|
|
213
|
+
if metadata.get("maintainer"):
|
|
214
|
+
dataset.extras["maintainer"] = metadata["maintainer"]
|
|
215
|
+
if metadata.get("maintainer_email"):
|
|
216
|
+
dataset.extras["maintainer_email"] = metadata["maintainer_email"]
|
|
217
|
+
for extra in metadata["extras"]:
|
|
218
|
+
dataset.extras[extra["key"]] = extra["value"]
|
|
219
|
+
|
|
220
|
+
return dataset
|
|
221
|
+
|
|
222
|
+
def parse_xml(self, xml):
|
|
223
|
+
root = etree.fromstring(xml)
|
|
224
|
+
self.xsd.validate(root)
|
|
225
|
+
_, tree = dictize(root)
|
|
226
|
+
return self.validate(tree, schema)
|
|
227
|
+
|
|
228
|
+
@property
|
|
229
|
+
def xsd(self):
|
|
230
|
+
if not getattr(self, "_xsd", None):
|
|
231
|
+
with open(XSD_PATH) as f:
|
|
232
|
+
doc = etree.parse(f)
|
|
233
|
+
self._xsd = etree.XMLSchema(doc)
|
|
234
|
+
return self._xsd
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<xs:schema
|
|
3
|
+
elementFormDefault="qualified"
|
|
4
|
+
version="0.1"
|
|
5
|
+
xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
6
|
+
<!--
|
|
7
|
+
méta-données ETALAB
|
|
8
|
+
contient les informations nécessaires à ETALAB pour référencer nos jeux de données sur data.gouv.fr
|
|
9
|
+
date de MAJ : 07/04/2014
|
|
10
|
+
créé par : Célia Carceller Kemiche
|
|
11
|
+
contact : celia.carceller-kemiche@agriculture.gouv.fr
|
|
12
|
+
-->
|
|
13
|
+
<xs:element name="ETALAB">
|
|
14
|
+
<xs:complexType>
|
|
15
|
+
<xs:sequence>
|
|
16
|
+
<!--
|
|
17
|
+
méta-données des jeux de données référencés sur data.gouv.fr
|
|
18
|
+
-->
|
|
19
|
+
<xs:element name="metadata">
|
|
20
|
+
<xs:complexType>
|
|
21
|
+
<xs:sequence>
|
|
22
|
+
<!--
|
|
23
|
+
Nom du bureau, département ou service producteur du jeu de données
|
|
24
|
+
|
|
25
|
+
Ce champ complète le champ organization, qui lui décrit l'organisme (Ministère, collectivité
|
|
26
|
+
territoriale, entreprise, association, etc) auquel appartient le bureau,
|
|
27
|
+
département ou service.
|
|
28
|
+
|
|
29
|
+
obligatoire - valeur fixe
|
|
30
|
+
|
|
31
|
+
Exemple : "Service de publication des données ouvertes"
|
|
32
|
+
-->
|
|
33
|
+
<xs:element name="author" type="xs:string" />
|
|
34
|
+
<!--
|
|
35
|
+
Courriel de contact
|
|
36
|
+
|
|
37
|
+
facultatif - valeur fixe
|
|
38
|
+
|
|
39
|
+
Exemple : "support@open-data.miniver.gouv.fr"
|
|
40
|
+
-->
|
|
41
|
+
<xs:element name="author_email" type="xs:string" />
|
|
42
|
+
<!--
|
|
43
|
+
Prévoir ici 3 champs personnalisés :
|
|
44
|
+
Key = Quartier et Value = le nom du quartier de SI Source
|
|
45
|
+
Key = Source et Value = le nom de la source de données
|
|
46
|
+
Key = ETL et Value = 0 ==> cas d'usage d'un flux ETL
|
|
47
|
+
|
|
48
|
+
Obligatoire - valeur fixe
|
|
49
|
+
|
|
50
|
+
Exemple :
|
|
51
|
+
<extras>
|
|
52
|
+
<key>Quartier</key>
|
|
53
|
+
<value>SIAL</value>
|
|
54
|
+
</extras>
|
|
55
|
+
<extras>
|
|
56
|
+
<key>Source</key>
|
|
57
|
+
<value>EPHY</value>
|
|
58
|
+
</extras>
|
|
59
|
+
<extras>
|
|
60
|
+
<key>ETL</key>
|
|
61
|
+
<value>0</value>
|
|
62
|
+
</extras>
|
|
63
|
+
-->
|
|
64
|
+
<xs:element name="extras">
|
|
65
|
+
<xs:complexType>
|
|
66
|
+
<xs:sequence>
|
|
67
|
+
<xs:element name="key" type="xs:string" />
|
|
68
|
+
<xs:element name="value" type="xs:string" />
|
|
69
|
+
</xs:sequence>
|
|
70
|
+
</xs:complexType>
|
|
71
|
+
</xs:element>
|
|
72
|
+
<!--
|
|
73
|
+
Fréquence de mise à jour des données
|
|
74
|
+
|
|
75
|
+
Valeurs possibles :
|
|
76
|
+
annuelle
|
|
77
|
+
au fil de l'eau
|
|
78
|
+
bimensuelle
|
|
79
|
+
bimestrielle
|
|
80
|
+
hebdomadaire
|
|
81
|
+
mensuelle
|
|
82
|
+
quotidienne
|
|
83
|
+
semestrielle
|
|
84
|
+
temps réel
|
|
85
|
+
trimestrielle
|
|
86
|
+
|
|
87
|
+
obligatoire - valeur fixe
|
|
88
|
+
-->
|
|
89
|
+
<xs:element name="frequency" type="xs:string" />
|
|
90
|
+
<!--
|
|
91
|
+
Liste des groupes auxquels appartient ce jeu de données
|
|
92
|
+
|
|
93
|
+
facultatif - valeur fixe
|
|
94
|
+
-->
|
|
95
|
+
<xs:element name="groups" type="xs:string" />
|
|
96
|
+
<!--
|
|
97
|
+
Identifiant unique du jeu de données
|
|
98
|
+
|
|
99
|
+
obligatoire
|
|
100
|
+
|
|
101
|
+
La règle d'unicité est la suivante :
|
|
102
|
+
- MINAGRI pour Ministère de l'agriculture
|
|
103
|
+
- QUARTIER : nom du quartier de SI source (référentiel Cellule sécurité pour les nommages des sites
|
|
104
|
+
internet)
|
|
105
|
+
- NOM_SIO ou NOM_SID : nom de la source de données SIO ou SID
|
|
106
|
+
- PERIMETRE : libellé qui caractérise le jeu de données => identique au libellé de la balise
|
|
107
|
+
<Tittle>
|
|
108
|
+
|
|
109
|
+
Exemple : MINAGRI-SIAL-EPHY-Les_produits_phytopharmaceutiques_vues_par_leur_substances
|
|
110
|
+
-->
|
|
111
|
+
<xs:element name="id" type="xs:ID" />
|
|
112
|
+
<!--
|
|
113
|
+
Identifiant unique de la licence jeu de données
|
|
114
|
+
La Licence ouverte / Open License, qui est la licence Etalab, dont le license_id vaut fr-lo.
|
|
115
|
+
|
|
116
|
+
obligatoire - valeur fixe
|
|
117
|
+
-->
|
|
118
|
+
<xs:element name="license_id" fixed="fr-lo" type="xs:string" />
|
|
119
|
+
<!--
|
|
120
|
+
Nom de la personne responsable du jeu de données
|
|
121
|
+
|
|
122
|
+
facultatif, masqué dans l'interface utilisateur - valeur fixe
|
|
123
|
+
-->
|
|
124
|
+
<xs:element name="maintainer" type="xs:string" />
|
|
125
|
+
<!--
|
|
126
|
+
Courriel de la personne responsable du jeu de données
|
|
127
|
+
|
|
128
|
+
facultatif, masqué dans l'interface utilisateur - valeur fixe
|
|
129
|
+
-->
|
|
130
|
+
<xs:element name="maintainer_email" type="xs:string" />
|
|
131
|
+
<!--
|
|
132
|
+
Description litterale du jeu de données
|
|
133
|
+
|
|
134
|
+
A noter : il est possible qu'une exception de sécurité apparaissent au téléchargement du fichiers
|
|
135
|
+
de données. Dans la description du jeu de données, vous devez insérer le
|
|
136
|
+
commentaire :
|
|
137
|
+
« Le site exposant les données est protégé par un certificat délivré par l'IGC/A (IGC officielle de
|
|
138
|
+
l'État). Une exception de sécurité peut apparaître si votre navigateur
|
|
139
|
+
ne reconnait pas cette autorité : vous trouverez la procédure à suivre
|
|
140
|
+
pour éviter une telle alerte à l'adresse :
|
|
141
|
+
http://www.ssi.gouv.fr/fr/anssi/services-securises/igc-a/modalites-de-verification-du-certificat-de-l-igc-a-rsa-4096.html »
|
|
142
|
+
|
|
143
|
+
obligatoire - valeur fixe
|
|
144
|
+
-->
|
|
145
|
+
<xs:element name="notes" type="xs:string" />
|
|
146
|
+
<!--
|
|
147
|
+
Organisme producteur du jeu de données
|
|
148
|
+
|
|
149
|
+
obligatoire - valeur fixe
|
|
150
|
+
-->
|
|
151
|
+
<xs:element name="organization"
|
|
152
|
+
fixed="Ministère de l’Agriculture, de l’Agroalimentaire et de la Forêt"
|
|
153
|
+
type="xs:string" />
|
|
154
|
+
<!--
|
|
155
|
+
Booléen indiquant si le jeu de données est public ou privé
|
|
156
|
+
Pendant les phases de tests (unitaire, intégration et qualif), les jeux de données doivent être
|
|
157
|
+
publiés obligatoirement en mode privé ("1").
|
|
158
|
+
ETALAB ne met pas à disposition d'environnement de tests.
|
|
159
|
+
|
|
160
|
+
obligatoire - valeur fixe
|
|
161
|
+
-->
|
|
162
|
+
<xs:element name="private" default="0" type="xs:boolean" />
|
|
163
|
+
<!--
|
|
164
|
+
Liste des fichiers constituant le jeu de données
|
|
165
|
+
|
|
166
|
+
A noter : chaque fichiers de données est accompagné de son fichier de signature (*.clé) calculé via
|
|
167
|
+
la fonction de hachage SHA-256
|
|
168
|
+
|
|
169
|
+
obligatoire - valeur variable
|
|
170
|
+
-->
|
|
171
|
+
<xs:element name="resources">
|
|
172
|
+
<xs:complexType>
|
|
173
|
+
<xs:sequence>
|
|
174
|
+
<!--
|
|
175
|
+
Exemple : Produits phytopharmaceutiques vus par leurs substances
|
|
176
|
+
|
|
177
|
+
Obligatoire
|
|
178
|
+
-->
|
|
179
|
+
<xs:element name="description" type="xs:string" />
|
|
180
|
+
<!--
|
|
181
|
+
Exemple : CSV
|
|
182
|
+
|
|
183
|
+
Liste possible :
|
|
184
|
+
- HTML
|
|
185
|
+
- CSV
|
|
186
|
+
- PDF
|
|
187
|
+
- XML
|
|
188
|
+
- JSON
|
|
189
|
+
- ODT
|
|
190
|
+
- ODS
|
|
191
|
+
-->
|
|
192
|
+
<xs:element name="format" type="xs:string" />
|
|
193
|
+
<!--
|
|
194
|
+
Exemple : Données brutes produites le 26-11-2011
|
|
195
|
+
-->
|
|
196
|
+
<xs:element name="name" type="xs:string" />
|
|
197
|
+
<!--
|
|
198
|
+
obligatoire
|
|
199
|
+
|
|
200
|
+
La règle d'unicité des noms des fichiers de données brutes est la suivante :
|
|
201
|
+
- PERIMETRE : ID du jeux de données
|
|
202
|
+
- DATE : date de dernière mise à jour
|
|
203
|
+
- EXTENSION : CSV pour les données brutes, CLE pour le fichier clé
|
|
204
|
+
|
|
205
|
+
Exemple nom de fichier :
|
|
206
|
+
MINAGRI-SIAL-EPHY-Les_produits_phytopharmaceutiques_vues_par_leur_substances_2011-10-26.csv
|
|
207
|
+
|
|
208
|
+
L'URL correspondante sera donc composé de :
|
|
209
|
+
- Nom du site web : https://fichiers-publics.agriculture.gouv.fr/etalab/
|
|
210
|
+
- Répertoire racine : ETALAB
|
|
211
|
+
- QUARTIER : ALIM
|
|
212
|
+
- Source : EPHY
|
|
213
|
+
- Nom du fichiers : Id du jeux de données + Date de MAJ + Extension
|
|
214
|
+
|
|
215
|
+
Exemple valueur <URL> :
|
|
216
|
+
https://fichiers-publics.agriculture.gouv.fr/etalab/ETALAB/ALIM/EPHY/MINAGRI-ALIM-EPHY-Les_produits_phyto-pharmaceutiques_vus_par_leurs_substances_2013-11-26.csv
|
|
217
|
+
|
|
218
|
+
-->
|
|
219
|
+
<xs:element name="url" type="xs:string" />
|
|
220
|
+
<!--
|
|
221
|
+
Date de dernière mise à jour du fichier ressource
|
|
222
|
+
|
|
223
|
+
Ce champ est une date au format ISO 8601
|
|
224
|
+
|
|
225
|
+
facultatif - valeur variable
|
|
226
|
+
-->
|
|
227
|
+
<xs:element name="last_modified" type="xs:dateTime" />
|
|
228
|
+
</xs:sequence>
|
|
229
|
+
</xs:complexType>
|
|
230
|
+
</xs:element>
|
|
231
|
+
<!--
|
|
232
|
+
État du jeu de données
|
|
233
|
+
|
|
234
|
+
facultatif - valeur fixe
|
|
235
|
+
-->
|
|
236
|
+
<xs:element name="state" type="xs:string" />
|
|
237
|
+
<!--
|
|
238
|
+
Organisme assurant la fourniture technique du jeu de données
|
|
239
|
+
|
|
240
|
+
Le fournisseur est soit le prestataire déposant automatiquement les jeux de données du producteur
|
|
241
|
+
dans le CKAN d'Etalab, soit l'organisme gérant le dépôt de données d'où
|
|
242
|
+
provient le jeu de données.
|
|
243
|
+
|
|
244
|
+
Ce champ a une structure identique à celle du champ organization.
|
|
245
|
+
|
|
246
|
+
facultatif - valeur fixe
|
|
247
|
+
-->
|
|
248
|
+
<xs:element name="supplier"
|
|
249
|
+
fixed="Ministère de l’Agriculture, de l’Agroalimentaire et de la Forêt"
|
|
250
|
+
type="xs:string" />
|
|
251
|
+
<!--
|
|
252
|
+
Mots-clés associés au jeu de données. L'ensemble des mots clés est présent dans la balise séparé
|
|
253
|
+
par une ","
|
|
254
|
+
|
|
255
|
+
obligatoire : au moins 1 mot clé - valeur fixe
|
|
256
|
+
-->
|
|
257
|
+
<xs:element name="tags" type="xs:string" />
|
|
258
|
+
<!--
|
|
259
|
+
Date de début de la période temporelle couverte par ce jeu de données
|
|
260
|
+
|
|
261
|
+
Ce champ est une date au format ISO 8601.
|
|
262
|
+
|
|
263
|
+
facultatif - valeur variable
|
|
264
|
+
|
|
265
|
+
Définition Wikipedia du format : http://fr.wikipedia.org/wiki/ISO_8601
|
|
266
|
+
Exemple :
|
|
267
|
+
2013-12-31
|
|
268
|
+
2013-12
|
|
269
|
+
2013
|
|
270
|
+
|
|
271
|
+
-->
|
|
272
|
+
<xs:element name="temporal_coverage_from" type="xs:dateTime" />
|
|
273
|
+
<!--
|
|
274
|
+
Date de fin de la période temporelle couverte par ce jeu de données
|
|
275
|
+
|
|
276
|
+
Ce champ est une date au format ISO 8601.
|
|
277
|
+
|
|
278
|
+
facultatif - valeur variable
|
|
279
|
+
|
|
280
|
+
Exemple :
|
|
281
|
+
2013-12-31
|
|
282
|
+
2013-12
|
|
283
|
+
2013
|
|
284
|
+
-->
|
|
285
|
+
<xs:element name="temporal_coverage_to" type="xs:dateTime" />
|
|
286
|
+
<xs:element name="territorial_coverage">
|
|
287
|
+
<xs:complexType>
|
|
288
|
+
<xs:sequence>
|
|
289
|
+
<!--
|
|
290
|
+
Territoire couvert par ce jeu de données
|
|
291
|
+
|
|
292
|
+
Ce champ est une chaîne de caractères contenant une liste de territoires séparés par une virgule.
|
|
293
|
+
|
|
294
|
+
Chaque territoire est au format type/code.
|
|
295
|
+
|
|
296
|
+
Le type peut valoir :
|
|
297
|
+
ArrondissemntOfCommuneOfFrance : Arrondissement municipal (pour Lyon, Marseille, Paris)
|
|
298
|
+
CantonOfFrance : Canton
|
|
299
|
+
CommuneOfFrance : Commune
|
|
300
|
+
Country : Pays
|
|
301
|
+
DepartmentOfFrance : Département
|
|
302
|
+
OverseasCollectivityOfFrance : Collectivité d'outremer
|
|
303
|
+
RegionOfFrance : Région
|
|
304
|
+
|
|
305
|
+
Le code est le code Insee correspondant au type de territoire
|
|
306
|
+
|
|
307
|
+
facultatif - valeur fixe
|
|
308
|
+
|
|
309
|
+
Exemple :
|
|
310
|
+
"CommuneOfFrance/44109" : Nantes
|
|
311
|
+
"DepartmentOfFrance/44,DepartmentOfFrance/973" : Départements de Loire-Atlantique et de Guyane
|
|
312
|
+
"RegionOfFrance/52,OverseasCollectivityOfFrance/986" : Région Pays de la Loire et collectivé
|
|
313
|
+
d'outremer de Wallis et Futuna
|
|
314
|
+
-->
|
|
315
|
+
<xs:element name="territorial_coverage_code"
|
|
316
|
+
type="xs:string" />
|
|
317
|
+
<!--
|
|
318
|
+
Granularité territoriale des informations contenu dans le jeu de données
|
|
319
|
+
|
|
320
|
+
Ce champ est une chaîne de caractères pouvant valoir :
|
|
321
|
+
poi (Point d'intérêt, ie point fourni avec des coordonnées géographiques)
|
|
322
|
+
iris (îlots infra-communaux regroupés en quartiers par l'Insee)
|
|
323
|
+
canton
|
|
324
|
+
commune
|
|
325
|
+
department (département ou collectivité d'outremer)
|
|
326
|
+
epci : Intercommunalité (EPCI)
|
|
327
|
+
france
|
|
328
|
+
region
|
|
329
|
+
|
|
330
|
+
Quand la granularité du jeu de données est infra-communale (point d'intérêt, IRIS, etc), utiliser
|
|
331
|
+
la valeur commune.
|
|
332
|
+
|
|
333
|
+
facultatif - valeur fixe
|
|
334
|
+
-->
|
|
335
|
+
<xs:element name="territorial_coverage_granularity"
|
|
336
|
+
type="xs:string" />
|
|
337
|
+
</xs:sequence>
|
|
338
|
+
</xs:complexType>
|
|
339
|
+
</xs:element>
|
|
340
|
+
<!--
|
|
341
|
+
Titre du jeu de données
|
|
342
|
+
|
|
343
|
+
Ce champ est celui défini en standard par CKAN.
|
|
344
|
+
|
|
345
|
+
obligatoire - valeur fixe
|
|
346
|
+
-->
|
|
347
|
+
<xs:element name="title" type="xs:string" />
|
|
348
|
+
</xs:sequence>
|
|
349
|
+
</xs:complexType>
|
|
350
|
+
</xs:element>
|
|
351
|
+
<!--
|
|
352
|
+
Signature SHA-256 des méta-données
|
|
353
|
+
Cette clé de signature est calculée via la fonction de hachage SHA-256 appliquée sur la balise
|
|
354
|
+
<metadata>
|
|
355
|
+
|
|
356
|
+
Facultatif - valeur variable
|
|
357
|
+
-->
|
|
358
|
+
<xs:element name="digest" type="xs:string" />
|
|
359
|
+
</xs:sequence>
|
|
360
|
+
</xs:complexType>
|
|
361
|
+
</xs:element>
|
|
362
|
+
</xs:schema>
|