udata 9.1.2.dev30355__py2.py3-none-any.whl → 9.1.2.dev30382__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.
- tasks/__init__.py +109 -107
- tasks/helpers.py +18 -18
- udata/__init__.py +4 -4
- udata/admin/views.py +5 -5
- udata/api/__init__.py +135 -124
- udata/api/commands.py +45 -37
- udata/api/errors.py +5 -4
- udata/api/fields.py +23 -21
- udata/api/oauth2.py +55 -74
- udata/api/parsers.py +15 -15
- udata/api/signals.py +1 -1
- udata/api_fields.py +137 -89
- udata/app.py +56 -54
- udata/assets.py +5 -5
- udata/auth/__init__.py +37 -26
- udata/auth/forms.py +23 -15
- udata/auth/helpers.py +1 -1
- udata/auth/mails.py +3 -3
- udata/auth/password_validation.py +19 -15
- udata/auth/views.py +94 -68
- udata/commands/__init__.py +71 -69
- udata/commands/cache.py +7 -7
- udata/commands/db.py +201 -140
- udata/commands/dcat.py +36 -30
- udata/commands/fixtures.py +100 -84
- udata/commands/images.py +21 -20
- udata/commands/info.py +17 -20
- udata/commands/init.py +10 -10
- udata/commands/purge.py +12 -13
- udata/commands/serve.py +41 -29
- udata/commands/static.py +16 -18
- udata/commands/test.py +20 -20
- udata/commands/tests/fixtures.py +26 -24
- udata/commands/worker.py +31 -33
- udata/core/__init__.py +12 -12
- udata/core/activity/__init__.py +0 -1
- udata/core/activity/api.py +59 -49
- udata/core/activity/models.py +28 -26
- udata/core/activity/signals.py +1 -1
- udata/core/activity/tasks.py +16 -10
- udata/core/badges/api.py +6 -6
- udata/core/badges/commands.py +14 -13
- udata/core/badges/fields.py +8 -5
- udata/core/badges/forms.py +7 -4
- udata/core/badges/models.py +16 -31
- udata/core/badges/permissions.py +1 -3
- udata/core/badges/signals.py +2 -2
- udata/core/badges/tasks.py +3 -2
- udata/core/badges/tests/test_commands.py +10 -10
- udata/core/badges/tests/test_model.py +24 -31
- udata/core/contact_point/api.py +19 -18
- udata/core/contact_point/api_fields.py +21 -14
- udata/core/contact_point/factories.py +2 -2
- udata/core/contact_point/forms.py +7 -6
- udata/core/contact_point/models.py +3 -5
- udata/core/dataservices/api.py +26 -21
- udata/core/dataservices/factories.py +13 -11
- udata/core/dataservices/models.py +35 -40
- udata/core/dataservices/permissions.py +4 -4
- udata/core/dataservices/rdf.py +40 -17
- udata/core/dataservices/tasks.py +4 -3
- udata/core/dataset/actions.py +10 -10
- udata/core/dataset/activities.py +21 -23
- udata/core/dataset/api.py +321 -298
- udata/core/dataset/api_fields.py +443 -271
- udata/core/dataset/apiv2.py +305 -229
- udata/core/dataset/commands.py +38 -36
- udata/core/dataset/constants.py +61 -54
- udata/core/dataset/csv.py +70 -74
- udata/core/dataset/events.py +39 -32
- udata/core/dataset/exceptions.py +8 -4
- udata/core/dataset/factories.py +57 -65
- udata/core/dataset/forms.py +87 -63
- udata/core/dataset/models.py +336 -280
- udata/core/dataset/permissions.py +9 -6
- udata/core/dataset/preview.py +15 -17
- udata/core/dataset/rdf.py +156 -122
- udata/core/dataset/search.py +92 -77
- udata/core/dataset/signals.py +1 -1
- udata/core/dataset/tasks.py +63 -54
- udata/core/discussions/actions.py +5 -5
- udata/core/discussions/api.py +124 -120
- udata/core/discussions/factories.py +2 -2
- udata/core/discussions/forms.py +9 -7
- udata/core/discussions/metrics.py +1 -3
- udata/core/discussions/models.py +25 -24
- udata/core/discussions/notifications.py +18 -14
- udata/core/discussions/permissions.py +3 -3
- udata/core/discussions/signals.py +4 -4
- udata/core/discussions/tasks.py +24 -28
- udata/core/followers/api.py +32 -33
- udata/core/followers/models.py +9 -9
- udata/core/followers/signals.py +3 -3
- udata/core/jobs/actions.py +7 -7
- udata/core/jobs/api.py +99 -92
- udata/core/jobs/commands.py +48 -49
- udata/core/jobs/forms.py +11 -11
- udata/core/jobs/models.py +6 -6
- udata/core/metrics/__init__.py +2 -2
- udata/core/metrics/commands.py +34 -30
- udata/core/metrics/models.py +2 -4
- udata/core/metrics/signals.py +1 -1
- udata/core/metrics/tasks.py +3 -3
- udata/core/organization/activities.py +12 -15
- udata/core/organization/api.py +167 -174
- udata/core/organization/api_fields.py +183 -124
- udata/core/organization/apiv2.py +32 -32
- udata/core/organization/commands.py +20 -22
- udata/core/organization/constants.py +11 -11
- udata/core/organization/csv.py +17 -15
- udata/core/organization/factories.py +8 -11
- udata/core/organization/forms.py +32 -26
- udata/core/organization/metrics.py +2 -1
- udata/core/organization/models.py +87 -67
- udata/core/organization/notifications.py +18 -14
- udata/core/organization/permissions.py +10 -11
- udata/core/organization/rdf.py +14 -14
- udata/core/organization/search.py +30 -28
- udata/core/organization/signals.py +7 -7
- udata/core/organization/tasks.py +42 -61
- udata/core/owned.py +38 -27
- udata/core/post/api.py +82 -81
- udata/core/post/constants.py +8 -5
- udata/core/post/factories.py +4 -4
- udata/core/post/forms.py +13 -14
- udata/core/post/models.py +20 -22
- udata/core/post/tests/test_api.py +30 -32
- udata/core/reports/api.py +8 -7
- udata/core/reports/constants.py +1 -3
- udata/core/reports/models.py +10 -10
- udata/core/reuse/activities.py +15 -19
- udata/core/reuse/api.py +123 -126
- udata/core/reuse/api_fields.py +120 -85
- udata/core/reuse/apiv2.py +11 -10
- udata/core/reuse/constants.py +23 -23
- udata/core/reuse/csv.py +18 -18
- udata/core/reuse/factories.py +5 -9
- udata/core/reuse/forms.py +24 -21
- udata/core/reuse/models.py +55 -51
- udata/core/reuse/permissions.py +2 -2
- udata/core/reuse/search.py +49 -46
- udata/core/reuse/signals.py +1 -1
- udata/core/reuse/tasks.py +4 -5
- udata/core/site/api.py +47 -50
- udata/core/site/factories.py +2 -2
- udata/core/site/forms.py +4 -5
- udata/core/site/models.py +94 -63
- udata/core/site/rdf.py +14 -14
- udata/core/spam/api.py +16 -9
- udata/core/spam/constants.py +4 -4
- udata/core/spam/fields.py +13 -7
- udata/core/spam/models.py +27 -20
- udata/core/spam/signals.py +1 -1
- udata/core/spam/tests/test_spam.py +6 -5
- udata/core/spatial/api.py +72 -80
- udata/core/spatial/api_fields.py +73 -58
- udata/core/spatial/commands.py +67 -64
- udata/core/spatial/constants.py +3 -3
- udata/core/spatial/factories.py +37 -54
- udata/core/spatial/forms.py +27 -26
- udata/core/spatial/geoids.py +17 -17
- udata/core/spatial/models.py +43 -47
- udata/core/spatial/tasks.py +2 -1
- udata/core/spatial/tests/test_api.py +115 -130
- udata/core/spatial/tests/test_fields.py +74 -77
- udata/core/spatial/tests/test_geoid.py +22 -22
- udata/core/spatial/tests/test_models.py +5 -7
- udata/core/spatial/translations.py +16 -16
- udata/core/storages/__init__.py +16 -18
- udata/core/storages/api.py +66 -64
- udata/core/storages/tasks.py +7 -7
- udata/core/storages/utils.py +15 -15
- udata/core/storages/views.py +5 -6
- udata/core/tags/api.py +17 -14
- udata/core/tags/csv.py +4 -4
- udata/core/tags/models.py +8 -5
- udata/core/tags/tasks.py +11 -13
- udata/core/tags/views.py +4 -4
- udata/core/topic/api.py +84 -73
- udata/core/topic/apiv2.py +157 -127
- udata/core/topic/factories.py +3 -4
- udata/core/topic/forms.py +12 -14
- udata/core/topic/models.py +14 -19
- udata/core/topic/parsers.py +26 -26
- udata/core/user/activities.py +30 -29
- udata/core/user/api.py +151 -152
- udata/core/user/api_fields.py +132 -100
- udata/core/user/apiv2.py +7 -7
- udata/core/user/commands.py +38 -38
- udata/core/user/factories.py +8 -9
- udata/core/user/forms.py +14 -11
- udata/core/user/metrics.py +2 -2
- udata/core/user/models.py +68 -69
- udata/core/user/permissions.py +4 -5
- udata/core/user/rdf.py +7 -8
- udata/core/user/tasks.py +2 -2
- udata/core/user/tests/test_user_model.py +24 -16
- udata/db/tasks.py +2 -1
- udata/entrypoints.py +35 -31
- udata/errors.py +2 -1
- udata/event/values.py +6 -6
- udata/factories.py +2 -2
- udata/features/identicon/api.py +5 -6
- udata/features/identicon/backends.py +48 -55
- udata/features/identicon/tests/test_backends.py +4 -5
- udata/features/notifications/__init__.py +0 -1
- udata/features/notifications/actions.py +9 -9
- udata/features/notifications/api.py +17 -13
- udata/features/territories/__init__.py +12 -10
- udata/features/territories/api.py +14 -15
- udata/features/territories/models.py +23 -28
- udata/features/transfer/actions.py +8 -11
- udata/features/transfer/api.py +84 -77
- udata/features/transfer/factories.py +2 -1
- udata/features/transfer/models.py +11 -12
- udata/features/transfer/notifications.py +19 -15
- udata/features/transfer/permissions.py +5 -5
- udata/forms/__init__.py +5 -2
- udata/forms/fields.py +164 -172
- udata/forms/validators.py +19 -22
- udata/forms/widgets.py +9 -13
- udata/frontend/__init__.py +31 -26
- udata/frontend/csv.py +68 -58
- udata/frontend/markdown.py +40 -44
- udata/harvest/actions.py +89 -77
- udata/harvest/api.py +294 -238
- udata/harvest/backends/__init__.py +4 -4
- udata/harvest/backends/base.py +128 -111
- udata/harvest/backends/dcat.py +80 -66
- udata/harvest/commands.py +56 -60
- udata/harvest/csv.py +8 -8
- udata/harvest/exceptions.py +6 -3
- udata/harvest/filters.py +24 -23
- udata/harvest/forms.py +27 -28
- udata/harvest/models.py +88 -80
- udata/harvest/notifications.py +15 -10
- udata/harvest/signals.py +13 -13
- udata/harvest/tasks.py +11 -10
- udata/harvest/tests/factories.py +23 -24
- udata/harvest/tests/test_actions.py +136 -166
- udata/harvest/tests/test_api.py +220 -214
- udata/harvest/tests/test_base_backend.py +117 -112
- udata/harvest/tests/test_dcat_backend.py +380 -308
- udata/harvest/tests/test_filters.py +33 -22
- udata/harvest/tests/test_models.py +11 -14
- udata/harvest/tests/test_notifications.py +6 -7
- udata/harvest/tests/test_tasks.py +7 -6
- udata/i18n.py +237 -78
- udata/linkchecker/backends.py +5 -11
- udata/linkchecker/checker.py +23 -22
- udata/linkchecker/commands.py +4 -6
- udata/linkchecker/models.py +6 -6
- udata/linkchecker/tasks.py +18 -20
- udata/mail.py +21 -21
- udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +9 -8
- udata/migrations/2020-08-24-add-fs-filename.py +9 -8
- udata/migrations/2020-09-28-update-reuses-datasets-metrics.py +5 -4
- udata/migrations/2020-10-16-migrate-ods-resources.py +9 -10
- udata/migrations/2021-04-08-update-schema-with-new-structure.py +8 -7
- udata/migrations/2021-05-27-fix-default-schema-name.py +7 -6
- udata/migrations/2021-07-05-remove-unused-badges.py +17 -15
- udata/migrations/2021-07-07-update-schema-for-community-resources.py +7 -6
- udata/migrations/2021-08-17-follow-integrity.py +5 -4
- udata/migrations/2021-08-17-harvest-integrity.py +13 -12
- udata/migrations/2021-08-17-oauth2client-integrity.py +5 -4
- udata/migrations/2021-08-17-transfer-integrity.py +5 -4
- udata/migrations/2021-08-17-users-integrity.py +9 -8
- udata/migrations/2021-12-14-reuse-topics.py +7 -6
- udata/migrations/2022-04-21-improve-extension-detection.py +8 -7
- udata/migrations/2022-09-22-clean-inactive-harvest-datasets.py +16 -14
- udata/migrations/2022-10-10-add-fs_uniquifier-to-user-model.py +6 -6
- udata/migrations/2022-10-10-migrate-harvest-extras.py +36 -26
- udata/migrations/2023-02-08-rename-internal-dates.py +46 -28
- udata/migrations/2024-01-29-fix-reuse-and-dataset-with-private-None.py +10 -8
- udata/migrations/2024-03-22-migrate-activity-kwargs-to-extras.py +6 -4
- udata/migrations/2024-06-11-fix-reuse-datasets-references.py +7 -6
- udata/migrations/__init__.py +123 -105
- udata/models/__init__.py +4 -4
- udata/mongo/__init__.py +13 -11
- udata/mongo/badges_field.py +3 -2
- udata/mongo/datetime_fields.py +13 -12
- udata/mongo/document.py +17 -16
- udata/mongo/engine.py +15 -16
- udata/mongo/errors.py +2 -1
- udata/mongo/extras_fields.py +30 -20
- udata/mongo/queryset.py +12 -12
- udata/mongo/slug_fields.py +38 -28
- udata/mongo/taglist_field.py +1 -2
- udata/mongo/url_field.py +5 -5
- udata/mongo/uuid_fields.py +4 -3
- udata/notifications/__init__.py +1 -1
- udata/notifications/mattermost.py +10 -9
- udata/rdf.py +167 -188
- udata/routing.py +40 -45
- udata/search/__init__.py +18 -19
- udata/search/adapter.py +17 -16
- udata/search/commands.py +44 -51
- udata/search/fields.py +13 -20
- udata/search/query.py +23 -18
- udata/search/result.py +9 -10
- udata/sentry.py +21 -19
- udata/settings.py +262 -198
- udata/sitemap.py +8 -6
- udata/static/chunks/{11.e9b9ca1f3e03d4020377.js → 11.52e531c19f8de80c00cf.js} +3 -3
- udata/static/chunks/{11.e9b9ca1f3e03d4020377.js.map → 11.52e531c19f8de80c00cf.js.map} +1 -1
- udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js → 13.c3343a7f1070061c0e10.js} +2 -2
- udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js.map → 13.c3343a7f1070061c0e10.js.map} +1 -1
- udata/static/chunks/{16.0baa2b64a74a2dcde25c.js → 16.8fa42440ad75ca172e6d.js} +2 -2
- udata/static/chunks/{16.0baa2b64a74a2dcde25c.js.map → 16.8fa42440ad75ca172e6d.js.map} +1 -1
- udata/static/chunks/{19.350a9f150b074b4ecefa.js → 19.9c6c8412729cd6d59cfa.js} +3 -3
- udata/static/chunks/{19.350a9f150b074b4ecefa.js.map → 19.9c6c8412729cd6d59cfa.js.map} +1 -1
- udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js → 5.71d15c2e4f21feee2a9a.js} +3 -3
- udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js.map → 5.71d15c2e4f21feee2a9a.js.map} +1 -1
- udata/static/chunks/{6.d8a5f7b017bcbd083641.js → 6.9139dc098b8ea640b890.js} +3 -3
- udata/static/chunks/{6.d8a5f7b017bcbd083641.js.map → 6.9139dc098b8ea640b890.js.map} +1 -1
- udata/static/common.js +1 -1
- udata/static/common.js.map +1 -1
- udata/storage/s3.py +20 -13
- udata/tags.py +4 -5
- udata/tasks.py +43 -42
- udata/tests/__init__.py +9 -6
- udata/tests/api/__init__.py +5 -6
- udata/tests/api/test_auth_api.py +395 -321
- udata/tests/api/test_base_api.py +31 -33
- udata/tests/api/test_contact_points.py +7 -9
- udata/tests/api/test_dataservices_api.py +211 -158
- udata/tests/api/test_datasets_api.py +823 -812
- udata/tests/api/test_follow_api.py +13 -15
- udata/tests/api/test_me_api.py +95 -112
- udata/tests/api/test_organizations_api.py +301 -339
- udata/tests/api/test_reports_api.py +35 -25
- udata/tests/api/test_reuses_api.py +134 -139
- udata/tests/api/test_swagger.py +5 -5
- udata/tests/api/test_tags_api.py +18 -25
- udata/tests/api/test_topics_api.py +94 -94
- udata/tests/api/test_transfer_api.py +53 -48
- udata/tests/api/test_user_api.py +128 -141
- udata/tests/apiv2/test_datasets.py +290 -198
- udata/tests/apiv2/test_me_api.py +10 -11
- udata/tests/apiv2/test_organizations.py +56 -74
- udata/tests/apiv2/test_swagger.py +5 -5
- udata/tests/apiv2/test_topics.py +69 -87
- udata/tests/cli/test_cli_base.py +8 -8
- udata/tests/cli/test_db_cli.py +21 -19
- udata/tests/dataservice/test_dataservice_tasks.py +8 -12
- udata/tests/dataset/test_csv_adapter.py +44 -35
- udata/tests/dataset/test_dataset_actions.py +2 -3
- udata/tests/dataset/test_dataset_commands.py +7 -8
- udata/tests/dataset/test_dataset_events.py +36 -29
- udata/tests/dataset/test_dataset_model.py +224 -217
- udata/tests/dataset/test_dataset_rdf.py +142 -131
- udata/tests/dataset/test_dataset_tasks.py +15 -15
- udata/tests/dataset/test_resource_preview.py +10 -13
- udata/tests/features/territories/__init__.py +9 -13
- udata/tests/features/territories/test_territories_api.py +71 -91
- udata/tests/forms/test_basic_fields.py +7 -7
- udata/tests/forms/test_current_user_field.py +39 -66
- udata/tests/forms/test_daterange_field.py +31 -39
- udata/tests/forms/test_dict_field.py +28 -26
- udata/tests/forms/test_extras_fields.py +102 -76
- udata/tests/forms/test_form_field.py +8 -8
- udata/tests/forms/test_image_field.py +33 -26
- udata/tests/forms/test_model_field.py +134 -123
- udata/tests/forms/test_model_list_field.py +7 -7
- udata/tests/forms/test_nested_model_list_field.py +117 -79
- udata/tests/forms/test_publish_as_field.py +36 -65
- udata/tests/forms/test_reference_field.py +34 -53
- udata/tests/forms/test_user_forms.py +23 -21
- udata/tests/forms/test_uuid_field.py +6 -10
- udata/tests/frontend/__init__.py +9 -6
- udata/tests/frontend/test_auth.py +7 -6
- udata/tests/frontend/test_csv.py +81 -96
- udata/tests/frontend/test_hooks.py +43 -43
- udata/tests/frontend/test_markdown.py +211 -191
- udata/tests/helpers.py +32 -37
- udata/tests/models.py +2 -2
- udata/tests/organization/test_csv_adapter.py +21 -16
- udata/tests/organization/test_notifications.py +11 -18
- udata/tests/organization/test_organization_model.py +13 -13
- udata/tests/organization/test_organization_rdf.py +29 -22
- udata/tests/organization/test_organization_tasks.py +16 -17
- udata/tests/plugin.py +76 -73
- udata/tests/reuse/test_reuse_model.py +21 -21
- udata/tests/reuse/test_reuse_task.py +11 -13
- udata/tests/search/__init__.py +11 -12
- udata/tests/search/test_adapter.py +60 -70
- udata/tests/search/test_query.py +16 -16
- udata/tests/search/test_results.py +10 -7
- udata/tests/site/test_site_api.py +11 -16
- udata/tests/site/test_site_metrics.py +20 -30
- udata/tests/site/test_site_model.py +4 -5
- udata/tests/site/test_site_rdf.py +94 -78
- udata/tests/test_activity.py +17 -17
- udata/tests/test_discussions.py +292 -299
- udata/tests/test_i18n.py +37 -40
- udata/tests/test_linkchecker.py +91 -85
- udata/tests/test_mail.py +13 -17
- udata/tests/test_migrations.py +219 -180
- udata/tests/test_model.py +164 -157
- udata/tests/test_notifications.py +17 -17
- udata/tests/test_owned.py +14 -14
- udata/tests/test_rdf.py +25 -23
- udata/tests/test_routing.py +89 -93
- udata/tests/test_storages.py +137 -128
- udata/tests/test_tags.py +44 -46
- udata/tests/test_topics.py +7 -7
- udata/tests/test_transfer.py +42 -49
- udata/tests/test_uris.py +160 -161
- udata/tests/test_utils.py +79 -71
- udata/tests/user/test_user_rdf.py +5 -9
- udata/tests/workers/test_jobs_commands.py +57 -58
- udata/tests/workers/test_tasks_routing.py +23 -29
- udata/tests/workers/test_workers_api.py +125 -131
- udata/tests/workers/test_workers_helpers.py +6 -6
- udata/tracking.py +4 -6
- udata/uris.py +45 -46
- udata/utils.py +68 -66
- udata/wsgi.py +1 -1
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/METADATA +3 -2
- udata-9.1.2.dev30382.dist-info/RECORD +704 -0
- udata-9.1.2.dev30355.dist-info/RECORD +0 -704
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/LICENSE +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/WHEEL +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/entry_points.txt +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/top_level.txt +0 -0
udata/rdf.py
CHANGED
|
@@ -1,71 +1,80 @@
|
|
|
1
|
-
|
|
1
|
+
"""
|
|
2
2
|
This module centralize udata-wide RDF helpers and configuration
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
5
|
import logging
|
|
6
6
|
import re
|
|
7
|
+
from html.parser import HTMLParser
|
|
7
8
|
|
|
8
|
-
from flask import
|
|
9
|
-
|
|
9
|
+
from flask import abort, current_app, request, url_for
|
|
10
10
|
from rdflib import Graph, Literal, URIRef
|
|
11
|
-
from rdflib.resource import Resource as RdfResource
|
|
12
11
|
from rdflib.namespace import (
|
|
13
|
-
|
|
12
|
+
DCTERMS,
|
|
13
|
+
FOAF,
|
|
14
|
+
RDF,
|
|
15
|
+
RDFS,
|
|
16
|
+
SKOS,
|
|
17
|
+
XSD,
|
|
18
|
+
Namespace,
|
|
19
|
+
NamespaceManager,
|
|
14
20
|
)
|
|
15
|
-
from rdflib.
|
|
21
|
+
from rdflib.resource import Resource as RdfResource
|
|
22
|
+
from rdflib.util import SUFFIX_FORMAT_MAP
|
|
23
|
+
from rdflib.util import guess_format as raw_guess_format
|
|
24
|
+
|
|
16
25
|
from udata import uris
|
|
17
26
|
from udata.core.contact_point.models import ContactPoint
|
|
27
|
+
from udata.frontend.markdown import parse_html
|
|
18
28
|
from udata.models import Schema
|
|
19
29
|
from udata.mongo.errors import FieldValidationError
|
|
20
|
-
from udata.frontend.markdown import parse_html
|
|
21
30
|
from udata.tags import slug as slugify_tag
|
|
22
31
|
|
|
23
32
|
log = logging.getLogger(__name__)
|
|
24
33
|
|
|
25
34
|
# Extra Namespaces
|
|
26
|
-
ADMS = Namespace(
|
|
27
|
-
DCAT = Namespace(
|
|
28
|
-
DCATAP = Namespace(
|
|
29
|
-
HYDRA = Namespace(
|
|
30
|
-
SCHEMA = Namespace(
|
|
31
|
-
SCV = Namespace(
|
|
32
|
-
SPDX = Namespace(
|
|
33
|
-
VCARD = Namespace(
|
|
34
|
-
FREQ = Namespace(
|
|
35
|
-
EUFREQ = Namespace(
|
|
36
|
-
EUFORMAT = Namespace(
|
|
37
|
-
IANAFORMAT = Namespace(
|
|
35
|
+
ADMS = Namespace("http://www.w3.org/ns/adms#")
|
|
36
|
+
DCAT = Namespace("http://www.w3.org/ns/dcat#")
|
|
37
|
+
DCATAP = Namespace("http://data.europa.eu/r5r/")
|
|
38
|
+
HYDRA = Namespace("http://www.w3.org/ns/hydra/core#")
|
|
39
|
+
SCHEMA = Namespace("http://schema.org/")
|
|
40
|
+
SCV = Namespace("http://purl.org/NET/scovo#")
|
|
41
|
+
SPDX = Namespace("http://spdx.org/rdf/terms#")
|
|
42
|
+
VCARD = Namespace("http://www.w3.org/2006/vcard/ns#")
|
|
43
|
+
FREQ = Namespace("http://purl.org/cld/freq/")
|
|
44
|
+
EUFREQ = Namespace("http://publications.europa.eu/resource/authority/frequency/") # noqa: E501
|
|
45
|
+
EUFORMAT = Namespace("http://publications.europa.eu/resource/authority/file-type/")
|
|
46
|
+
IANAFORMAT = Namespace("https://www.iana.org/assignments/media-types/")
|
|
38
47
|
DCT = DCTERMS # More common usage
|
|
39
|
-
VCARD = Namespace(
|
|
48
|
+
VCARD = Namespace("http://www.w3.org/2006/vcard/ns#")
|
|
40
49
|
|
|
41
50
|
namespace_manager = NamespaceManager(Graph())
|
|
42
|
-
namespace_manager.bind(
|
|
43
|
-
namespace_manager.bind(
|
|
44
|
-
namespace_manager.bind(
|
|
45
|
-
namespace_manager.bind(
|
|
46
|
-
namespace_manager.bind(
|
|
47
|
-
namespace_manager.bind(
|
|
48
|
-
namespace_manager.bind(
|
|
49
|
-
namespace_manager.bind(
|
|
50
|
-
namespace_manager.bind(
|
|
51
|
-
namespace_manager.bind(
|
|
52
|
-
namespace_manager.bind(
|
|
53
|
-
namespace_manager.bind(
|
|
51
|
+
namespace_manager.bind("dcat", DCAT)
|
|
52
|
+
namespace_manager.bind("dcatap", DCATAP)
|
|
53
|
+
namespace_manager.bind("dct", DCT)
|
|
54
|
+
namespace_manager.bind("foaf", FOAF)
|
|
55
|
+
namespace_manager.bind("foaf", FOAF)
|
|
56
|
+
namespace_manager.bind("hydra", HYDRA)
|
|
57
|
+
namespace_manager.bind("rdfs", RDFS)
|
|
58
|
+
namespace_manager.bind("scv", SCV)
|
|
59
|
+
namespace_manager.bind("skos", SKOS)
|
|
60
|
+
namespace_manager.bind("vcard", VCARD)
|
|
61
|
+
namespace_manager.bind("xsd", XSD)
|
|
62
|
+
namespace_manager.bind("freq", FREQ)
|
|
54
63
|
|
|
55
64
|
# Support JSON-LD in format detection
|
|
56
65
|
FORMAT_MAP = SUFFIX_FORMAT_MAP.copy()
|
|
57
|
-
FORMAT_MAP[
|
|
58
|
-
FORMAT_MAP[
|
|
59
|
-
FORMAT_MAP[
|
|
66
|
+
FORMAT_MAP["json"] = "json-ld"
|
|
67
|
+
FORMAT_MAP["jsonld"] = "json-ld"
|
|
68
|
+
FORMAT_MAP["xml"] = "xml"
|
|
60
69
|
|
|
61
70
|
# Map serialization formats to MIME types
|
|
62
71
|
RDF_MIME_TYPES = {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
"xml": "application/rdf+xml",
|
|
73
|
+
"n3": "text/n3",
|
|
74
|
+
"turtle": "application/x-turtle",
|
|
75
|
+
"nt": "application/n-triples",
|
|
76
|
+
"json-ld": "application/ld+json",
|
|
77
|
+
"trig": "application/trig",
|
|
69
78
|
# Available but not activated
|
|
70
79
|
# 'nquads': 'application/n-quads',
|
|
71
80
|
# 'trix': 'text/xml',
|
|
@@ -73,16 +82,16 @@ RDF_MIME_TYPES = {
|
|
|
73
82
|
|
|
74
83
|
# Map accepted MIME types to known formats
|
|
75
84
|
ACCEPTED_MIME_TYPES = {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
"application/rdf+xml": "xml",
|
|
86
|
+
"application/xml": "xml",
|
|
87
|
+
"text/n3": "n3",
|
|
88
|
+
"application/x-turtle": "turtle",
|
|
89
|
+
"text/turtle": "turtle",
|
|
90
|
+
"application/n-triples": "nt",
|
|
91
|
+
"application/ld+json": "json-ld",
|
|
92
|
+
"application/json": "json-ld",
|
|
93
|
+
"application/trig": "trig",
|
|
94
|
+
"text/xml": "xml",
|
|
86
95
|
# Available but not activated
|
|
87
96
|
# 'application/n-quads': 'nquads',
|
|
88
97
|
# 'text/xml': 'trix',
|
|
@@ -90,19 +99,19 @@ ACCEPTED_MIME_TYPES = {
|
|
|
90
99
|
|
|
91
100
|
# Map formats to default used extensions
|
|
92
101
|
RDF_EXTENSIONS = {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
"xml": "xml",
|
|
103
|
+
"n3": "n3",
|
|
104
|
+
"turtle": "ttl",
|
|
105
|
+
"nt": "nt",
|
|
106
|
+
"trig": "trig",
|
|
107
|
+
"json-ld": "json",
|
|
99
108
|
# Available but not activated
|
|
100
109
|
# 'nquads': 'nq',
|
|
101
110
|
# 'trix': 'trix',
|
|
102
111
|
}
|
|
103
112
|
|
|
104
113
|
# Includes control characters, unicode surrogate characters and unicode end-of-plane non-characters
|
|
105
|
-
ILLEGAL_XML_CHARS =
|
|
114
|
+
ILLEGAL_XML_CHARS = "[\x00-\x08\x0b\x0c\x0e-\x1f\ud800-\udfff\ufffe\uffff]"
|
|
106
115
|
|
|
107
116
|
# Map High Value Datasets URIs to keyword categories
|
|
108
117
|
EU_HVD_CATEGORIES = {
|
|
@@ -111,26 +120,27 @@ EU_HVD_CATEGORIES = {
|
|
|
111
120
|
"http://data.europa.eu/bna/c_ac64a52d": "Géospatiales",
|
|
112
121
|
"http://data.europa.eu/bna/c_b79e35eb": "Mobilité",
|
|
113
122
|
"http://data.europa.eu/bna/c_dd313021": "Observation de la terre et environnement",
|
|
114
|
-
"http://data.europa.eu/bna/c_e1da4e07": "Statistiques"
|
|
123
|
+
"http://data.europa.eu/bna/c_e1da4e07": "Statistiques",
|
|
115
124
|
}
|
|
116
|
-
HVD_LEGISLATION =
|
|
125
|
+
HVD_LEGISLATION = "http://data.europa.eu/eli/reg_impl/2023/138/oj"
|
|
117
126
|
TAG_TO_EU_HVD_CATEGORIES = {slugify_tag(EU_HVD_CATEGORIES[uri]): uri for uri in EU_HVD_CATEGORIES}
|
|
118
127
|
|
|
128
|
+
|
|
119
129
|
def guess_format(string):
|
|
120
|
-
|
|
130
|
+
"""Guess format given an extension or a mime-type"""
|
|
121
131
|
if string in ACCEPTED_MIME_TYPES:
|
|
122
132
|
return ACCEPTED_MIME_TYPES[string]
|
|
123
133
|
return raw_guess_format(string, FORMAT_MAP)
|
|
124
134
|
|
|
125
135
|
|
|
126
|
-
def negociate_content(default=
|
|
127
|
-
|
|
136
|
+
def negociate_content(default="json-ld"):
|
|
137
|
+
"""Perform a content negociation on the format given the Accept header"""
|
|
128
138
|
mimetype = request.accept_mimetypes.best_match(ACCEPTED_MIME_TYPES.keys())
|
|
129
139
|
return ACCEPTED_MIME_TYPES.get(mimetype, default)
|
|
130
140
|
|
|
131
141
|
|
|
132
142
|
def want_rdf():
|
|
133
|
-
|
|
143
|
+
"""Check wether client prefer RDF over the default HTML"""
|
|
134
144
|
mimetype = request.accept_mimetypes.best
|
|
135
145
|
return mimetype in ACCEPTED_MIME_TYPES
|
|
136
146
|
|
|
@@ -138,97 +148,56 @@ def want_rdf():
|
|
|
138
148
|
# JSON-LD context used for udata DCAT representation
|
|
139
149
|
CONTEXT = {
|
|
140
150
|
# Namespaces
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
"@vocab": "http://www.w3.org/ns/dcat#",
|
|
152
|
+
"dcat": "http://www.w3.org/ns/dcat#",
|
|
153
|
+
"dct": "http://purl.org/dc/terms/",
|
|
154
|
+
"foaf": "http://xmlns.com/foaf/0.1/",
|
|
155
|
+
"org": "http://www.w3.org/ns/org#",
|
|
156
|
+
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
|
|
157
|
+
"skos": "http://www.w3.org/2004/02/skos/core#",
|
|
158
|
+
"spdx": "http://spdx.org/rdf/terms#",
|
|
159
|
+
"vcard": "http://www.w3.org/2006/vcard/ns#",
|
|
160
|
+
"schema": "http://schema.org/",
|
|
161
|
+
"hydra": "http://www.w3.org/ns/hydra/core#",
|
|
162
|
+
"freq": "http://purl.org/cld/freq/",
|
|
153
163
|
# Aliased field
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
},
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
'homepage': {
|
|
189
|
-
'@id': 'foaf:homepage',
|
|
190
|
-
'@type': '@id'
|
|
191
|
-
},
|
|
192
|
-
'publisher': {
|
|
193
|
-
'@id': 'dct:publisher',
|
|
194
|
-
'@type': '@id'
|
|
195
|
-
},
|
|
196
|
-
'fn': 'vcard:fn',
|
|
197
|
-
'hasEmail': 'vcard:email',
|
|
198
|
-
'subOrganizationOf': 'org:subOrganizationOf',
|
|
199
|
-
'checksum': 'spdx:checksum',
|
|
200
|
-
'algorithm': {
|
|
201
|
-
'@id': 'spdx:algorithm',
|
|
202
|
-
'@type': '@id'
|
|
203
|
-
},
|
|
204
|
-
'checksumValue': 'spdx:checksumValue',
|
|
205
|
-
'label': 'rdfs:label',
|
|
206
|
-
'name': 'foaf:name',
|
|
207
|
-
'startDate': 'schema:startDate',
|
|
208
|
-
'endDate': 'schema:endDate',
|
|
209
|
-
'view': {
|
|
210
|
-
'@id': 'hydra:view',
|
|
211
|
-
'@type': '@id'
|
|
212
|
-
},
|
|
213
|
-
'first': {
|
|
214
|
-
'@id': 'hydra:first',
|
|
215
|
-
'@type': '@id'
|
|
216
|
-
},
|
|
217
|
-
'last': {
|
|
218
|
-
'@id': 'hydra:last',
|
|
219
|
-
'@type': '@id'
|
|
220
|
-
},
|
|
221
|
-
'next': {
|
|
222
|
-
'@id': 'hydra:next',
|
|
223
|
-
'@type': '@id'
|
|
224
|
-
},
|
|
225
|
-
'previous': {
|
|
226
|
-
'@id': 'hydra:previous',
|
|
227
|
-
'@type': '@id'
|
|
228
|
-
},
|
|
229
|
-
'totalItems': 'hydra:totalItems',
|
|
164
|
+
"downloadURL": {"@id": "dcat:downloadURL", "@type": "@id"},
|
|
165
|
+
"accessURL": {"@id": "dcat:accessURL", "@type": "@id"},
|
|
166
|
+
"dataset": {"@id": "dcat:dataset", "@type": "@id"},
|
|
167
|
+
"distribution": {"@id": "dcat:distribution", "@type": "@id"},
|
|
168
|
+
"title": "dct:title",
|
|
169
|
+
"description": "dct:description",
|
|
170
|
+
"issued": {"@id": "dct:issued", "@type": "http://www.w3.org/2001/XMLSchema#dateTime"},
|
|
171
|
+
"modified": {"@id": "dct:modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime"},
|
|
172
|
+
"language": "dct:language",
|
|
173
|
+
"license": "dct:license",
|
|
174
|
+
"rights": "dct:rights",
|
|
175
|
+
"spatial": "dct:spatial",
|
|
176
|
+
"identifier": "dct:identifier",
|
|
177
|
+
"temporal": "dct:temporal",
|
|
178
|
+
"format": "dct:format",
|
|
179
|
+
"accrualPeriodicity": "dct:accrualPeriodicity",
|
|
180
|
+
"homepage": {"@id": "foaf:homepage", "@type": "@id"},
|
|
181
|
+
"publisher": {"@id": "dct:publisher", "@type": "@id"},
|
|
182
|
+
"fn": "vcard:fn",
|
|
183
|
+
"hasEmail": "vcard:email",
|
|
184
|
+
"subOrganizationOf": "org:subOrganizationOf",
|
|
185
|
+
"checksum": "spdx:checksum",
|
|
186
|
+
"algorithm": {"@id": "spdx:algorithm", "@type": "@id"},
|
|
187
|
+
"checksumValue": "spdx:checksumValue",
|
|
188
|
+
"label": "rdfs:label",
|
|
189
|
+
"name": "foaf:name",
|
|
190
|
+
"startDate": "schema:startDate",
|
|
191
|
+
"endDate": "schema:endDate",
|
|
192
|
+
"view": {"@id": "hydra:view", "@type": "@id"},
|
|
193
|
+
"first": {"@id": "hydra:first", "@type": "@id"},
|
|
194
|
+
"last": {"@id": "hydra:last", "@type": "@id"},
|
|
195
|
+
"next": {"@id": "hydra:next", "@type": "@id"},
|
|
196
|
+
"previous": {"@id": "hydra:previous", "@type": "@id"},
|
|
197
|
+
"totalItems": "hydra:totalItems",
|
|
230
198
|
}
|
|
231
199
|
|
|
200
|
+
|
|
232
201
|
def serialize_value(value):
|
|
233
202
|
if isinstance(value, (URIRef, Literal)):
|
|
234
203
|
return value.toPython()
|
|
@@ -240,6 +209,7 @@ def rdf_value(obj, predicate, default=None):
|
|
|
240
209
|
value = obj.value(predicate)
|
|
241
210
|
return serialize_value(value) if value else default
|
|
242
211
|
|
|
212
|
+
|
|
243
213
|
class HTMLDetector(HTMLParser):
|
|
244
214
|
def __init__(self, *args, **kwargs):
|
|
245
215
|
HTMLParser.__init__(self, *args, **kwargs)
|
|
@@ -259,7 +229,7 @@ def is_html(text):
|
|
|
259
229
|
|
|
260
230
|
|
|
261
231
|
def sanitize_html(text):
|
|
262
|
-
text = text.toPython() if isinstance(text, Literal) else
|
|
232
|
+
text = text.toPython() if isinstance(text, Literal) else ""
|
|
263
233
|
if is_html(text):
|
|
264
234
|
return parse_html(text)
|
|
265
235
|
else:
|
|
@@ -267,28 +237,29 @@ def sanitize_html(text):
|
|
|
267
237
|
|
|
268
238
|
|
|
269
239
|
def url_from_rdf(rdf, prop):
|
|
270
|
-
|
|
240
|
+
"""
|
|
271
241
|
Try to extract An URL from a resource property.
|
|
272
242
|
It can be expressed in many forms as a URIRef or a Literal
|
|
273
|
-
|
|
243
|
+
"""
|
|
274
244
|
value = rdf.value(prop)
|
|
275
245
|
if isinstance(value, (URIRef, Literal)):
|
|
276
246
|
return value.toPython()
|
|
277
247
|
elif isinstance(value, RdfResource):
|
|
278
248
|
return value.identifier.toPython()
|
|
279
249
|
|
|
250
|
+
|
|
280
251
|
def theme_labels_from_rdf(rdf):
|
|
281
|
-
|
|
252
|
+
"""
|
|
282
253
|
Get theme labels to use as keywords.
|
|
283
254
|
Map HVD keywords from known URIs resources if HVD support is activated.
|
|
284
|
-
|
|
255
|
+
"""
|
|
285
256
|
for theme in rdf.objects(DCAT.theme):
|
|
286
257
|
if isinstance(theme, RdfResource):
|
|
287
258
|
uri = theme.identifier.toPython()
|
|
288
|
-
if current_app.config[
|
|
259
|
+
if current_app.config["HVD_SUPPORT"] and uri in EU_HVD_CATEGORIES:
|
|
289
260
|
label = EU_HVD_CATEGORIES[uri]
|
|
290
261
|
# Additionnally yield hvd keyword
|
|
291
|
-
yield
|
|
262
|
+
yield "hvd"
|
|
292
263
|
else:
|
|
293
264
|
label = rdf_value(theme, SKOS.prefLabel)
|
|
294
265
|
else:
|
|
@@ -296,37 +267,45 @@ def theme_labels_from_rdf(rdf):
|
|
|
296
267
|
if label:
|
|
297
268
|
yield label
|
|
298
269
|
|
|
270
|
+
|
|
299
271
|
def themes_from_rdf(rdf):
|
|
300
272
|
tags = [tag.toPython() for tag in rdf.objects(DCAT.keyword)]
|
|
301
273
|
tags += theme_labels_from_rdf(rdf)
|
|
302
274
|
return list(set(tags))
|
|
303
275
|
|
|
276
|
+
|
|
304
277
|
def contact_point_from_rdf(rdf, dataset):
|
|
305
278
|
contact_point = rdf.value(DCAT.contactPoint)
|
|
306
279
|
if contact_point:
|
|
307
|
-
name = rdf_value(contact_point, VCARD.fn) or
|
|
308
|
-
email = (
|
|
309
|
-
|
|
310
|
-
|
|
280
|
+
name = rdf_value(contact_point, VCARD.fn) or ""
|
|
281
|
+
email = (
|
|
282
|
+
rdf_value(contact_point, VCARD.hasEmail)
|
|
283
|
+
or rdf_value(contact_point, VCARD.email)
|
|
284
|
+
or rdf_value(contact_point, DCAT.email)
|
|
285
|
+
)
|
|
311
286
|
if not email:
|
|
312
287
|
return
|
|
313
|
-
email = email.replace(
|
|
288
|
+
email = email.replace("mailto:", "").strip()
|
|
314
289
|
if dataset.organization:
|
|
315
290
|
contact_point = ContactPoint.objects(
|
|
316
|
-
name=name, email=email, organization=dataset.organization
|
|
317
|
-
|
|
318
|
-
|
|
291
|
+
name=name, email=email, organization=dataset.organization
|
|
292
|
+
).first()
|
|
293
|
+
return (
|
|
294
|
+
contact_point
|
|
295
|
+
or ContactPoint(name=name, email=email, organization=dataset.organization).save()
|
|
296
|
+
)
|
|
319
297
|
elif dataset.owner:
|
|
320
298
|
contact_point = ContactPoint.objects(
|
|
321
|
-
name=name, email=email, owner=dataset.owner
|
|
322
|
-
|
|
323
|
-
|
|
299
|
+
name=name, email=email, owner=dataset.owner
|
|
300
|
+
).first()
|
|
301
|
+
return contact_point or ContactPoint(name=name, email=email, owner=dataset.owner).save()
|
|
302
|
+
|
|
324
303
|
|
|
325
304
|
def remote_url_from_rdf(rdf):
|
|
326
|
-
|
|
305
|
+
"""
|
|
327
306
|
Return DCAT.landingPage if found and uri validation succeeds.
|
|
328
307
|
Use RDF identifier as fallback if uri validation succeeds.
|
|
329
|
-
|
|
308
|
+
"""
|
|
330
309
|
landing_page = url_from_rdf(rdf, DCAT.landingPage)
|
|
331
310
|
uri = rdf.identifier.toPython()
|
|
332
311
|
for candidate in [landing_page, uri]:
|
|
@@ -337,11 +316,12 @@ def remote_url_from_rdf(rdf):
|
|
|
337
316
|
except uris.ValidationError:
|
|
338
317
|
pass
|
|
339
318
|
|
|
319
|
+
|
|
340
320
|
def schema_from_rdf(rdf):
|
|
341
|
-
|
|
321
|
+
"""
|
|
342
322
|
Try to extract a schema from a conformsTo property.
|
|
343
323
|
Currently the "issued" property is not harvest.
|
|
344
|
-
|
|
324
|
+
"""
|
|
345
325
|
resource = rdf.value(DCT.conformsTo)
|
|
346
326
|
if not resource:
|
|
347
327
|
return None
|
|
@@ -380,20 +360,21 @@ def schema_from_rdf(rdf):
|
|
|
380
360
|
log.warning(f"Invalid schema inside RDF {e}")
|
|
381
361
|
return None
|
|
382
362
|
|
|
383
|
-
|
|
363
|
+
|
|
364
|
+
def escape_xml_illegal_chars(val, replacement="?"):
|
|
384
365
|
illegal_xml_chars_RE = re.compile(ILLEGAL_XML_CHARS)
|
|
385
366
|
return illegal_xml_chars_RE.sub(replacement, val)
|
|
386
367
|
|
|
387
368
|
|
|
388
369
|
def paginate_catalog(catalog, graph, datasets, format, rdf_catalog_endpoint, **values):
|
|
389
370
|
if not format:
|
|
390
|
-
raise ValueError(
|
|
371
|
+
raise ValueError("Pagination requires format")
|
|
391
372
|
catalog.add(RDF.type, HYDRA.Collection)
|
|
392
373
|
catalog.set(HYDRA.totalItems, Literal(datasets.total))
|
|
393
374
|
kwargs = {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
375
|
+
"format": format,
|
|
376
|
+
"page_size": datasets.page_size,
|
|
377
|
+
"_external": True,
|
|
397
378
|
}
|
|
398
379
|
|
|
399
380
|
kwargs.update(values)
|
|
@@ -419,18 +400,16 @@ def paginate_catalog(catalog, graph, datasets, format, rdf_catalog_endpoint, **v
|
|
|
419
400
|
|
|
420
401
|
|
|
421
402
|
def graph_response(graph, format):
|
|
422
|
-
|
|
403
|
+
"""
|
|
423
404
|
Return a proper flask response for a RDF resource given an expected format.
|
|
424
|
-
|
|
405
|
+
"""
|
|
425
406
|
fmt = guess_format(format)
|
|
426
407
|
if not fmt:
|
|
427
408
|
abort(404)
|
|
428
|
-
headers = {
|
|
429
|
-
'Content-Type': RDF_MIME_TYPES[fmt]
|
|
430
|
-
}
|
|
409
|
+
headers = {"Content-Type": RDF_MIME_TYPES[fmt]}
|
|
431
410
|
kwargs = {}
|
|
432
|
-
if fmt ==
|
|
433
|
-
kwargs[
|
|
411
|
+
if fmt == "json-ld":
|
|
412
|
+
kwargs["context"] = CONTEXT
|
|
434
413
|
if isinstance(graph, RdfResource):
|
|
435
414
|
graph = graph.graph
|
|
436
415
|
return escape_xml_illegal_chars(graph.serialize(format=fmt, **kwargs)), 200, headers
|