c2cgeoportal-geoportal 2.6.0__py2.py3-none-any.whl → 2.7.1.156__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 +224 -84
- c2cgeoportal_geoportal/lib/__init__.py +67 -43
- c2cgeoportal_geoportal/lib/authentication.py +50 -22
- c2cgeoportal_geoportal/lib/bashcolor.py +17 -13
- c2cgeoportal_geoportal/lib/cacheversion.py +16 -8
- c2cgeoportal_geoportal/lib/caching.py +61 -191
- c2cgeoportal_geoportal/lib/check_collector.py +17 -10
- c2cgeoportal_geoportal/lib/checker.py +61 -63
- c2cgeoportal_geoportal/lib/common_headers.py +170 -0
- c2cgeoportal_geoportal/lib/dbreflection.py +54 -39
- c2cgeoportal_geoportal/lib/filter_capabilities.py +122 -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 +361 -237
- c2cgeoportal_geoportal/lib/loader.py +10 -15
- c2cgeoportal_geoportal/lib/metrics.py +28 -17
- c2cgeoportal_geoportal/lib/oauth2.py +214 -145
- c2cgeoportal_geoportal/lib/wmstparsing.py +115 -90
- 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} +18 -9
- 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 +102 -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/{create/geoportal/setup.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/setup.py} +6 -7
- 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 +1 -1
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/__init__.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py} +11 -22
- 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 -7
- 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 +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} +20 -11
- 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 +162 -0
- c2cgeoportal_geoportal/scaffolds/create/{ci/config.yaml_tmpl → {{cookiecutter.project}}/ci/config.yaml} +7 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose-lib.yaml → {{cookiecutter.project}}/docker-compose-lib.yaml} +133 -17
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.override.sample.yaml +67 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose.yaml → {{cookiecutter.project}}/docker-compose.yaml} +17 -12
- c2cgeoportal_geoportal/scaffolds/create/{env.default_tmpl → {{cookiecutter.project}}/env.default} +29 -14
- c2cgeoportal_geoportal/scaffolds/create/{env.project_tmpl → {{cookiecutter.project}}/env.project} +16 -4
- c2cgeoportal_geoportal/scaffolds/create/{geoportal/vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/vars.yaml} +93 -27
- 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 +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 +8 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Portrait.jrxml +8 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Landscape.jrxml +8 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Portrait.jrxml +8 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/config.yaml.tmpl +5 -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/{qgisserver/pg_service.conf.tmpl_tmpl → {{cookiecutter.project}}/qgisserver/pg_service.conf.tmpl} +2 -2
- 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 +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/{+dot+upgrade.yaml_tmpl → {{cookiecutter.project}}/.upgrade.yaml} +49 -39
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +1160 -0
- c2cgeoportal_geoportal/scaffolds/update/{geoportal → {{cookiecutter.project}}/geoportal}/CONST_config-schema.yaml +47 -2
- c2cgeoportal_geoportal/scaffolds/update/{geoportal/CONST_vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/CONST_vars.yaml} +350 -17
- c2cgeoportal_geoportal/scripts/__init__.py +16 -30
- c2cgeoportal_geoportal/scripts/c2cupgrade.py +271 -232
- c2cgeoportal_geoportal/scripts/create_demo_theme.py +3 -6
- c2cgeoportal_geoportal/scripts/manage_users.py +34 -39
- c2cgeoportal_geoportal/scripts/pcreate.py +312 -0
- c2cgeoportal_geoportal/scripts/theme2fts.py +72 -23
- 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 -4
- c2cgeoportal_geoportal/views/dev.py +9 -7
- c2cgeoportal_geoportal/views/dynamic.py +56 -19
- c2cgeoportal_geoportal/views/entry.py +93 -24
- c2cgeoportal_geoportal/views/fulltextsearch.py +28 -22
- c2cgeoportal_geoportal/views/geometry_processing.py +15 -7
- c2cgeoportal_geoportal/views/i18n.py +91 -9
- c2cgeoportal_geoportal/views/layers.py +160 -126
- c2cgeoportal_geoportal/views/login.py +106 -93
- c2cgeoportal_geoportal/views/mapserverproxy.py +46 -29
- c2cgeoportal_geoportal/views/memory.py +12 -12
- c2cgeoportal_geoportal/views/ogcproxy.py +48 -30
- c2cgeoportal_geoportal/views/pdfreport.py +26 -22
- c2cgeoportal_geoportal/views/printproxy.py +60 -52
- c2cgeoportal_geoportal/views/profile.py +24 -23
- c2cgeoportal_geoportal/views/proxy.py +87 -69
- c2cgeoportal_geoportal/views/raster.py +35 -24
- c2cgeoportal_geoportal/views/resourceproxy.py +13 -11
- c2cgeoportal_geoportal/views/shortener.py +27 -24
- c2cgeoportal_geoportal/views/theme.py +427 -321
- c2cgeoportal_geoportal/views/tinyowsproxy.py +46 -39
- c2cgeoportal_geoportal/views/vector_tiles.py +80 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.156.dist-info}/METADATA +25 -20
- c2cgeoportal_geoportal-2.7.1.156.dist-info/RECORD +185 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.156.dist-info}/WHEEL +1 -1
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.156.dist-info}/entry_points.txt +3 -1
- tests/__init__.py +7 -3
- tests/test_cachebuster.py +0 -2
- tests/test_caching.py +17 -25
- tests/test_checker.py +0 -2
- tests/test_decimaljson.py +4 -4
- tests/test_headerstween.py +0 -2
- tests/test_i18n.py +1 -1
- tests/test_init.py +4 -7
- tests/test_locale_negociator.py +0 -2
- tests/test_mapserverproxy_route_predicate.py +0 -2
- tests/test_raster.py +0 -2
- tests/test_wmstparsing.py +0 -2
- 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/Makefile +0 -3
- c2cgeoportal_geoportal/scaffolds/create/build_tmpl +0 -167
- 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/geoportal/+dot+dockerignore_tmpl +0 -6
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+eslintrc_tmpl +0 -15
- 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/requirements.txt +0 -2
- 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/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/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/scaffolds/create/{pyproject.toml → {{cookiecutter.project}}/pyproject.toml} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{run_alembic.sh → {{cookiecutter.project}}/run_alembic.sh} +0 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.156.dist-info}/top_level.txt +0 -0
@@ -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
|
@@ -27,8 +25,6 @@
|
|
27
25
|
# of the authors and should not be interpreted as representing official policies,
|
28
26
|
# either expressed or implied, of the FreeBSD Project.
|
29
27
|
|
30
|
-
# pylint: disable=no-member
|
31
|
-
|
32
28
|
|
33
29
|
import argparse
|
34
30
|
import logging
|
@@ -40,7 +36,8 @@ from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings, get_
|
|
40
36
|
LOG = logging.getLogger(__name__)
|
41
37
|
|
42
38
|
|
43
|
-
def main():
|
39
|
+
def main() -> None:
|
40
|
+
"""Create and populate the database tables."""
|
44
41
|
parser = argparse.ArgumentParser(description="Create and populate the database tables.")
|
45
42
|
fill_arguments(parser)
|
46
43
|
options = parser.parse_args()
|
@@ -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
|
@@ -27,32 +25,20 @@
|
|
27
25
|
# of the authors and should not be interpreted as representing official policies,
|
28
26
|
# either expressed or implied, of the FreeBSD Project.
|
29
27
|
|
30
|
-
# pylint: disable=no-member
|
31
|
-
|
32
28
|
|
33
29
|
import argparse
|
34
30
|
import sys
|
31
|
+
from typing import cast
|
35
32
|
|
36
33
|
import transaction
|
37
34
|
|
38
35
|
from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings, get_session
|
39
36
|
|
40
37
|
|
41
|
-
def
|
42
|
-
"""
|
43
|
-
Emergency user create and password reset script
|
44
|
-
example, reset toto password to foobar:
|
45
|
-
docker-compose exec geoportal manage-users --password=foobar toto
|
46
|
-
example, create user foo with password bar and role admin:
|
47
|
-
docker-compose exec geoportal manage-users --create --rolename=role_admin --password=bar foo
|
48
|
-
|
49
|
-
to get the options list, do:
|
50
|
-
docker-compose exec geoportal manage-users --help
|
51
|
-
"""
|
38
|
+
def get_argparser() -> argparse.ArgumentParser:
|
39
|
+
"""Get the argument parser for this script."""
|
52
40
|
|
53
|
-
usage = """
|
54
|
-
|
55
|
-
Reset a user password.
|
41
|
+
usage = """Reset a user password.
|
56
42
|
The username is used as password if the password is not provided with the corresponding option.
|
57
43
|
User can be created if it does not exist yet."""
|
58
44
|
|
@@ -67,12 +53,27 @@ User can be created if it does not exist yet."""
|
|
67
53
|
)
|
68
54
|
parser.add_argument("--email", "-e", default=None, help="The user email")
|
69
55
|
parser.add_argument("user", help="The user")
|
56
|
+
return parser
|
57
|
+
|
58
|
+
|
59
|
+
def main() -> None:
|
60
|
+
"""
|
61
|
+
Emergency user create and password reset script example.
|
62
|
+
|
63
|
+
Reset toto password to foobar: docker-compose
|
64
|
+
exec geoportal manage-users --password=foobar toto example, create user foo with password bar and role
|
65
|
+
admin: docker-compose exec geoportal manage-users --create --rolename=role_admin --password=bar foo.
|
66
|
+
|
67
|
+
to get the options list, do: docker-compose exec geoportal manage-users --help
|
68
|
+
"""
|
69
|
+
|
70
|
+
parser = get_argparser()
|
70
71
|
options = parser.parse_args()
|
71
72
|
username = options.user
|
72
73
|
settings = get_appsettings(options)
|
73
74
|
|
74
75
|
with transaction.manager:
|
75
|
-
|
76
|
+
session = get_session(settings, transaction.manager)
|
76
77
|
|
77
78
|
# Must be done only once we have loaded the project config
|
78
79
|
from c2cgeoportal_commons.models.main import Role # pylint: disable=import-outside-toplevel
|
@@ -81,13 +82,13 @@ User can be created if it does not exist yet."""
|
|
81
82
|
print("\n")
|
82
83
|
|
83
84
|
# Check that user exists
|
84
|
-
query =
|
85
|
+
query = session.query(User).filter_by(username=username)
|
85
86
|
|
86
87
|
result = query.count()
|
87
88
|
if result == 0:
|
88
89
|
if not options.create:
|
89
90
|
# If doesn't exist and no -c option, throw error
|
90
|
-
print("User {} does not exist in database"
|
91
|
+
print(f"User {username} does not exist in database")
|
91
92
|
sys.exit(1)
|
92
93
|
else:
|
93
94
|
if options.password is None:
|
@@ -96,46 +97,40 @@ User can be created if it does not exist yet."""
|
|
96
97
|
parser.error("The email is mandatory on user creation")
|
97
98
|
|
98
99
|
# Get roles
|
99
|
-
query_role =
|
100
|
+
query_role = session.query(Role).filter(Role.name == options.rolename)
|
100
101
|
|
101
102
|
if query_role.count() == 0:
|
102
103
|
# Role not found in db?
|
103
|
-
print("Role matching {} does not exist in database"
|
104
|
+
print(f"Role matching {options.rolename} does not exist in database")
|
104
105
|
sys.exit(1)
|
105
106
|
|
106
107
|
role = query_role.first()
|
107
108
|
|
108
109
|
user = User(
|
109
110
|
username=username,
|
110
|
-
password=options.password,
|
111
|
-
email=options.email,
|
111
|
+
password=cast(str, options.password),
|
112
|
+
email=cast(str, options.email),
|
112
113
|
settings_role=role,
|
113
114
|
roles=[role],
|
114
115
|
)
|
115
|
-
|
116
|
-
|
117
|
-
print(
|
118
|
-
(
|
119
|
-
"User {} created with password {} and role {}".format(
|
120
|
-
username, options.password, options.rolename
|
121
|
-
)
|
122
|
-
)
|
123
|
-
)
|
116
|
+
session.add(user)
|
117
|
+
|
118
|
+
print(f"User {username} created with password {options.password} and role {options.rolename}")
|
124
119
|
|
125
120
|
else:
|
126
121
|
# If user exists (assuming username are unique)
|
127
122
|
user = query.first()
|
128
123
|
|
129
124
|
if options.password is not None:
|
130
|
-
print("Password set to: {
|
131
|
-
user.password = "{
|
125
|
+
print(f"Password set to: {options.password}")
|
126
|
+
user.password = f"{options.password}"
|
132
127
|
|
133
128
|
if options.email is not None:
|
134
129
|
user.email = options.email
|
135
130
|
|
136
|
-
|
131
|
+
session.add(user)
|
137
132
|
|
138
|
-
print("Password reset for user {}"
|
133
|
+
print(f"Password reset for user {username}")
|
139
134
|
|
140
135
|
|
141
136
|
if __name__ == "__main__":
|
@@ -0,0 +1,312 @@
|
|
1
|
+
# Copyright (c) 2021-2024, Camptocamp SA
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
# this list of conditions and the following disclaimer in the documentation
|
11
|
+
# and/or other materials provided with the distribution.
|
12
|
+
|
13
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
14
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
15
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
16
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
17
|
+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
18
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
19
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
20
|
+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
21
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
22
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
|
+
|
24
|
+
# The views and conclusions contained in the software and documentation are those
|
25
|
+
# of the authors and should not be interpreted as representing official policies,
|
26
|
+
# either expressed or implied, of the FreeBSD Project.
|
27
|
+
|
28
|
+
|
29
|
+
import json
|
30
|
+
import os
|
31
|
+
import re
|
32
|
+
import subprocess
|
33
|
+
import sys
|
34
|
+
from argparse import ArgumentParser
|
35
|
+
from typing import Any, Dict, List, Optional, Type, Union, cast
|
36
|
+
|
37
|
+
import pkg_resources
|
38
|
+
import requests
|
39
|
+
import yaml
|
40
|
+
from cookiecutter.log import configure_logger
|
41
|
+
from cookiecutter.main import cookiecutter
|
42
|
+
|
43
|
+
_bad_chars_re = re.compile("[^a-zA-Z0-9_]")
|
44
|
+
SCAFFOLDS_DIR = pkg_resources.resource_filename("c2cgeoportal_geoportal", "scaffolds")
|
45
|
+
|
46
|
+
|
47
|
+
def get_argparser() -> ArgumentParser:
|
48
|
+
"""Get the argument parser for this script."""
|
49
|
+
|
50
|
+
parser = ArgumentParser(
|
51
|
+
prog=sys.argv[0],
|
52
|
+
add_help=True,
|
53
|
+
description="Wrapper around cookiecutter that create appropriated context.",
|
54
|
+
)
|
55
|
+
parser.add_argument(
|
56
|
+
"-s",
|
57
|
+
"--scaffold",
|
58
|
+
dest="scaffold_names",
|
59
|
+
action="append",
|
60
|
+
help=("Add a scaffold to the create process " "(multiple -s args accepted)"),
|
61
|
+
)
|
62
|
+
parser.add_argument(
|
63
|
+
"-l",
|
64
|
+
"--list",
|
65
|
+
dest="list",
|
66
|
+
action="store_true",
|
67
|
+
help="List all available scaffold names",
|
68
|
+
)
|
69
|
+
parser.add_argument(
|
70
|
+
"--package-name",
|
71
|
+
dest="package_name",
|
72
|
+
action="store",
|
73
|
+
help="Package name to use. The name provided is "
|
74
|
+
"assumed to be a valid Python package name, and "
|
75
|
+
"will not be validated. By default the package "
|
76
|
+
"name is derived from the value of "
|
77
|
+
"output_directory.",
|
78
|
+
)
|
79
|
+
parser.add_argument(
|
80
|
+
"--overwrite",
|
81
|
+
dest="overwrite",
|
82
|
+
action="store_true",
|
83
|
+
help="Always overwrite",
|
84
|
+
)
|
85
|
+
parser.add_argument(
|
86
|
+
"output_directory",
|
87
|
+
nargs="?",
|
88
|
+
default=None,
|
89
|
+
help="The directory where the project will be " "created.",
|
90
|
+
)
|
91
|
+
return parser
|
92
|
+
|
93
|
+
|
94
|
+
def main() -> int:
|
95
|
+
"""Entry point to run PCreateCommand."""
|
96
|
+
command = PCreateCommand(sys.argv)
|
97
|
+
try:
|
98
|
+
return command.run()
|
99
|
+
except KeyboardInterrupt: # pragma: no cover
|
100
|
+
return 1
|
101
|
+
|
102
|
+
|
103
|
+
class PCreateCommand:
|
104
|
+
"""
|
105
|
+
Wrapper around cookiecutter with appropriated context creator for our scaffolds.
|
106
|
+
|
107
|
+
This is a port of Pyramid 1 PCreateCommand using cookiecutter as a backend.
|
108
|
+
"""
|
109
|
+
|
110
|
+
def __init__(self, argv: List[str], quiet: bool = False) -> None:
|
111
|
+
self.quiet = quiet
|
112
|
+
self.parser = get_argparser()
|
113
|
+
self.args = self.parser.parse_args(argv[1:])
|
114
|
+
self.scaffolds = self.all_scaffolds()
|
115
|
+
|
116
|
+
def run(self) -> int:
|
117
|
+
if self.args.list:
|
118
|
+
return self.show_scaffolds()
|
119
|
+
if not self.args.scaffold_names and not self.args.output_directory:
|
120
|
+
if not self.quiet: # pragma: no cover
|
121
|
+
self.parser.print_help()
|
122
|
+
self.out("")
|
123
|
+
self.show_scaffolds()
|
124
|
+
return 2
|
125
|
+
|
126
|
+
return self.render_scaffolds()
|
127
|
+
|
128
|
+
@property
|
129
|
+
def output_path(self) -> str:
|
130
|
+
return cast(str, os.path.abspath(os.path.normpath(self.args.output_directory)))
|
131
|
+
|
132
|
+
def render_scaffolds(self) -> int:
|
133
|
+
verbose = True
|
134
|
+
debug_file = None
|
135
|
+
configure_logger(stream_level="DEBUG" if verbose else "INFO", debug_file=debug_file)
|
136
|
+
|
137
|
+
context = self.get_context()
|
138
|
+
|
139
|
+
for scaffold_name in self.args.scaffold_names:
|
140
|
+
# Needed to be backward compatible for the `test-upgrade init` command
|
141
|
+
if scaffold_name.startswith("c2cgeoportal_"):
|
142
|
+
scaffold_name = scaffold_name[len("c2cgeoportal_") :]
|
143
|
+
self.out(f"Rendering scaffold: {scaffold_name}")
|
144
|
+
cookiecutter(
|
145
|
+
template=os.path.join(SCAFFOLDS_DIR, scaffold_name),
|
146
|
+
extra_context=context,
|
147
|
+
no_input=True,
|
148
|
+
overwrite_if_exists=self.args.overwrite,
|
149
|
+
output_dir=os.path.dirname(self.output_path),
|
150
|
+
)
|
151
|
+
return 0
|
152
|
+
|
153
|
+
def show_scaffolds(self) -> int:
|
154
|
+
scaffolds = sorted(self.scaffolds)
|
155
|
+
if scaffolds:
|
156
|
+
self.out("Available scaffolds:")
|
157
|
+
for scaffold in scaffolds:
|
158
|
+
self.out(f" {scaffold}")
|
159
|
+
else:
|
160
|
+
self.out("No scaffolds available")
|
161
|
+
return 0
|
162
|
+
|
163
|
+
@staticmethod
|
164
|
+
def all_scaffolds() -> List[str]:
|
165
|
+
return os.listdir(SCAFFOLDS_DIR)
|
166
|
+
|
167
|
+
def out(self, msg: str) -> None:
|
168
|
+
if not self.quiet:
|
169
|
+
print(msg)
|
170
|
+
|
171
|
+
def get_context(self) -> Dict[str, Union[str, int]]:
|
172
|
+
output_dir = self.output_path
|
173
|
+
project_name = os.path.basename(output_dir)
|
174
|
+
if self.args.package_name is None:
|
175
|
+
pkg_name = _bad_chars_re.sub("", project_name.lower().replace("-", "_"))
|
176
|
+
else:
|
177
|
+
pkg_name = self.args.package_name
|
178
|
+
|
179
|
+
context: Dict[str, Union[str, int]] = {
|
180
|
+
"project": project_name,
|
181
|
+
"package": pkg_name,
|
182
|
+
"authtkt_secret": gen_authtkt_secret(),
|
183
|
+
}
|
184
|
+
context.update(self.read_project_file())
|
185
|
+
if os.environ.get("CI") == "true":
|
186
|
+
context["authtkt_secret"] = ( # nosec
|
187
|
+
"io7heoDui8xaikie1rushaeGeiph8Bequei6ohchaequob6viejei0xooWeuvohf"
|
188
|
+
)
|
189
|
+
|
190
|
+
self.get_var(context, "srid", "Spatial Reference System Identifier (e.g. 2056): ", int)
|
191
|
+
srid = cast(int, context["srid"])
|
192
|
+
extent = self.epsg2bbox(srid)
|
193
|
+
self.get_var(
|
194
|
+
context,
|
195
|
+
"extent",
|
196
|
+
(
|
197
|
+
f"Extent (minx miny maxx maxy): in EPSG: {srid} projection, default is "
|
198
|
+
f"[{extent[0]} {extent[1]} {extent[2]} {extent[3]}]: "
|
199
|
+
if extent
|
200
|
+
else f"Extent (minx miny maxx maxy): in EPSG: {srid} projection: "
|
201
|
+
),
|
202
|
+
)
|
203
|
+
match = re.match(
|
204
|
+
r"([\d.]+)[,; ] *([\d.]+)[,; ] *([\d.]+)[,; ] *([\d.]+)",
|
205
|
+
cast(str, context["extent"]),
|
206
|
+
)
|
207
|
+
if match is not None:
|
208
|
+
extent = [match.group(n + 1) for n in range(4)]
|
209
|
+
assert extent is not None
|
210
|
+
context["extent"] = ",".join(extent)
|
211
|
+
context["extent_mapserver"] = " ".join(extent)
|
212
|
+
|
213
|
+
if context["package"] == "site":
|
214
|
+
raise ValueError(
|
215
|
+
"Sorry, you may not name your package 'site'. "
|
216
|
+
"The package name 'site' has a special meaning in "
|
217
|
+
"Python. Please name it anything except 'site'."
|
218
|
+
)
|
219
|
+
|
220
|
+
package_logger = context["package"]
|
221
|
+
if package_logger == "root":
|
222
|
+
# Rename the app logger in the rare case a project
|
223
|
+
# is named "root"
|
224
|
+
package_logger = "app"
|
225
|
+
context["package_logger"] = package_logger
|
226
|
+
context["geomapfish_version"] = os.environ["VERSION"]
|
227
|
+
# Used in the Docker files to shoos the version of the build image
|
228
|
+
context["geomapfish_version_tag"] = "GEOMAPFISH_VERSION"
|
229
|
+
context["geomapfish_version_tag_env"] = "${GEOMAPFISH_VERSION}"
|
230
|
+
geomapfish_major_version_tag = (
|
231
|
+
"GEOMAPFISH_VERSION"
|
232
|
+
if context.get("unsafe_long_version", False)
|
233
|
+
else "GEOMAPFISH_MAIN_MINOR_VERSION"
|
234
|
+
)
|
235
|
+
# Used in the Docker files to shoos the version of the run image
|
236
|
+
context["geomapfish_major_version_tag"] = geomapfish_major_version_tag
|
237
|
+
context["geomapfish_major_version_tag_env"] = "${" + geomapfish_major_version_tag + "}"
|
238
|
+
context["geomapfish_main_version"] = os.environ["MAJOR_VERSION"]
|
239
|
+
context["geomapfish_main_version_dash"] = os.environ["MAJOR_VERSION"].replace(".", "-")
|
240
|
+
context["geomapfish_main_minor_version"] = os.environ["MAJOR_MINOR_VERSION"]
|
241
|
+
|
242
|
+
return context
|
243
|
+
|
244
|
+
def read_project_file(self) -> Dict[str, Union[str, int]]:
|
245
|
+
project_file = os.path.join(self.output_path, "project.yaml")
|
246
|
+
if os.path.exists(project_file):
|
247
|
+
with open(project_file, encoding="utf8") as f:
|
248
|
+
project = yaml.safe_load(f)
|
249
|
+
return cast(Dict[str, Union[str, int]], project.get("template_vars", {}))
|
250
|
+
else:
|
251
|
+
return {}
|
252
|
+
|
253
|
+
@staticmethod
|
254
|
+
def get_var(
|
255
|
+
context: Dict[str, Any],
|
256
|
+
name: str,
|
257
|
+
prompt: str,
|
258
|
+
type_: Optional[Type[Any]] = None,
|
259
|
+
) -> None:
|
260
|
+
if name.upper() in os.environ and os.environ[name.upper()] != "":
|
261
|
+
value = os.environ.get(name.upper())
|
262
|
+
else:
|
263
|
+
value = context.get(name)
|
264
|
+
|
265
|
+
if value is None:
|
266
|
+
value = input(prompt).strip()
|
267
|
+
|
268
|
+
if type_ is not None and not isinstance(value, type_):
|
269
|
+
try:
|
270
|
+
value = type_(value)
|
271
|
+
except ValueError:
|
272
|
+
print(f"The attribute {name}={value} is not a {type_}")
|
273
|
+
sys.exit(1)
|
274
|
+
|
275
|
+
context[name] = value
|
276
|
+
|
277
|
+
@staticmethod
|
278
|
+
def epsg2bbox(srid: int) -> Optional[List[str]]:
|
279
|
+
try:
|
280
|
+
r = requests.get(f"https://epsg.io/?format=json&q={srid}")
|
281
|
+
bbox = r.json()["results"][0]["bbox"]
|
282
|
+
r = requests.get(
|
283
|
+
"https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[1]},{bbox[0]}".format(
|
284
|
+
srid=srid, bbox=bbox
|
285
|
+
)
|
286
|
+
)
|
287
|
+
r1 = r.json()[0]
|
288
|
+
r = requests.get(
|
289
|
+
"https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[3]},{bbox[2]}".format(
|
290
|
+
srid=srid, bbox=bbox
|
291
|
+
)
|
292
|
+
)
|
293
|
+
r2 = r.json()[0]
|
294
|
+
return [r1["x"], r2["y"], r2["x"], r1["y"]]
|
295
|
+
except requests.RequestException:
|
296
|
+
print("Failed to establish a connection to epsg.io.")
|
297
|
+
except json.JSONDecodeError:
|
298
|
+
print("epsg.io doesn't return a correct json.")
|
299
|
+
except IndexError:
|
300
|
+
print("Unable to get the bbox")
|
301
|
+
except Exception as exception:
|
302
|
+
print(f"unexpected error: {str(exception)}")
|
303
|
+
return None
|
304
|
+
|
305
|
+
|
306
|
+
def gen_authtkt_secret() -> str:
|
307
|
+
"""Generate a random authtkt secret."""
|
308
|
+
return subprocess.run(["pwgen", "64"], stdout=subprocess.PIPE, check=True).stdout.decode().strip()
|
309
|
+
|
310
|
+
|
311
|
+
if __name__ == "__main__": # pragma: no cover
|
312
|
+
sys.exit(main() or 0)
|
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2014-2020, Camptocamp SA
|
1
|
+
# Copyright (c) 2014-2021, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -31,19 +29,25 @@
|
|
31
29
|
import gettext
|
32
30
|
import os
|
33
31
|
import sys
|
34
|
-
from argparse import ArgumentParser
|
35
|
-
from typing import Any, Dict, List, Set
|
32
|
+
from argparse import ArgumentParser, Namespace
|
33
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set
|
36
34
|
|
35
|
+
import pyramid.config
|
37
36
|
import transaction
|
38
37
|
from sqlalchemy import func
|
38
|
+
from sqlalchemy.orm.session import Session
|
39
39
|
|
40
|
-
from c2cgeoportal_geoportal.lib.bashcolor import
|
40
|
+
from c2cgeoportal_geoportal.lib.bashcolor import Color, colorize
|
41
41
|
from c2cgeoportal_geoportal.lib.fulltextsearch import Normalize
|
42
42
|
from c2cgeoportal_geoportal.lib.i18n import LOCALE_PATH
|
43
43
|
from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings, get_session
|
44
44
|
|
45
|
+
if TYPE_CHECKING:
|
46
|
+
import c2cgeoportal_commons.models.main
|
47
|
+
|
45
48
|
|
46
|
-
def
|
49
|
+
def get_argparser() -> ArgumentParser:
|
50
|
+
"""Get the argument parser for this script."""
|
47
51
|
parser = ArgumentParser(
|
48
52
|
prog=sys.argv[0],
|
49
53
|
add_help=True,
|
@@ -53,7 +57,7 @@ def main():
|
|
53
57
|
parser.add_argument(
|
54
58
|
"--locale-folder",
|
55
59
|
default=LOCALE_PATH,
|
56
|
-
help="The folder where the locale files are stored (default
|
60
|
+
help=f"The folder where the locale files are stored (default is {LOCALE_PATH})",
|
57
61
|
)
|
58
62
|
parser.add_argument("--interfaces", action="append", help="the interfaces to export")
|
59
63
|
parser.add_argument(
|
@@ -85,7 +89,13 @@ def main():
|
|
85
89
|
)
|
86
90
|
parser.add_argument("--package", help="the application package")
|
87
91
|
fill_arguments(parser)
|
88
|
-
|
92
|
+
return parser
|
93
|
+
|
94
|
+
|
95
|
+
def main() -> None:
|
96
|
+
"""Run the command."""
|
97
|
+
|
98
|
+
options = get_argparser().parse_args()
|
89
99
|
settings = get_appsettings(options)
|
90
100
|
|
91
101
|
with transaction.manager:
|
@@ -95,7 +105,13 @@ def main():
|
|
95
105
|
|
96
106
|
|
97
107
|
class Import:
|
98
|
-
|
108
|
+
"""
|
109
|
+
To import all the themes, layer groups and layers names into the full-text search table.
|
110
|
+
|
111
|
+
Done by interface and by language.
|
112
|
+
"""
|
113
|
+
|
114
|
+
def __init__(self, session: Session, settings: pyramid.config.Configurator, options: Namespace):
|
99
115
|
self.options = options
|
100
116
|
self.imported: Set[Any] = set()
|
101
117
|
package = settings["package"]
|
@@ -106,9 +122,9 @@ class Import:
|
|
106
122
|
|
107
123
|
fts_missing_langs = [lang for lang in self.languages if lang not in self.fts_languages]
|
108
124
|
if fts_missing_langs:
|
109
|
-
msg = "Keys {} are missing in fulltextsearch languages configuration."
|
125
|
+
msg = f"Keys {fts_missing_langs} are missing in fulltextsearch languages configuration."
|
110
126
|
if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
|
111
|
-
print(colorize(msg, RED))
|
127
|
+
print(colorize(msg, Color.RED))
|
112
128
|
self.languages = [lang for lang in self.languages if lang in self.fts_languages]
|
113
129
|
else:
|
114
130
|
raise KeyError(KeyError(msg))
|
@@ -122,19 +138,19 @@ class Import:
|
|
122
138
|
)
|
123
139
|
|
124
140
|
self.session = session
|
125
|
-
self.session.execute(FullTextSearch.__table__.delete().where(FullTextSearch.from_theme))
|
141
|
+
self.session.execute(FullTextSearch.__table__.delete().where(FullTextSearch.from_theme))
|
126
142
|
|
127
143
|
self._: Dict[str, gettext.NullTranslations] = {}
|
128
144
|
for lang in self.languages:
|
129
145
|
try:
|
130
146
|
self._[lang] = gettext.translation(
|
131
|
-
"{}_geoportal-client"
|
147
|
+
f"{package}_geoportal-client",
|
132
148
|
options.locale_folder.format(package=package),
|
133
149
|
[lang],
|
134
150
|
)
|
135
151
|
except OSError as e:
|
136
152
|
self._[lang] = gettext.NullTranslations()
|
137
|
-
print("Warning: {} (language: {})"
|
153
|
+
print(f"Warning: {e} (language: {lang})")
|
138
154
|
|
139
155
|
query = self.session.query(Interface)
|
140
156
|
if options.interfaces is not None:
|
@@ -156,7 +172,13 @@ class Import:
|
|
156
172
|
for theme in self.session.query(Theme).all():
|
157
173
|
self._add_theme(theme, role)
|
158
174
|
|
159
|
-
def _add_fts(
|
175
|
+
def _add_fts(
|
176
|
+
self,
|
177
|
+
item: "c2cgeoportal_commons.models.main.TreeItem",
|
178
|
+
interface: "c2cgeoportal_commons.models.main.Interface",
|
179
|
+
action: str,
|
180
|
+
role: Optional["c2cgeoportal_commons.models.main.Role"],
|
181
|
+
) -> None:
|
160
182
|
from c2cgeoportal_commons.models.main import FullTextSearch # pylint: disable=import-outside-toplevel
|
161
183
|
|
162
184
|
key = (
|
@@ -177,14 +199,18 @@ class Import:
|
|
177
199
|
self.fts_languages[lang],
|
178
200
|
" ".join(
|
179
201
|
[self.fts_normalizer(self._[lang].gettext(item.name))]
|
180
|
-
+ [v.strip() for m in item.
|
202
|
+
+ [v.strip() for m in item.get_metadata("searchAlias") for v in m.value.split(",")]
|
181
203
|
),
|
182
204
|
)
|
183
205
|
fts.actions = [{"action": action, "data": item.name}]
|
184
206
|
fts.from_theme = True
|
185
207
|
self.session.add(fts)
|
186
208
|
|
187
|
-
def _add_theme(
|
209
|
+
def _add_theme(
|
210
|
+
self,
|
211
|
+
theme: "c2cgeoportal_commons.models.main.Theme",
|
212
|
+
role: Optional["c2cgeoportal_commons.models.main.Role"] = None,
|
213
|
+
) -> None:
|
188
214
|
fill = False
|
189
215
|
for interface in self.interfaces:
|
190
216
|
if interface in theme.interfaces:
|
@@ -198,13 +224,29 @@ class Import:
|
|
198
224
|
if role is None or theme.id not in self.public_theme[interface.id]:
|
199
225
|
self._add_fts(theme, interface, "add_theme", role)
|
200
226
|
|
201
|
-
def _add_block(
|
227
|
+
def _add_block(
|
228
|
+
self,
|
229
|
+
group: "c2cgeoportal_commons.models.main.LayerGroup",
|
230
|
+
interface: "c2cgeoportal_commons.models.main.Interface",
|
231
|
+
role: Optional["c2cgeoportal_commons.models.main.Role"],
|
232
|
+
) -> bool:
|
202
233
|
return self._add_group(group, interface, self.options.blocks, role)
|
203
234
|
|
204
|
-
def _add_folder(
|
235
|
+
def _add_folder(
|
236
|
+
self,
|
237
|
+
group: "c2cgeoportal_commons.models.main.LayerGroup",
|
238
|
+
interface: "c2cgeoportal_commons.models.main.Interface",
|
239
|
+
role: Optional["c2cgeoportal_commons.models.main.Role"],
|
240
|
+
) -> bool:
|
205
241
|
return self._add_group(group, interface, self.options.folders, role)
|
206
242
|
|
207
|
-
def _add_group(
|
243
|
+
def _add_group(
|
244
|
+
self,
|
245
|
+
group: "c2cgeoportal_commons.models.main.LayerGroup",
|
246
|
+
interface: "c2cgeoportal_commons.models.main.Interface",
|
247
|
+
export: bool,
|
248
|
+
role: Optional["c2cgeoportal_commons.models.main.Role"],
|
249
|
+
) -> bool:
|
208
250
|
from c2cgeoportal_commons.models.main import LayerGroup # pylint: disable=import-outside-toplevel
|
209
251
|
|
210
252
|
fill = False
|
@@ -224,13 +266,20 @@ class Import:
|
|
224
266
|
return fill
|
225
267
|
|
226
268
|
@staticmethod
|
227
|
-
def _layer_visible(
|
269
|
+
def _layer_visible(
|
270
|
+
layer: "c2cgeoportal_commons.models.main.Layer", role: "c2cgeoportal_commons.models.main.Role"
|
271
|
+
) -> bool:
|
228
272
|
for restrictionarea in layer.restrictionareas:
|
229
273
|
if role in restrictionarea.roles:
|
230
274
|
return True
|
231
275
|
return False
|
232
276
|
|
233
|
-
def _add_layer(
|
277
|
+
def _add_layer(
|
278
|
+
self,
|
279
|
+
layer: "c2cgeoportal_commons.models.main.Layer",
|
280
|
+
interface: "c2cgeoportal_commons.models.main.Interface",
|
281
|
+
role: Optional["c2cgeoportal_commons.models.main.Role"],
|
282
|
+
) -> bool:
|
234
283
|
if role is None:
|
235
284
|
fill = layer.public and interface in layer.interfaces
|
236
285
|
else:
|