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,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  # Copyright (c) 2018-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
@@ -30,8 +28,9 @@
30
28
 
31
29
  import logging
32
30
  import time
33
- from typing import Any, Dict
31
+ from typing import Any, Dict, cast
34
32
 
33
+ import pyramid.request
35
34
  from c2cwsgiutils import broadcast
36
35
  from c2cwsgiutils.auth import auth_view
37
36
  from c2cwsgiutils.debug import get_size
@@ -43,27 +42,28 @@ from c2cgeoportal_geoportal.views import raster
43
42
  LOG = logging.getLogger(__name__)
44
43
 
45
44
 
46
- @view_config(route_name="memory", renderer="fast_json")
47
- def memory(request):
45
+ @view_config(route_name="memory", renderer="fast_json") # type: ignore
46
+ def memory(request: pyramid.request.Request) -> Dict[str, Any]:
47
+ """Offer an authenticated view throw c2cwsgiutils to provide some memory information."""
48
48
  auth_view(request)
49
- return _memory()
49
+ return cast(Dict[str, Any], _memory())
50
50
 
51
51
 
52
- def _nice_type_name(obj, dogpile_cache=False):
52
+ def _nice_type_name(obj: Any, dogpile_cache: bool = False) -> str:
53
53
  # See: https://dogpilecache.sqlalchemy.org/en/latest/api.html#dogpile.cache.api.CachedValue
54
54
  if dogpile_cache:
55
55
  obj, _ = obj
56
56
  type_ = type(obj)
57
- return "{}.{}".format(type_.__module__, type_.__name__)
57
+ return f"{type_.__module__}.{type_.__name__}"
58
58
 
59
59
 
60
- def _process_dict(dict_, dogpile_cache=False):
60
+ def _process_dict(dict_: Dict[str, Any], dogpile_cache: bool = False) -> Dict[str, Any]:
61
61
  # Timeout after one minute, must be set to a bit less that the timeout of the broadcast
62
62
  timeout = time.monotonic() + 20
63
63
 
