c2cgeoportal-geoportal 2.5.0.100__py2.py3-none-any.whl → 2.7.1.83__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 +261 -130
- c2cgeoportal_geoportal/lib/__init__.py +72 -120
- c2cgeoportal_geoportal/lib/authentication.py +170 -21
- c2cgeoportal_geoportal/lib/bashcolor.py +17 -13
- c2cgeoportal_geoportal/lib/cacheversion.py +19 -11
- c2cgeoportal_geoportal/lib/caching.py +66 -160
- c2cgeoportal_geoportal/lib/check_collector.py +17 -10
- c2cgeoportal_geoportal/lib/checker.py +62 -64
- c2cgeoportal_geoportal/lib/common_headers.py +170 -0
- c2cgeoportal_geoportal/lib/dbreflection.py +70 -31
- c2cgeoportal_geoportal/lib/filter_capabilities.py +124 -96
- c2cgeoportal_geoportal/lib/fulltextsearch.py +50 -0
- c2cgeoportal_geoportal/lib/functionality.py +36 -21
- c2cgeoportal_geoportal/lib/headers.py +14 -5
- c2cgeoportal_geoportal/lib/i18n.py +39 -0
- c2cgeoportal_geoportal/lib/layers.py +29 -10
- c2cgeoportal_geoportal/lib/lingua_extractor.py +408 -211
- c2cgeoportal_geoportal/lib/loader.py +18 -16
- c2cgeoportal_geoportal/lib/metrics.py +29 -18
- c2cgeoportal_geoportal/lib/oauth2.py +1036 -0
- c2cgeoportal_geoportal/lib/wmstparsing.py +115 -90
- c2cgeoportal_geoportal/lib/xsd.py +29 -19
- 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/+dot+prospector.yaml → advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml} +8 -4
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/Dockerfile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Dockerfile} +24 -15
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/alembic.ini +1 -0
- 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 +104 -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/advance_create/{{cookiecutter.project}}/geoportal/requirements.txt +2 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/setup.py +25 -0
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/tools/extract-messages.js +8 -6
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/tsconfig.json +8 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +75 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/webpack.apps.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js} +31 -28
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.commons.js +3 -7
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.config.js +4 -4
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py +47 -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/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/api/index.js +12 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/js/{{cookiecutter.package}}module.js +25 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/subscribers.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/subscribers.py} +3 -6
- c2cgeoportal_geoportal/scaffolds/advance_update/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/{update/geoportal/CONST_Makefile_tmpl → advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile} +32 -20
- 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} +4 -8
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/main.yaml +43 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/rebuild.yaml +46 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +65 -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/{Dockerfile_tmpl → {{cookiecutter.project}}/Dockerfile} +34 -24
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +14 -0
- c2cgeoportal_geoportal/scaffolds/create/{README.rst_tmpl → {{cookiecutter.project}}/README.rst} +4 -4
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +158 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/config.yaml +25 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-lib.yaml +474 -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} +43 -18
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.default +82 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.project +60 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/vars.yaml +396 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/mobile.css +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-blue.png +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-gold.png +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-green.png +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker.png +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/Readme.txt +1 -1
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/demo.map.tmpl +224 -0
- c2cgeoportal_geoportal/scaffolds/create/{mapserver/mapserver.map.tmpl_tmpl → {{cookiecutter.project}}/mapserver/mapserver.map.tmpl} +7 -15
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Landscape.jrxml +17 -9
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Portrait.jrxml +17 -9
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Landscape.jrxml +17 -9
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Portrait.jrxml +17 -9
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/config.yaml.tmpl +30 -27
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/legend.jrxml +109 -0
- 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/{{cookiecutter.project}}/pyproject.toml +3 -0
- c2cgeoportal_geoportal/scaffolds/create/{qgisserver/pg_service.conf.tmpl_tmpl → {{cookiecutter.project}}/qgisserver/pg_service.conf.tmpl} +2 -2
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-backup +107 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +111 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/setup.cfg +7 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/spell-ignore-words.txt +3 -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 +191 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +1153 -0
- c2cgeoportal_geoportal/scaffolds/update/{geoportal → {{cookiecutter.project}}/geoportal}/CONST_config-schema.yaml +99 -47
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/CONST_vars.yaml +1412 -0
- c2cgeoportal_geoportal/scripts/__init__.py +17 -33
- c2cgeoportal_geoportal/scripts/c2cupgrade.py +295 -200
- c2cgeoportal_geoportal/scripts/create_demo_theme.py +5 -6
- c2cgeoportal_geoportal/scripts/manage_users.py +34 -37
- c2cgeoportal_geoportal/scripts/pcreate.py +312 -0
- c2cgeoportal_geoportal/scripts/theme2fts.py +92 -25
- c2cgeoportal_geoportal/scripts/urllogin.py +23 -17
- c2cgeoportal_geoportal/templates/login.html +88 -84
- c2cgeoportal_geoportal/templates/notlogin.html +62 -0
- c2cgeoportal_geoportal/templates/testi18n.html +6 -8
- c2cgeoportal_geoportal/views/__init__.py +23 -4
- c2cgeoportal_geoportal/views/dev.py +9 -7
- c2cgeoportal_geoportal/views/dynamic.py +70 -40
- c2cgeoportal_geoportal/views/entry.py +93 -24
- c2cgeoportal_geoportal/views/fulltextsearch.py +36 -29
- c2cgeoportal_geoportal/views/geometry_processing.py +15 -7
- c2cgeoportal_geoportal/views/i18n.py +91 -9
- c2cgeoportal_geoportal/views/layers.py +173 -134
- c2cgeoportal_geoportal/views/login.py +206 -87
- c2cgeoportal_geoportal/views/mapserverproxy.py +59 -35
- c2cgeoportal_geoportal/views/memory.py +13 -13
- c2cgeoportal_geoportal/views/ogcproxy.py +48 -30
- c2cgeoportal_geoportal/views/pdfreport.py +31 -27
- c2cgeoportal_geoportal/views/printproxy.py +67 -53
- c2cgeoportal_geoportal/views/profile.py +25 -24
- c2cgeoportal_geoportal/views/proxy.py +97 -68
- c2cgeoportal_geoportal/views/raster.py +47 -29
- c2cgeoportal_geoportal/views/resourceproxy.py +13 -11
- c2cgeoportal_geoportal/views/shortener.py +31 -24
- c2cgeoportal_geoportal/views/theme.py +475 -365
- c2cgeoportal_geoportal/views/tinyowsproxy.py +46 -39
- c2cgeoportal_geoportal/views/vector_tiles.py +80 -0
- {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/METADATA +16 -11
- c2cgeoportal_geoportal-2.7.1.83.dist-info/RECORD +185 -0
- {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/WHEEL +1 -1
- {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/entry_points.txt +3 -1
- tests/__init__.py +24 -3
- tests/test_cachebuster.py +1 -3
- tests/test_caching.py +19 -26
- tests/test_checker.py +2 -3
- tests/test_decimaljson.py +4 -4
- tests/test_headerstween.py +0 -3
- tests/test_i18n.py +31 -0
- tests/test_init.py +12 -27
- tests/test_locale_negociator.py +6 -6
- tests/test_mapserverproxy_route_predicate.py +0 -2
- tests/test_raster.py +18 -5
- tests/test_wmstparsing.py +7 -8
- c2cgeoportal_geoportal/scaffolds/__init__.py +0 -226
- c2cgeoportal_geoportal/scaffolds/create/+dot+dockerignore_tmpl +0 -11
- c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/ci.yaml_tmpl +0 -56
- c2cgeoportal_geoportal/scaffolds/create/+dot+gitignore_tmpl +0 -12
- c2cgeoportal_geoportal/scaffolds/create/build_tmpl +0 -144
- c2cgeoportal_geoportal/scaffolds/create/docker-compose-lib.yaml_tmpl +0 -302
- c2cgeoportal_geoportal/scaffolds/create/docker-compose.override.sample.yaml_tmpl +0 -54
- c2cgeoportal_geoportal/scaffolds/create/env.default_tmpl +0 -49
- c2cgeoportal_geoportal/scaffolds/create/env.project_tmpl +0 -39
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+dockerignore_tmpl +0 -5
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+eslintrc_tmpl +0 -19
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/__init__.py_tmpl +0 -48
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/models.py_tmpl +0 -10
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/images/favicon.ico +0 -0
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/robot.txt +0 -3
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static-ngeo/api/index.js_tmpl +0 -37
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static-ngeo/js/+package+module.js_tmpl +0 -22
- c2cgeoportal_geoportal/scaffolds/create/geoportal/production.ini_tmpl +0 -106
- c2cgeoportal_geoportal/scaffolds/create/geoportal/requirements.txt +0 -2
- c2cgeoportal_geoportal/scaffolds/create/geoportal/setup.py_tmpl +0 -18
- c2cgeoportal_geoportal/scaffolds/create/geoportal/tsconfig.json_tmpl +0 -9
- c2cgeoportal_geoportal/scaffolds/create/geoportal/vars.yaml_tmpl +0 -224
- c2cgeoportal_geoportal/scaffolds/create/geoportal/webpack.api.js_tmpl +0 -71
- 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 -166
- c2cgeoportal_geoportal/scaffolds/create/print/print-apps/+package+/legend.jrxml +0 -27
- c2cgeoportal_geoportal/scaffolds/create/qgisserver/geomapfish.yaml.tmpl_tmpl +0 -29
- c2cgeoportal_geoportal/scaffolds/create/scripts/publish-docker +0 -124
- c2cgeoportal_geoportal/scaffolds/create/setup.cfg_tmpl +0 -3
- c2cgeoportal_geoportal/scaffolds/create/spell-ignore-words.txt +0 -1
- c2cgeoportal_geoportal/scaffolds/create/tilegeneration/config.yaml.tmpl_tmpl +0 -169
- c2cgeoportal_geoportal/scaffolds/create/yamllint.yaml +0 -11
- c2cgeoportal_geoportal/scaffolds/update/+dot+upgrade.yaml_tmpl +0 -171
- c2cgeoportal_geoportal/scaffolds/update/CONST_CHANGELOG.txt_tmpl +0 -64
- c2cgeoportal_geoportal/scaffolds/update/geoportal/CONST_vars.yaml_tmpl +0 -783
- c2cgeoportal_geoportal/templates/dynamic.js +0 -21
- c2cgeoportal_geoportal-2.5.0.100.dist-info/RECORD +0 -162
- tests/test_get_url.py +0 -96
- tests/test_lib.py +0 -77
- /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/language_mapping +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-server.cfg +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/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}}}/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/scaffolds/create/{run_alembic.sh → {{cookiecutter.project}}/run_alembic.sh} +0 -0
- {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2018-2020, Camptocamp SA
|
1
|
+
# Copyright (c) 2018-2021, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -28,36 +26,37 @@
|
|
28
26
|
# either expressed or implied, of the FreeBSD Project.
|
29
27
|
|
30
28
|
|
31
|
-
import json
|
32
29
|
import re
|
33
|
-
from typing import Dict, List, Union
|
34
30
|
import urllib.parse
|
31
|
+
from typing import Any, Dict, List, Union, cast
|
35
32
|
|
33
|
+
import pyramid.request
|
34
|
+
from pyramid.httpexceptions import HTTPNotFound
|
36
35
|
from pyramid.view import view_config
|
37
36
|
from sqlalchemy import func
|
38
37
|
|
39
38
|
from c2cgeoportal_commons import models
|
40
39
|
from c2cgeoportal_commons.models import main
|
41
40
|
from c2cgeoportal_geoportal.lib.cacheversion import get_cache_version
|
42
|
-
from c2cgeoportal_geoportal.lib.caching import
|
41
|
+
from c2cgeoportal_geoportal.lib.caching import get_region
|
42
|
+
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
|
43
43
|
|
44
44
|
CACHE_REGION = get_region("std")
|
45
45
|
|
46
46
|
|
47
47
|
class DynamicView:
|
48
|
-
|
48
|
+
"""The dynamic vies that provide the configuration of the client application."""
|
49
|
+
|
50
|
+
def __init__(self, request: pyramid.request.Request):
|
49
51
|
self.request = request
|
50
52
|
self.settings = request.registry.settings
|
51
53
|
self.interfaces_config = self.settings["interfaces_config"]
|
52
|
-
self.default = self.interfaces_config.get("default", {})
|
53
54
|
|
54
|
-
def get(self, value, interface):
|
55
|
-
|
56
|
-
result.update(self.interfaces_config.get(interface, {}).get(value, {}))
|
57
|
-
return result
|
55
|
+
def get(self, value: Dict[str, Any], interface: str) -> Dict[str, Any]:
|
56
|
+
return cast(Dict[str, Any], self.interfaces_config.get(interface, {}).get(value, {}))
|
58
57
|
|
59
|
-
@CACHE_REGION.cache_on_arguments()
|
60
|
-
def _fulltextsearch_groups(self): # pylint: disable=no-self-use
|
58
|
+
@CACHE_REGION.cache_on_arguments() # type: ignore
|
59
|
+
def _fulltextsearch_groups(self) -> List[str]: # pylint: disable=no-self-use
|
61
60
|
return [
|
62
61
|
group[0]
|
63
62
|
for group in models.DBSession.query(func.distinct(main.FullTextSearch.layer_name))
|
@@ -65,7 +64,34 @@ class DynamicView:
|
|
65
64
|
.all()
|
66
65
|
]
|
67
66
|
|
68
|
-
def _interface(
|
67
|
+
def _interface(
|
68
|
+
self,
|
69
|
+
interface_config: Dict[str, Any],
|
70
|
+
interface_name: str,
|
71
|
+
original_interface_name: str,
|
72
|
+
dynamic: Dict[str, Any],
|
73
|
+
) -> Dict[str, Any]:
|
74
|
+
"""
|
75
|
+
Get the interface configuration.
|
76
|
+
|
77
|
+
Arguments:
|
78
|
+
|
79
|
+
interface_config: Current interface configuration
|
80
|
+
interface_name: Interface name (we use in the configuration)
|
81
|
+
original_interface_name: Original interface name (directly for the query string)
|
82
|
+
dynamic: The values that's dynamically generated
|
83
|
+
"""
|
84
|
+
|
85
|
+
if "extends" in interface_config:
|
86
|
+
constants = self._interface(
|
87
|
+
self.interfaces_config[interface_config["extends"]],
|
88
|
+
interface_name,
|
89
|
+
original_interface_name,
|
90
|
+
dynamic,
|
91
|
+
)
|
92
|
+
else:
|
93
|
+
constants = {}
|
94
|
+
|
69
95
|
constants.update(interface_config.get("constants", {}))
|
70
96
|
constants.update(
|
71
97
|
{
|
@@ -81,35 +107,40 @@ class DynamicView:
|
|
81
107
|
}
|
82
108
|
)
|
83
109
|
|
84
|
-
|
85
|
-
|
86
|
-
for constant, config in routes.items():
|
110
|
+
for constant, config in interface_config.get("routes", {}).items():
|
111
|
+
route_name = original_interface_name if config.get("currentInterface", False) else config["name"]
|
87
112
|
params: Dict[str, str] = {}
|
88
113
|
params.update(config.get("params", {}))
|
89
114
|
for name, dyn in config.get("dynamic_params", {}).items():
|
90
115
|
params[name] = dynamic[dyn]
|
91
116
|
constants[constant] = self.request.route_url(
|
92
|
-
|
117
|
+
route_name, *config.get("elements", []), _query=params, **config.get("kw", {})
|
93
118
|
)
|
94
119
|
|
95
120
|
return constants
|
96
121
|
|
97
|
-
@view_config(route_name="dynamic", renderer="
|
98
|
-
def dynamic(self):
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
assert len(default_interfaces_names) == 1, "More than one default interface in: " + json.dumps(
|
106
|
-
self.settings.get("interfaces")
|
107
|
-
)
|
108
|
-
default_interface_name = default_interfaces_names[0]
|
109
|
-
interface_name = self.request.params.get("interface")
|
110
|
-
if interface_name not in interfaces_names:
|
111
|
-
interface_name = default_interface_name
|
122
|
+
@view_config(route_name="dynamic", renderer="json") # type: ignore
|
123
|
+
def dynamic(self) -> Dict[str, Any]:
|
124
|
+
original_interface_name = self.request.params.get("interface")
|
125
|
+
interface_name = self.request.get_organization_interface(original_interface_name)
|
126
|
+
|
127
|
+
if interface_name not in self.interfaces_config:
|
128
|
+
raise HTTPNotFound("Interface {} doesn't exists in the 'interfaces_config'.")
|
129
|
+
|
112
130
|
interface_config = self.interfaces_config[interface_name]
|
131
|
+
lang_urls_suffix = interface_config.get("lang_urls_suffix", "")
|
132
|
+
|
133
|
+
i18next_configuration = self.settings.get("i18next", {})
|
134
|
+
i18next_configuration.setdefault("backend", {})
|
135
|
+
if "loadPath" not in i18next_configuration["backend"]:
|
136
|
+
path: List[str] = [
|
137
|
+
self.request.route_url("base").rstrip("/"),
|
138
|
+
"static-{{ns}}",
|
139
|
+
get_cache_version(),
|
140
|
+
"locales",
|
141
|
+
"{{lng}}.json",
|
142
|
+
]
|
143
|
+
i18next_configuration["backend"]["loadPath"] = "/".join(path)
|
113
144
|
|
114
145
|
dynamic = {
|
115
146
|
"interface": interface_name,
|
@@ -117,23 +148,22 @@ class DynamicView:
|
|
117
148
|
"two_factor": self.request.registry.settings.get("authentication", {}).get("two_factor", False),
|
118
149
|
"lang_urls": {
|
119
150
|
lang: self.request.static_url(
|
120
|
-
"/etc/geomapfish/static/{lang}.json"
|
121
|
-
_query={"cache": get_cache_version()},
|
151
|
+
f"/etc/geomapfish/static/{lang}{lang_urls_suffix}.json",
|
122
152
|
)
|
123
153
|
for lang in self.request.registry.settings["available_locale_names"]
|
124
154
|
},
|
155
|
+
"i18next_configuration": i18next_configuration,
|
125
156
|
"fulltextsearch_groups": self._fulltextsearch_groups(),
|
126
157
|
}
|
127
158
|
|
128
|
-
constants = self._interface(
|
129
|
-
constants = self._interface(interface_config, interface_name, dynamic, constants)
|
159
|
+
constants = self._interface(interface_config, interface_name, original_interface_name, dynamic)
|
130
160
|
|
131
161
|
do_redirect = False
|
132
162
|
url = None
|
133
163
|
if "redirect_interface" in interface_config:
|
134
164
|
no_redirect_query: Dict[str, Union[str, List[str]]] = {"no_redirect": "t"}
|
135
165
|
if "query" in self.request.params:
|
136
|
-
query = urllib.parse.parse_qs(self.request.params["query"][1:])
|
166
|
+
query = urllib.parse.parse_qs(self.request.params["query"][1:], keep_blank_values=True)
|
137
167
|
no_redirect_query.update(query)
|
138
168
|
else:
|
139
169
|
query = {}
|
@@ -165,5 +195,5 @@ class DynamicView:
|
|
165
195
|
else:
|
166
196
|
constants["redirectUrl"] = no_redirect_url
|
167
197
|
|
168
|
-
set_common_headers(self.request, "dynamic",
|
198
|
+
set_common_headers(self.request, "dynamic", Cache.PUBLIC_NO)
|
169
199
|
return {"constants": constants, "doRedirect": do_redirect, "redirectUrl": url}
|
@@ -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,52 +26,123 @@
|
|
28
26
|
# either expressed or implied, of the FreeBSD Project.
|
29
27
|
|
30
28
|
|
29
|
+
import glob
|
31
30
|
import logging
|
32
|
-
|
33
|
-
import
|
31
|
+
import os
|
32
|
+
from typing import Any, Dict, List, Optional
|
34
33
|
|
34
|
+
import pyramid.request
|
35
35
|
from pyramid.i18n import TranslationStringFactory
|
36
36
|
from pyramid.view import view_config
|
37
37
|
|
38
|
-
from c2cgeoportal_geoportal.lib.caching import
|
38
|
+
from c2cgeoportal_geoportal.lib.caching import get_region
|
39
|
+
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
|
39
40
|
|
40
41
|
_ = TranslationStringFactory("c2cgeoportal")
|
41
42
|
LOG = logging.getLogger(__name__)
|
43
|
+
CACHE_REGION = get_region("std")
|
42
44
|
|
43
45
|
|
44
46
|
class Entry:
|
45
|
-
|
47
|
+
"""All the entry points views."""
|
48
|
+
|
49
|
+
def __init__(self, request: pyramid.request.Request):
|
46
50
|
self.request = request
|
47
51
|
|
48
|
-
@view_config(route_name="testi18n", renderer="testi18n.html")
|
49
|
-
def testi18n(self)
|
52
|
+
@view_config(route_name="testi18n", renderer="testi18n.html") # type: ignore
|
53
|
+
def testi18n(self) -> Dict[str, Any]:
|
50
54
|
_ = self.request.translate
|
51
55
|
return {"title": _("title i18n")}
|
52
56
|
|
53
|
-
def get_ngeo_index_vars(self):
|
54
|
-
set_common_headers(self.request, "index",
|
57
|
+
def get_ngeo_index_vars(self) -> Dict[str, Any]:
|
58
|
+
set_common_headers(self.request, "index", Cache.PUBLIC_NO, content_type="text/html")
|
59
|
+
# Force urllogin to be converted to cookie when requesting the main HTML page
|
60
|
+
self.request.user # noqa
|
55
61
|
return {}
|
56
62
|
|
57
|
-
|
58
|
-
|
63
|
+
@staticmethod
|
64
|
+
@CACHE_REGION.cache_on_arguments() # type: ignore
|
65
|
+
def get_apijs(api_name: Optional[str]) -> str:
|
66
|
+
with open("/etc/static-ngeo/api.js", encoding="utf-8") as api_file:
|
67
|
+
api = api_file.read().split("\n")
|
68
|
+
sourcemap = api.pop(-1)
|
69
|
+
if api_name:
|
70
|
+
api += [
|
71
|
+
f"if (window.{api_name} === undefined && window.geomapfishapp) {{",
|
72
|
+
f" window.{api_name} = window.geomapfishapp;",
|
73
|
+
"}",
|
74
|
+
]
|
75
|
+
api.append(sourcemap)
|
76
|
+
|
77
|
+
return "\n".join(api)
|
78
|
+
|
79
|
+
@view_config(route_name="apijs") # type: ignore
|
80
|
+
def apijs(self) -> pyramid.response.Response:
|
81
|
+
self.request.response.text = self.get_apijs(self.request.registry.settings["api"].get("name"))
|
82
|
+
set_common_headers(self.request, "api", Cache.PUBLIC, content_type="application/javascript")
|
83
|
+
return self.request.response
|
84
|
+
|
85
|
+
def favicon(self) -> Dict[str, Any]:
|
86
|
+
set_common_headers(self.request, "index", Cache.PUBLIC, content_type="image/vnd.microsoft.icon")
|
59
87
|
return {}
|
60
88
|
|
61
|
-
def
|
62
|
-
set_common_headers(self.request, "index",
|
89
|
+
def robot_txt(self) -> Dict[str, Any]:
|
90
|
+
set_common_headers(self.request, "index", Cache.PUBLIC, content_type="text/plain")
|
63
91
|
return {}
|
64
92
|
|
65
|
-
def
|
66
|
-
set_common_headers(self.request, "
|
93
|
+
def apijsmap(self) -> Dict[str, Any]:
|
94
|
+
set_common_headers(self.request, "api", Cache.PUBLIC, content_type="application/octet-stream")
|
67
95
|
return {}
|
68
96
|
|
69
|
-
def
|
70
|
-
set_common_headers(self.request, "api",
|
97
|
+
def apicss(self) -> Dict[str, Any]:
|
98
|
+
set_common_headers(self.request, "api", Cache.PUBLIC, content_type="text/css")
|
71
99
|
return {}
|
72
100
|
|
73
|
-
def
|
74
|
-
set_common_headers(self.request, "
|
101
|
+
def apihelp(self) -> Dict[str, Any]:
|
102
|
+
set_common_headers(self.request, "apihelp", Cache.PUBLIC)
|
75
103
|
return {}
|
76
104
|
|
77
|
-
|
78
|
-
|
79
|
-
|
105
|
+
|
106
|
+
def _get_ngeo_resources(pattern: str) -> List[str]:
|
107
|
+
"""Return the list of ngeo dist files matching the pattern."""
|
108
|
+
results = glob.glob(f"/opt/c2cgeoportal/geoportal/node_modules/ngeo/dist/{pattern}")
|
109
|
+
if not results:
|
110
|
+
LOG.error(
|
111
|
+
"No file found for pattern %s, in: [%s]",
|
112
|
+
pattern,
|
113
|
+
", ".join(os.listdir("/opt/c2cgeoportal/geoportal/node_modules/ngeo/dist/")),
|
114
|
+
)
|
115
|
+
return results
|
116
|
+
|
117
|
+
|
118
|
+
def canvas_view(request: pyramid.request.Request, interface_config: Dict[str, Any]) -> Dict[str, Any]:
|
119
|
+
"""Get view used as entry point of a canvas interface."""
|
120
|
+
|
121
|
+
js_files = _get_ngeo_resources(f"{interface_config.get('layout', interface_config['name'])}*.js")
|
122
|
+
css_files = _get_ngeo_resources(f"{interface_config.get('layout', interface_config['name'])}*.css")
|
123
|
+
css = "\n ".join(
|
124
|
+
[
|
125
|
+
f'<link href="{request.static_url(css)}" rel="stylesheet" crossorigin="anonymous">'
|
126
|
+
for css in css_files
|
127
|
+
]
|
128
|
+
)
|
129
|
+
|
130
|
+
set_common_headers(request, "index", Cache.PUBLIC_NO, content_type="text/html")
|
131
|
+
|
132
|
+
spinner = ""
|
133
|
+
spinner_filenames = _get_ngeo_resources("spinner*.svg")
|
134
|
+
if spinner_filenames:
|
135
|
+
with open(spinner_filenames[0], encoding="utf-8") as spinner_file:
|
136
|
+
spinner = spinner_file.read()
|
137
|
+
|
138
|
+
return {
|
139
|
+
"request": request,
|
140
|
+
"header": f"""
|
141
|
+
<meta name="dynamicUrl" content="{request.route_url("dynamic")}">
|
142
|
+
<meta name="interface" content="{interface_config['name']}">
|
143
|
+
{css}""",
|
144
|
+
"footer": "\n ".join(
|
145
|
+
[f'<script src="{request.static_url(js)}" crossorigin="anonymous"></script>' for js in js_files]
|
146
|
+
),
|
147
|
+
"spinner": spinner,
|
148
|
+
}
|
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2011-2020, Camptocamp SA
|
1
|
+
# Copyright (c) 2011-2021, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -29,7 +27,9 @@
|
|
29
27
|
|
30
28
|
|
31
29
|
import re
|
30
|
+
from typing import cast
|
32
31
|
|
32
|
+
import pyramid.request
|
33
33
|
from geoalchemy2.shape import to_shape
|
34
34
|
from geojson import Feature, FeatureCollection
|
35
35
|
from pyramid.httpexceptions import HTTPBadRequest, HTTPInternalServerError
|
@@ -39,37 +39,42 @@ from sqlalchemy import and_, desc, func, or_
|
|
39
39
|
from c2cgeoportal_commons.models import DBSession
|
40
40
|
from c2cgeoportal_commons.models.main import FullTextSearch, Interface
|
41
41
|
from c2cgeoportal_geoportal import locale_negotiator
|
42
|
-
from c2cgeoportal_geoportal.lib.caching import
|
42
|
+
from c2cgeoportal_geoportal.lib.caching import get_region
|
43
|
+
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
|
44
|
+
from c2cgeoportal_geoportal.lib.fulltextsearch import Normalize
|
43
45
|
|
44
46
|
CACHE_REGION = get_region("std")
|
45
|
-
IGNORED_CHARS_RE = re.compile(r"[()
|
47
|
+
IGNORED_CHARS_RE = re.compile(r"[()&|!:<>\t]")
|
46
48
|
IGNORED_STARTUP_CHARS_RE = re.compile(r"^[']*")
|
47
49
|
|
48
50
|
|
49
51
|
class FullTextSearchView:
|
50
|
-
|
52
|
+
"""All the full-text search view."""
|
53
|
+
|
54
|
+
def __init__(self, request: pyramid.request.Request):
|
51
55
|
self.request = request
|
52
|
-
set_common_headers(request, "fulltextsearch",
|
56
|
+
set_common_headers(request, "fulltextsearch", Cache.PUBLIC_NO)
|
53
57
|
self.settings = request.registry.settings.get("fulltextsearch", {})
|
54
58
|
self.languages = self.settings.get("languages", {})
|
59
|
+
self.fts_normalizer = Normalize(self.settings)
|
55
60
|
|
56
61
|
@staticmethod
|
57
|
-
@CACHE_REGION.cache_on_arguments()
|
58
|
-
def _get_interface_id(interface):
|
59
|
-
return DBSession.query(Interface).filter_by(name=interface).one().id
|
62
|
+
@CACHE_REGION.cache_on_arguments() # type: ignore
|
63
|
+
def _get_interface_id(interface: str) -> int:
|
64
|
+
return cast(int, DBSession.query(Interface).filter_by(name=interface).one().id)
|
60
65
|
|
61
|
-
@view_config(route_name="fulltextsearch", renderer="geojson")
|
62
|
-
def fulltextsearch(self):
|
66
|
+
@view_config(route_name="fulltextsearch", renderer="geojson") # type: ignore
|
67
|
+
def fulltextsearch(self) -> FeatureCollection:
|
63
68
|
lang = locale_negotiator(self.request)
|
64
69
|
|
65
70
|
try:
|
66
71
|
language = self.languages[lang]
|
67
72
|
except KeyError:
|
68
|
-
return HTTPInternalServerError(detail="{
|
73
|
+
return HTTPInternalServerError(detail=f"{lang!s} not defined in languages")
|
69
74
|
|
70
75
|
if "query" not in self.request.params:
|
71
76
|
return HTTPBadRequest(detail="no query")
|
72
|
-
terms = self.request.params.get("query")
|
77
|
+
terms = self.fts_normalizer(self.request.params.get("query"))
|
73
78
|
|
74
79
|
maxlimit = self.settings.get("maxlimit", 200)
|
75
80
|
|
@@ -77,21 +82,18 @@ class FullTextSearchView:
|
|
77
82
|
limit = int(self.request.params.get("limit", self.settings.get("defaultlimit", 30)))
|
78
83
|
except ValueError:
|
79
84
|
return HTTPBadRequest(detail="limit value is incorrect")
|
80
|
-
|
81
|
-
limit = maxlimit
|
85
|
+
limit = min(limit, maxlimit)
|
82
86
|
|
83
87
|
try:
|
84
88
|
partitionlimit = int(self.request.params.get("partitionlimit", 0))
|
85
89
|
except ValueError:
|
86
90
|
return HTTPBadRequest(detail="partitionlimit value is incorrect")
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
if w != ""
|
94
|
-
)
|
91
|
+
partitionlimit = min(partitionlimit, maxlimit)
|
92
|
+
|
93
|
+
terms_array = [
|
94
|
+
IGNORED_STARTUP_CHARS_RE.sub("", elem) for elem in IGNORED_CHARS_RE.sub(" ", terms).split(" ")
|
95
|
+
]
|
96
|
+
terms_ts = "&".join(w + ":*" for w in terms_array if w != "")
|
95
97
|
_filter = FullTextSearch.ts.op("@@")(func.to_tsquery(language, terms_ts))
|
96
98
|
|
97
99
|
if self.request.user is None:
|
@@ -143,21 +145,26 @@ class FullTextSearchView:
|
|
143
145
|
.over(partition_by=FullTextSearch.layer_name, order_by=(desc(rank), FullTextSearch.label))
|
144
146
|
.label("row_number")
|
145
147
|
)
|
146
|
-
|
148
|
+
sub_query = DBSession.query(FullTextSearch).add_columns(row_number).filter(_filter).subquery()
|
147
149
|
query = DBSession.query(
|
148
|
-
|
150
|
+
sub_query.c.id,
|
151
|
+
sub_query.c.label,
|
152
|
+
sub_query.c.params,
|
153
|
+
sub_query.c.layer_name,
|
154
|
+
sub_query.c.the_geom,
|
155
|
+
sub_query.c.actions,
|
149
156
|
)
|
150
|
-
query = query.filter(
|
157
|
+
query = query.filter(sub_query.c.row_number <= partitionlimit)
|
151
158
|
else:
|
152
159
|
query = DBSession.query(FullTextSearch).filter(_filter)
|
153
160
|
query = query.order_by(desc(rank))
|
154
161
|
query = query.order_by(FullTextSearch.label)
|
155
162
|
|
156
163
|
query = query.limit(limit)
|
157
|
-
|
164
|
+
objects = query.all()
|
158
165
|
|
159
166
|
features = []
|
160
|
-
for o in
|
167
|
+
for o in objects:
|
161
168
|
properties = {"label": o.label}
|
162
169
|
if o.layer_name is not None:
|
163
170
|
properties["layer_name"] = o.layer_name
|
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2011-2020, Camptocamp SA
|
1
|
+
# Copyright (c) 2011-2021, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -28,28 +26,38 @@
|
|
28
26
|
# either expressed or implied, of the FreeBSD Project.
|
29
27
|
|
30
28
|
|
29
|
+
from typing import Optional
|
30
|
+
|
31
|
+
import pyramid.request
|
31
32
|
from geoalchemy2.shape import from_shape, to_shape
|
32
33
|
from geojson import loads
|
33
34
|
from pyramid.httpexceptions import HTTPBadRequest
|
34
35
|
from pyramid.view import view_config
|
35
36
|
from shapely.geometry import asShape
|
37
|
+
from shapely.geometry.base import BaseGeometry
|
36
38
|
from sqlalchemy import func
|
37
39
|
|
38
40
|
from c2cgeoportal_commons.models import DBSession
|
39
41
|
|
40
42
|
|
41
43
|
class GeometryProcessing:
|
42
|
-
|
44
|
+
"""
|
45
|
+
View used to provide processing on a geometry.
|
46
|
+
|
47
|
+
Currently only difference between geometries.
|
48
|
+
"""
|
49
|
+
|
50
|
+
def __init__(self, request: pyramid.request.Request):
|
43
51
|
self.request = request
|
44
52
|
|
45
|
-
@view_config(route_name="difference", renderer="geojson")
|
46
|
-
def difference(self):
|
53
|
+
@view_config(route_name="difference", renderer="geojson") # type: ignore
|
54
|
+
def difference(self) -> Optional[BaseGeometry]:
|
47
55
|
body = loads(self.request.body)
|
48
56
|
if (
|
49
57
|
"geometries" not in body
|
50
58
|
or not isinstance(body["geometries"], list)
|
51
59
|
or len(body["geometries"]) != 2
|
52
|
-
):
|
60
|
+
):
|
53
61
|
raise HTTPBadRequest(
|
54
62
|
"""Wrong body, it should be like that:
|
55
63
|
{
|
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2019-2020, Camptocamp SA
|
1
|
+
# Copyright (c) 2019-2022, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -28,20 +26,104 @@
|
|
28
26
|
# either expressed or implied, of the FreeBSD Project.
|
29
27
|
|
30
28
|
|
31
|
-
|
29
|
+
import glob
|
30
|
+
import logging
|
31
|
+
|
32
|
+
import pyramid.request
|
33
|
+
import pyramid.response
|
34
|
+
from lingua.extract import ( # strip_linenumbers,
|
35
|
+
ExtractorOptions,
|
36
|
+
POEntry,
|
37
|
+
create_catalog,
|
38
|
+
find_file,
|
39
|
+
list_files,
|
40
|
+
no_duplicates,
|
41
|
+
read_config,
|
42
|
+
)
|
43
|
+
from lingua.extractors import get_extractor, register_extractors
|
44
|
+
from lingua.extractors.babel import register_babel_plugins
|
45
|
+
from pyramid.httpexceptions import HTTPFound, HTTPInternalServerError
|
32
46
|
from pyramid.view import view_config
|
33
47
|
|
34
48
|
from c2cgeoportal_geoportal.lib.cacheversion import get_cache_version
|
35
|
-
from c2cgeoportal_geoportal.lib.
|
49
|
+
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
|
36
50
|
|
51
|
+
LOG = logging.getLogger(__name__)
|
52
|
+
_INITIALIZED = False
|
37
53
|
|
38
|
-
|
39
|
-
|
54
|
+
|
55
|
+
@view_config(route_name="localejson") # type: ignore
|
56
|
+
def locale(request: pyramid.request.Request) -> pyramid.response.Response:
|
57
|
+
"""Get the locale json file for the API."""
|
40
58
|
response = HTTPFound(
|
41
59
|
request.static_url(
|
42
|
-
"/etc/geomapfish/static/{
|
60
|
+
f"/etc/geomapfish/static/{request.locale_name}.json",
|
43
61
|
_query={"cache": get_cache_version()},
|
44
62
|
)
|
45
63
|
)
|
46
|
-
set_common_headers(request, "api",
|
64
|
+
set_common_headers(request, "api", Cache.PUBLIC_NO, response=response)
|
47
65
|
return response
|
66
|
+
|
67
|
+
|
68
|
+
@view_config(route_name="localepot") # type: ignore
|
69
|
+
def localepot(request: pyramid.request.Request) -> pyramid.response.Response:
|
70
|
+
"""Get the pot from an HTTP request."""
|
71
|
+
|
72
|
+
# Build the list of files to be processed
|
73
|
+
sources = []
|
74
|
+
sources += glob.glob(f"/app/{request.registry.package_name}/static-ngeo/js/apps/*.html.ejs")
|
75
|
+
sources += glob.glob(f"/app/{request.registry.package_name}/static-ngeo/js/**/*.js", recursive=True)
|
76
|
+
sources += glob.glob(f"/app/{request.registry.package_name}/static-ngeo/js/**/*.html", recursive=True)
|
77
|
+
sources += glob.glob("/usr/local/tomcat/webapps/ROOT/**/config.yaml", recursive=True)
|
78
|
+
sources += ["/etc/geomapfish/config.yaml", "/app/development.ini"]
|
79
|
+
|
80
|
+
# The following code is a modified version of the main function of this file:
|
81
|
+
# https://github.com/wichert/lingua/blob/master/src/lingua/extract.py
|
82
|
+
|
83
|
+
global _INITIALIZED
|
84
|
+
if not _INITIALIZED:
|
85
|
+
register_extractors()
|
86
|
+
register_babel_plugins()
|
87
|
+
_INITIALIZED = True
|
88
|
+
|
89
|
+
with open("/app/lingua-client.cfg", encoding="utf-8") as config_file:
|
90
|
+
read_config(config_file)
|
91
|
+
_INITIALIZED = True
|
92
|
+
|
93
|
+
catalog = create_catalog(
|
94
|
+
width=110,
|
95
|
+
copyright_holder="",
|
96
|
+
package_name="GeoMapFish-project",
|
97
|
+
package_version="1.0",
|
98
|
+
msgid_bugs_address=None,
|
99
|
+
)
|
100
|
+
|
101
|
+
for filename in no_duplicates(list_files(None, sources)):
|
102
|
+
real_filename = find_file(filename)
|
103
|
+
if real_filename is None:
|
104
|
+
LOG.error("Can not find file %s", filename)
|
105
|
+
raise HTTPInternalServerError(f"Can not find file {filename}")
|
106
|
+
extractor = get_extractor(real_filename)
|
107
|
+
if extractor is None:
|
108
|
+
LOG.error("No extractor available for file %s", filename)
|
109
|
+
raise HTTPInternalServerError(f"No extractor available for file {filename}")
|
110
|
+
|
111
|
+
extractor_options = ExtractorOptions(
|
112
|
+
comment_tag=True,
|
113
|
+
domain=None,
|
114
|
+
keywords=None,
|
115
|
+
)
|
116
|
+
for message in extractor(real_filename, extractor_options):
|
117
|
+
entry = catalog.find(message.msgid, msgctxt=message.msgctxt)
|
118
|
+
if entry is None:
|
119
|
+
entry = POEntry(msgctxt=message.msgctxt, msgid=message.msgid)
|
120
|
+
catalog.append(entry)
|
121
|
+
entry.update(message)
|
122
|
+
|
123
|
+
# for entry in catalog:
|
124
|
+
# strip_linenumbers(entry)
|
125
|
+
|
126
|
+
# Build the response
|
127
|
+
request.response.text = catalog.__unicode__()
|
128
|
+
set_common_headers(request, "api", Cache.PUBLIC, content_type="text/x-gettext-translation")
|
129
|
+
return request.response
|