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-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,17 +25,36 @@
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
 
28
+ from typing import Dict, List
30
29
 
30
+ import pyramid.config
31
+ import pyramid.request
31
32
  from pyramid.httpexceptions import HTTPFound
32
33
 
33
34
 
34
- def add_ending_slash(request):
35
+ def add_ending_slash(request: pyramid.request.Request) -> HTTPFound:
36
+ """Add an ending slash view."""
35
37
  return HTTPFound(location=request.path + "/")
36
38
 
37
39
 
38
- def add_redirect(config, name, from_, to):
39
- def redirect_view(request):
40
+ def add_redirect(config: pyramid.config.Configurator, name: str, from_: str, to: str) -> None:
41
+ """Add a redirect view."""
42
+
43
+ def redirect_view(request: pyramid.request.Request) -> HTTPFound:
40
44
  return HTTPFound(location=request.route_url(to))
41
45
 
42
46
  config.add_route(name, from_, request_method="GET")
43
47
  config.add_view(redirect_view, route_name=name)
48
+
49
+
50
+ def restrict_headers(headers: Dict[str, str], whitelist: List[str], blacklist: List[str]) -> Dict[str, str]:
51
+ """
52
+ Filter headers with a whitelist then a blacklist.
53
+
54
+ Some default pyramid headers will be added back by pyramid.
55
+ """
56
+ if len(whitelist) > 0:
57
+ headers = {key: value for key, value in headers.items() if key in whitelist}
58
+
59
+ headers = {key: value for key, value in headers.items() if key not in blacklist}
60
+ return headers
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
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
@@ -31,25 +29,29 @@
31
29
  import logging
32
30
  import re
33
31
 
32
+ import pyramid.request
33
+ import pyramid.response
34
34
  from pyramid.httpexceptions import HTTPFound
35
35
  from pyramid.view import view_config
36
36
 
37
+ from c2cgeoportal_commons.lib.url import Url
37
38
  from c2cgeoportal_geoportal.views.proxy import Proxy
38
39
 
39
40
  logger = logging.getLogger(__name__)
40
41
 
41
42
 
42
43
  class Dev(Proxy):
44
+ """All the development views."""
43
45
 
44
46
  THEME_RE = re.compile(r"/theme/.*$")
45
47
 
46
- def __init__(self, request):
48
+ def __init__(self, request: pyramid.request.Request):
47
49
  super().__init__(request)
48
50
  self.dev_url = self.request.registry.settings["devserver_url"]
49
51
 
50
- @view_config(route_name="dev")
51
- def dev(self):
52
+ @view_config(route_name="dev") # type: ignore
53
+ def dev(self) -> pyramid.response.Response:
52
54
  path = self.THEME_RE.sub("", self.request.path_info)
53
55
  if self.request.path.endswith("/dynamic.js"):
54
56
  return HTTPFound(location=self.request.route_url("dynamic", _query=self.request.params))
55
- return self._proxy_response("dev", "{}/{}".format(self.dev_url.rstrip("/"), path.lstrip("/")))
57
+ return self._proxy_response("dev", Url(f"{self.dev_url.rstrip('/')}/{path.lstrip('/')}"))
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2018-2021, Camptocamp SA
1
+ # Copyright (c) 2018-2025, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -30,8 +28,9 @@
30
28
 
31
29
  import re
32
30
  import urllib.parse
33
- from typing import Dict, List, Union
31
+ from typing import Any, Dict, List, Union, cast
34
32
 
33
+ import pyramid.request
35
34
  from pyramid.httpexceptions import HTTPNotFound
36
35
  from pyramid.view import view_config
37
36
  from sqlalchemy import func
@@ -39,22 +38,25 @@ from sqlalchemy import func
39
38
  from c2cgeoportal_commons import models
40
39
  from c2cgeoportal_commons.models import main
41
40
  from c2cgeoportal_geoportal.lib.cacheversion import get_cache_version
42
- from c2cgeoportal_geoportal.lib.caching import NO_CACHE, get_region, set_common_headers
41
+ from c2cgeoportal_geoportal.lib.caching import get_region
42
+ from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
43
43
 
44
44
  CACHE_REGION = get_region("std")
45
45
 
46
46
 
47
47
  class DynamicView:
48
- def __init__(self, request):
48
+ """The dynamic vies that provide the configuration of the client application."""
49
+
50
+ def __init__(self, request: pyramid.request.Request):
49
51
  self.request = request
50
52
  self.settings = request.registry.settings
51
53
  self.interfaces_config = self.settings["interfaces_config"]
52
54
 
