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.

Files changed (24) hide show
  1. udata/harvest/backends/maaf.py +234 -0
  2. udata/harvest/backends/maaf.xsd +362 -0
  3. udata/static/chunks/{10.8ca60413647062717b1e.js → 10.471164b2a9fe15614797.js} +3 -3
  4. udata/static/chunks/{10.8ca60413647062717b1e.js.map → 10.471164b2a9fe15614797.js.map} +1 -1
  5. udata/static/chunks/{11.b6f741fcc366abfad9c4.js → 11.51d706fb9521c16976bc.js} +3 -3
  6. udata/static/chunks/{11.b6f741fcc366abfad9c4.js.map → 11.51d706fb9521c16976bc.js.map} +1 -1
  7. udata/static/chunks/{13.2d06442dd9a05d9777b5.js → 13.f29411b06be1883356a3.js} +2 -2
  8. udata/static/chunks/{13.2d06442dd9a05d9777b5.js.map → 13.f29411b06be1883356a3.js.map} +1 -1
  9. udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js → 17.3bd0340930d4a314ce9c.js} +2 -2
  10. udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js.map → 17.3bd0340930d4a314ce9c.js.map} +1 -1
  11. udata/static/chunks/{19.f03a102365af4315f9db.js → 19.8da42e8359d72afc2618.js} +3 -3
  12. udata/static/chunks/{19.f03a102365af4315f9db.js.map → 19.8da42e8359d72afc2618.js.map} +1 -1
  13. udata/static/chunks/{8.778091d55cd8ea39af6b.js → 8.54e44b102164ae5e7a67.js} +2 -2
  14. udata/static/chunks/{8.778091d55cd8ea39af6b.js.map → 8.54e44b102164ae5e7a67.js.map} +1 -1
  15. udata/static/chunks/{9.033d7e190ca9e226a5d0.js → 9.07515e5187f475bce828.js} +3 -3
  16. udata/static/chunks/{9.033d7e190ca9e226a5d0.js.map → 9.07515e5187f475bce828.js.map} +1 -1
  17. udata/static/common.js +1 -1
  18. udata/static/common.js.map +1 -1
  19. {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/METADATA +2 -1
  20. {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/RECORD +24 -22
  21. {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/entry_points.txt +1 -0
  22. {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/LICENSE +0 -0
  23. {udata-10.3.1.dev34819.dist-info → udata-10.3.1.dev34843.dist-info}/WHEEL +0 -0
  24. {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>