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,5 +1,3 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
1
|
# Copyright (c) 2018-2021, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
@@ -30,8 +28,9 @@
|
|
30
28
|
|
31
29
|
import logging
|
32
30
|
import time
|
33
|
-
from typing import Any, Dict
|
31
|
+
from typing import Any, Dict, cast
|
34
32
|
|
33
|
+
import pyramid.request
|
35
34
|
from c2cwsgiutils import broadcast
|
36
35
|
from c2cwsgiutils.auth import auth_view
|
37
36
|
from c2cwsgiutils.debug import get_size
|
@@ -43,27 +42,28 @@ from c2cgeoportal_geoportal.views import raster
|
|
43
42
|
LOG = logging.getLogger(__name__)
|
44
43
|
|
45
44
|
|
46
|
-
@view_config(route_name="memory", renderer="fast_json")
|
47
|
-
def memory(request):
|
45
|
+
@view_config(route_name="memory", renderer="fast_json") # type: ignore
|
46
|
+
def memory(request: pyramid.request.Request) -> Dict[str, Any]:
|
47
|
+
"""Offer an authenticated view throw c2cwsgiutils to provide some memory information."""
|
48
48
|
auth_view(request)
|
49
|
-
return _memory()
|
49
|
+
return cast(Dict[str, Any], _memory())
|
50
50
|
|
51
51
|
|
52
|
-
def _nice_type_name(obj, dogpile_cache=False):
|
52
|
+
def _nice_type_name(obj: Any, dogpile_cache: bool = False) -> str:
|
53
53
|
# See: https://dogpilecache.sqlalchemy.org/en/latest/api.html#dogpile.cache.api.CachedValue
|
54
54
|
if dogpile_cache:
|
55
55
|
obj, _ = obj
|
56
56
|
type_ = type(obj)
|
57
|
-
return "{}.{
|
57
|
+
return f"{type_.__module__}.{type_.__name__}"
|
58
58
|
|
59
59
|
|
60
|
-
def _process_dict(dict_, dogpile_cache=False):
|
60
|
+
def _process_dict(dict_: Dict[str, Any], dogpile_cache: bool = False) -> Dict[str, Any]:
|
61
61
|
# Timeout after one minute, must be set to a bit less that the timeout of the broadcast
|
62
62
|
timeout = time.monotonic() + 20
|
63
63
|
|
64
64
|
return {
|
65
65
|
"elements": sorted(
|
66
|
-
|
66
|
+
(
|
67
67
|
{
|
68
68
|
"key": key,
|
69
69
|
"type": _nice_type_name(value, dogpile_cache),
|
@@ -72,8 +72,8 @@ def _process_dict(dict_, dogpile_cache=False):
|
|
72
72
|
"size_kb": get_size(value) / 1024 if time.monotonic() < timeout else -1,
|
73
73
|
}
|
74
74
|
for key, value in dict_.items()
|
75
|
-
|
76
|
-
key=lambda i: -i["size_kb"],
|
75
|
+
),
|
76
|
+
key=lambda i: cast(float, -i["size_kb"]),
|
77
77
|
),
|
78
78
|
"id": id(dict_),
|
79
79
|
"size_kb": get_size(dict_) / 1024 if time.monotonic() < timeout else -1,
|
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2011-2020, Camptocamp SA
|
1
|
+
# Copyright (c) 2011-2023, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -28,14 +26,14 @@
|
|
28
26
|
# either expressed or implied, of the FreeBSD Project.
|
29
27
|
|
30
28
|
import logging
|
31
|
-
from typing import Set
|
29
|
+
from typing import Dict, Optional, Set, cast
|
32
30
|
|
31
|
+
import pyramid.request
|
33
32
|
from pyramid.httpexceptions import HTTPBadRequest
|
34
33
|
from sqlalchemy.orm.exc import NoResultFound
|
35
34
|
|
36
|
-
from c2cgeoportal_commons.lib.url import get_url2
|
37
|
-
from c2cgeoportal_commons.models import DBSession
|
38
|
-
from c2cgeoportal_commons.models.main import OGCServer
|
35
|
+
from c2cgeoportal_commons.lib.url import Url, get_url2
|
36
|
+
from c2cgeoportal_commons.models import DBSession, main
|
39
37
|
from c2cgeoportal_geoportal.lib.caching import get_region
|
40
38
|
from c2cgeoportal_geoportal.views.proxy import Proxy
|
41
39
|
|
@@ -44,54 +42,78 @@ LOG = logging.getLogger(__name__)
|
|
44
42
|
|
45
43
|
|
46
44
|
class OGCProxy(Proxy):
|
47
|
-
|
45
|
+
"""
|
46
|
+
Proxy implementation that manly manage the ogcserver parameter.
|
47
|
+
|
48
|
+
Then load the corresponding OGCServer.
|
49
|
+
"""
|
50
|
+
|
51
|
+
def __init__(self, request: pyramid.request.Request, has_default_ogc_server: bool = False):
|
48
52
|
Proxy.__init__(self, request)
|
49
53
|
|
50
54
|
# params hold the parameters we"re going to send to backend
|
51
55
|
self.params = dict(self.request.params)
|
52
56
|
|
53
57
|
# reset possible value of role_id and user_id
|
54
|
-
if "role_id" in self.params:
|
58
|
+
if "role_id" in self.params:
|
55
59
|
del self.params["role_id"]
|
56
|
-
if "user_id" in self.params:
|
60
|
+
if "user_id" in self.params:
|
57
61
|
del self.params["user_id"]
|
58
62
|
|
63
|
+
main_ogc_server = self.request.registry.settings.get("main_ogc_server")
|
64
|
+
|
59
65
|
self.lower_params = self._get_lower_params(self.params)
|
60
|
-
|
66
|
+
|
67
|
+
# We need original case for OGCSERVER parameter value
|
68
|
+
self.lower_key_params = {k.lower(): v for k, v in self.params.items()}
|
69
|
+
|
70
|
+
if "ogcserver" in request.matchdict:
|
71
|
+
self.ogc_server = self._get_ogcserver_byname(request.matchdict["ogcserver"])
|
72
|
+
elif "ogcserver" in self.lower_key_params:
|
73
|
+
self.ogc_server = self._get_ogcserver_byname(self.lower_key_params["ogcserver"])
|
74
|
+
elif main_ogc_server is not None:
|
75
|
+
self.ogc_server = self._get_ogcserver_byname(main_ogc_server)
|
76
|
+
elif not has_default_ogc_server:
|
61
77
|
raise HTTPBadRequest("The querystring argument 'ogcserver' is required")
|
62
|
-
if "ogcserver" in self.params:
|
63
|
-
self.ogc_server = self._get_ogcserver_byname(self.params["ogcserver"])
|
64
78
|
|
65
|
-
@CACHE_REGION.cache_on_arguments()
|
66
|
-
def _get_ogcserver_byname(self, name
|
79
|
+
@CACHE_REGION.cache_on_arguments() # type: ignore
|
80
|
+
def _get_ogcserver_byname(self, name: str) -> main.OGCServer:
|
67
81
|
try:
|
68
|
-
result = DBSession.query(OGCServer).filter(OGCServer.name == name).one()
|
82
|
+
result = DBSession.query(main.OGCServer).filter(main.OGCServer.name == name).one()
|
69
83
|
DBSession.expunge(result)
|
70
|
-
return result
|
71
|
-
except NoResultFound:
|
72
|
-
raise HTTPBadRequest(
|
73
|
-
"
|
74
|
-
|
75
|
-
)
|
84
|
+
return cast(main.OGCServer, result)
|
85
|
+
except NoResultFound:
|
86
|
+
raise HTTPBadRequest( # pylint: disable=raise-missing-from
|
87
|
+
f"The OGC Server '{name}' does not exist (existing: "
|
88
|
+
f"{','.join([t[0] for t in DBSession.query(main.OGCServer.name).all()])})."
|
76
89
|
)
|
77
90
|
|
78
|
-
def _get_wms_url(self):
|
91
|
+
def _get_wms_url(self, errors: Set[str]) -> Optional[Url]:
|
79
92
|
ogc_server = self.ogc_server
|
80
|
-
|
81
|
-
|
82
|
-
if errors: # pragma: no cover
|
93
|
+
url = get_url2(f"The OGC server '{ogc_server.name}'", ogc_server.url, self.request, errors)
|
94
|
+
if errors:
|
83
95
|
LOG.error("\n".join(errors))
|
84
96
|
return url
|
85
97
|
|
86
|
-
def _get_wfs_url(self):
|
98
|
+
def _get_wfs_url(self, errors: Set[str]) -> Optional[Url]:
|
87
99
|
ogc_server = self.ogc_server
|
88
|
-
errors: Set[str] = set()
|
89
100
|
url = get_url2(
|
90
|
-
"The OGC server (WFS) '{}'"
|
101
|
+
f"The OGC server (WFS) '{ogc_server.name}'",
|
91
102
|
ogc_server.url_wfs or ogc_server.url,
|
92
103
|
self.request,
|
93
104
|
errors,
|
94
105
|
)
|
95
|
-
if errors:
|
106
|
+
if errors:
|
96
107
|
LOG.error("\n".join(errors))
|
97
108
|
return url
|
109
|
+
|
110
|
+
def get_headers(self) -> Dict[str, str]:
|
111
|
+
headers: Dict[str, str] = super().get_headers()
|
112
|
+
if self.ogc_server.type == main.OGCSERVER_TYPE_QGISSERVER:
|
113
|
+
if self.request.matched_route.name.endswith("_path"):
|
114
|
+
headers["X-Qgis-Service-Url"] = self.request.current_route_url(path=[], _query={})
|
115
|
+
else:
|
116
|
+
headers["X-Qgis-Service-Url"] = self.request.current_route_url(
|
117
|
+
_query={"ogcserver": self.ogc_server.name}
|
118
|
+
)
|
119
|
+
return headers
|
@@ -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
|
@@ -29,44 +27,49 @@
|
|
29
27
|
|
30
28
|
import logging
|
31
29
|
from json import dumps, loads
|
30
|
+
from typing import Any, Dict, List, Union
|
32
31
|
|
32
|
+
import pyramid.request
|
33
|
+
import pyramid.response
|
33
34
|
from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden
|
34
35
|
from pyramid.view import view_config
|
35
36
|
|
36
37
|
from c2cgeoportal_commons import models
|
37
|
-
from c2cgeoportal_commons.lib.url import
|
38
|
+
from c2cgeoportal_commons.lib.url import Url
|
38
39
|
from c2cgeoportal_commons.models import main
|
39
|
-
from c2cgeoportal_geoportal.lib.
|
40
|
+
from c2cgeoportal_geoportal.lib.common_headers import Cache
|
40
41
|
from c2cgeoportal_geoportal.lib.layers import get_private_layers, get_protected_layers
|
41
42
|
from c2cgeoportal_geoportal.views.ogcproxy import OGCProxy
|
42
43
|
|
43
44
|
LOG = logging.getLogger(__name__)
|
44
45
|
|
45
46
|
|
46
|
-
class PdfReport(OGCProxy):
|
47
|
+
class PdfReport(OGCProxy):
|
48
|
+
"""All the views concerned the PDF report."""
|
47
49
|
|
48
50
|
layername = None
|
49
51
|
|
50
|
-
def __init__(self, request):
|
52
|
+
def __init__(self, request: pyramid.request.Request):
|
51
53
|
OGCProxy.__init__(self, request)
|
52
54
|
self.config = self.request.registry.settings.get("pdfreport", {})
|
53
55
|
|
54
|
-
def _do_print(self, spec):
|
56
|
+
def _do_print(self, spec: Dict[str, Any]) -> pyramid.response.Response:
|
55
57
|
"""Create and get report PDF."""
|
56
|
-
|
57
58
|
headers = dict(self.request.headers)
|
58
59
|
headers["Content-Type"] = "application/json"
|
59
60
|
response = self._proxy(
|
60
|
-
"{
|
61
|
+
Url(f"{self.config['print_url']}/buildreport.{spec['outputFormat']}"),
|
61
62
|
method="POST",
|
62
63
|
body=dumps(spec).encode("utf-8"),
|
63
64
|
headers=headers,
|
64
65
|
)
|
65
66
|
|
66
|
-
return self._build_response(response, response.content,
|
67
|
+
return self._build_response(response, response.content, Cache.PRIVATE_NO, "pdfreport")
|
67
68
|
|
68
69
|
@staticmethod
|
69
|
-
def _build_map(
|
70
|
+
def _build_map(
|
71
|
+
mapserv_url: str, vector_request_url: str, srs: str, map_config: Dict[str, Any]
|
72
|
+
) -> Dict[str, Any]:
|
70
73
|
backgroundlayers = map_config["backgroundlayers"]
|
71
74
|
imageformat = map_config["imageformat"]
|
72
75
|
return {
|
@@ -98,19 +101,19 @@ class PdfReport(OGCProxy): # pragma: no cover
|
|
98
101
|
],
|
99
102
|
}
|
100
103
|
|
101
|
-
@view_config(route_name="pdfreport", renderer="json")
|
102
|
-
def get_report(self):
|
104
|
+
@view_config(route_name="pdfreport", renderer="json") # type: ignore
|
105
|
+
def get_report(self) -> pyramid.response.Response:
|
103
106
|
self.layername = self.request.matchdict["layername"]
|
104
107
|
layer_config = self.config["layers"].get(self.layername)
|
105
108
|
|
109
|
+
if layer_config is None:
|
110
|
+
raise HTTPBadRequest("Layer not found: " + self.layername)
|
111
|
+
|
106
112
|
multiple = layer_config.get("multiple", False)
|
107
113
|
ids = self.request.matchdict["ids"]
|
108
114
|
if multiple:
|
109
115
|
ids = ids.split(",")
|
110
116
|
|
111
|
-
if layer_config is None:
|
112
|
-
raise HTTPBadRequest("Layer not found")
|
113
|
-
|
114
117
|
features_ids = (
|
115
118
|
[self.layername + "." + id_ for id_ in ids] if multiple else [self.layername + "." + ids]
|
116
119
|
)
|
@@ -138,8 +141,8 @@ class PdfReport(OGCProxy): # pragma: no cover
|
|
138
141
|
mapserv_url = self.request.route_url(
|
139
142
|
"mapserverproxy", _query={"ogcserver": layer_config["ogc_server"]}
|
140
143
|
)
|
141
|
-
|
142
|
-
|
144
|
+
url = Url(mapserv_url)
|
145
|
+
url.add_query(
|
143
146
|
{
|
144
147
|
"service": "WFS",
|
145
148
|
"version": "1.1.0",
|
@@ -148,8 +151,9 @@ class PdfReport(OGCProxy): # pragma: no cover
|
|
148
151
|
"typeName": self.layername,
|
149
152
|
"featureid": ",".join(features_ids),
|
150
153
|
"srsName": srs,
|
151
|
-
}
|
154
|
+
}
|
152
155
|
)
|
156
|
+
vector_request_url = url.url()
|
153
157
|
|
154
158
|
spec = layer_config["spec"]
|
155
159
|
if spec is None:
|
@@ -221,7 +225,7 @@ class PdfReport(OGCProxy): # pragma: no cover
|
|
221
225
|
|
222
226
|
return self._do_print(spec)
|
223
227
|
|
224
|
-
def walker(self, spec, name, value):
|
228
|
+
def walker(self, spec: Union[Dict[str, Any], List[Dict[str, Any]]], name: str, value: Any) -> None:
|
225
229
|
if isinstance(spec, dict):
|
226
230
|
for k, v in spec.items():
|
227
231
|
if isinstance(v, str):
|
@@ -231,9 +235,9 @@ class PdfReport(OGCProxy): # pragma: no cover
|
|
231
235
|
self.walker(v, name, value)
|
232
236
|
|
233
237
|
if isinstance(spec, list):
|
234
|
-
for
|
235
|
-
if isinstance(
|
236
|
-
if
|
237
|
-
spec[
|
238
|
+
for k2, v2 in enumerate(spec):
|
239
|
+
if isinstance(v2, str):
|
240
|
+
if v2 == name:
|
241
|
+
spec[k2] = value
|
238
242
|
else:
|
239
|
-
self.walker(
|
243
|
+
self.walker(v2, name, value)
|
@@ -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
|
@@ -31,12 +29,18 @@
|
|
31
29
|
import json
|
32
30
|
import logging
|
33
31
|
import urllib.parse
|
32
|
+
from typing import Dict, List, Tuple
|
34
33
|
|
34
|
+
import pyramid.request
|
35
|
+
import pyramid.response
|
36
|
+
import requests
|
35
37
|
from pyramid.httpexceptions import HTTPBadGateway, HTTPFound
|
36
38
|
from pyramid.view import view_config
|
37
39
|
|
40
|
+
from c2cgeoportal_commons.lib.url import Url
|
38
41
|
from c2cgeoportal_geoportal.lib import is_intranet
|
39
|
-
from c2cgeoportal_geoportal.lib.caching import
|
42
|
+
from c2cgeoportal_geoportal.lib.caching import get_region
|
43
|
+
from c2cgeoportal_geoportal.lib.common_headers import Cache
|
40
44
|
from c2cgeoportal_geoportal.lib.functionality import get_functionality
|
41
45
|
from c2cgeoportal_geoportal.views.proxy import Proxy
|
42
46
|
|
@@ -44,93 +48,97 @@ LOG = logging.getLogger(__name__)
|
|
44
48
|
CACHE_REGION = get_region("std")
|
45
49
|
|
46
50
|
|
47
|
-
class PrintProxy(Proxy):
|
48
|
-
|
51
|
+
class PrintProxy(Proxy):
|
52
|
+
"""All the view concerned the print."""
|
53
|
+
|
54
|
+
def __init__(self, request: pyramid.request.Request):
|
49
55
|
Proxy.__init__(self, request)
|
50
56
|
|
51
|
-
@view_config(route_name="printproxy_capabilities")
|
52
|
-
def capabilities(self):
|
57
|
+
@view_config(route_name="printproxy_capabilities") # type: ignore
|
58
|
+
def capabilities(self) -> pyramid.response.Response:
|
53
59
|
"""Get print capabilities."""
|
54
|
-
|
55
60
|
templates = get_functionality("print_template", self.request, is_intranet(self.request))
|
56
61
|
|
57
62
|
# get query string
|
58
63
|
params = dict(self.request.params)
|
59
64
|
query_string = urllib.parse.urlencode(params)
|
60
65
|
|
61
|
-
resp, content = self._capabilities(
|
66
|
+
resp, content = self._capabilities(
|
67
|
+
templates, query_string, self.request.method, self.request.referrer, self.request.host
|
68
|
+
)
|
62
69
|
|
63
|
-
|
70
|
+
response = self._build_response(resp, content, Cache.PRIVATE, "print")
|
71
|
+
# Mapfish print will check the referrer header to return the capabilities.
|
72
|
+
response.vary += ("Referrer", "Referer")
|
73
|
+
return response
|
64
74
|
|
65
|
-
@CACHE_REGION.cache_on_arguments()
|
66
|
-
def _capabilities(
|
75
|
+
@CACHE_REGION.cache_on_arguments() # type: ignore
|
76
|
+
def _capabilities(
|
77
|
+
self, templates: List[str], query_string: Dict[str, str], method: str, referrer: str, host: str
|
78
|
+
) -> Tuple[requests.Response, str]:
|
67
79
|
del query_string # Just for caching
|
68
80
|
del method # Just for caching
|
69
|
-
#
|
81
|
+
del referrer # Just for caching
|
82
|
+
del host # Just for caching
|
83
|
+
|
84
|
+
# Get URL
|
70
85
|
_url = self.request.get_organization_print_url() + "/capabilities.json"
|
71
86
|
|
72
|
-
response = self._proxy(_url)
|
87
|
+
response = self._proxy(Url(_url))
|
88
|
+
response.raise_for_status()
|
73
89
|
|
74
90
|
if self.request.method == "GET":
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
)
|
88
|
-
|
89
|
-
pretty = self.request.params.get("pretty", "false") == "true"
|
90
|
-
content = json.dumps(
|
91
|
-
capabilities, separators=None if pretty else (",", ":"), indent=4 if pretty else None
|
92
|
-
)
|
91
|
+
try:
|
92
|
+
capabilities = response.json()
|
93
|
+
except json.decoder.JSONDecodeError:
|
94
|
+
LOG.exception("Unable to parse capabilities: %s", response.text)
|
95
|
+
raise HTTPBadGateway(response.text) # pylint: disable=raise-missing-from
|
96
|
+
|
97
|
+
capabilities["layouts"] = list(
|
98
|
+
layout for layout in capabilities["layouts"] if layout["name"] in templates
|
99
|
+
)
|
100
|
+
|
101
|
+
pretty = self.request.params.get("pretty", "false") == "true"
|
102
|
+
content = json.dumps(
|
103
|
+
capabilities, separators=None if pretty else (",", ":"), indent=4 if pretty else None
|
104
|
+
)
|
93
105
|
else:
|
94
106
|
content = ""
|
95
107
|
|
96
108
|
return response, content
|
97
109
|
|
98
|
-
@view_config(route_name="printproxy_report_create")
|
99
|
-
def report_create(self):
|
110
|
+
@view_config(route_name="printproxy_report_create") # type: ignore
|
111
|
+
def report_create(self) -> pyramid.response.Response:
|
100
112
|
"""Create PDF."""
|
101
113
|
return self._proxy_response(
|
102
114
|
"print",
|
103
|
-
|
104
|
-
self.request.get_organization_print_url()
|
115
|
+
Url(
|
116
|
+
f"{ self.request.get_organization_print_url()}/report.{self.request.matchdict.get('format')}"
|
105
117
|
),
|
106
118
|
)
|
107
119
|
|
108
|
-
@view_config(route_name="printproxy_status")
|
109
|
-
def status(self):
|
120
|
+
@view_config(route_name="printproxy_status") # type: ignore
|
121
|
+
def status(self) -> pyramid.response.Response:
|
110
122
|
"""PDF status."""
|
111
123
|
return self._proxy_response(
|
112
124
|
"print",
|
113
|
-
|
114
|
-
self.request.get_organization_print_url()
|
125
|
+
Url(
|
126
|
+
f"{self.request.get_organization_print_url()}/status/{self.request.matchdict.get('ref')}.json"
|
115
127
|
),
|
116
128
|
)
|
117
129
|
|
118
|
-
@view_config(route_name="printproxy_cancel")
|
119
|
-
def cancel(self):
|
130
|
+
@view_config(route_name="printproxy_cancel") # type: ignore
|
131
|
+
def cancel(self) -> pyramid.response.Response:
|
120
132
|
"""PDF cancel."""
|
121
133
|
return self._proxy_response(
|
122
134
|
"print",
|
123
|
-
"{
|
124
|
-
self.request.get_organization_print_url(), self.request.matchdict.get("ref")
|
125
|
-
),
|
135
|
+
Url(f"{self.request.get_organization_print_url()}/cancel/{self.request.matchdict.get('ref')}"),
|
126
136
|
)
|
127
137
|
|
128
|
-
@view_config(route_name="printproxy_report_get")
|
129
|
-
def report_get(self):
|
138
|
+
@view_config(route_name="printproxy_report_get") # type: ignore
|
139
|
+
def report_get(self) -> pyramid.response.Response:
|
130
140
|
"""Get the PDF."""
|
131
|
-
url = "{
|
132
|
-
self.request.get_organization_print_url(), self.request.matchdict.get("ref")
|
133
|
-
)
|
141
|
+
url = Url(f"{self.request.get_organization_print_url()}/report/{self.request.matchdict.get('ref')}")
|
134
142
|
if self.request.registry.settings.get("print_get_redirect", False):
|
135
|
-
raise HTTPFound(location=url)
|
143
|
+
raise HTTPFound(location=url.url())
|
136
144
|
return self._proxy_response("print", url)
|
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2012-2020, Camptocamp SA
|
1
|
+
# Copyright (c) 2012-2023, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -30,33 +28,38 @@
|
|
30
28
|
|
31
29
|
import math
|
32
30
|
from decimal import Decimal
|
31
|
+
from typing import Any, Dict, List, Tuple
|
33
32
|
|
34
33
|
import geojson
|
34
|
+
import pyramid.request
|
35
35
|
from pyramid.httpexceptions import HTTPNotFound
|
36
36
|
from pyramid.i18n import TranslationStringFactory
|
37
37
|
from pyramid.view import view_config
|
38
38
|
|
39
|
-
from c2cgeoportal_geoportal.lib.
|
39
|
+
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
|
40
40
|
from c2cgeoportal_geoportal.views.raster import Raster
|
41
41
|
|
42
42
|
_ = TranslationStringFactory("c2cgeoportal")
|
43
43
|
|
44
44
|
|
45
45
|
class Profile(Raster):
|
46
|
-
|
46
|
+
"""All the view concerned the profile."""
|
47
|
+
|
48
|
+
def __init__(self, request: pyramid.request.Request):
|
47
49
|
Raster.__init__(self, request)
|
48
50
|
|
49
|
-
@view_config(route_name="profile.json", renderer="fast_json")
|
50
|
-
def json(self):
|
51
|
-
"""
|
51
|
+
@view_config(route_name="profile.json", renderer="fast_json") # type: ignore
|
52
|
+
def json(self) -> Dict[str, Any]:
|
53
|
+
"""Answer to /profile.json."""
|
52
54
|
_, points = self._compute_points()
|
53
|
-
set_common_headers(self.request, "profile",
|
55
|
+
set_common_headers(self.request, "profile", Cache.PUBLIC_NO)
|
54
56
|
return {"profile": points}
|
55
57
|
|
56
|
-
def _compute_points(self):
|
57
|
-
"""Compute the alt=fct(dist) array"""
|
58
|
+
def _compute_points(self) -> Tuple[List[str], List[Dict[str, Any]]]:
|
59
|
+
"""Compute the alt=fct(dist) array."""
|
58
60
|
geom = geojson.loads(self.request.params["geom"], object_hook=geojson.GeoJSON.to_instance)
|
59
61
|
|
62
|
+
layers: List[str]
|
60
63
|
if "layers" in self.request.params:
|
61
64
|
rasters = {}
|
62
65
|
layers = self.request.params["layers"].split(",")
|
@@ -64,13 +67,13 @@ class Profile(Raster):
|
|
64
67
|
if layer in self.rasters:
|
65
68
|
rasters[layer] = self.rasters[layer]
|
66
69
|
else:
|
67
|
-
raise HTTPNotFound("Layer {
|
70
|
+
raise HTTPNotFound(f"Layer {layer!s} not found")
|
68
71
|
else:
|
69
72
|
rasters = self.rasters
|
70
73
|
layers = list(rasters.keys())
|
71
74
|
layers.sort()
|
72
75
|
|
73
|
-
points = []
|
76
|
+
points: List[Dict[str, Any]] = []
|
74
77
|
|
75
78
|
dist = 0
|
76
79
|
prev_coord = None
|
@@ -92,12 +95,12 @@ class Profile(Raster):
|
|
92
95
|
return layers, points
|
93
96
|
|
94
97
|
@staticmethod
|
95
|
-
def _dist(coord1, coord2):
|
96
|
-
"""Compute the distance between 2 points"""
|
98
|
+
def _dist(coord1: Tuple[float, float], coord2: Tuple[float, float]) -> float:
|
99
|
+
"""Compute the distance between 2 points."""
|
97
100
|
return math.sqrt(math.pow(coord1[0] - coord2[0], 2.0) + math.pow(coord1[1] - coord2[1], 2.0))
|
98
101
|
|
99
|
-
def _create_points(self, coords, nb_points):
|
100
|
-
"""Add some points in order to reach roughly the asked number of points"""
|
102
|
+
def _create_points(self, coords: List[Tuple[float, float]], nb_points: int) -> List[Tuple[float, float]]:
|
103
|
+
"""Add some points in order to reach roughly the asked number of points."""
|
101
104
|
total_length = 0
|
102
105
|
prev_coord = None
|
103
106
|
for coord in coords:
|
@@ -108,19 +111,17 @@ class Profile(Raster):
|
|
108
111
|
if total_length == 0.0:
|
109
112
|
return coords
|
110
113
|
|
111
|
-
result = []
|
114
|
+
result: List[Tuple[float, float]] = []
|
112
115
|
prev_coord = None
|
113
116
|
for coord in coords:
|
114
117
|
if prev_coord is not None:
|
115
118
|
cur_length = self._dist(prev_coord, coord)
|
116
|
-
cur_nb_points = int(nb_points * cur_length / total_length + 0.5)
|
117
|
-
if cur_nb_points < 1:
|
118
|
-
cur_nb_points = 1
|
119
|
+
cur_nb_points = max(int(nb_points * cur_length / total_length + 0.5), 1)
|
119
120
|
dx = (coord[0] - prev_coord[0]) / float(cur_nb_points)
|
120
121
|
dy = (coord[1] - prev_coord[1]) / float(cur_nb_points)
|
121
122
|
for i in range(1, cur_nb_points + 1):
|
122
|
-
result.append(
|
123
|
+
result.append((prev_coord[0] + dx * i, prev_coord[1] + dy * i))
|
123
124
|
else:
|
124
|
-
result.append(
|
125
|
+
result.append((coord[0], coord[1]))
|
125
126
|
prev_coord = coord
|
126
127
|
return result
|