53
- def get(self, value, interface):
54
- return self.interfaces_config.get(interface, {}).get(value, {})
55
+ def get(self, value: Dict[str, Any], interface: str) -> Dict[str, Any]:
56
+ return cast(Dict[str, Any], self.interfaces_config.get(interface, {}).get(value, {}))
55
57
 
56
- @CACHE_REGION.cache_on_arguments()
57
- def _fulltextsearch_groups(self): # pylint: disable=no-self-use
58
+ @CACHE_REGION.cache_on_arguments() # type: ignore
59
+ def _fulltextsearch_groups(self) -> List[str]:
58
60
  return [
59
61
  group[0]
60
62
  for group in models.DBSession.query(func.distinct(main.FullTextSearch.layer_name))
@@ -62,11 +64,30 @@ class DynamicView:
62
64
  .all()
63
65
  ]
64
66
 
65
- def _interface(self, interface_config, interface_name, dynamic):
67
+ def _interface(
68
+ self,
69
+ interface_config: Dict[str, Any],
70
+ interface_name: str,
71
+ original_interface_name: str,
72
+ dynamic: Dict[str, Any],
73
+ ) -> Dict[str, Any]:
74
+ """
75
+ Get the interface configuration.
76
+
77
+ Arguments:
78
+
79
+ interface_config: Current interface configuration
80
+ interface_name: Interface name (we use in the configuration)
81
+ original_interface_name: Original interface name (directly for the query string)
82
+ dynamic: The values that's dynamically generated
83
+ """
66
84
 
67
85
  if "extends" in interface_config:
68
86
  constants = self._interface(
69
- self.interfaces_config[interface_config["extends"]], interface_name, dynamic
87
+ self.interfaces_config[interface_config["extends"]],
88
+ interface_name,
89
+ original_interface_name,
90
+ dynamic,
70
91
  )
71
92
  else:
72
93
  constants = {}
@@ -87,7 +108,7 @@ class DynamicView:
87
108
  )
88
109
 
89
110
  for constant, config in interface_config.get("routes", {}).items():
90
- route_name = interface_name if config.get("currentInterface", False) else config["name"]
111
+ route_name = original_interface_name if config.get("currentInterface", False) else config["name"]
91
112
  params: Dict[str, str] = {}
92
113
  params.update(config.get("params", {}))
93
114
  for name, dyn in config.get("dynamic_params", {}).items():
@@ -98,14 +119,29 @@ class DynamicView:
98
119
 
99
120
  return constants
100
121
 
101
- @view_config(route_name="dynamic", renderer="json")
102
- def dynamic(self):
103
- interface_name = self.request.get_organization_interface(self.request.params.get("interface"))
122
+ @view_config(route_name="dynamic", renderer="json") # type: ignore
123
+ def dynamic(self) -> Dict[str, Any]:
124
+ self.request.response.headers["Vary"] = "Host"
125
+ original_interface_name = self.request.params.get("interface")
126
+ interface_name = self.request.get_organization_interface(original_interface_name)
104
127
 
105
128
  if interface_name not in self.interfaces_config:
106
129
  raise HTTPNotFound("Interface {} doesn't exists in the 'interfaces_config'.")
107
130
 
108
131
  interface_config = self.interfaces_config[interface_name]
132
+ lang_urls_suffix = interface_config.get("lang_urls_suffix", "")
133
+
134
+ i18next_configuration = self.settings.get("i18next", {})
135
+ i18next_configuration.setdefault("backend", {})
136
+ if "loadPath" not in i18next_configuration["backend"]:
137
+ path: List[str] = [
138
+ self.request.route_url("base").rstrip("/"),
139
+ "static-{{ns}}",
140
+ get_cache_version(),
141
+ "locales",
142
+ "{{lng}}.json",
143
+ ]
144
+ i18next_configuration["backend"]["loadPath"] = "/".join(path)
109
145
 
110
146
  dynamic = {
111
147
  "interface": interface_name,
@@ -113,14 +149,15 @@ class DynamicView:
113
149
  "two_factor": self.request.registry.settings.get("authentication", {}).get("two_factor", False),
114
150
  "lang_urls": {
115
151
  lang: self.request.static_url(
116
- "/etc/geomapfish/static/{lang}.json".format(lang=lang),
152
+ f"/etc/geomapfish/static/{lang}{lang_urls_suffix}.json",
117
153
  )
118
154
  for lang in self.request.registry.settings["available_locale_names"]
119
155
  },
156
+ "i18next_configuration": i18next_configuration,
120
157
  "fulltextsearch_groups": self._fulltextsearch_groups(),
121
158
  }
