udata 10.8.1.dev36652__py2.py3-none-any.whl → 10.8.2__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/__init__.py +1 -1
- udata/app.py +0 -2
- udata/commands/db.py +22 -9
- udata/core/dataset/models.py +5 -3
- udata/core/discussions/api.py +2 -2
- udata/core/jobs/api.py +3 -3
- udata/core/metrics/helpers.py +10 -0
- udata/core/metrics/tasks.py +144 -1
- udata/core/organization/api.py +2 -2
- udata/core/post/api.py +1 -1
- udata/core/user/api.py +1 -1
- udata/features/identicon/api.py +1 -1
- udata/harvest/actions.py +24 -28
- udata/harvest/api.py +28 -36
- udata/harvest/backends/ckan/__init__.py +3 -0
- udata/harvest/backends/ckan/harvesters.py +274 -0
- udata/harvest/backends/ckan/schemas/__init__.py +0 -0
- udata/harvest/backends/ckan/schemas/ckan.py +86 -0
- udata/harvest/backends/ckan/schemas/dkan.py +98 -0
- udata/harvest/commands.py +7 -7
- udata/harvest/tasks.py +1 -1
- udata/harvest/tests/ckan/conftest.py +67 -0
- udata/harvest/tests/ckan/data/dkan-french-w-license.json +226 -0
- udata/harvest/tests/ckan/test_ckan_backend.py +697 -0
- udata/harvest/tests/ckan/test_ckan_backend_errors.py +140 -0
- udata/harvest/tests/ckan/test_ckan_backend_filters.py +130 -0
- udata/harvest/tests/ckan/test_dkan_backend.py +68 -0
- udata/harvest/tests/test_actions.py +27 -32
- udata/harvest/tests/test_api.py +23 -18
- udata/harvest/tests/test_dcat_backend.py +29 -29
- udata/migrations/2025-07-30-purge-old-harvest-dynamic-fields.py +29 -0
- udata/mongo/slug_fields.py +25 -8
- udata/routing.py +6 -0
- 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.39e106d56f794ebd06a0.js} +2 -2
- udata/static/chunks/{13.2d06442dd9a05d9777b5.js.map → 13.39e106d56f794ebd06a0.js.map} +1 -1
- udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js → 17.70cbb4a91b002338007e.js} +2 -2
- udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js.map → 17.70cbb4a91b002338007e.js.map} +1 -1
- udata/static/chunks/{19.f03a102365af4315f9db.js → 19.a348a5fff8fe2801e52a.js} +3 -3
- udata/static/chunks/{19.f03a102365af4315f9db.js.map → 19.a348a5fff8fe2801e52a.js.map} +1 -1
- udata/static/chunks/{5.0fa1408dae4e76b87b2e.js → 5.343ca020a2d38cec1a14.js} +3 -3
- udata/static/chunks/{5.0fa1408dae4e76b87b2e.js.map → 5.343ca020a2d38cec1a14.js.map} +1 -1
- udata/static/chunks/{6.d663709d877baa44a71e.js → 6.a3b07de9dd2ca2d24e85.js} +3 -3
- udata/static/chunks/{6.d663709d877baa44a71e.js.map → 6.a3b07de9dd2ca2d24e85.js.map} +1 -1
- udata/static/chunks/{8.778091d55cd8ea39af6b.js → 8.462bb3029de008497675.js} +2 -2
- udata/static/chunks/{8.778091d55cd8ea39af6b.js.map → 8.462bb3029de008497675.js.map} +1 -1
- udata/static/common.js +1 -1
- udata/static/common.js.map +1 -1
- udata/tests/api/test_datasets_api.py +0 -46
- udata/tests/api/test_organizations_api.py +5 -0
- udata/tests/cli/test_db_cli.py +12 -0
- udata/tests/dataset/test_dataset_model.py +0 -16
- udata/tests/metrics/__init__.py +0 -0
- udata/tests/metrics/conftest.py +15 -0
- udata/tests/metrics/helpers.py +58 -0
- udata/tests/metrics/test_metrics.py +67 -0
- udata/tests/metrics/test_tasks.py +171 -0
- udata/translations/ar/LC_MESSAGES/udata.mo +0 -0
- udata/translations/ar/LC_MESSAGES/udata.po +72 -65
- udata/translations/de/LC_MESSAGES/udata.mo +0 -0
- udata/translations/de/LC_MESSAGES/udata.po +72 -65
- udata/translations/es/LC_MESSAGES/udata.mo +0 -0
- udata/translations/es/LC_MESSAGES/udata.po +72 -65
- udata/translations/fr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/fr/LC_MESSAGES/udata.po +72 -65
- udata/translations/it/LC_MESSAGES/udata.mo +0 -0
- udata/translations/it/LC_MESSAGES/udata.po +72 -65
- udata/translations/pt/LC_MESSAGES/udata.mo +0 -0
- udata/translations/pt/LC_MESSAGES/udata.po +72 -65
- udata/translations/sr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/sr/LC_MESSAGES/udata.po +72 -65
- udata/translations/udata.pot +74 -70
- {udata-10.8.1.dev36652.dist-info → udata-10.8.2.dist-info}/METADATA +16 -2
- {udata-10.8.1.dev36652.dist-info → udata-10.8.2.dist-info}/RECORD +79 -62
- {udata-10.8.1.dev36652.dist-info → udata-10.8.2.dist-info}/entry_points.txt +2 -0
- {udata-10.8.1.dev36652.dist-info → udata-10.8.2.dist-info}/LICENSE +0 -0
- {udata-10.8.1.dev36652.dist-info → udata-10.8.2.dist-info}/WHEEL +0 -0
- {udata-10.8.1.dev36652.dist-info → udata-10.8.2.dist-info}/top_level.txt +0 -0
udata/harvest/commands.py
CHANGED
|
@@ -44,7 +44,7 @@ def create(name, url, backend, frequency=None, owner=None, org=None):
|
|
|
44
44
|
@click.argument("identifier")
|
|
45
45
|
def validate(identifier):
|
|
46
46
|
"""Validate a source given its identifier"""
|
|
47
|
-
source = actions.validate_source(identifier)
|
|
47
|
+
source = actions.validate_source(actions.get_source(identifier))
|
|
48
48
|
log.info("Source %s (%s) has been validated", source.slug, str(source.id))
|
|
49
49
|
|
|
50
50
|
|
|
@@ -52,7 +52,7 @@ def validate(identifier):
|
|
|
52
52
|
def delete(identifier):
|
|
53
53
|
"""Delete a harvest source"""
|
|
54
54
|
log.info('Deleting source "%s"', identifier)
|
|
55
|
-
actions.delete_source(identifier)
|
|
55
|
+
actions.delete_source(actions.get_source(identifier))
|
|
56
56
|
log.info('Deleted source "%s"', identifier)
|
|
57
57
|
|
|
58
58
|
|
|
@@ -61,7 +61,7 @@ def delete(identifier):
|
|
|
61
61
|
def clean(identifier):
|
|
62
62
|
"""Delete all datasets linked to a harvest source"""
|
|
63
63
|
log.info(f'Cleaning source "{identifier}"')
|
|
64
|
-
num_of_datasets = actions.clean_source(identifier)
|
|
64
|
+
num_of_datasets = actions.clean_source(actions.get_source(identifier))
|
|
65
65
|
log.info(f'Cleaned source "{identifier}" - deleted {num_of_datasets} dataset(s)')
|
|
66
66
|
|
|
67
67
|
|
|
@@ -99,7 +99,7 @@ def backends():
|
|
|
99
99
|
def launch(identifier):
|
|
100
100
|
"""Launch a source harvesting on the workers"""
|
|
101
101
|
log.info('Launching harvest job for source "%s"', identifier)
|
|
102
|
-
actions.launch(identifier)
|
|
102
|
+
actions.launch(actions.get_source(identifier))
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
@grp.command()
|
|
@@ -107,7 +107,7 @@ def launch(identifier):
|
|
|
107
107
|
def run(identifier):
|
|
108
108
|
"""Run a harvester synchronously"""
|
|
109
109
|
log.info('Harvesting source "%s"', identifier)
|
|
110
|
-
actions.run(identifier)
|
|
110
|
+
actions.run(actions.get_source(identifier))
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
@grp.command()
|
|
@@ -121,7 +121,7 @@ def run(identifier):
|
|
|
121
121
|
@click.option("-M", "--month-of-year", default="*", help="The crontab expression for month of year")
|
|
122
122
|
def schedule(identifier, **kwargs):
|
|
123
123
|
"""Schedule a harvest job to run periodically"""
|
|
124
|
-
source = actions.schedule(identifier, **kwargs)
|
|
124
|
+
source = actions.schedule(actions.get_source(identifier), **kwargs)
|
|
125
125
|
msg = "Scheduled {source.name} with the following crontab: {cron}"
|
|
126
126
|
log.info(msg.format(source=source, cron=source.periodic_task.crontab))
|
|
127
127
|
|
|
@@ -130,7 +130,7 @@ def schedule(identifier, **kwargs):
|
|
|
130
130
|
@click.argument("identifier")
|
|
131
131
|
def unschedule(identifier):
|
|
132
132
|
"""Unschedule a periodical harvest job"""
|
|
133
|
-
source = actions.unschedule(identifier)
|
|
133
|
+
source = actions.unschedule(actions.get_source(identifier))
|
|
134
134
|
log.info('Unscheduled harvest source "%s"', source.name)
|
|
135
135
|
|
|
136
136
|
|
udata/harvest/tasks.py
CHANGED
|
@@ -14,7 +14,7 @@ def harvest(self, ident):
|
|
|
14
14
|
|
|
15
15
|
source = HarvestSource.get(ident)
|
|
16
16
|
if source.deleted or not source.active:
|
|
17
|
-
log.info('Ignoring inactive or deleted source "%s"',
|
|
17
|
+
log.info('Ignoring inactive or deleted source "%s"', source.id)
|
|
18
18
|
return # Ignore deleted and inactive sources
|
|
19
19
|
Backend = backends.get(current_app, source.backend)
|
|
20
20
|
backend = Backend(source)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from urllib.parse import urljoin
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
import requests
|
|
6
|
+
from faker.providers import BaseProvider
|
|
7
|
+
|
|
8
|
+
from udata.utils import faker, faker_provider
|
|
9
|
+
|
|
10
|
+
CKAN_URL = "http://localhost:5000"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def pytest_configure(config):
|
|
14
|
+
config.addinivalue_line(
|
|
15
|
+
"markers",
|
|
16
|
+
"ckan_data(fixture): specify the data fixture they rely on. This allows `data`, `result` and `kwargs` fixtures to be populated with the associated data harvest data.",
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CkanError(ValueError):
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CkanClient(object):
|
|
25
|
+
BASE_URL = CKAN_URL
|
|
26
|
+
API_URL = "{}/api/3/action/".format(BASE_URL)
|
|
27
|
+
PACKAGE_LIST_URL = "{}package_list".format(API_URL)
|
|
28
|
+
PACKAGE_SEARCH_URL = "{}package_search".format(API_URL)
|
|
29
|
+
PACKAGE_SHOW_URL = "{}package_show".format(API_URL)
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def headers(self):
|
|
33
|
+
return {
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
"Authorization": "dummy_apikey",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
def get(self, url, **kwargs):
|
|
39
|
+
return requests.get(url, headers=self.headers, **kwargs)
|
|
40
|
+
|
|
41
|
+
def post(self, url, data, **kwargs):
|
|
42
|
+
return requests.post(url, data=json.dumps(data), headers=self.headers, **kwargs)
|
|
43
|
+
|
|
44
|
+
def action_url(self, endpoint):
|
|
45
|
+
path = "/".join(["api/3/action", endpoint])
|
|
46
|
+
return urljoin(self.BASE_URL, path)
|
|
47
|
+
|
|
48
|
+
def action(self, endpoint, data=None, **kwargs):
|
|
49
|
+
url = self.action_url(endpoint)
|
|
50
|
+
if data:
|
|
51
|
+
response = self.post(url, data, params=kwargs)
|
|
52
|
+
else:
|
|
53
|
+
response = self.get(url, params=kwargs)
|
|
54
|
+
if not 200 <= response.status_code < 300:
|
|
55
|
+
raise CkanError(response.text.strip('"'))
|
|
56
|
+
return response.json()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@pytest.fixture(scope="session")
|
|
60
|
+
def ckan():
|
|
61
|
+
return CkanClient()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@faker_provider
|
|
65
|
+
class UdataCkanProvider(BaseProvider):
|
|
66
|
+
def unique_url(self):
|
|
67
|
+
return "{0}?_={1}".format(faker.uri(), faker.unique_string())
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
{
|
|
2
|
+
"help": "Return the metadata of a dataset (package) and its resources. :param id: the id or name of the dataset :type id: string",
|
|
3
|
+
"success": true,
|
|
4
|
+
"result": [
|
|
5
|
+
{
|
|
6
|
+
"id": "04be6288-696d-4331-850d-a144871a7e3a",
|
|
7
|
+
"name": "antennes-regionales-de-la-region-hauts-de-france-au-01102019-0",
|
|
8
|
+
"title": "Antennes régionales de la Région Hauts-de-France (au 01/10/2019)",
|
|
9
|
+
"author_email": "sig@hautsdefrance.fr",
|
|
10
|
+
"maintainer": "Opendata de la Région Hauts-de-France",
|
|
11
|
+
"maintainer_email": "opendata@hautsdefrance.fr",
|
|
12
|
+
"license_title": "http://www.etalab.gouv.fr/pages/Licence_ouverte_Open_licence-5899923.html",
|
|
13
|
+
"notes": "<p>Liste et coordonnées des antennes de proximité du conseil régional Hauts-de-France.</p>\n",
|
|
14
|
+
"url": "https://opendata.hautsdefrance.fr/?q=dataset/antennes-regionales-de-la-region-hauts-de-france-au-01102019-0",
|
|
15
|
+
"state": "Active",
|
|
16
|
+
"private": true,
|
|
17
|
+
"revision_timestamp": "jeu, 19/12/2019 - 03:00",
|
|
18
|
+
"metadata_created": "mar, 10/12/2019 - 09:23",
|
|
19
|
+
"metadata_modified": "2019-09-30 22:00:00",
|
|
20
|
+
"creator_user_id": "235f2695-89bd-4a0d-8bcf-b6e26b7b3981",
|
|
21
|
+
"type": "Dataset",
|
|
22
|
+
"resources": [
|
|
23
|
+
{
|
|
24
|
+
"id": "33f30271-cd5c-49ae-b44b-595caae16126",
|
|
25
|
+
"revision_id": "",
|
|
26
|
+
"url": "https://geocatalogue.hautsdefrance.fr/geonetwork/srv/api/records/4b5f8e1b-de37-47cd-9203-37a59f318b09/attachments/coordonnees_antennes.xlsx",
|
|
27
|
+
"description": "<p>Tableau des données</p>\n",
|
|
28
|
+
"format": "xlsx",
|
|
29
|
+
"state": "Active",
|
|
30
|
+
"revision_timestamp": "jeu, 19/12/2019 - 03:00",
|
|
31
|
+
"name": "coordonnees_antennes.xlsx",
|
|
32
|
+
"mimetype": "xlsx",
|
|
33
|
+
"size": "42 octets",
|
|
34
|
+
"created": "jeu, 19/12/2019 - 03:00",
|
|
35
|
+
"resource_group_id": "b72cd25d-1cec-49f6-8c71-297bd373fa01",
|
|
36
|
+
"last_modified": "Date changed jeu, 19/12/2019 - 03:00"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "ab5948b1-95be-4806-ad8d-efaa9ffe43dc",
|
|
40
|
+
"revision_id": "",
|
|
41
|
+
"url": "https://sig.hautsdefrance.fr/ext/mv/?config=antenne_regionale.xml#",
|
|
42
|
+
"description": "<p>Visionneuse cartographique avec une représentation simplifiée des données</p>\n",
|
|
43
|
+
"format": "",
|
|
44
|
+
"state": "Active",
|
|
45
|
+
"revision_timestamp": "jeu, 19/12/2019 - 03:00",
|
|
46
|
+
"name": "Visionneuse mviewer",
|
|
47
|
+
"mimetype": "",
|
|
48
|
+
"size": "",
|
|
49
|
+
"created": "jeu, 19/12/2019 - 03:00",
|
|
50
|
+
"resource_group_id": "b72cd25d-1cec-49f6-8c71-297bd373fa01",
|
|
51
|
+
"last_modified": "Date changed jeu, 19/12/2019 - 03:00"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"tags": [
|
|
55
|
+
{
|
|
56
|
+
"id": "0800bf74-0728-48ef-b6bb-6e458feff785",
|
|
57
|
+
"vocabulary_id": "2",
|
|
58
|
+
"name": "ADMINISTRATION"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "3e213764-c884-402b-88f5-097a5de38876",
|
|
62
|
+
"vocabulary_id": "2",
|
|
63
|
+
"name": "ADRESSE"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"id": "8da693f4-e4d3-432e-8192-fa4d12ee21e8",
|
|
67
|
+
"vocabulary_id": "2",
|
|
68
|
+
"name": "AISNE"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"id": "40577117-4987-4588-b08c-e1636fa0865b",
|
|
72
|
+
"vocabulary_id": "2",
|
|
73
|
+
"name": "ANTENNE REGIONALE"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"id": "46af567e-d862-4d65-8912-0f7eff3f94a8",
|
|
77
|
+
"vocabulary_id": "2",
|
|
78
|
+
"name": "DONNEES OUVERTES"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "713c6627-5caa-4434-9583-159b8f9fbfea",
|
|
82
|
+
"vocabulary_id": "2",
|
|
83
|
+
"name": "HAUTS-DE-FRANCE"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"id": "1e14a78d-127f-4401-ac4a-09159f5d22b2",
|
|
87
|
+
"vocabulary_id": "2",
|
|
88
|
+
"name": "NORD"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": "08f08873-ce41-465b-a055-826f6cee0ca4",
|
|
92
|
+
"vocabulary_id": "2",
|
|
93
|
+
"name": "OISE"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"id": "de6a5ac7-c9cb-42c8-b6a9-506740c54be3",
|
|
97
|
+
"vocabulary_id": "2",
|
|
98
|
+
"name": "PAS-DE-CALAIS"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "b428bef2-9a4c-4545-9a70-1549ae2384a7",
|
|
102
|
+
"vocabulary_id": "2",
|
|
103
|
+
"name": "POLITIQUE REGIONALE"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": "f8676e82-0864-4b8f-afd2-2ca3368ccb53",
|
|
107
|
+
"vocabulary_id": "2",
|
|
108
|
+
"name": "PROXIMITE"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"id": "c18de608-ae9b-4043-81e1-27e367461a0d",
|
|
112
|
+
"vocabulary_id": "2",
|
|
113
|
+
"name": "SOMME"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"id": "33efc6a3-86b4-4ca3-b9b1-301d8ce7a379",
|
|
117
|
+
"vocabulary_id": "2",
|
|
118
|
+
"name": "Services d utilité publique et services publics"
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
"groups": [
|
|
122
|
+
{
|
|
123
|
+
"description": "<p>Conseil régional des Hauts-de-France</p>\n",
|
|
124
|
+
"id": "b72cd25d-1cec-49f6-8c71-297bd373fa01",
|
|
125
|
+
"image_display_url": "https://opendata.hautsdefrance.fr/sites/default/files/Logo%20R%C3%A9gion%20HDF-pourleweb.jpg",
|
|
126
|
+
"title": "Région Hauts-de-France",
|
|
127
|
+
"name": "group/region-hauts-de-france"
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"extras": [
|
|
131
|
+
{
|
|
132
|
+
"key": "access_constraints",
|
|
133
|
+
"value": "[]"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"key": "bbox-east-long",
|
|
137
|
+
"value": "4.65820313"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"key": "bbox-north-lat",
|
|
141
|
+
"value": "51.16423318"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"key": "bbox-south-lat",
|
|
145
|
+
"value": "48.80546301"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"key": "bbox-west-long",
|
|
149
|
+
"value": "1.18652344"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"key": "contact-email",
|
|
153
|
+
"value": "sig@hautsdefrance.fr"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"key": "coupled-resource",
|
|
157
|
+
"value": "[]"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"key": "dataset-reference-date",
|
|
161
|
+
"value": "[{"type": "revision", "value": "2019-10-01"}]"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"key": "frequency-of-update",
|
|
165
|
+
"value": "asNeeded"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"key": "graphic-preview-description",
|
|
169
|
+
"value": "logohdf.png"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"key": "graphic-preview-file",
|
|
173
|
+
"value": "https://geocatalogue.hautsdefrance.fr/geonetwork/srv/api/records/4b5f8e1b-de37-47cd-9203-37a59f318b09/attachments/logohdf.png"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"key": "guid",
|
|
177
|
+
"value": "4b5f8e1b-de37-47cd-9203-37a59f318b09"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"key": "licence",
|
|
181
|
+
"value": "[]"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"key": "metadata-date",
|
|
185
|
+
"value": "2019-11-13T11:24:54"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"key": "metadata-language",
|
|
189
|
+
"value": "fre"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"key": "metadata_created",
|
|
193
|
+
"value": "2019-11-13T11:24:54"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"key": "metadata_modified",
|
|
197
|
+
"value": "2019-11-13T11:24:54"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"key": "resource-type",
|
|
201
|
+
"value": "dataset"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"key": "responsible-party",
|
|
205
|
+
"value": "[{"name": "R\\u00e9gion Hauts-de-France", "roles": ["pointOfContact"]}]"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"key": "spatial_harvester",
|
|
209
|
+
"value": "true"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"key": "harvest_object_id",
|
|
213
|
+
"value": "281dfceb-ed90-46da-aef6-4ad5e1348150"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"key": "harvest_source_id",
|
|
217
|
+
"value": "c6a6feb7-fc9a-4a26-ab6a-cd13024c4fdd"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"key": "harvest_source_title",
|
|
221
|
+
"value": "Données ouvertes publiées par la région Hauts-de-France"
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
]
|
|
226
|
+
}
|