c2cgeoportal-geoportal 2.6.0__py2.py3-none-any.whl → 2.8.1.180__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.
- c2cgeoportal_geoportal/__init__.py +245 -95
- c2cgeoportal_geoportal/lib/__init__.py +67 -43
- c2cgeoportal_geoportal/lib/authentication.py +50 -26
- c2cgeoportal_geoportal/lib/bashcolor.py +17 -13
- c2cgeoportal_geoportal/lib/cacheversion.py +16 -8
- c2cgeoportal_geoportal/lib/caching.py +65 -193
- c2cgeoportal_geoportal/lib/check_collector.py +17 -10
- c2cgeoportal_geoportal/lib/checker.py +67 -65
- c2cgeoportal_geoportal/lib/common_headers.py +167 -0
- c2cgeoportal_geoportal/lib/dbreflection.py +61 -46
- c2cgeoportal_geoportal/lib/filter_capabilities.py +126 -88
- c2cgeoportal_geoportal/lib/fulltextsearch.py +6 -5
- c2cgeoportal_geoportal/lib/functionality.py +20 -17
- c2cgeoportal_geoportal/lib/headers.py +14 -5
- c2cgeoportal_geoportal/lib/i18n.py +4 -4
- c2cgeoportal_geoportal/lib/layers.py +30 -11
- c2cgeoportal_geoportal/lib/lingua_extractor.py +363 -240
- c2cgeoportal_geoportal/lib/loader.py +11 -16
- c2cgeoportal_geoportal/lib/metrics.py +28 -17
- c2cgeoportal_geoportal/lib/oauth2.py +392 -206
- c2cgeoportal_geoportal/lib/wmstparsing.py +105 -84
- c2cgeoportal_geoportal/lib/xsd.py +26 -16
- c2cgeoportal_geoportal/resources.py +15 -9
- c2cgeoportal_geoportal/scaffolds/advance_create/ci/config.yaml +26 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.dockerignore +6 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.eslintrc.yaml +19 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+dot+prospector.yaml → advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml} +8 -2
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/Dockerfile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Dockerfile} +22 -15
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/alembic.yaml_tmpl → advance_create/{{cookiecutter.project}}/geoportal/alembic.yaml} +1 -1
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/development.ini_tmpl → advance_create/{{cookiecutter.project}}/geoportal/development.ini} +34 -15
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py +100 -0
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-client.cfg +1 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/production.ini +38 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/setup.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/setup.py} +6 -7
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/tsconfig.json +8 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +77 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/webpack.apps.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js} +29 -28
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.commons.js +4 -7
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.config.js +1 -1
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py +42 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py +10 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/dev.py +14 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py +8 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py +7 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/resources.py +4 -3
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/static-ngeo/api/index.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/api/index.js} +1 -2
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/static-ngeo/js/+package+module.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/js/{{cookiecutter.package}}module.js} +4 -4
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/subscribers.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/subscribers.py} +1 -3
- c2cgeoportal_geoportal/scaffolds/advance_update/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/{update/geoportal/CONST_Makefile_tmpl → advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile} +3 -27
- c2cgeoportal_geoportal/scaffolds/create/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.dockerignore +14 -0
- c2cgeoportal_geoportal/scaffolds/create/{+dot+editorconfig → {{cookiecutter.project}}/.editorconfig} +2 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/main.yaml +57 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/rebuild.yaml +46 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +66 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.gitignore +16 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierignore +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierrc.yaml +2 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Dockerfile +76 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +70 -0
- c2cgeoportal_geoportal/scaffolds/create/{README.rst_tmpl → {{cookiecutter.project}}/README.rst} +4 -4
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +186 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/config.yaml +22 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/docker-compose-check +25 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-db.yaml +26 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose-lib.yaml → {{cookiecutter.project}}/docker-compose-lib.yaml} +165 -22
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-qgis.yaml +23 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.override.sample.yaml +66 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose.yaml → {{cookiecutter.project}}/docker-compose.yaml} +20 -15
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.default +101 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.project +69 -0
- c2cgeoportal_geoportal/scaffolds/create/{geoportal/vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/vars.yaml} +126 -36
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/mobile.css +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/Readme.txt +3 -3
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/demo.map.tmpl +224 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/mapserver.conf +15 -0
- c2cgeoportal_geoportal/scaffolds/create/{mapserver/mapserver.map.tmpl_tmpl → {{cookiecutter.project}}/mapserver/mapserver.map.tmpl} +9 -18
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Landscape.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Portrait.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Landscape.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Portrait.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/config.yaml.tmpl +11 -4
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation.properties +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation_fr.properties +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{project.yaml_tmpl → {{cookiecutter.project}}/project.yaml} +6 -6
- c2cgeoportal_geoportal/scaffolds/create/{pyproject.toml → {{cookiecutter.project}}/pyproject.toml} +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{qgisserver/pg_service.conf.tmpl_tmpl → {{cookiecutter.project}}/qgisserver/pg_service.conf.tmpl} +2 -2
- c2cgeoportal_geoportal/scaffolds/create/{run_alembic.sh → {{cookiecutter.project}}/run_alembic.sh} +3 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-backup +110 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +114 -0
- c2cgeoportal_geoportal/scaffolds/create/{setup.cfg_tmpl → {{cookiecutter.project}}/setup.cfg} +1 -1
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/spell-ignore-words.txt +5 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/__init__.py +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/test_app.py +38 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tilegeneration/config.yaml.tmpl +195 -0
- c2cgeoportal_geoportal/scaffolds/update/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/.upgrade.yaml +61 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +273 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py +48 -0
- c2cgeoportal_geoportal/scaffolds/update/{geoportal → {{cookiecutter.project}}/geoportal}/CONST_config-schema.yaml +64 -17
- c2cgeoportal_geoportal/scaffolds/update/{geoportal/CONST_vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/CONST_vars.yaml} +396 -19
- c2cgeoportal_geoportal/scripts/__init__.py +16 -30
- c2cgeoportal_geoportal/scripts/c2cupgrade.py +272 -234
- c2cgeoportal_geoportal/scripts/create_demo_theme.py +3 -6
- c2cgeoportal_geoportal/scripts/manage_users.py +34 -39
- c2cgeoportal_geoportal/scripts/pcreate.py +310 -0
- c2cgeoportal_geoportal/scripts/theme2fts.py +128 -24
- c2cgeoportal_geoportal/scripts/urllogin.py +19 -11
- c2cgeoportal_geoportal/templates/login.html +88 -84
- c2cgeoportal_geoportal/templates/notlogin.html +59 -59
- c2cgeoportal_geoportal/templates/testi18n.html +6 -8
- c2cgeoportal_geoportal/views/__init__.py +23 -6
- c2cgeoportal_geoportal/views/dev.py +9 -7
- c2cgeoportal_geoportal/views/dynamic.py +56 -19
- c2cgeoportal_geoportal/views/entry.py +85 -24
- c2cgeoportal_geoportal/views/fulltextsearch.py +29 -23
- c2cgeoportal_geoportal/views/geometry_processing.py +17 -9
- c2cgeoportal_geoportal/views/i18n.py +91 -9
- c2cgeoportal_geoportal/views/layers.py +166 -133
- c2cgeoportal_geoportal/views/login.py +161 -93
- c2cgeoportal_geoportal/views/mapserverproxy.py +47 -31
- c2cgeoportal_geoportal/views/memory.py +12 -12
- c2cgeoportal_geoportal/views/ogcproxy.py +52 -30
- c2cgeoportal_geoportal/views/pdfreport.py +30 -26
- c2cgeoportal_geoportal/views/printproxy.py +60 -52
- c2cgeoportal_geoportal/views/profile.py +24 -23
- c2cgeoportal_geoportal/views/proxy.py +88 -72
- c2cgeoportal_geoportal/views/raster.py +37 -26
- c2cgeoportal_geoportal/views/resourceproxy.py +13 -11
- c2cgeoportal_geoportal/views/shortener.py +27 -25
- c2cgeoportal_geoportal/views/theme.py +472 -332
- c2cgeoportal_geoportal/views/tinyowsproxy.py +42 -44
- c2cgeoportal_geoportal/views/vector_tiles.py +80 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/METADATA +19 -8
- c2cgeoportal_geoportal-2.8.1.180.dist-info/RECORD +191 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/WHEEL +1 -1
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/entry_points.txt +3 -0
- tests/__init__.py +10 -5
- tests/test_cachebuster.py +3 -5
- tests/test_caching.py +18 -26
- tests/test_checker.py +1 -3
- tests/test_decimaljson.py +5 -5
- tests/test_headerstween.py +1 -3
- tests/test_i18n.py +2 -2
- tests/test_init.py +16 -20
- tests/test_locale_negociator.py +4 -6
- tests/test_mapserverproxy_route_predicate.py +1 -4
- tests/test_raster.py +15 -17
- tests/test_wmstparsing.py +10 -12
- tests/xmlstr.py +1 -3
- c2cgeoportal_geoportal/scaffolds/__init__.py +0 -227
- c2cgeoportal_geoportal/scaffolds/create/+dot+dockerignore_tmpl +0 -12
- c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/main.yaml_tmpl +0 -89
- c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/rebuild.yaml_tmpl +0 -78
- c2cgeoportal_geoportal/scaffolds/create/+dot+gitignore_tmpl +0 -16
- c2cgeoportal_geoportal/scaffolds/create/Dockerfile_tmpl +0 -67
- c2cgeoportal_geoportal/scaffolds/create/Makefile +0 -3
- c2cgeoportal_geoportal/scaffolds/create/build_tmpl +0 -167
- c2cgeoportal_geoportal/scaffolds/create/ci/config.yaml_tmpl +0 -23
- c2cgeoportal_geoportal/scaffolds/create/ci/requirements.txt +0 -1
- c2cgeoportal_geoportal/scaffolds/create/ci/trigger +0 -68
- c2cgeoportal_geoportal/scaffolds/create/docker-compose.override.sample.yaml +0 -54
- c2cgeoportal_geoportal/scaffolds/create/env.default_tmpl +0 -67
- c2cgeoportal_geoportal/scaffolds/create/env.project_tmpl +0 -48
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+dockerignore_tmpl +0 -6
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+eslintrc_tmpl +0 -15
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/__init__.py_tmpl +0 -58
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/models.py_tmpl +0 -10
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/robot.txt +0 -3
- c2cgeoportal_geoportal/scaffolds/create/geoportal/production.ini_tmpl +0 -106
- c2cgeoportal_geoportal/scaffolds/create/geoportal/tools/extract-messages.js +0 -39
- c2cgeoportal_geoportal/scaffolds/create/geoportal/tsconfig.json_tmpl +0 -9
- c2cgeoportal_geoportal/scaffolds/create/geoportal/webpack.api.js_tmpl +0 -72
- c2cgeoportal_geoportal/scaffolds/create/mapserver/demo.map.tmpl_tmpl +0 -262
- c2cgeoportal_geoportal/scaffolds/create/mapserver/tinyows.xml +0 -36
- c2cgeoportal_geoportal/scaffolds/create/print/print-apps/+package+/config.yaml +0 -168
- c2cgeoportal_geoportal/scaffolds/create/qgisserver/geomapfish.yaml.tmpl_tmpl +0 -16
- c2cgeoportal_geoportal/scaffolds/create/spell-ignore-words.txt +0 -1
- c2cgeoportal_geoportal/scaffolds/create/tilegeneration/config.yaml.tmpl_tmpl +0 -185
- c2cgeoportal_geoportal/scaffolds/create/yamllint.yaml +0 -11
- c2cgeoportal_geoportal/scaffolds/update/+dot+upgrade.yaml_tmpl +0 -181
- c2cgeoportal_geoportal/scaffolds/update/CONST_CHANGELOG.txt_tmpl +0 -454
- c2cgeoportal_geoportal/templates/dynamic.js +0 -21
- c2cgeoportal_geoportal-2.6.0.dist-info/RECORD +0 -173
- /c2cgeoportal_geoportal/{scaffolds/create/geoportal/+package+_geoportal/static/css/desktop.css → py.typed} +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create/geoportal/Makefile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Makefile} +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/alembic.ini +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/language_mapping +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-server.cfg +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/requirements.txt +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/views/__init__.py +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/locale/en/LC_MESSAGES/+package+_geoportal-client.po → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/locale/en/LC_MESSAGES/{{cookiecutter.package}}_geoportal-client.po} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/iframe_api.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/desktop.css} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/mobile.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/iframe_api.css} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_left.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_right.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/blank.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-blue.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-gold.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-green.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/robot.txt.tmpl +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/TM_EUROPE_BORDERS-0.3.sql +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arial.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbd.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbi.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Ariali.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Bold.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-BoldItalic.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Italic.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Regular.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdana.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanab.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanai.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanaz.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts.conf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/tinyows.xml.tmpl +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/legend.jrxml +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/logo.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/north.svg +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/results.jrxml +0 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2011-2021, Camptocamp SA
|
1
|
+
# Copyright (c) 2011-2024, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -30,15 +28,22 @@
|
|
30
28
|
import importlib
|
31
29
|
import logging
|
32
30
|
import os
|
31
|
+
from functools import partial
|
32
|
+
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, cast
|
33
33
|
from urllib.parse import urlsplit
|
34
34
|
|
35
35
|
import c2cgeoform
|
36
36
|
import c2cwsgiutils
|
37
37
|
import c2cwsgiutils.db
|
38
38
|
import c2cwsgiutils.index
|
39
|
+
import pyramid.config
|
40
|
+
import pyramid.renderers
|
41
|
+
import pyramid.request
|
42
|
+
import pyramid.response
|
39
43
|
import pyramid.security
|
40
44
|
import zope.event.classhandler
|
41
45
|
from c2cgeoform import Form, translator
|
46
|
+
from c2cwsgiutils.broadcast import decorator
|
42
47
|
from c2cwsgiutils.health_check import HealthCheck
|
43
48
|
from c2cwsgiutils.metrics import MemoryMapProvider, add_provider
|
44
49
|
from dogpile.cache import register_backend
|
@@ -54,7 +59,7 @@ import c2cgeoportal_geoportal.views
|
|
54
59
|
from c2cgeoportal_commons.models import InvalidateCacheEvent
|
55
60
|
from c2cgeoportal_geoportal.lib import C2CPregenerator, caching, check_collector, checker
|
56
61
|
from c2cgeoportal_geoportal.lib.cacheversion import version_cache_buster
|
57
|
-
from c2cgeoportal_geoportal.lib.
|
62
|
+
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
|
58
63
|
from c2cgeoportal_geoportal.lib.i18n import available_locale_names
|
59
64
|
from c2cgeoportal_geoportal.lib.metrics import (
|
60
65
|
MemoryCacheSizeProvider,
|
@@ -62,7 +67,11 @@ from c2cgeoportal_geoportal.lib.metrics import (
|
|
62
67
|
TotalPythonObjectMemoryProvider,
|
63
68
|
)
|
64
69
|
from c2cgeoportal_geoportal.lib.xsd import XSD
|
65
|
-
from c2cgeoportal_geoportal.views.entry import Entry
|
70
|
+
from c2cgeoportal_geoportal.views.entry import Entry, canvas_view
|
71
|
+
|
72
|
+
if TYPE_CHECKING:
|
73
|
+
from c2cgeoportal_commons.models import static # pylint: disable=ungrouped-imports,useless-suppression
|
74
|
+
|
66
75
|
|
67
76
|
LOG = logging.getLogger(__name__)
|
68
77
|
|
@@ -72,54 +81,132 @@ GEOJSON_CONTENT_TYPE = r"Content-Type:application/geo\+json"
|
|
72
81
|
|
73
82
|
|
74
83
|
class AssetRendererFactory:
|
75
|
-
|
84
|
+
"""Get a renderer for the assets."""
|
85
|
+
|
86
|
+
def __init__(self, info: Any):
|
76
87
|
del info # unused
|
77
88
|
self.resolver = AssetResolver("c2cgeoportal_geoportal")
|
78
89
|
|
79
|
-
def __call__(self, value, system):
|
90
|
+
def __call__(self, value: Any, system: Dict[str, str]) -> bytes:
|
91
|
+
del value
|
80
92
|
asset = self.resolver.resolve(system["renderer_name"])
|
81
|
-
return asset.stream().read()
|
93
|
+
return cast(bytes, asset.stream().read())
|
82
94
|
|
83
95
|
|
84
96
|
INTERFACE_TYPE_NGEO = "ngeo"
|
97
|
+
INTERFACE_TYPE_CANVAS = "canvas"
|
85
98
|
|
86
99
|
|
87
|
-
def
|
88
|
-
|
89
|
-
|
90
|
-
del interface_type # unused
|
91
|
-
route = "/" if default else "/{}".format(interface_name)
|
92
|
-
add_interface_ngeo(
|
100
|
+
def add_interface_config(config: pyramid.config.Configurator, interface_config: Dict[str, Any]) -> None:
|
101
|
+
"""Add the interface (desktop, mobile, ...) views and routes with only the config."""
|
102
|
+
add_interface(
|
93
103
|
config,
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
104
|
+
interface_config["name"],
|
105
|
+
interface_config.get("type", INTERFACE_TYPE_NGEO),
|
106
|
+
interface_config,
|
107
|
+
default=interface_config.get("default", False),
|
98
108
|
)
|
99
109
|
|
100
110
|
|
101
|
-
def
|
111
|
+
def add_interface(
|
112
|
+
config: pyramid.config.Configurator,
|
113
|
+
interface_name: str = "desktop",
|
114
|
+
interface_type: str = INTERFACE_TYPE_NGEO,
|
115
|
+
interface_config: Optional[Dict[str, Any]] = None,
|
116
|
+
default: bool = False,
|
117
|
+
**kwargs: Any,
|
118
|
+
) -> None:
|
119
|
+
"""Add the interface (desktop, mobile, ...) views and routes."""
|
120
|
+
route = "/" if default else f"/{interface_name}"
|
121
|
+
if interface_type == INTERFACE_TYPE_NGEO:
|
122
|
+
add_interface_ngeo(
|
123
|
+
config,
|
124
|
+
route_name=interface_name,
|
125
|
+
route=route,
|
126
|
+
renderer=f"/etc/static-ngeo/{interface_name}.html",
|
127
|
+
**kwargs,
|
128
|
+
)
|
129
|
+
elif interface_type == INTERFACE_TYPE_CANVAS:
|
130
|
+
assert interface_config is not None
|
131
|
+
add_interface_canvas(
|
132
|
+
config,
|
133
|
+
route_name=interface_name,
|
134
|
+
route=route,
|
135
|
+
interface_config=interface_config,
|
136
|
+
**kwargs,
|
137
|
+
)
|
138
|
+
else:
|
139
|
+
LOG.error(
|
140
|
+
"Unknown interface type '%s', should be '%s' or '%s'.",
|
141
|
+
interface_type,
|
142
|
+
INTERFACE_TYPE_NGEO,
|
143
|
+
INTERFACE_TYPE_CANVAS,
|
144
|
+
)
|
145
|
+
|
146
|
+
|
147
|
+
def add_interface_ngeo(
|
148
|
+
config: pyramid.config.Configurator,
|
149
|
+
route_name: str,
|
150
|
+
route: str,
|
151
|
+
renderer: Optional[str] = None,
|
152
|
+
permission: Optional[str] = None,
|
153
|
+
) -> None:
|
154
|
+
"""Add the ngeo interfaces views and routes."""
|
102
155
|
|
103
156
|
config.add_route(route_name, route, request_method="GET")
|
104
|
-
config.add_view(
|
105
|
-
Entry, attr="get_ngeo_index_vars", route_name=route_name, renderer=renderer, permission=permission
|
106
|
-
)
|
107
157
|
# Permalink theme: recover the theme for generating custom viewer.js url
|
108
158
|
config.add_route(
|
109
|
-
"{}theme"
|
110
|
-
"{}{
|
159
|
+
f"{route_name}theme",
|
160
|
+
f"{route}{'' if route[-1] == '/' else '/'}theme/{{themes}}",
|
111
161
|
request_method="GET",
|
112
162
|
)
|
163
|
+
config.add_view(
|
164
|
+
Entry, attr="get_ngeo_index_vars", route_name=route_name, renderer=renderer, permission=permission
|
165
|
+
)
|
113
166
|
config.add_view(
|
114
167
|
Entry,
|
115
168
|
attr="get_ngeo_index_vars",
|
116
|
-
route_name="{}theme"
|
169
|
+
route_name=f"{route_name}theme",
|
117
170
|
renderer=renderer,
|
118
171
|
permission=permission,
|
119
172
|
)
|
120
173
|
|
121
174
|
|
122
|
-
def
|
175
|
+
def add_interface_canvas(
|
176
|
+
config: pyramid.config.Configurator,
|
177
|
+
route_name: str,
|
178
|
+
route: str,
|
179
|
+
interface_config: Dict[str, Any],
|
180
|
+
permission: Optional[str] = None,
|
181
|
+
) -> None:
|
182
|
+
"""Add the ngeo interfaces views and routes."""
|
183
|
+
|
184
|
+
renderer = f"/etc/geomapfish/interfaces/{route_name}.html.mako"
|
185
|
+
config.add_route(route_name, route, request_method="GET")
|
186
|
+
# Permalink theme: recover the theme for generating custom viewer.js URL
|
187
|
+
config.add_route(
|
188
|
+
f"{route_name}theme",
|
189
|
+
f"{route}{'' if route[-1] == '/' else '/'}theme/{{themes}}",
|
190
|
+
request_method="GET",
|
191
|
+
)
|
192
|
+
view = partial(canvas_view, interface_config=interface_config)
|
193
|
+
view.__module__ = canvas_view.__module__
|
194
|
+
config.add_view(
|
195
|
+
view,
|
196
|
+
route_name=route_name,
|
197
|
+
renderer=renderer,
|
198
|
+
permission=permission,
|
199
|
+
)
|
200
|
+
config.add_view(
|
201
|
+
view,
|
202
|
+
route_name=f"{route_name}theme",
|
203
|
+
renderer=renderer,
|
204
|
+
permission=permission,
|
205
|
+
)
|
206
|
+
|
207
|
+
|
208
|
+
def add_admin_interface(config: pyramid.config.Configurator) -> None:
|
209
|
+
"""Add the administration interface views and routes."""
|
123
210
|
if config.get_settings().get("enable_admin_interface", False):
|
124
211
|
config.add_request_method(
|
125
212
|
lambda request: c2cgeoportal_commons.models.DBSession(),
|
@@ -131,7 +218,8 @@ def add_admin_interface(config):
|
|
131
218
|
config.include("c2cgeoportal_admin")
|
132
219
|
|
133
220
|
|
134
|
-
def add_getitfixed(config):
|
221
|
+
def add_getitfixed(config: pyramid.config.Configurator) -> None:
|
222
|
+
"""Add the get it fixed views and routes."""
|
135
223
|
if config.get_settings()["getitfixed"].get("enabled", False):
|
136
224
|
for route_name, pattern in (
|
137
225
|
("getitfixed_add_ending_slash", "/getitfixed"),
|
@@ -144,8 +232,9 @@ def add_getitfixed(config):
|
|
144
232
|
Form.set_zpt_renderer(c2cgeoform.default_search_paths, translator=translator)
|
145
233
|
|
146
234
|
|
147
|
-
def locale_negotiator(request):
|
148
|
-
|
235
|
+
def locale_negotiator(request: pyramid.request.Request) -> str:
|
236
|
+
"""Get the current language."""
|
237
|
+
lang: str = request.params.get("lang")
|
149
238
|
if lang is None:
|
150
239
|
lang = request.cookies.get("_LOCALE_")
|
151
240
|
else:
|
@@ -159,43 +248,48 @@ def locale_negotiator(request):
|
|
159
248
|
return lang
|
160
249
|
|
161
250
|
|
162
|
-
def _match_url_start(reference, value):
|
163
|
-
"""
|
164
|
-
Checks that the val URL starts like the ref URL.
|
165
|
-
"""
|
251
|
+
def _match_url_start(reference: str, value: List[str]) -> bool:
|
252
|
+
"""Check that the val URL starts like the ref URL."""
|
166
253
|
reference_parts = reference.rstrip("/").split("/")
|
167
|
-
|
168
|
-
value_parts = value[0:len(reference_parts)]
|
169
|
-
# fmt: on
|
254
|
+
value_parts = value[0 : len(reference_parts)]
|
170
255
|
return reference_parts == value_parts
|
171
256
|
|
172
257
|
|
173
|
-
def
|
174
|
-
if
|
175
|
-
|
258
|
+
def is_valid_referrer(request: pyramid.request.Request, settings: Optional[Dict[str, Any]] = None) -> bool:
|
259
|
+
"""Check if the referrer is valid."""
|
260
|
+
if request.referrer is not None:
|
261
|
+
referrer = urlsplit(request.referrer)._replace(query="", fragment="").geturl().rstrip("/").split("/")
|
176
262
|
if settings is None:
|
177
263
|
settings = request.registry.settings
|
178
264
|
list_ = settings.get("authorized_referers", [])
|
179
|
-
return any(_match_url_start(e,
|
265
|
+
return any(_match_url_start(e, referrer) for e in list_)
|
180
266
|
return True
|
181
267
|
|
182
268
|
|
183
|
-
def create_get_user_from_request(
|
184
|
-
|
185
|
-
|
269
|
+
def create_get_user_from_request(
|
270
|
+
settings: Dict[str, Any]
|
271
|
+
) -> Callable[[pyramid.request.Request, Optional[str]], Optional["static.User"]]:
|
272
|
+
"""Get the get_user_from_request function."""
|
273
|
+
|
274
|
+
def get_user_from_request(
|
275
|
+
request: pyramid.request.Request, username: Optional[str] = None
|
276
|
+
) -> Optional["static.User"]:
|
277
|
+
"""
|
278
|
+
Return the User object for the request.
|
186
279
|
|
187
280
|
Return ``None`` if:
|
188
281
|
* user is anonymous
|
189
282
|
* it does not exist in the database
|
190
|
-
*
|
283
|
+
* it has been deactivated
|
284
|
+
* the referrer is invalid
|
191
285
|
"""
|
192
286
|
from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
|
193
287
|
from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel
|
194
288
|
|
195
289
|
if not hasattr(request, "is_valid_referer"):
|
196
|
-
request.is_valid_referer =
|
290
|
+
request.is_valid_referer = is_valid_referrer(request, settings)
|
197
291
|
if not request.is_valid_referer:
|
198
|
-
LOG.debug("Invalid
|
292
|
+
LOG.debug("Invalid referrer for %s: %s", request.path_qs, repr(request.referrer))
|
199
293
|
return None
|
200
294
|
|
201
295
|
if not hasattr(request, "user_"):
|
@@ -206,16 +300,22 @@ def create_get_user_from_request(settings):
|
|
206
300
|
# We know we will need the role object of the
|
207
301
|
# user so we use joined loading
|
208
302
|
request.user_ = (
|
209
|
-
DBSession.query(User)
|
303
|
+
DBSession.query(User)
|
304
|
+
.filter_by(username=username, deactivated=False)
|
305
|
+
.options(joinedload("roles"))
|
306
|
+
.first()
|
210
307
|
)
|
211
308
|
|
212
|
-
return request.user_
|
309
|
+
return cast(User, request.user_)
|
213
310
|
|
214
311
|
return get_user_from_request
|
215
312
|
|
216
313
|
|
217
|
-
def set_user_validator(
|
218
|
-
|
314
|
+
def set_user_validator(
|
315
|
+
config: pyramid.config.Configurator, user_validator: Callable[[pyramid.request.Request, str, str], str]
|
316
|
+
) -> None:
|
317
|
+
"""
|
318
|
+
Call this function to register a user validator function.
|
219
319
|
|
220
320
|
The validator function is passed three arguments: ``request``,
|
221
321
|
``username``, and ``password``. The function should return the
|
@@ -231,11 +331,12 @@ def set_user_validator(config, user_validator):
|
|
231
331
|
config.action("user_validator", register)
|
232
332
|
|
233
333
|
|
234
|
-
def default_user_validator(request, username, password):
|
334
|
+
def default_user_validator(request: pyramid.request.Request, username: str, password: str) -> Optional[str]:
|
235
335
|
"""
|
236
|
-
Validate the username/password.
|
237
|
-
|
238
|
-
Return None if we are anonymous, the string to remember
|
336
|
+
Validate the username/password.
|
337
|
+
|
338
|
+
This is c2cgeoportal's default user validator. Return None if we are anonymous, the string to remember
|
339
|
+
otherwise.
|
239
340
|
"""
|
240
341
|
del request # unused
|
241
342
|
from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
|
@@ -243,7 +344,7 @@ def default_user_validator(request, username, password):
|
|
243
344
|
|
244
345
|
user = DBSession.query(User).filter_by(username=username).first()
|
245
346
|
if user is None:
|
246
|
-
LOG.info('
|
347
|
+
LOG.info('Unknown user "%s" tried to log in', username)
|
247
348
|
return None
|
248
349
|
if user.deactivated:
|
249
350
|
LOG.info('Deactivated user "%s" tried to log in', username)
|
@@ -258,49 +359,52 @@ def default_user_validator(request, username, password):
|
|
258
359
|
|
259
360
|
|
260
361
|
class MapserverproxyRoutePredicate:
|
261
|
-
"""
|
262
|
-
|
263
|
-
return 404s on GetCapabilities requests."""
|
362
|
+
"""
|
363
|
+
Serve as a custom route predicate function for mapserverproxy.
|
264
364
|
|
265
|
-
|
266
|
-
|
365
|
+
If the hide_capabilities setting is set and is true then we want to return 404s on GetCapabilities
|
366
|
+
requests.
|
367
|
+
"""
|
267
368
|
|
268
|
-
def
|
369
|
+
def __init__(self, val: Any, config: pyramid.config.Configurator) -> None:
|
370
|
+
del val, config
|
371
|
+
|
372
|
+
def __call__(self, context: Any, request: pyramid.request.Request) -> bool:
|
373
|
+
del context
|
269
374
|
hide_capabilities = request.registry.settings.get("hide_capabilities")
|
270
375
|
if not hide_capabilities:
|
271
376
|
return True
|
272
|
-
params =
|
377
|
+
params = {k.lower(): v.lower() for k, v in request.params.items()}
|
273
378
|
return "request" not in params or params["request"] not in ("getcapabilities", "capabilities")
|
274
379
|
|
275
380
|
@staticmethod
|
276
|
-
def text():
|
381
|
+
def text() -> str:
|
277
382
|
return "mapserverproxy"
|
278
383
|
|
279
384
|
phash = text
|
280
385
|
|
281
386
|
|
282
|
-
def add_cors_route(config, pattern, service):
|
283
|
-
"""
|
284
|
-
Add the OPTIONS route and view need for services supporting CORS.
|
285
|
-
"""
|
387
|
+
def add_cors_route(config: pyramid.config.Configurator, pattern: str, service: str) -> None:
|
388
|
+
"""Add the OPTIONS route and view need for services supporting CORS."""
|
286
389
|
|
287
|
-
def view(request
|
288
|
-
return set_common_headers(request, service,
|
390
|
+
def view(request: pyramid.request.Request) -> pyramid.response.Response:
|
391
|
+
return set_common_headers(request, service, Cache.PRIVATE_NO)
|
289
392
|
|
290
393
|
name = pattern + "_options"
|
291
394
|
config.add_route(name, pattern, request_method="OPTIONS")
|
292
395
|
config.add_view(view, route_name=name)
|
293
396
|
|
294
397
|
|
295
|
-
def error_handler(
|
296
|
-
|
297
|
-
|
298
|
-
"""
|
398
|
+
def error_handler(
|
399
|
+
http_exception: HTTPException, request: pyramid.request.Request
|
400
|
+
) -> pyramid.response.Response:
|
401
|
+
"""View callable for handling all the exceptions that are not already handled."""
|
299
402
|
LOG.warning("%s returned status code %s", request.url, http_exception.status_code)
|
300
|
-
return
|
403
|
+
return set_common_headers(request, "error", Cache.PRIVATE_NO, http_exception)
|
301
404
|
|
302
405
|
|
303
|
-
def call_hook(settings, name, *args, **kwargs):
|
406
|
+
def call_hook(settings: pyramid.config.Configurator, name: str, *args: Any, **kwargs: Any) -> None:
|
407
|
+
"""Call the hook defined in the settings."""
|
304
408
|
hooks = settings.get("hooks", {})
|
305
409
|
hook = hooks.get(name)
|
306
410
|
if hook is None:
|
@@ -311,11 +415,8 @@ def call_hook(settings, name, *args, **kwargs):
|
|
311
415
|
function_(*args, **kwargs)
|
312
416
|
|
313
417
|
|
314
|
-
def includeme(config: pyramid.config.Configurator):
|
315
|
-
"""
|
316
|
-
This function returns a Pyramid WSGI application.
|
317
|
-
"""
|
318
|
-
|
418
|
+
def includeme(config: pyramid.config.Configurator) -> None:
|
419
|
+
"""Get the Pyramid WSGI application."""
|
319
420
|
settings = config.get_settings()
|
320
421
|
|
321
422
|
if "available_locale_names" not in settings:
|
@@ -327,7 +428,7 @@ def includeme(config: pyramid.config.Configurator):
|
|
327
428
|
config.add_request_method(get_user_from_request, name="user", property=True)
|
328
429
|
config.add_request_method(get_user_from_request, name="get_user")
|
329
430
|
# Be able for an organization to override the method to use alternate:
|
330
|
-
# - Organization roles name for the standard roles 'anonymous', '
|
431
|
+
# - Organization roles name for the standard roles 'anonymous', 'registered' and 'intranet'.
|
331
432
|
config.add_request_method(lambda request, role_type: role_type, name="get_organization_role")
|
332
433
|
# - Organization print URL
|
333
434
|
config.add_request_method(
|
@@ -339,6 +440,7 @@ def includeme(config: pyramid.config.Configurator):
|
|
339
440
|
# Configure 'locale' dir as the translation dir for c2cgeoportal app
|
340
441
|
config.add_translation_dirs("c2cgeoportal_geoportal:locale/")
|
341
442
|
|
443
|
+
config.include("pyramid_mako")
|
342
444
|
config.include("c2cwsgiutils.pyramid.includeme")
|
343
445
|
health_check = HealthCheck(config)
|
344
446
|
config.registry["health_check"] = health_check
|
@@ -355,8 +457,8 @@ def includeme(config: pyramid.config.Configurator):
|
|
355
457
|
if metrics_config["total_python_object_memory"]:
|
356
458
|
add_provider(TotalPythonObjectMemoryProvider())
|
357
459
|
|
358
|
-
#
|
359
|
-
|
460
|
+
# Initialize DBSessions
|
461
|
+
init_db_sessions(settings, config, health_check)
|
360
462
|
|
361
463
|
checker.init(config, health_check)
|
362
464
|
check_collector.init(config, health_check)
|
@@ -370,17 +472,19 @@ def includeme(config: pyramid.config.Configurator):
|
|
370
472
|
for name, cache_config in settings["cache"].items():
|
371
473
|
caching.init_region(cache_config, name)
|
372
474
|
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
475
|
+
@zope.event.classhandler.handler(InvalidateCacheEvent) # type: ignore
|
476
|
+
def handle(event: InvalidateCacheEvent) -> None:
|
477
|
+
del event
|
478
|
+
caching.invalidate_region("ogc-server")
|
479
|
+
caching.invalidate_region("std")
|
480
|
+
caching.invalidate_region("obj")
|
481
|
+
if caching.MEMORY_CACHE_DICT:
|
482
|
+
caching.get_region("std").delete_multi(list(caching.MEMORY_CACHE_DICT.keys()))
|
483
|
+
caching.MEMORY_CACHE_DICT.clear()
|
380
484
|
|
381
485
|
# Register a tween to get back the cache buster path.
|
382
486
|
if "cache_path" not in config.get_settings():
|
383
|
-
config.get_settings()["cache_path"] = ["static"]
|
487
|
+
config.get_settings()["cache_path"] = ["static", "static-geomapfish"]
|
384
488
|
config.add_tween("c2cgeoportal_geoportal.lib.cacheversion.CachebusterTween")
|
385
489
|
config.add_tween("c2cgeoportal_geoportal.lib.headers.HeadersTween")
|
386
490
|
|
@@ -398,8 +502,10 @@ def includeme(config: pyramid.config.Configurator):
|
|
398
502
|
config.add_directive("set_user_validator", set_user_validator)
|
399
503
|
config.set_user_validator(default_user_validator)
|
400
504
|
|
505
|
+
config.add_route("oauth2introspect", "/oauth/introspect", request_method="POST")
|
401
506
|
config.add_route("oauth2token", "/oauth/token", request_method="POST")
|
402
507
|
config.add_route("oauth2loginform", "/oauth/login", request_method="GET")
|
508
|
+
config.add_route("oauth2revoke_token", "/oauth/revoke_token", request_method="GET")
|
403
509
|
config.add_route("notlogin", "/notlogin", request_method="GET")
|
404
510
|
|
405
511
|
config.add_route("dynamic", "/dynamic.json", request_method="GET")
|
@@ -420,6 +526,22 @@ def includeme(config: pyramid.config.Configurator):
|
|
420
526
|
pregenerator=C2CPregenerator(role=True),
|
421
527
|
request_method="POST",
|
422
528
|
)
|
529
|
+
# The tow next views are used to serve the application on the URL /mapserv_proxy/<ogc server name>
|
530
|
+
# instead of /mapserv_proxy?ogcserver=<ogc server name>, required for QGIS server landing page
|
531
|
+
config.add_route(
|
532
|
+
"mapserverproxy_get_path",
|
533
|
+
"/mapserv_proxy/{ogcserver}/*path",
|
534
|
+
mapserverproxy=True,
|
535
|
+
pregenerator=C2CPregenerator(role=True),
|
536
|
+
request_method="GET",
|
537
|
+
)
|
538
|
+
config.add_route(
|
539
|
+
"mapserverproxy_post_path",
|
540
|
+
"/mapserv_proxy/{ogcserver}/*path",
|
541
|
+
mapserverproxy=True,
|
542
|
+
pregenerator=C2CPregenerator(role=True),
|
543
|
+
request_method="POST",
|
544
|
+
)
|
423
545
|
add_cors_route(config, "/mapserv_proxy", "mapserver")
|
424
546
|
|
425
547
|
# Add route to the tinyows proxy
|
@@ -444,14 +566,15 @@ def includeme(config: pyramid.config.Configurator):
|
|
444
566
|
config.add_renderer(".css", AssetRendererFactory)
|
445
567
|
config.add_renderer(".ico", AssetRendererFactory)
|
446
568
|
config.add_route("localejson", "/locale.json", request_method="GET")
|
569
|
+
config.add_route("localepot", "/locale.pot", request_method="GET")
|
447
570
|
|
448
|
-
def add_static_route(name: str, attr: str, path: str, renderer: str):
|
571
|
+
def add_static_route(name: str, attr: str, path: str, renderer: str) -> None:
|
449
572
|
config.add_route(name, path, request_method="GET")
|
450
573
|
config.add_view(Entry, attr=attr, route_name=name, renderer=renderer)
|
451
574
|
|
452
575
|
add_static_route("favicon", "favicon", "/favicon.ico", "/etc/geomapfish/static/images/favicon.ico")
|
453
576
|
add_static_route("robot.txt", "robot_txt", "/robot.txt", "/etc/geomapfish/static/robot.txt")
|
454
|
-
|
577
|
+
config.add_route("apijs", "/api.js", request_method="GET")
|
455
578
|
add_static_route("apijsmap", "apijsmap", "/api.js.map", "/etc/static-ngeo/api.js.map")
|
456
579
|
add_static_route("apicss", "apicss", "/api.css", "/etc/static-ngeo/api.css")
|
457
580
|
add_static_route("apihelp", "apihelp", "/apihelp/index.html", "/etc/geomapfish/static/apihelp/index.html")
|
@@ -491,6 +614,13 @@ def includeme(config: pyramid.config.Configurator):
|
|
491
614
|
add_cors_route(config, "/profile.json", "profile")
|
492
615
|
config.add_route("profile.json", "/profile.json", request_method="POST")
|
493
616
|
|
617
|
+
# Access to vector tiles
|
618
|
+
add_cors_route(config, "/vector_tiles", "vector_tiles")
|
619
|
+
config.add_route("vector_tiles", "/vector_tiles/{layer_name}/{z}/{x}/{y}.pbf", request_method="GET")
|
620
|
+
# There is no view corresponding to that route, it is to be used from
|
621
|
+
# mako templates to get the root of the "vector_tiles" web service
|
622
|
+
config.add_route("vector_tiles_root", "/vector_tiles", request_method="HEAD")
|
623
|
+
|
494
624
|
# Shortener
|
495
625
|
add_cors_route(config, "/short/create", "shortener")
|
496
626
|
config.add_route("shortener_create", "/short/create", request_method="POST")
|
@@ -544,6 +674,8 @@ def includeme(config: pyramid.config.Configurator):
|
|
544
674
|
# Used memory in caches
|
545
675
|
config.add_route("memory", "/memory", request_method="GET")
|
546
676
|
|
677
|
+
config.add_route("ogc_server_clear_cache", "clear-ogc-server-cache/{id}", request_method="GET")
|
678
|
+
|
547
679
|
# Scan view decorator for adding routes
|
548
680
|
config.scan(
|
549
681
|
ignore=[
|
@@ -571,6 +703,21 @@ def includeme(config: pyramid.config.Configurator):
|
|
571
703
|
cache_max_age=int(config.get_settings()["default_max_age"]),
|
572
704
|
)
|
573
705
|
|
706
|
+
# Add the c2cgeoportal static view with cache buster
|
707
|
+
config.add_static_view(
|
708
|
+
name="static-geomapfish",
|
709
|
+
path="c2cgeoportal_geoportal:static",
|
710
|
+
cache_max_age=int(config.get_settings()["default_max_age"]),
|
711
|
+
)
|
712
|
+
config.add_cache_buster("c2cgeoportal_geoportal:static", version_cache_buster)
|
713
|
+
|
714
|
+
# Add the project static view without cache buster
|
715
|
+
config.add_static_view(
|
716
|
+
name="static-ngeo-dist",
|
717
|
+
path="/opt/c2cgeoportal/geoportal/node_modules/ngeo/dist",
|
718
|
+
cache_max_age=int(config.get_settings()["default_max_age"]),
|
719
|
+
)
|
720
|
+
|
574
721
|
# Handles the other HTTP errors raised by the views. Without that,
|
575
722
|
# the client receives a status=200 without content.
|
576
723
|
config.add_view(error_handler, context=HTTPException)
|
@@ -603,7 +750,10 @@ def includeme(config: pyramid.config.Configurator):
|
|
603
750
|
c2cwsgiutils.index.additional_noauth.append("</div></div><hr>")
|
604
751
|
|
605
752
|
|
606
|
-
def
|
753
|
+
def init_db_sessions(
|
754
|
+
settings: Dict[str, Any], config: Configurator, health_check: Optional[HealthCheck] = None
|
755
|
+
) -> None:
|
756
|
+
"""Initialize the database sessions."""
|
607
757
|
db_chooser = settings.get("db_chooser", {})
|
608
758
|
master_paths = [i.replace("//", "/") for i in db_chooser.get("master", [])]
|
609
759
|
slave_paths = [i.replace("//", "/") for i in db_chooser.get("slave", [])]
|
@@ -644,7 +794,7 @@ def init_dbsessions(settings: dict, config: Configurator, health_check: HealthCh
|
|
644
794
|
version_schema=settings["schema_static"],
|
645
795
|
level=1,
|
646
796
|
)
|
647
|
-
else:
|
797
|
+
else:
|
648
798
|
|
649
799
|
def check(session_: Session) -> None:
|
650
800
|
session_.execute("SELECT 1")
|