122
159
 
123
- constants = self._interface(interface_config, interface_name, dynamic)
160
+ constants = self._interface(interface_config, interface_name, original_interface_name, dynamic)
124
161
 
125
162
  do_redirect = False
126
163
  url = None
@@ -159,5 +196,5 @@ class DynamicView:
159
196
  else:
160
197
  constants["redirectUrl"] = no_redirect_url
161
198
 
162
- set_common_headers(self.request, "dynamic", NO_CACHE)
199
+ set_common_headers(self.request, "dynamic", Cache.PUBLIC_NO)
163
200
  return {"constants": constants, "doRedirect": do_redirect, "redirectUrl": url}
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
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,115 @@
28
26
  # either expressed or implied, of the FreeBSD Project.
29
27
 
30
28
 
29
+ import glob
31
30
  import logging
32
- import xml.dom.minidom # noqa # pylint: disable=unused-import
33
- from typing import Dict, Set, Tuple # noqa # pylint: disable=unused-import
31
+ from typing import Any, Dict, List, Optional
34
32
 
33
+ import pyramid.request
35
34
  from pyramid.i18n import TranslationStringFactory
36
35
  from pyramid.view import view_config
37
36
 
38
- from c2cgeoportal_geoportal.lib.caching import NO_CACHE, PUBLIC_CACHE, set_common_headers
37
+ from c2cgeoportal_geoportal.lib.caching import get_region
38
+ from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
39
39
 
40
40
  _ = TranslationStringFactory("c2cgeoportal")
41
41
  LOG = logging.getLogger(__name__)
42
+ CACHE_REGION = get_region("std")
42
43
 
43
44
 
44
45
  class Entry:
45
- def __init__(self, request):
46
+ """All the entry points views."""
47
+
48
+ def __init__(self, request: pyramid.request.Request):
46
49
  self.request = request
47
50
 
48
- @view_config(route_name="testi18n", renderer="testi18n.html")
49
- def testi18n(self): # pragma: no cover
51
+ @view_config(route_name="testi18n", renderer="testi18n.html") # type: ignore
52
+ def testi18n(self) -> Dict[str, Any]:
50
53
  _ = self.request.translate
51
54
  return {"title": _("title i18n")}
52
55
 
53
- def get_ngeo_index_vars(self):
54
- set_common_headers(self.request, "index", NO_CACHE, content_type="text/html")
56
+ def get_ngeo_index_vars(self) -> Dict[str, Any]:
57
+ set_common_headers(self.request, "index", Cache.PUBLIC_NO, content_type="text/html")
58
+ # Force urllogin to be converted to cookie when requesting the main HTML page
59
+ self.request.user # pylint: disable=pointless-statement
55
60
  return {}
56
61
 
57
- def apijs(self):
58
- set_common_headers(self.request, "api", PUBLIC_CACHE, content_type="application/javascript")
62
+ @staticmethod
63
+ @CACHE_REGION.cache_on_arguments() # type: ignore
64
+ def get_apijs(api_name: Optional[str]) -> str:
65
+ with open("/etc/static-ngeo/api.js", encoding="utf-8") as api_file:
66
+ api = api_file.read().split("\n")
67
+ sourcemap = api.pop(-1)
68
+ if api_name:
69
+ api += [
70
+ f"if (window.{api_name} === undefined && window.geomapfishapp) {{",
71
+ f" window.{api_name} = window.geomapfishapp;",
72
+ "}",
73
+ ]
74
+ api.append(sourcemap)
75
+
76
+ return "\n".join(api)
77
+
78
+ @view_config(route_name="apijs") # type: ignore
79
+ def apijs(self) -> pyramid.response.Response:
80
+ self.request.response.text = self.get_apijs(self.request.registry.settings["api"].get("name"))
81
+ set_common_headers(self.request, "api", Cache.PUBLIC, content_type="application/javascript")
82
+ return self.request.response
83
+
84
+ def favicon(self) -> Dict[str, Any]:
85
+ set_common_headers(self.request, "index", Cache.PUBLIC, content_type="image/vnd.microsoft.icon")
59
86
  return {}
60
87
 
61
- def favicon(self):
62
- set_common_headers(self.request, "index", NO_CACHE, content_type="image/vnd.microsoft.icon")
88
+ def robot_txt(self) -> Dict[str, Any]:
89
+ set_common_headers(self.request, "index", Cache.PUBLIC, content_type="text/plain")
63
90
  return {}
64
91
 
