c2cgeoportal-geoportal 2.6.0__py2.py3-none-any.whl → 2.8.1.180__py2.py3-none-any.whl

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