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
tasks/__init__.py
CHANGED
|
@@ -2,112 +2,116 @@ import itertools
|
|
|
2
2
|
import json
|
|
3
3
|
import os
|
|
4
4
|
import re
|
|
5
|
-
|
|
6
5
|
from datetime import datetime
|
|
7
6
|
from glob import iglob
|
|
8
|
-
from os.path import
|
|
7
|
+
from os.path import exists, join
|
|
9
8
|
from sys import exit
|
|
10
9
|
|
|
11
10
|
from babel.messages.pofile import read_po, write_po
|
|
12
11
|
from babel.util import LOCALTZ
|
|
13
12
|
from invoke import task
|
|
14
13
|
|
|
15
|
-
from .helpers import ROOT,
|
|
14
|
+
from .helpers import ROOT, cyan, header, info, success
|
|
16
15
|
|
|
17
|
-
I18N_DOMAIN =
|
|
16
|
+
I18N_DOMAIN = "udata"
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
@task
|
|
21
20
|
def clean(ctx, node=False, translations=False, all=False):
|
|
22
|
-
|
|
23
|
-
header(
|
|
21
|
+
"""Cleanup all build artifacts"""
|
|
22
|
+
header("Clean all build artifacts")
|
|
24
23
|
patterns = [
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
"build",
|
|
25
|
+
"dist",
|
|
26
|
+
"cover",
|
|
27
|
+
"docs/_build",
|
|
28
|
+
"**/*.pyc",
|
|
29
|
+
"*.egg-info",
|
|
30
|
+
".tox",
|
|
31
|
+
"udata/static/*",
|
|
27
32
|
]
|
|
28
33
|
if node or all:
|
|
29
|
-
patterns.append(
|
|
34
|
+
patterns.append("node_modules")
|
|
30
35
|
if translations or all:
|
|
31
|
-
patterns.append(
|
|
36
|
+
patterns.append("udata/translations/*/LC_MESSAGES/udata.mo")
|
|
32
37
|
for pattern in patterns:
|
|
33
38
|
info(pattern)
|
|
34
39
|
with ctx.cd(ROOT):
|
|
35
|
-
ctx.run(
|
|
40
|
+
ctx.run("rm -rf {0}".format(" ".join(patterns)))
|
|
36
41
|
|
|
37
42
|
|
|
38
43
|
@task
|
|
39
44
|
def update(ctx, migrate=False):
|
|
40
|
-
|
|
41
|
-
msg =
|
|
45
|
+
"""Perform a development update"""
|
|
46
|
+
msg = "Update all dependencies"
|
|
42
47
|
if migrate:
|
|
43
|
-
msg +=
|
|
48
|
+
msg += " and migrate data"
|
|
44
49
|
header(msg)
|
|
45
|
-
info(
|
|
50
|
+
info("Updating Python dependencies")
|
|
46
51
|
with ctx.cd(ROOT):
|
|
47
|
-
ctx.run(
|
|
48
|
-
ctx.run(
|
|
49
|
-
info(
|
|
50
|
-
ctx.run(
|
|
52
|
+
ctx.run("pi3 install -e .")
|
|
53
|
+
ctx.run("pip install -r requirements/develop.pip")
|
|
54
|
+
info("Updating JavaScript dependencies")
|
|
55
|
+
ctx.run("npm install")
|
|
51
56
|
if migrate:
|
|
52
|
-
info(
|
|
53
|
-
ctx.run(
|
|
57
|
+
info("Migrating database")
|
|
58
|
+
ctx.run("udata db migrate")
|
|
54
59
|
|
|
55
60
|
|
|
56
61
|
@task
|
|
57
62
|
def i18n(ctx, update=False):
|
|
58
|
-
|
|
59
|
-
header(
|
|
63
|
+
"""Extract translatable strings"""
|
|
64
|
+
header("Extract translatable strings")
|
|
60
65
|
|
|
61
|
-
info(
|
|
66
|
+
info("Extract Python strings")
|
|
62
67
|
with ctx.cd(ROOT):
|
|
63
|
-
ctx.run(
|
|
68
|
+
ctx.run("python setup.py extract_messages")
|
|
64
69
|
|
|
65
70
|
# Fix crowdin requiring Language with `2-digit` iso code in potfile
|
|
66
71
|
# to produce 2-digit iso code pofile
|
|
67
72
|
# Opening the catalog also allows to set extra metadata
|
|
68
|
-
potfile = join(ROOT,
|
|
69
|
-
with open(potfile,
|
|
70
|
-
catalog = read_po(infile,
|
|
71
|
-
catalog.copyright_holder =
|
|
72
|
-
catalog.msgid_bugs_address =
|
|
73
|
-
catalog.language_team =
|
|
74
|
-
catalog.last_translator =
|
|
73
|
+
potfile = join(ROOT, "udata", "translations", "{}.pot".format(I18N_DOMAIN))
|
|
74
|
+
with open(potfile, "rb") as infile:
|
|
75
|
+
catalog = read_po(infile, "en")
|
|
76
|
+
catalog.copyright_holder = "Open Data Team"
|
|
77
|
+
catalog.msgid_bugs_address = "i18n@opendata.team"
|
|
78
|
+
catalog.language_team = "Open Data Team <i18n@opendata.team>"
|
|
79
|
+
catalog.last_translator = "Open Data Team <i18n@opendata.team>"
|
|
75
80
|
catalog.revision_date = datetime.now(LOCALTZ)
|
|
76
|
-
with open(potfile,
|
|
81
|
+
with open(potfile, "wb") as outfile:
|
|
77
82
|
write_po(outfile, catalog, width=80)
|
|
78
83
|
|
|
79
84
|
if update:
|
|
80
85
|
with ctx.cd(ROOT):
|
|
81
|
-
ctx.run(
|
|
86
|
+
ctx.run("python setup.py update_catalog")
|
|
82
87
|
|
|
83
|
-
info(
|
|
88
|
+
info("Extract JavaScript strings")
|
|
84
89
|
keys = set()
|
|
85
90
|
catalog = {}
|
|
86
|
-
catalog_filename = join(ROOT,
|
|
87
|
-
'{}.en.json'.format(I18N_DOMAIN))
|
|
91
|
+
catalog_filename = join(ROOT, "js", "locales", "{}.en.json".format(I18N_DOMAIN))
|
|
88
92
|
if exists(catalog_filename):
|
|
89
93
|
with open(catalog_filename) as f:
|
|
90
94
|
catalog = json.load(f)
|
|
91
95
|
|
|
92
|
-
globs =
|
|
96
|
+
globs = "*.js", "*.vue", "*.hbs"
|
|
93
97
|
regexps = [
|
|
94
98
|
re.compile(r'(?:|\.|\s|\{)_\(\s*(?:"|\')(.*?)(?:"|\')\s*(?:\)|,)'), # JS _('trad')
|
|
95
99
|
re.compile(r'v-i18n="(.*?)"'), # Vue.js directive v-i18n="trad"
|
|
96
100
|
re.compile(r'"\{\{\{?\s*\'(.*?)\'\s*\|\s*i18n\}\}\}?"'), # Vue.js filter {{ 'trad'|i18n }}
|
|
97
101
|
re.compile(r'{{_\s*"(.*?)"\s*}}'), # Handlebars {{_ "trad" }}
|
|
98
|
-
re.compile(r
|
|
102
|
+
re.compile(r"{{_\s*\'(.*?)\'\s*}}"), # Handlebars {{_ 'trad' }}
|
|
99
103
|
re.compile(r'\:[a-z0-9_\-]+="\s*_\(\'(.*?)\'\)\s*"'), # Vue.js binding :prop="_('trad')"
|
|
100
104
|
]
|
|
101
105
|
|
|
102
|
-
for directory, _, _ in os.walk(join(ROOT,
|
|
106
|
+
for directory, _, _ in os.walk(join(ROOT, "js")):
|
|
103
107
|
glob_patterns = (iglob(join(directory, g)) for g in globs)
|
|
104
108
|
for filename in itertools.chain(*glob_patterns):
|
|
105
|
-
print(
|
|
109
|
+
print("Extracting messages from {0}".format(cyan(filename)))
|
|
106
110
|
content = open(filename).read()
|
|
107
111
|
for regexp in regexps:
|
|
108
112
|
for match in regexp.finditer(content):
|
|
109
113
|
key = match.group(1)
|
|
110
|
-
key = key.replace(
|
|
114
|
+
key = key.replace("\\n", "\n")
|
|
111
115
|
keys.add(key)
|
|
112
116
|
if key not in catalog:
|
|
113
117
|
catalog[key] = key
|
|
@@ -117,163 +121,161 @@ def i18n(ctx, update=False):
|
|
|
117
121
|
if key not in keys:
|
|
118
122
|
del catalog[key]
|
|
119
123
|
|
|
120
|
-
with open(catalog_filename,
|
|
121
|
-
json.dump(catalog, f, sort_keys=True, indent=4, ensure_ascii=False,
|
|
122
|
-
separators=(',', ': '))
|
|
124
|
+
with open(catalog_filename, "w") as f:
|
|
125
|
+
json.dump(catalog, f, sort_keys=True, indent=4, ensure_ascii=False, separators=(",", ": "))
|
|
123
126
|
|
|
124
127
|
|
|
125
128
|
@task
|
|
126
129
|
def i18nc(ctx):
|
|
127
|
-
|
|
128
|
-
header(
|
|
130
|
+
"""Compile translations"""
|
|
131
|
+
header("Compiling translations")
|
|
129
132
|
with ctx.cd(ROOT):
|
|
130
|
-
ctx.run(
|
|
133
|
+
ctx.run("python setup.py compile_catalog")
|
|
131
134
|
|
|
132
135
|
|
|
133
136
|
@task(i18nc)
|
|
134
137
|
def test(ctx, fast=False, report=False, verbose=False, ci=False):
|
|
135
|
-
|
|
136
|
-
header(
|
|
137
|
-
cmd = [
|
|
138
|
+
"""Run tests suite"""
|
|
139
|
+
header("Run tests suite")
|
|
140
|
+
cmd = ["pytest udata"]
|
|
138
141
|
if ci:
|
|
139
|
-
cmd.append(
|
|
142
|
+
cmd.append("-p no:sugar --color=yes")
|
|
140
143
|
if verbose:
|
|
141
|
-
cmd.append(
|
|
144
|
+
cmd.append("-v")
|
|
142
145
|
if fast:
|
|
143
|
-
cmd.append(
|
|
146
|
+
cmd.append("-x")
|
|
144
147
|
if report:
|
|
145
|
-
cmd.append(
|
|
148
|
+
cmd.append("--junitxml=reports/python/tests.xml")
|
|
146
149
|
with ctx.cd(ROOT):
|
|
147
|
-
ctx.run(
|
|
150
|
+
ctx.run(" ".join(cmd), pty=True)
|
|
148
151
|
|
|
149
152
|
|
|
150
153
|
@task
|
|
151
154
|
def cover(ctx, html=False):
|
|
152
|
-
|
|
153
|
-
header(
|
|
154
|
-
cmd =
|
|
155
|
+
"""Run tests suite with coverage"""
|
|
156
|
+
header("Run tests suite with coverage")
|
|
157
|
+
cmd = "pytest --cov udata --cov-report term"
|
|
155
158
|
if html:
|
|
156
|
-
cmd =
|
|
159
|
+
cmd = " ".join((cmd, "--cov-report html:reports/python/cover"))
|
|
157
160
|
with ctx.cd(ROOT):
|
|
158
161
|
ctx.run(cmd, pty=True)
|
|
159
162
|
|
|
160
163
|
|
|
161
164
|
@task
|
|
162
165
|
def jstest(ctx, watch=False):
|
|
163
|
-
|
|
164
|
-
header(
|
|
165
|
-
cmd =
|
|
166
|
+
"""Run Karma tests suite"""
|
|
167
|
+
header("Run Karma/Mocha test suite")
|
|
168
|
+
cmd = "npm run -s test:{0}".format("watch" if watch else "unit")
|
|
166
169
|
with ctx.cd(ROOT):
|
|
167
170
|
ctx.run(cmd)
|
|
168
171
|
|
|
169
172
|
|
|
170
173
|
@task
|
|
171
174
|
def doc(ctx):
|
|
172
|
-
|
|
173
|
-
header(
|
|
175
|
+
"""Build the documentation"""
|
|
176
|
+
header("Building documentation")
|
|
174
177
|
with ctx.cd(ROOT):
|
|
175
|
-
ctx.run(
|
|
178
|
+
ctx.run("mkdocs serve", pty=True)
|
|
176
179
|
|
|
177
180
|
|
|
178
181
|
@task
|
|
179
182
|
def qa(ctx):
|
|
180
|
-
|
|
181
|
-
header(
|
|
182
|
-
info(
|
|
183
|
+
"""Run a quality report"""
|
|
184
|
+
header("Performing static analysis")
|
|
185
|
+
info("Python static analysis")
|
|
183
186
|
with ctx.cd(ROOT):
|
|
184
|
-
flake8_results = ctx.run(
|
|
185
|
-
info(
|
|
187
|
+
flake8_results = ctx.run("flake8 udata --jobs 1", pty=True, warn=True)
|
|
188
|
+
info("JavaScript static analysis")
|
|
186
189
|
with ctx.cd(ROOT):
|
|
187
|
-
eslint_results = ctx.run(
|
|
190
|
+
eslint_results = ctx.run("npm -s run lint", pty=True, warn=True)
|
|
188
191
|
if flake8_results.failed or eslint_results.failed:
|
|
189
192
|
exit(flake8_results.return_code or eslint_results.return_code)
|
|
190
|
-
success(
|
|
193
|
+
success("OK")
|
|
191
194
|
|
|
192
195
|
|
|
193
196
|
@task
|
|
194
|
-
def serve(ctx, host=
|
|
195
|
-
|
|
197
|
+
def serve(ctx, host="localhost"):
|
|
198
|
+
"""Run a development server"""
|
|
196
199
|
with ctx.cd(ROOT):
|
|
197
|
-
ctx.run(
|
|
200
|
+
ctx.run("python manage.py serve -d -r -h %s" % host)
|
|
198
201
|
|
|
199
202
|
|
|
200
203
|
@task
|
|
201
|
-
def work(ctx, loglevel=
|
|
202
|
-
|
|
203
|
-
ctx.run(
|
|
204
|
-
pty=True)
|
|
204
|
+
def work(ctx, loglevel="info"):
|
|
205
|
+
"""Run a development worker"""
|
|
206
|
+
ctx.run("celery -A udata.worker worker --purge -l %s" % loglevel, pty=True)
|
|
205
207
|
|
|
206
208
|
|
|
207
209
|
@task
|
|
208
|
-
def beat(ctx, loglevel=
|
|
209
|
-
|
|
210
|
-
ctx.run(
|
|
210
|
+
def beat(ctx, loglevel="info"):
|
|
211
|
+
"""Run celery beat process"""
|
|
212
|
+
ctx.run("celery -A udata.worker beat -l %s" % loglevel)
|
|
211
213
|
|
|
212
214
|
|
|
213
215
|
@task
|
|
214
216
|
def assets_build(ctx):
|
|
215
|
-
|
|
216
|
-
header(
|
|
217
|
+
"""Install and compile assets"""
|
|
218
|
+
header("Building static assets")
|
|
217
219
|
with ctx.cd(ROOT):
|
|
218
|
-
ctx.run(
|
|
220
|
+
ctx.run("npm run assets:build", pty=True)
|
|
219
221
|
|
|
220
222
|
|
|
221
223
|
@task
|
|
222
224
|
def widgets_build(ctx):
|
|
223
|
-
|
|
224
|
-
header(
|
|
225
|
+
"""Compile and minify widgets"""
|
|
226
|
+
header("Building widgets")
|
|
225
227
|
with ctx.cd(ROOT):
|
|
226
|
-
ctx.run(
|
|
228
|
+
ctx.run("npm run widgets:build", pty=True)
|
|
227
229
|
|
|
228
230
|
|
|
229
231
|
@task
|
|
230
232
|
def oembed_build(ctx):
|
|
231
|
-
|
|
232
|
-
header(
|
|
233
|
+
"""Compile and minify OEmbed assets"""
|
|
234
|
+
header("Building OEmbed assets")
|
|
233
235
|
with ctx.cd(ROOT):
|
|
234
|
-
ctx.run(
|
|
236
|
+
ctx.run("npm run oembed:build", pty=True)
|
|
235
237
|
|
|
236
238
|
|
|
237
239
|
@task
|
|
238
240
|
def assets_watch(ctx):
|
|
239
|
-
|
|
241
|
+
"""Build assets on change"""
|
|
240
242
|
with ctx.cd(ROOT):
|
|
241
|
-
ctx.run(
|
|
243
|
+
ctx.run("npm run assets:watch", pty=True)
|
|
242
244
|
|
|
243
245
|
|
|
244
246
|
@task
|
|
245
247
|
def widgets_watch(ctx):
|
|
246
|
-
|
|
248
|
+
"""Build widgets on changes"""
|
|
247
249
|
with ctx.cd(ROOT):
|
|
248
|
-
ctx.run(
|
|
250
|
+
ctx.run("npm run widgets:watch", pty=True)
|
|
249
251
|
|
|
250
252
|
|
|
251
253
|
@task
|
|
252
254
|
def oembed_watch(ctx):
|
|
253
|
-
|
|
255
|
+
"""Build OEmbed assets on changes"""
|
|
254
256
|
with ctx.cd(ROOT):
|
|
255
|
-
ctx.run(
|
|
257
|
+
ctx.run("npm run oembed:watch", pty=True)
|
|
256
258
|
|
|
257
259
|
|
|
258
260
|
@task(clean, i18nc, assets_build, widgets_build, oembed_build, default=True)
|
|
259
261
|
def dist(ctx, buildno=None):
|
|
260
|
-
|
|
262
|
+
"""Package for distribution"""
|
|
261
263
|
perform_dist(ctx, buildno)
|
|
262
264
|
|
|
263
265
|
|
|
264
266
|
@task(i18nc)
|
|
265
267
|
def pydist(ctx, buildno=None):
|
|
266
|
-
|
|
268
|
+
"""Perform python packaging (without compiling assets)"""
|
|
267
269
|
perform_dist(ctx, buildno)
|
|
268
270
|
|
|
269
271
|
|
|
270
272
|
def perform_dist(ctx, buildno=None):
|
|
271
|
-
header(
|
|
272
|
-
cmd = [
|
|
273
|
+
header("Building a distribuable package")
|
|
274
|
+
cmd = ["python setup.py"]
|
|
273
275
|
if buildno:
|
|
274
|
-
cmd.append(
|
|
275
|
-
cmd.append(
|
|
276
|
+
cmd.append("egg_info -b {0}".format(buildno))
|
|
277
|
+
cmd.append("bdist_wheel")
|
|
276
278
|
with ctx.cd(ROOT):
|
|
277
|
-
ctx.run(
|
|
278
|
-
ctx.run(
|
|
279
|
-
success(
|
|
279
|
+
ctx.run(" ".join(cmd), pty=True)
|
|
280
|
+
ctx.run("twine check dist/*")
|
|
281
|
+
success("Distribution is available in dist directory")
|
tasks/helpers.py
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
from os.path import
|
|
1
|
+
from os.path import abspath, dirname, join
|
|
2
2
|
|
|
3
3
|
#: Project absolute root path
|
|
4
|
-
ROOT = abspath(join(dirname(__file__),
|
|
4
|
+
ROOT = abspath(join(dirname(__file__), ".."))
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def color(code):
|
|
8
|
-
|
|
9
|
-
return lambda t:
|
|
8
|
+
"""A simple ANSI color wrapper factory"""
|
|
9
|
+
return lambda t: "\033[{0}{1}\033[0;m".format(code, t)
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
green = color(
|
|
13
|
-
red = color(
|
|
14
|
-
blue = color(
|
|
15
|
-
cyan = color(
|
|
16
|
-
purple = color(
|
|
17
|
-
white = color(
|
|
12
|
+
green = color("1;32m")
|
|
13
|
+
red = color("1;31m")
|
|
14
|
+
blue = color("1;30m")
|
|
15
|
+
cyan = color("1;36m")
|
|
16
|
+
purple = color("1;35m")
|
|
17
|
+
white = color("1;39m")
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def header(text, *args, **kwargs):
|
|
21
|
-
|
|
21
|
+
"""Display an header"""
|
|
22
22
|
text = text.format(*args, **kwargs)
|
|
23
|
-
print(
|
|
23
|
+
print(" ".join((blue(">>"), cyan(text))))
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def info(text, *args, **kwargs):
|
|
27
|
-
|
|
27
|
+
"""Display informations"""
|
|
28
28
|
text = text.format(*args, **kwargs)
|
|
29
|
-
print(
|
|
29
|
+
print(" ".join((purple(">>>"), text)))
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def success(text, *args, **kwargs):
|
|
33
|
-
|
|
33
|
+
"""Display a success message"""
|
|
34
34
|
text = text.format(*args, **kwargs)
|
|
35
|
-
print(
|
|
35
|
+
print(" ".join((green("✔"), white(text))))
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def error(text, *args, **kwargs):
|
|
39
|
-
|
|
39
|
+
"""Display an error message"""
|
|
40
40
|
text = text.format(*args, **kwargs)
|
|
41
|
-
print(red(
|
|
41
|
+
print(red("✘ {0}".format(text)))
|
udata/__init__.py
CHANGED
udata/admin/views.py
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from flask import render_template
|
|
2
|
+
|
|
2
3
|
from udata.auth import login_required
|
|
3
4
|
from udata.i18n import I18nBlueprint
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
blueprint = I18nBlueprint('admin', __name__, url_prefix='/admin')
|
|
6
|
+
blueprint = I18nBlueprint("admin", __name__, url_prefix="/admin")
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
@blueprint.route(
|
|
10
|
-
@blueprint.route(
|
|
9
|
+
@blueprint.route("/", defaults={"path": ""})
|
|
10
|
+
@blueprint.route("/<path:path>")
|
|
11
11
|
@login_required
|
|
12
12
|
def index(path):
|
|
13
|
-
return render_template(
|
|
13
|
+
return render_template("admin.html")
|