64
64
  return {
65
65
  "elements": sorted(
66
- [
66
+ (
67
67
  {
68
68
  "key": key,
69
69
  "type": _nice_type_name(value, dogpile_cache),
@@ -72,8 +72,8 @@ def _process_dict(dict_, dogpile_cache=False):
72
72
  "size_kb": get_size(value) / 1024 if time.monotonic() < timeout else -1,
73
73
  }
74
74
  for key, value in dict_.items()
75
- ],
76
- key=lambda i: -i["size_kb"],
75
+ ),
76
+ key=lambda i: cast(float, -i["size_kb"]),
77
77
  ),
78
78
  "id": id(dict_),
79
79
  "size_kb": get_size(dict_) / 1024 if time.monotonic() < timeout else -1,
@@ -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,14 +26,14 @@
28
26
  # either expressed or implied, of the FreeBSD Project.
29
27
 
30
28
  import logging
31
- from typing import Set
29
+ from typing import Dict, Optional, Set, cast
32
30
 
31
+ import pyramid.request
33
32
  from pyramid.httpexceptions import HTTPBadRequest
34
33
  from sqlalchemy.orm.exc import NoResultFound
35
34
 
36
- from c2cgeoportal_commons.lib.url import get_url2
37
- from c2cgeoportal_commons.models import DBSession
38
- from c2cgeoportal_commons.models.main import OGCServer
35
+ from c2cgeoportal_commons.lib.url import Url, get_url2
36
+ from c2cgeoportal_commons.models import DBSession, main
39
37
  from c2cgeoportal_geoportal.lib.caching import get_region
40
38
  from c2cgeoportal_geoportal.views.proxy import Proxy
41
39
 
@@ -44,54 +42,78 @@ LOG = logging.getLogger(__name__)
44
42
 
45
43
 
46
44
  class OGCProxy(Proxy):
47
- def __init__(self, request, has_default_ogc_server=False):
45
+ """
46
+ Proxy implementation that manly manage the ogcserver parameter.
47
+
48
+ Then load the corresponding OGCServer.
49
+ """
50
+
51
+ def __init__(self, request: pyramid.request.Request, has_default_ogc_server: bool = False):
48
52
  Proxy.__init__(self, request)
49
53
 
50
54
  # params hold the parameters we"re going to send to backend
51
55
  self.params = dict(self.request.params)
52
56
 
53
57
  # reset possible value of role_id and user_id
54
- if "role_id" in self.params: # pragma: no cover
58
+ if "role_id" in self.params:
55
59
  del self.params["role_id"]
56
- if "user_id" in self.params: # pragma: no cover
60
+ if "user_id" in self.params:
57
61
  del self.params["user_id"]
58
62
 
63
+ main_ogc_server = self.request.registry.settings.get("main_ogc_server")
64
+
59
65
  self.lower_params = self._get_lower_params(self.params)
60
- if not has_default_ogc_server and "ogcserver" not in self.params:
66
+
67
+ # We need original case for OGCSERVER parameter value
68
+ self.lower_key_params = {k.lower(): v for k, v in self.params.items()}
69
+
70
+ if "ogcserver" in request.matchdict:
71
+ self.ogc_server = self._get_ogcserver_byname(request.matchdict["ogcserver"])
72
+ elif "ogcserver" in self.lower_key_params:
73
+ self.ogc_server = self._get_ogcserver_byname(self.lower_key_params["ogcserver"])
74
+ elif main_ogc_server is not None:
75
+ self.ogc_server = self._get_ogcserver_byname(main_ogc_server)
76
+ elif not has_default_ogc_server:
61
77
  raise HTTPBadRequest("The querystring argument 'ogcserver' is required")
62
- if "ogcserver" in self.params:
63
- self.ogc_server = self._get_ogcserver_byname(self.params["ogcserver"])
64
78
 
65
- @CACHE_REGION.cache_on_arguments()
66
- def _get_ogcserver_byname(self, name): # pylint: disable=no-self-use
79
+ @CACHE_REGION.cache_on_arguments() # type: ignore
80
+ def _get_ogcserver_byname(self, name: str) -> main.OGCServer:
67
81
  try:
68
- result = DBSession.query(OGCServer).filter(OGCServer.name == name).one()
82
+ result = DBSession.query(main.OGCServer).filter(main.OGCServer.name == name).one()
69
83
  DBSession.expunge(result)
70
- return result
71
- except NoResultFound: # pragma nocover
72
- raise HTTPBadRequest(
73
- "OGSServer '{}' does not exists (existing: {}).".format(
74
- name, ",".join([t[0] for t in DBSession.query(OGCServer.name).all()])
75
- )
84
+ return cast(main.OGCServer, result)
85
+ except NoResultFound:
86
+ raise HTTPBadRequest( # pylint: disable=raise-missing-from
87
+ f"The OGC Server '{name}' does not exist (existing: "
88
+ f"{','.join([t[0] for t in DBSession.query(main.OGCServer.name).all()])})."
76
89
  )
77
90
 
78
- def _get_wms_url(self):
91
+ def _get_wms_url(self, errors: Set[str]) -> Optional[Url]:
79
92
  ogc_server = self.ogc_server
80
- errors: Set[str] = set()
81
- url = get_url2("The OGC server '{}'".format(ogc_server.name), ogc_server.url, self.request, errors)
82
- if errors: # pragma: no cover
93
+ url = get_url2(f"The OGC server '{ogc_server.name}'", ogc_server.url, self.request, errors)
94
+ if errors:
83
95
  LOG.error("\n".join(errors))
84
96
  return url
85
97
 
86
- def _get_wfs_url(self):
98
+ def _get_wfs_url(self, errors: Set[str]) -> Optional[Url]:
87
99
  ogc_server = self.ogc_server
88
- errors: Set[str] = set()
89
100
  url = get_url2(
90
- "The OGC server (WFS) '{}'".format(ogc_server.name),
101
+ f"The OGC server (WFS) '{ogc_server.name}'",
91
102
  ogc_server.url_wfs or ogc_server.url,
92
103
  self.request,
93
104
  errors,
94
105
  )
95
- if errors: # pragma: no cover
106
+ if errors:
96
107
  LOG.error("\n".join(errors))
97
108
  return url
109
+
110
+ def get_headers(self) -> Dict[str, str]:
111
+ headers: Dict[str, str] = super().get_headers()
112
+ if self.ogc_server.type == main.OGCSERVER_TYPE_QGISSERVER:
113
+ if self.request.matched_route.name.endswith("_path"):
114
+ headers["X-Qgis-Service-Url"] = self.request.current_route_url(path=[], _query={})
115
+ else:
116
+ headers["X-Qgis-Service-Url"] = self.request.current_route_url(
117
+ _query={"ogcserver": self.ogc_server.name}
118
+ )
119
+ return headers
@@ -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
@@ -29,44 +27,49 @@
29
27
 
30
28
  import logging
31
29
  from json import dumps, loads
30
+ from typing import Any, Dict, List, Union
32
31
 
32
+ import pyramid.request
33
+ import pyramid.response
33
34
  from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden
34
35
  from pyramid.view import view_config
35
36
 
36
37
  from c2cgeoportal_commons import models
37
- from c2cgeoportal_commons.lib.url import add_url_params
38
+ from c2cgeoportal_commons.lib.url import Url
38
39
  from c2cgeoportal_commons.models import main
39
- from c2cgeoportal_geoportal.lib.caching import NO_CACHE
40
+ from c2cgeoportal_geoportal.lib.common_headers import Cache
40
41
  from c2cgeoportal_geoportal.lib.layers import get_private_layers, get_protected_layers
41
42
  from c2cgeoportal_geoportal.views.ogcproxy import OGCProxy
42
43
 
43
44
  LOG = logging.getLogger(__name__)
44
45
 
45
46
 
46
- class PdfReport(OGCProxy): # pragma: no cover
47
+ class PdfReport(OGCProxy):
48
+ """All the views concerned the PDF report."""
47
49
 
48
50
  layername = None
49
51
 
50
- def __init__(self, request):
52
+ def __init__(self, request: pyramid.request.Request):
51
53
  OGCProxy.__init__(self, request)
52
54
  self.config = self.request.registry.settings.get("pdfreport", {})
53
55
 
54
- def _do_print(self, spec):
56
+ def _do_print(self, spec: Dict[str, Any]) -> pyramid.response.Response:
55
57
  """Create and get report PDF."""
56
-
57
58
  headers = dict(self.request.headers)
58
59
  headers["Content-Type"] = "application/json"
59
60
  response = self._proxy(
60
- "{0!s}/buildreport.{1!s}".format(self.config["print_url"], spec["outputFormat"]),
61
+ Url(f"{self.config['print_url']}/buildreport.{spec['outputFormat']}"),
61
62
  method="POST",
62
63
  body=dumps(spec).encode("utf-8"),
63
64
  headers=headers,
64
65
  )
65
66
 
66
- return self._build_response(response, response.content, NO_CACHE, "pdfreport")
67
+ return self._build_response(response, response.content, Cache.PRIVATE_NO, "pdfreport")
67
68
 
68
69
  @staticmethod
69
- def _build_map(mapserv_url, vector_request_url, srs, map_config):
70
+ def _build_map(
71
+ mapserv_url: str, vector_request_url: str, srs: str, map_config: Dict[str, Any]
72
+ ) -> Dict[str, Any]:
70
73
  backgroundlayers = map_config["backgroundlayers"]
71
74
  imageformat = map_config["imageformat"]
72
75
  return {
@@ -98,19 +101,19 @@ class PdfReport(OGCProxy): # pragma: no cover
98
101
  ],
99
102
  }
100
103
 
101
- @view_config(route_name="pdfreport", renderer="json")
102
- def get_report(self):
104
+ @view_config(route_name="pdfreport", renderer="json") # type: ignore
105
+ def get_report(self) -> pyramid.response.Response:
103
106
  self.layername = self.request.matchdict["layername"]
104
107
  layer_config = self.config["layers"].get(self.layername)
105
108
 
109
+ if layer_config is None:
110
+ raise HTTPBadRequest("Layer not found: " + self.layername)
111
+
106
112
  multiple = layer_config.get("multiple", False)
107
113
  ids = self.request.matchdict["ids"]
108
114
  if multiple:
109
115
  ids = ids.split(",")
110
116
 
111
- if layer_config is None:
112
- raise HTTPBadRequest("Layer not found")
113
-
114
117
  features_ids = (
115
118
  [self.layername + "." + id_ for id_ in ids] if multiple else [self.layername + "." + ids]
116
119
  )
@@ -138,8 +141,8 @@ class PdfReport(OGCProxy): # pragma: no cover
138
141
  mapserv_url = self.request.route_url(
139
142
  "mapserverproxy", _query={"ogcserver": layer_config["ogc_server"]}
140
143
  )
141
- vector_request_url = add_url_params(
142
- mapserv_url,
144
+ url = Url(mapserv_url)
145
+ url.add_query(
143
146
  {
144
147
  "service": "WFS",
145
148
  "version": "1.1.0",
@@ -148,8 +151,9 @@ class PdfReport(OGCProxy): # pragma: no cover
148
151
  "typeName": self.layername,
149
152
  "featureid": ",".join(features_ids),
150
153
  "srsName": srs,
151
- },
154
+ }
152
155
  )
156
+ vector_request_url = url.url()
153
157
 
154
158
  spec = layer_config["spec"]
155
159
  if spec is None:
@@ -221,7 +225,7 @@ class PdfReport(OGCProxy): # pragma: no cover
221
225
 
222
226
  return self._do_print(spec)
223
227
 
224
- def walker(self, spec, name, value):
228
+ def walker(self, spec: Union[Dict[str, Any], List[Dict[str, Any]]], name: str, value: Any) -> None:
225
229
  if isinstance(spec, dict):
226
230
  for k, v in spec.items():
227
231
  if isinstance(v, str):
@@ -231,9 +235,9 @@ class PdfReport(OGCProxy): # pragma: no cover
231
235
  self.walker(v, name, value)
232
236
 
233
237
  if isinstance(spec, list):
234
- for k, v in enumerate(spec):
235
- if isinstance(v, str):
236
- if v == name:
237
- spec[k] = value
238
+ for k2, v2 in enumerate(spec):
239
+ if isinstance(v2, str):
240
+ if v2 == name:
241
+ spec[k2] = value
238
242
  else:
239
- self.walker(v, name, value)
243
+ self.walker(v2, name, value)
@@ -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
@@ -31,12 +29,18 @@
31
29
  import json
32
30
  import logging
33
31
  import urllib.parse
32
+ from typing import Dict, List, Tuple
34
33
 
34
+ import pyramid.request
35
+ import pyramid.response
36
+ import requests
35
37
  from pyramid.httpexceptions import HTTPBadGateway, HTTPFound
36
38
  from pyramid.view import view_config
37
39
 
40
+ from c2cgeoportal_commons.lib.url import Url
38
41
  from c2cgeoportal_geoportal.lib import is_intranet
39
- from c2cgeoportal_geoportal.lib.caching import PRIVATE_CACHE, get_region
42
+ from c2cgeoportal_geoportal.lib.caching import get_region
43
+ from c2cgeoportal_geoportal.lib.common_headers import Cache
40
44
  from c2cgeoportal_geoportal.lib.functionality import get_functionality
41
45
  from c2cgeoportal_geoportal.views.proxy import Proxy
42
46
 
@@ -44,93 +48,97 @@ LOG = logging.getLogger(__name__)
44
48
  CACHE_REGION = get_region("std")
45
49
 
46
50
 
47
- class PrintProxy(Proxy): # pragma: no cover
48
- def __init__(self, request):
51
+ class PrintProxy(Proxy):
52
+ """All the view concerned the print."""
53
+
54
+ def __init__(self, request: pyramid.request.Request):
49
55
  Proxy.__init__(self, request)
50
56
 
51
- @view_config(route_name="printproxy_capabilities")
52
- def capabilities(self):
57
+ @view_config(route_name="printproxy_capabilities") # type: ignore
58
+ def capabilities(self) -> pyramid.response.Response:
53
59
  """Get print capabilities."""
54
-
55
60
  templates = get_functionality("print_template", self.request, is_intranet(self.request))
56
61
 
57
62
  # get query string
58
63
  params = dict(self.request.params)
59
64
  query_string = urllib.parse.urlencode(params)
60
65
 
61
- resp, content = self._capabilities(templates, query_string, self.request.method)
66
+ resp, content = self._capabilities(
67
+ templates, query_string, self.request.method, self.request.referrer, self.request.host
68
+ )
62
69
 
63
- return self._build_response(resp, content, PRIVATE_CACHE, "print")
70
+ response = self._build_response(resp, content, Cache.PRIVATE, "print")
71
+ # Mapfish print will check the referrer header to return the capabilities.
72
+ response.vary += ("Referrer", "Referer")
73
+ return response
64
74
 
65
- @CACHE_REGION.cache_on_arguments()
66
- def _capabilities(self, templates, query_string, method):
75
+ @CACHE_REGION.cache_on_arguments() # type: ignore
76
+ def _capabilities(
77
+ self, templates: List[str], query_string: Dict[str, str], method: str, referrer: str, host: str
78
+ ) -> Tuple[requests.Response, str]:
67
79
  del query_string # Just for caching
68
80
  del method # Just for caching
69
- # get URL
81
+ del referrer # Just for caching
82
+ del host # Just for caching
83
+
84
+ # Get URL
70
85
  _url = self.request.get_organization_print_url() + "/capabilities.json"
71
86
 
72
- response = self._proxy(_url)
87
+ response = self._proxy(Url(_url))
88
+ response.raise_for_status()
73
89
 
74
90
  if self.request.method == "GET":
75
- if response.ok:
76
- try:
77
- capabilities = response.json()
78
- except json.decoder.JSONDecodeError as e:
79
- # log and raise
80
- LOG.error("Unable to parse capabilities.")
81
- LOG.exception(e)
82
- LOG.error(response.text)
83
- raise HTTPBadGateway(response.text)
84
-
85
- capabilities["layouts"] = list(
86
- layout for layout in capabilities["layouts"] if layout["name"] in templates
87
- )
88
-
89
- pretty = self.request.params.get("pretty", "false") == "true"
90
- content = json.dumps(
91
- capabilities, separators=None if pretty else (",", ":"), indent=4 if pretty else None
92
- )
91
+ try:
92
+ capabilities = response.json()
93
+ except json.decoder.JSONDecodeError:
94
+ LOG.exception("Unable to parse capabilities: %s", response.text)
95
+ raise HTTPBadGateway(response.text) # pylint: disable=raise-missing-from
96
+
97
+ capabilities["layouts"] = list(
98
+ layout for layout in capabilities["layouts"] if layout["name"] in templates
99
+ )
100
+
101
+ pretty = self.request.params.get("pretty", "false") == "true"
102
+ content = json.dumps(
103
+ capabilities, separators=None if pretty else (",", ":"), indent=4 if pretty else None
104
+ )
93
105
  else:
94
106
  content = ""
95
107
 
96
108
  return response, content
97
109
 
98
- @view_config(route_name="printproxy_report_create")
99
- def report_create(self):
110
+ @view_config(route_name="printproxy_report_create") # type: ignore
111
+ def report_create(self) -> pyramid.response.Response:
100
112
  """Create PDF."""
101
113
  return self._proxy_response(
102
114
  "print",
103
- "{0!s}/report.{1!s}".format(
104
- self.request.get_organization_print_url(), self.request.matchdict.get("format")
115
+ Url(
116
+ f"{ self.request.get_organization_print_url()}/report.{self.request.matchdict.get('format')}"
105
117
  ),
106
118
  )
107
119
 
108
- @view_config(route_name="printproxy_status")
109
- def status(self):
120
+ @view_config(route_name="printproxy_status") # type: ignore
121
+ def status(self) -> pyramid.response.Response:
110
122
  """PDF status."""
111
123
  return self._proxy_response(
112
124
  "print",
113
- "{0!s}/status/{1!s}.json".format(
114
- self.request.get_organization_print_url(), self.request.matchdict.get("ref")
125
+ Url(
126
+ f"{self.request.get_organization_print_url()}/status/{self.request.matchdict.get('ref')}.json"
115
127
  ),
116
128
  )
117
129
 
118
- @view_config(route_name="printproxy_cancel")
119
- def cancel(self):
130
+ @view_config(route_name="printproxy_cancel") # type: ignore
131
+ def cancel(self) -> pyramid.response.Response:
120
132
  """PDF cancel."""
121
133
  return self._proxy_response(
122
134
  "print",
123
- "{0!s}/cancel/{1!s}".format(
124
- self.request.get_organization_print_url(), self.request.matchdict.get("ref")
125
- ),
135
+ Url(f"{self.request.get_organization_print_url()}/cancel/{self.request.matchdict.get('ref')}"),
126
136
  )
127
137
 
128
- @view_config(route_name="printproxy_report_get")
129
- def report_get(self):
138
+ @view_config(route_name="printproxy_report_get") # type: ignore
139
+ def report_get(self) -> pyramid.response.Response:
130
140
  """Get the PDF."""
131
- url = "{0!s}/report/{1!s}".format(
132
- self.request.get_organization_print_url(), self.request.matchdict.get("ref")
133
- )
141
+ url = Url(f"{self.request.get_organization_print_url()}/report/{self.request.matchdict.get('ref')}")
134
142
  if self.request.registry.settings.get("print_get_redirect", False):
135
- raise HTTPFound(location=url)
143
+ raise HTTPFound(location=url.url())
136
144
  return self._proxy_response("print", url)
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2012-2020, Camptocamp SA
1
+ # Copyright (c) 2012-2023, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -30,33 +28,38 @@
30
28
 
31
29
  import math
32
30
  from decimal import Decimal
31
+ from typing import Any, Dict, List, Tuple
33
32
 
34
33
  import geojson
34
+ import pyramid.request
35
35
  from pyramid.httpexceptions import HTTPNotFound
36
36
  from pyramid.i18n import TranslationStringFactory
37
37
  from pyramid.view import view_config
38
38
 
39
- from c2cgeoportal_geoportal.lib.caching import NO_CACHE, set_common_headers
39
+ from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
40
40
  from c2cgeoportal_geoportal.views.raster import Raster
41
41
 
42
42
  _ = TranslationStringFactory("c2cgeoportal")
43
43
 
44
44
 
45
45
  class Profile(Raster):
46
- def __init__(self, request):
46
+ """All the view concerned the profile."""
47
+
48
+ def __init__(self, request: pyramid.request.Request):
47
49
  Raster.__init__(self, request)
48
50
 
49
- @view_config(route_name="profile.json", renderer="fast_json")
50
- def json(self):
51
- """answers to /profile.json"""
51
+ @view_config(route_name="profile.json", renderer="fast_json") # type: ignore
52
+ def json(self) -> Dict[str, Any]:
53
+ """Answer to /profile.json."""
52
54
  _, points = self._compute_points()
53
- set_common_headers(self.request, "profile", NO_CACHE)
55
+ set_common_headers(self.request, "profile", Cache.PUBLIC_NO)
54
56
  return {"profile": points}
55
57
 
56
- def _compute_points(self):
57
- """Compute the alt=fct(dist) array"""
58
+ def _compute_points(self) -> Tuple[List[str], List[Dict[str, Any]]]:
59
+ """Compute the alt=fct(dist) array."""
58
60
  geom = geojson.loads(self.request.params["geom"], object_hook=geojson.GeoJSON.to_instance)
59
61
 
62
+ layers: List[str]
60
63
  if "layers" in self.request.params:
61
64
  rasters = {}
62
65
  layers = self.request.params["layers"].split(",")
@@ -64,13 +67,13 @@ class Profile(Raster):
64
67
  if layer in self.rasters:
65
68
  rasters[layer] = self.rasters[layer]
66
69
  else:
67
- raise HTTPNotFound("Layer {0!s} not found".format(layer))
70
+ raise HTTPNotFound(f"Layer {layer!s} not found")
68
71
  else:
69
72
  rasters = self.rasters
70
73
  layers = list(rasters.keys())
71
74
  layers.sort()
72
75
 
73
- points = []
76
+ points: List[Dict[str, Any]] = []
74
77
 
75
78
  dist = 0
76
79
  prev_coord = None
@@ -92,12 +95,12 @@ class Profile(Raster):
92
95
  return layers, points
93
96
 
94
97
  @staticmethod
95
- def _dist(coord1, coord2):
96
- """Compute the distance between 2 points"""
98
+ def _dist(coord1: Tuple[float, float], coord2: Tuple[float, float]) -> float:
99
+ """Compute the distance between 2 points."""
97
100
  return math.sqrt(math.pow(coord1[0] - coord2[0], 2.0) + math.pow(coord1[1] - coord2[1], 2.0))
98
101
 
99
- def _create_points(self, coords, nb_points):
100
- """Add some points in order to reach roughly the asked number of points"""
102
+ def _create_points(self, coords: List[Tuple[float, float]], nb_points: int) -> List[Tuple[float, float]]:
103
+ """Add some points in order to reach roughly the asked number of points."""
101
104
  total_length = 0
102
105
  prev_coord = None
103
106
  for coord in coords:
@@ -108,19 +111,17 @@ class Profile(Raster):
108
111
  if total_length == 0.0:
109
112
  return coords
110
113
 
111
- result = []
114
+ result: List[Tuple[float, float]] = []
112
115
  prev_coord = None
113
116
  for coord in coords:
114
117
  if prev_coord is not None:
115
118
  cur_length = self._dist(prev_coord, coord)
116
- cur_nb_points = int(nb_points * cur_length / total_length + 0.5)
117
- if cur_nb_points < 1:
118
- cur_nb_points = 1
119
+ cur_nb_points = max(int(nb_points * cur_length / total_length + 0.5), 1)
119
120
  dx = (coord[0] - prev_coord[0]) / float(cur_nb_points)
120
121
  dy = (coord[1] - prev_coord[1]) / float(cur_nb_points)
121
122
  for i in range(1, cur_nb_points + 1):
122
- result.append([prev_coord[0] + dx * i, prev_coord[1] + dy * i])
123
+ result.append((prev_coord[0] + dx * i, prev_coord[1] + dy * i))
123
124
  else:
124
- result.append([coord[0], coord[1]])
125
+ result.append((coord[0], coord[1]))
125
126
  prev_coord = coord
126
127
  return result