65
- def robot_txt(self):
66
- set_common_headers(self.request, "index", NO_CACHE, content_type="text/plain")
92
+ def apijsmap(self) -> Dict[str, Any]:
93
+ set_common_headers(self.request, "api", Cache.PUBLIC, content_type="application/octet-stream")
67
94
  return {}
68
95
 
69
- def apijsmap(self):
70
- set_common_headers(self.request, "api", NO_CACHE, content_type="application/octet-stream")
96
+ def apicss(self) -> Dict[str, Any]:
97
+ set_common_headers(self.request, "api", Cache.PUBLIC, content_type="text/css")
71
98
  return {}
72
99
 
73
- def apicss(self):
74
- set_common_headers(self.request, "api", PUBLIC_CACHE, content_type="text/css")
100
+ def apihelp(self) -> Dict[str, Any]:
101
+ set_common_headers(self.request, "apihelp", Cache.PUBLIC)
75
102
  return {}
76
103
 
77
- def apihelp(self):
78
- set_common_headers(self.request, "apihelp", NO_CACHE)
79
- return {}
104
+
105
+ def _get_ngeo_resources(pattern: str) -> List[str]:
106
+ """Return the list of ngeo dist files matching the pattern."""
107
+ return glob.glob(f"/opt/c2cgeoportal/geoportal/node_modules/ngeo/dist/{pattern}")
108
+
109
+
110
+ def canvas_view(request: pyramid.request.Request, interface_config: Dict[str, Any]) -> Dict[str, Any]:
111
+ """Get view used as entry point of a canvas interface."""
112
+
113
+ js_files = _get_ngeo_resources(f"{interface_config.get('layout', interface_config['name'])}*.js")
114
+ css_files = _get_ngeo_resources(f"{interface_config.get('layout', interface_config['name'])}*.css")
115
+ css = "\n ".join(
116
+ [
117
+ f'<link href="{request.static_url(css)}" rel="stylesheet" crossorigin="anonymous">'
118
+ for css in css_files
119
+ ]
120
+ )
121
+
122
+ set_common_headers(request, "index", Cache.PUBLIC_NO, content_type="text/html")
123
+
124
+ spinner = ""
125
+ spinner_filenames = _get_ngeo_resources("spinner*.svg")
126
+ if spinner_filenames:
127
+ with open(spinner_filenames[0], encoding="utf-8") as spinner_file:
128
+ spinner = spinner_file.read()
129
+
130
+ return {
131
+ "request": request,
132
+ "header": f"""
133
+ <meta name="dynamicUrl" content="{request.route_url("dynamic")}">
134
+ <meta name="interface" content="{interface_config['name']}">
135
+ {css}""",
136
+ "footer": "\n ".join(
137
+ [f'<script src="{request.static_url(js)}" crossorigin="anonymous"></script>' for js in js_files]
138
+ ),
139
+ "spinner": spinner,
140
+ }
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2011-2021, 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
@@ -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 NO_CACHE, get_region, set_common_headers
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
- def __init__(self, request):
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", NO_CACHE)
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.fts_normiliser = Normalize(self.settings)
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="{0!s} not defined in languages".format(lang))
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.fts_normiliser(self.request.params.get("query"))
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
- if limit > maxlimit:
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
- if partitionlimit > maxlimit:
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
- subq = DBSession.query(FullTextSearch).add_columns(row_number).filter(_filter).subquery()
148
+ sub_query = DBSession.query(FullTextSearch).add_columns(row_number).filter(_filter).subquery()
148
149
  query = DBSession.query(
149
- subq.c.id, subq.c.label, subq.c.params, subq.c.layer_name, subq.c.the_geom, subq.c.actions
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(subq.c.row_number <= partitionlimit)
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
- objs = query.all()
164
+ objects = query.all()
159
165
 
160
166
  features = []
161
- for o in objs:
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
- # -*- coding: utf-8 -*-
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,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
- from shapely.geometry import asShape
36
+ from shapely.geometry import shape
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
- def __init__(self, request):
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
- ): # pragma: no cover
60
+ ):
53
61
  raise HTTPBadRequest(
54
62
  """Wrong body, it should be like that:
55
63
  {
@@ -61,7 +69,7 @@ class GeometryProcessing:
61
69
  return to_shape(
62
70
  DBSession.query(
63
71
  func.ST_Difference(
64
- from_shape(asShape(body["geometries"][0])), from_shape(asShape(body["geometries"][1]))
72
+ from_shape(shape(body["geometries"][0])), from_shape(shape(body["geometries"][1]))
65
73
  )
66
74
  ).scalar()
67
75
  )