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-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
|
-
import
|
33
|
-
from typing import Dict,
|
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,5 +1,3 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
1
|
# Copyright (c) 2011-2021, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
@@ -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,7 +39,8 @@ 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
|
43
44
|
from c2cgeoportal_geoportal.lib.fulltextsearch import Normalize
|
44
45
|
|
45
46
|
CACHE_REGION = get_region("std")
|
@@ -48,30 +49,32 @@ IGNORED_STARTUP_CHARS_RE = re.compile(r"^[']*")
|
|
48
49
|
|
49
50
|
|
50
51
|
class FullTextSearchView:
|
51
|
-
|
52
|
+
"""All the full-text search view."""
|
53
|
+
|
54
|
+
def __init__(self, request: pyramid.request.Request):
|
52
55
|
self.request = request
|
53
|
-
set_common_headers(request, "fulltextsearch",
|
56
|
+
set_common_headers(request, "fulltextsearch", Cache.PUBLIC_NO)
|
54
57
|
self.settings = request.registry.settings.get("fulltextsearch", {})
|
55
58
|
self.languages = self.settings.get("languages", {})
|
56
|
-
self.
|
59
|
+
self.fts_normalizer = Normalize(self.settings)
|
57
60
|
|
58
61
|
@staticmethod
|
59
|
-
@CACHE_REGION.cache_on_arguments()
|
60
|
-
def _get_interface_id(interface):
|
61
|
-
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)
|
62
65
|
|
63
|
-
@view_config(route_name="fulltextsearch", renderer="geojson")
|
64
|
-
def fulltextsearch(self):
|
66
|
+
@view_config(route_name="fulltextsearch", renderer="geojson") # type: ignore
|
67
|
+
def fulltextsearch(self) -> FeatureCollection:
|
65
68
|
lang = locale_negotiator(self.request)
|
66
69
|
|
67
70
|
try:
|
68
71
|
language = self.languages[lang]
|
69
72
|
except KeyError:
|
70
|
-
return HTTPInternalServerError(detail="{
|
73
|
+
return HTTPInternalServerError(detail=f"{lang!s} not defined in languages")
|
71
74
|
|
72
75
|
if "query" not in self.request.params:
|
73
76
|
return HTTPBadRequest(detail="no query")
|
74
|
-
terms = self.
|
77
|
+
terms = self.fts_normalizer(self.request.params.get("query"))
|
75
78
|
|
76
79
|
maxlimit = self.settings.get("maxlimit", 200)
|
77
80
|
|
@@ -79,15 +82,13 @@ class FullTextSearchView:
|
|
79
82
|
limit = int(self.request.params.get("limit", self.settings.get("defaultlimit", 30)))
|
80
83
|
except ValueError:
|
81
84
|
return HTTPBadRequest(detail="limit value is incorrect")
|
82
|
-
|
83
|
-
limit = maxlimit
|
85
|
+
limit = min(limit, maxlimit)
|
84
86
|
|
85
87
|
try:
|
86
88
|
partitionlimit = int(self.request.params.get("partitionlimit", 0))
|
87
89
|
except ValueError:
|
88
90
|
return HTTPBadRequest(detail="partitionlimit value is incorrect")
|
89
|
-
|
90
|
-
partitionlimit = maxlimit
|
91
|
+
partitionlimit = min(partitionlimit, maxlimit)
|
91
92
|
|
92
93
|
terms_array = [
|
93
94
|
IGNORED_STARTUP_CHARS_RE.sub("", elem) for elem in IGNORED_CHARS_RE.sub(" ", terms).split(" ")
|
@@ -144,21 +145,26 @@ class FullTextSearchView:
|
|
144
145
|
.over(partition_by=FullTextSearch.layer_name, order_by=(desc(rank), FullTextSearch.label))
|
145
146
|
.label("row_number")
|
146
147
|
)
|
147
|
-
|
148
|
+
sub_query = DBSession.query(FullTextSearch).add_columns(row_number).filter(_filter).subquery()
|
148
149
|
query = DBSession.query(
|
149
|
-
|
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,
|
150
156
|
)
|
151
|
-
query = query.filter(
|
157
|
+
query = query.filter(sub_query.c.row_number <= partitionlimit)
|
152
158
|
else:
|
153
159
|
query = DBSession.query(FullTextSearch).filter(_filter)
|
154
160
|
query = query.order_by(desc(rank))
|
155
161
|
query = query.order_by(FullTextSearch.label)
|
156
162
|
|
157
163
|
query = query.limit(limit)
|
158
|
-
|
164
|
+
objects = query.all()
|
159
165
|
|
160
166
|
features = []
|
161
|
-
for o in
|
167
|
+
for o in objects:
|
162
168
|
properties = {"label": o.label}
|
163
169
|
if o.layer_name is not None:
|
164
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
|