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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. c2cgeoportal_geoportal/__init__.py +224 -84
  2. c2cgeoportal_geoportal/lib/__init__.py +67 -43
  3. c2cgeoportal_geoportal/lib/authentication.py +50 -22
  4. c2cgeoportal_geoportal/lib/bashcolor.py +17 -13
  5. c2cgeoportal_geoportal/lib/cacheversion.py +16 -8
  6. c2cgeoportal_geoportal/lib/caching.py +61 -191
  7. c2cgeoportal_geoportal/lib/check_collector.py +17 -10
  8. c2cgeoportal_geoportal/lib/checker.py +61 -63
  9. c2cgeoportal_geoportal/lib/common_headers.py +170 -0
  10. c2cgeoportal_geoportal/lib/dbreflection.py +54 -39
  11. c2cgeoportal_geoportal/lib/filter_capabilities.py +122 -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 +361 -237
  18. c2cgeoportal_geoportal/lib/loader.py +10 -15
  19. c2cgeoportal_geoportal/lib/metrics.py +28 -17
  20. c2cgeoportal_geoportal/lib/oauth2.py +214 -145
  21. c2cgeoportal_geoportal/lib/wmstparsing.py +115 -90
  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} +18 -9
  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 +102 -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/advance_create/{{cookiecutter.project}}/geoportal/requirements.txt +2 -0
  36. c2cgeoportal_geoportal/scaffolds/{create/geoportal/setup.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/setup.py} +6 -7
  37. c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/tools/extract-messages.js +8 -6
  38. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/tsconfig.json +8 -0
  39. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +75 -0
  40. c2cgeoportal_geoportal/scaffolds/{create/geoportal/webpack.apps.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js} +31 -28
  41. c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.commons.js +3 -7
  42. c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.config.js +1 -1
  43. c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/__init__.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py} +11 -22
  44. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py +10 -0
  45. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/dev.py +14 -0
  46. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py +8 -0
  47. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py +7 -0
  48. c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/resources.py +4 -3
  49. 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
  50. 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
  51. c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/subscribers.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/subscribers.py} +1 -3
  52. c2cgeoportal_geoportal/scaffolds/advance_update/cookiecutter.json +18 -0
  53. c2cgeoportal_geoportal/scaffolds/{update/geoportal/CONST_Makefile_tmpl → advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile} +3 -7
  54. c2cgeoportal_geoportal/scaffolds/create/cookiecutter.json +18 -0
  55. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.dockerignore +14 -0
  56. c2cgeoportal_geoportal/scaffolds/create/{+dot+editorconfig → {{cookiecutter.project}}/.editorconfig} +2 -5
  57. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/main.yaml +43 -0
  58. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/rebuild.yaml +46 -0
  59. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +65 -0
  60. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.gitignore +16 -0
  61. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierignore +1 -0
  62. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierrc.yaml +2 -0
  63. c2cgeoportal_geoportal/scaffolds/create/{Dockerfile_tmpl → {{cookiecutter.project}}/Dockerfile} +20 -11
  64. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +14 -0
  65. c2cgeoportal_geoportal/scaffolds/create/{README.rst_tmpl → {{cookiecutter.project}}/README.rst} +4 -4
  66. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +162 -0
  67. c2cgeoportal_geoportal/scaffolds/create/{ci/config.yaml_tmpl → {{cookiecutter.project}}/ci/config.yaml} +7 -5
  68. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -0
  69. c2cgeoportal_geoportal/scaffolds/create/{docker-compose-lib.yaml → {{cookiecutter.project}}/docker-compose-lib.yaml} +133 -17
  70. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.override.sample.yaml +67 -0
  71. c2cgeoportal_geoportal/scaffolds/create/{docker-compose.yaml → {{cookiecutter.project}}/docker-compose.yaml} +17 -12
  72. c2cgeoportal_geoportal/scaffolds/create/{env.default_tmpl → {{cookiecutter.project}}/env.default} +29 -14
  73. c2cgeoportal_geoportal/scaffolds/create/{env.project_tmpl → {{cookiecutter.project}}/env.project} +16 -4
  74. c2cgeoportal_geoportal/scaffolds/create/{geoportal/vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/vars.yaml} +93 -27
  75. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/mobile.css +0 -0
  76. c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/Readme.txt +1 -1
  77. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/demo.map.tmpl +224 -0
  78. c2cgeoportal_geoportal/scaffolds/create/{mapserver/mapserver.map.tmpl_tmpl → {{cookiecutter.project}}/mapserver/mapserver.map.tmpl} +7 -15
  79. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Landscape.jrxml +8 -8
  80. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Portrait.jrxml +8 -8
  81. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Landscape.jrxml +8 -8
  82. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Portrait.jrxml +8 -8
  83. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/config.yaml.tmpl +5 -4
  84. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation.properties +4 -0
  85. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation_fr.properties +4 -0
  86. c2cgeoportal_geoportal/scaffolds/create/{project.yaml_tmpl → {{cookiecutter.project}}/project.yaml} +6 -6
  87. c2cgeoportal_geoportal/scaffolds/create/{qgisserver/pg_service.conf.tmpl_tmpl → {{cookiecutter.project}}/qgisserver/pg_service.conf.tmpl} +2 -2
  88. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-backup +110 -0
  89. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +114 -0
  90. c2cgeoportal_geoportal/scaffolds/create/{setup.cfg_tmpl → {{cookiecutter.project}}/setup.cfg} +1 -1
  91. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/spell-ignore-words.txt +3 -0
  92. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tilegeneration/config.yaml.tmpl +195 -0
  93. c2cgeoportal_geoportal/scaffolds/update/cookiecutter.json +18 -0
  94. c2cgeoportal_geoportal/scaffolds/update/{+dot+upgrade.yaml_tmpl → {{cookiecutter.project}}/.upgrade.yaml} +49 -39
  95. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +1160 -0
  96. c2cgeoportal_geoportal/scaffolds/update/{geoportal → {{cookiecutter.project}}/geoportal}/CONST_config-schema.yaml +47 -2
  97. c2cgeoportal_geoportal/scaffolds/update/{geoportal/CONST_vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/CONST_vars.yaml} +350 -17
  98. c2cgeoportal_geoportal/scripts/__init__.py +16 -30
  99. c2cgeoportal_geoportal/scripts/c2cupgrade.py +271 -232
  100. c2cgeoportal_geoportal/scripts/create_demo_theme.py +3 -6
  101. c2cgeoportal_geoportal/scripts/manage_users.py +34 -39
  102. c2cgeoportal_geoportal/scripts/pcreate.py +312 -0
  103. c2cgeoportal_geoportal/scripts/theme2fts.py +72 -23
  104. c2cgeoportal_geoportal/scripts/urllogin.py +19 -11
  105. c2cgeoportal_geoportal/templates/login.html +88 -84
  106. c2cgeoportal_geoportal/templates/notlogin.html +59 -59
  107. c2cgeoportal_geoportal/templates/testi18n.html +6 -8
  108. c2cgeoportal_geoportal/views/__init__.py +23 -4
  109. c2cgeoportal_geoportal/views/dev.py +9 -7
  110. c2cgeoportal_geoportal/views/dynamic.py +56 -19
  111. c2cgeoportal_geoportal/views/entry.py +93 -24
  112. c2cgeoportal_geoportal/views/fulltextsearch.py +28 -22
  113. c2cgeoportal_geoportal/views/geometry_processing.py +15 -7
  114. c2cgeoportal_geoportal/views/i18n.py +91 -9
  115. c2cgeoportal_geoportal/views/layers.py +160 -126
  116. c2cgeoportal_geoportal/views/login.py +106 -93
  117. c2cgeoportal_geoportal/views/mapserverproxy.py +46 -29
  118. c2cgeoportal_geoportal/views/memory.py +12 -12
  119. c2cgeoportal_geoportal/views/ogcproxy.py +48 -30
  120. c2cgeoportal_geoportal/views/pdfreport.py +26 -22
  121. c2cgeoportal_geoportal/views/printproxy.py +60 -52
  122. c2cgeoportal_geoportal/views/profile.py +24 -23
  123. c2cgeoportal_geoportal/views/proxy.py +87 -69
  124. c2cgeoportal_geoportal/views/raster.py +35 -24
  125. c2cgeoportal_geoportal/views/resourceproxy.py +13 -11
  126. c2cgeoportal_geoportal/views/shortener.py +27 -24
  127. c2cgeoportal_geoportal/views/theme.py +427 -321
  128. c2cgeoportal_geoportal/views/tinyowsproxy.py +46 -39
  129. c2cgeoportal_geoportal/views/vector_tiles.py +80 -0
  130. {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.156.dist-info}/METADATA +25 -20
  131. c2cgeoportal_geoportal-2.7.1.156.dist-info/RECORD +185 -0
  132. {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.156.dist-info}/WHEEL +1 -1
  133. {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.156.dist-info}/entry_points.txt +3 -1
  134. tests/__init__.py +7 -3
  135. tests/test_cachebuster.py +0 -2
  136. tests/test_caching.py +17 -25
  137. tests/test_checker.py +0 -2
  138. tests/test_decimaljson.py +4 -4
  139. tests/test_headerstween.py +0 -2
  140. tests/test_i18n.py +1 -1
  141. tests/test_init.py +4 -7
  142. tests/test_locale_negociator.py +0 -2
  143. tests/test_mapserverproxy_route_predicate.py +0 -2
  144. tests/test_raster.py +0 -2
  145. tests/test_wmstparsing.py +0 -2
  146. c2cgeoportal_geoportal/scaffolds/__init__.py +0 -227
  147. c2cgeoportal_geoportal/scaffolds/create/+dot+dockerignore_tmpl +0 -12
  148. c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/main.yaml_tmpl +0 -89
  149. c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/rebuild.yaml_tmpl +0 -78
  150. c2cgeoportal_geoportal/scaffolds/create/+dot+gitignore_tmpl +0 -16
  151. c2cgeoportal_geoportal/scaffolds/create/Makefile +0 -3
  152. c2cgeoportal_geoportal/scaffolds/create/build_tmpl +0 -167
  153. c2cgeoportal_geoportal/scaffolds/create/ci/requirements.txt +0 -1
  154. c2cgeoportal_geoportal/scaffolds/create/ci/trigger +0 -68
  155. c2cgeoportal_geoportal/scaffolds/create/docker-compose.override.sample.yaml +0 -54
  156. c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+dockerignore_tmpl +0 -6
  157. c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+eslintrc_tmpl +0 -15
  158. c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/models.py_tmpl +0 -10
  159. c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/robot.txt +0 -3
  160. c2cgeoportal_geoportal/scaffolds/create/geoportal/production.ini_tmpl +0 -106
  161. c2cgeoportal_geoportal/scaffolds/create/geoportal/requirements.txt +0 -2
  162. c2cgeoportal_geoportal/scaffolds/create/geoportal/tsconfig.json_tmpl +0 -9
  163. c2cgeoportal_geoportal/scaffolds/create/geoportal/webpack.api.js_tmpl +0 -72
  164. c2cgeoportal_geoportal/scaffolds/create/mapserver/demo.map.tmpl_tmpl +0 -262
  165. c2cgeoportal_geoportal/scaffolds/create/mapserver/tinyows.xml +0 -36
  166. c2cgeoportal_geoportal/scaffolds/create/print/print-apps/+package+/config.yaml +0 -168
  167. c2cgeoportal_geoportal/scaffolds/create/qgisserver/geomapfish.yaml.tmpl_tmpl +0 -16
  168. c2cgeoportal_geoportal/scaffolds/create/spell-ignore-words.txt +0 -1
  169. c2cgeoportal_geoportal/scaffolds/create/tilegeneration/config.yaml.tmpl_tmpl +0 -185
  170. c2cgeoportal_geoportal/scaffolds/create/yamllint.yaml +0 -11
  171. c2cgeoportal_geoportal/scaffolds/update/CONST_CHANGELOG.txt_tmpl +0 -454
  172. c2cgeoportal_geoportal/templates/dynamic.js +0 -21
  173. c2cgeoportal_geoportal-2.6.0.dist-info/RECORD +0 -173
  174. /c2cgeoportal_geoportal/{scaffolds/create/geoportal/+package+_geoportal/static/css/desktop.css → py.typed} +0 -0
  175. /c2cgeoportal_geoportal/scaffolds/{create/geoportal/Makefile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Makefile} +0 -0
  176. /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/alembic.ini +0 -0
  177. /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/language_mapping +0 -0
  178. /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-server.cfg +0 -0
  179. /c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/views/__init__.py +0 -0
  180. /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
  181. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/iframe_api.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/desktop.css} +0 -0
  182. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/mobile.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/iframe_api.css} +0 -0
  183. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_left.png +0 -0
  184. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_right.png +0 -0
  185. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/blank.png +0 -0
  186. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-blue.png +0 -0
  187. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-gold.png +0 -0
  188. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-green.png +0 -0
  189. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker.png +0 -0
  190. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/robot.txt.tmpl +0 -0
  191. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/TM_EUROPE_BORDERS-0.3.sql +0 -0
  192. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arial.ttf +0 -0
  193. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbd.ttf +0 -0
  194. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbi.ttf +0 -0
  195. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Ariali.ttf +0 -0
  196. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Bold.ttf +0 -0
  197. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-BoldItalic.ttf +0 -0
  198. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Italic.ttf +0 -0
  199. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Regular.ttf +0 -0
  200. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdana.ttf +0 -0
  201. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanab.ttf +0 -0
  202. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanai.ttf +0 -0
  203. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanaz.ttf +0 -0
  204. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts.conf +0 -0
  205. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/tinyows.xml.tmpl +0 -0
  206. /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/legend.jrxml +0 -0
  207. /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/logo.png +0 -0
  208. /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/north.svg +0 -0
  209. /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/results.jrxml +0 -0
  210. /c2cgeoportal_geoportal/scaffolds/create/{pyproject.toml → {{cookiecutter.project}}/pyproject.toml} +0 -0
  211. /c2cgeoportal_geoportal/scaffolds/create/{run_alembic.sh → {{cookiecutter.project}}/run_alembic.sh} +0 -0
  212. {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.7.1.156.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2014-2020, Camptocamp SA
1
+ # Copyright (c) 2014-2024, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -30,51 +28,58 @@
30
28
 
31
29
  import copy
32
30
  import logging
33
- import xml.sax.handler
31
+ import xml.sax.handler # nosec
34
32
  from io import StringIO
35
- from typing import Callable, Dict, List
36
- from urllib.parse import urlsplit
37
- from xml.sax.saxutils import XMLFilterBase, XMLGenerator
33
+ from typing import Any, Callable, Dict, List, Optional, Set, Union
34
+ from xml.sax.saxutils import XMLFilterBase, XMLGenerator # nosec
38
35
 
39
36
  import defusedxml.expatreader
37
+ import pyramid.request
40
38
  import requests
39
+ from owslib.map.wms111 import ContentMetadata as ContentMetadata111
40
+ from owslib.map.wms130 import ContentMetadata as ContentMetadata130
41
41
  from owslib.wms import WebMapService
42
42
  from pyramid.httpexceptions import HTTPBadGateway
43
43
 
44
- from c2cgeoportal_commons.lib.url import add_url_params
44
+ from c2cgeoportal_commons.lib.url import Url
45
45
  from c2cgeoportal_geoportal.lib import caching, get_ogc_server_wfs_url_ids, get_ogc_server_wms_url_ids
46
46
  from c2cgeoportal_geoportal.lib.layers import get_private_layers, get_protected_layers, get_writable_layers
47
47
 
48
48
  CACHE_REGION = caching.get_region("std")
49
49
  LOG = logging.getLogger(__name__)
50
+ ContentMetadata = Union[ContentMetadata111, ContentMetadata130]
50
51
 
51
52
 
52
- @CACHE_REGION.cache_on_arguments()
53
- def wms_structure(wms_url, host, request):
54
- url = urlsplit(wms_url)
55
- wms_url = add_url_params(wms_url, {"SERVICE": "WMS", "VERSION": "1.1.1", "REQUEST": "GetCapabilities"})
53
+ @CACHE_REGION.cache_on_arguments() # type: ignore
54
+ def wms_structure(wms_url: Url, host: str, request: pyramid.request.Request) -> Dict[str, List[str]]:
55
+ """Get a simple serializable structure of the WMS capabilities."""
56
+ url = wms_url.clone().add_query({"SERVICE": "WMS", "VERSION": "1.1.1", "REQUEST": "GetCapabilities"})
56
57
 
57
58
  # Forward request to target (without Host Header)
58
- headers = dict()
59
- if url.hostname == "localhost" and host is not None: # pragma: no cover
59
+ headers = {}
60
+ if url.hostname == "localhost" and host is not None:
60
61
  headers["Host"] = host
61
62
  try:
62
- response = requests.get(wms_url, headers=headers, **request.registry.settings.get("http_options", {}))
63
- except Exception: # pragma: no cover
64
- raise HTTPBadGateway("Unable to GetCapabilities from wms_url {0!s}".format(wms_url))
63
+ response = requests.get(
64
+ url.url(), headers=headers, **request.registry.settings.get("http_options", {})
65
+ )
66
+ except Exception:
67
+ LOG.exception("Unable to GetCapabilities from wms_url '%s'", wms_url)
68
+ raise HTTPBadGateway( # pylint: disable=raise-missing-from
69
+ "Unable to GetCapabilities, see logs for details"
70
+ )
65
71
 
66
- if not response.ok: # pragma: no cover
72
+ if not response.ok:
67
73
  raise HTTPBadGateway(
68
- "GetCapabilities from wms_url {0!s} return the error: {1:d} {2!s}".format(
69
- wms_url, response.status_code, response.reason
70
- )
74
+ f"GetCapabilities from wms_url {url.url()} return the error: "
75
+ f"{response.status_code:d} {response.reason}"
71
76
  )
72
77
 
73
78
  try:
74
79
  wms = WebMapService(None, xml=response.content)
75
80
  result: Dict[str, List[str]] = {}
76
81
 
77
- def _fill(name, parent):
82
+ def _fill(name: str, parent: ContentMetadata) -> None:
78
83
  if parent is None:
79
84
  return
80
85
  if parent.name not in result:
@@ -86,37 +91,48 @@ def wms_structure(wms_url, host, request):
86
91
  _fill(layer.name, layer.parent)
87
92
  return result
88
93
 
89
- except AttributeError: # pragma: no cover
94
+ except AttributeError:
90
95
  error = "WARNING! an error occurred while trying to read the mapfile and recover the themes."
91
- error = "{0!s}\nurl: {1!s}\nxml:\n{2!s}".format(error, wms_url, response.text)
96
+ error = f"{error}\nurl: {wms_url}\nxml:\n{response.text}"
92
97
  LOG.exception(error)
93
- raise HTTPBadGateway(error)
98
+ raise HTTPBadGateway(error) # pylint: disable=raise-missing-from
94
99
 
95
- except SyntaxError: # pragma: no cover
100
+ except SyntaxError:
96
101
  error = "WARNING! an error occurred while trying to read the mapfile and recover the themes."
97
- error = "{0!s}\nurl: {1!s}\nxml:\n{2!s}".format(error, wms_url, response.text)
102
+ error = f"{error}\nurl: {wms_url}\nxml:\n{response.text}"
98
103
  LOG.exception(error)
99
- raise HTTPBadGateway(error)
104
+ raise HTTPBadGateway(error) # pylint: disable=raise-missing-from
100
105
 
101
106
 
102
- def filter_capabilities(content, wms, url, headers, request):
107
+ def filter_capabilities(
108
+ content: str, wms: bool, url: Url, headers: Dict[str, str], request: pyramid.request.Request
109
+ ) -> str:
110
+ """Filter the WMS/WFS capabilities."""
103
111
 
104
112
  wms_structure_ = wms_structure(url, headers.get("Host"), request)
105
113
 
106
114
  ogc_server_ids = (
107
- get_ogc_server_wms_url_ids(request) if wms else get_ogc_server_wfs_url_ids(request)
108
- ).get(url)
115
+ get_ogc_server_wms_url_ids(request, request.host)
116
+ if wms
117
+ else get_ogc_server_wfs_url_ids(request, request.host)
118
+ ).get(url.url())
109
119
  gmf_private_layers = copy.copy(get_private_layers(ogc_server_ids))
110
120
  for id_ in list(get_protected_layers(request, ogc_server_ids).keys()):
111
121
  if id_ in gmf_private_layers:
112
122
  del gmf_private_layers[id_]
113
123
 
114
124
  private_layers = set()
115
- for gmflayer in list(gmf_private_layers.values()):
116
- for ogclayer in gmflayer.layer.split(","):
117
- private_layers.add(ogclayer)
118
- if ogclayer in wms_structure_:
119
- private_layers.update(wms_structure_[ogclayer])
125
+ for gmf_layer in list(gmf_private_layers.values()):
126
+ for ogc_layer in gmf_layer.layer.split(","):
127
+ private_layers.add(ogc_layer)
128
+ if ogc_layer in wms_structure_:
129
+ private_layers.update(wms_structure_[ogc_layer])
130
+
131
+ LOG.debug(
132
+ "Filter capabilities of OGC server %s\nprivate_layers: %s",
133
+ ", ".join([str(e) for e in ogc_server_ids]),
134
+ ", ".join(private_layers),
135
+ )
120
136
 
121
137
  parser = defusedxml.expatreader.create_parser(forbid_external=False)
122
138
  # skip inclusion of DTDs
@@ -128,15 +144,24 @@ def filter_capabilities(content, wms, url, headers, request):
128
144
  filter_handler = _CapabilitiesFilter(
129
145
  parser, downstream_handler, "Layer" if wms else "FeatureType", layers_blacklist=private_layers
130
146
  )
131
- filter_handler.parse(StringIO(content))
147
+ filter_handler.parse(StringIO(content)) # type: ignore
132
148
  return result.getvalue()
133
149
 
134
150
 
135
- def filter_wfst_capabilities(content, wfs_url, request):
136
- writable_layers: List[str] = []
137
- ogc_server_ids = get_ogc_server_wfs_url_ids(request).get(wfs_url)
138
- for gmflayer in list(get_writable_layers(request, ogc_server_ids).values()):
139
- writable_layers += gmflayer.layer.split(",")
151
+ def filter_wfst_capabilities(content: str, wfs_url: Url, request: pyramid.request.Request) -> str:
152
+ """Filter the WTS capabilities."""
153
+
154
+ writable_layers: Set[str] = set()
155
+ ogc_server_ids = get_ogc_server_wfs_url_ids(request, request.host).get(wfs_url.url())
156
+
157
+ for gmf_layer in list(get_writable_layers(request, ogc_server_ids).values()):
158
+ writable_layers |= set(gmf_layer.layer.split(","))
159
+
160
+ LOG.debug(
161
+ "Filter WFS-T capabilities of OGC server %s\nlayers: %s",
162
+ ", ".join([str(e) for e in ogc_server_ids]),
163
+ ", ".join(writable_layers),
164
+ )
140
165
 
141
166
  parser = defusedxml.expatreader.create_parser(forbid_external=False)
142
167
  # skip inclusion of DTDs
@@ -148,13 +173,13 @@ def filter_wfst_capabilities(content, wfs_url, request):
148
173
  filter_handler = _CapabilitiesFilter(
149
174
  parser, downstream_handler, "FeatureType", layers_whitelist=writable_layers
150
175
  )
151
- filter_handler.parse(StringIO(content))
176
+ filter_handler.parse(StringIO(content)) # type: ignore
152
177
  return result.getvalue()
153
178
 
154
179
 
155
180
  class _Layer:
156
- def __init__(self, self_hidden=False):
157
- self.accumul: List[Callable] = []
181
+ def __init__(self, self_hidden: bool = False):
182
+ self.accumulator: List[Callable[[], None]] = []
158
183
  self.hidden = True
159
184
  self.self_hidden = self_hidden
160
185
  self.has_children = False
@@ -164,13 +189,20 @@ class _Layer:
164
189
  class _CapabilitiesFilter(XMLFilterBase):
165
190
  """
166
191
  SAX filter to show only the allowed layers in a GetCapabilities request.
167
- The filter removes elements of type `tag_name` where the `name`
168
- attribute is part of the set `layers_blacklist` (when `layers_blacklist`
169
- is given) or is not part of the set `layers_whitelist` (when
192
+
193
+ The filter removes elements of type `tag_name` where the `name` attribute is part of the set
194
+ `layers_blacklist` (when `layers_blacklist` is given) or is not part of the set `layers_whitelist` (when
170
195
  `layers_whitelist` is given).
171
196
  """
172
197
 
173
- def __init__(self, upstream, downstream, tag_name, layers_blacklist=None, layers_whitelist=None):
198
+ def __init__(
199
+ self,
200
+ upstream: XMLFilterBase,
201
+ downstream: XMLGenerator,
202
+ tag_name: str,
203
+ layers_blacklist: Optional[Set[str]] = None,
204
+ layers_whitelist: Optional[Set[str]] = None,
205
+ ):
174
206
  XMLFilterBase.__init__(self, upstream)
175
207
  self._downstream = downstream
176
208
  self._accumulator: List[str] = []
@@ -183,9 +215,9 @@ class _CapabilitiesFilter(XMLFilterBase):
183
215
  ), "only either layers_blacklist OR layers_whitelist can be set"
184
216
 
185
217
  if layers_blacklist is not None:
186
- layers_blacklist = [layer.lower() for layer in layers_blacklist]
218
+ layers_blacklist = {layer.lower() for layer in layers_blacklist}
187
219
  if layers_whitelist is not None:
188
- layers_whitelist = [layer.lower() for layer in layers_whitelist]
220
+ layers_whitelist = {layer.lower() for layer in layers_whitelist}
189
221
  self.layers_blacklist = layers_blacklist
190
222
  self.layers_whitelist = layers_whitelist
191
223
 
@@ -196,39 +228,39 @@ class _CapabilitiesFilter(XMLFilterBase):
196
228
 
197
229
  def _complete_text_node(self) -> None:
198
230
  if self._accumulator:
199
- self._downstream.characters("".join(self._accumulator))
231
+ self._downstream.characters("".join(self._accumulator)) # type: ignore
200
232
  self._accumulator = []
201
233
 
202
- def _do(self, action):
234
+ def _do(self, action: Callable[[], Any]) -> None:
203
235
  if self.layers_path:
204
- self.layers_path[-1].accumul.append(action)
236
+ self.layers_path[-1].accumulator.append(action)
205
237
  else:
206
238
  self._complete_text_node()
207
239
  action()
208
240
 
209
- def _add_child(self, layer):
241
+ def _add_child(self, layer: _Layer) -> None:
210
242
  if not layer.hidden and not (layer.has_children and layer.children_nb == 0):
211
- for action in layer.accumul:
243
+ for action in layer.accumulator:
212
244
  self._complete_text_node()
213
245
  action()
214
- layer.accumul = []
246
+ layer.accumulator = []
215
247
 
216
- def setDocumentLocator(self, locator): # noqa
217
- self._downstream.setDocumentLocator(locator)
248
+ def setDocumentLocator(self, locator: str) -> None: # noqa: ignore=N802
249
+ self._downstream.setDocumentLocator(locator) # type: ignore
218
250
 
219
- def startDocument(self): # noqa
220
- self._downstream.startDocument()
251
+ def startDocument(self) -> None: # noqa: ignore=N802
252
+ self._downstream.startDocument() # type: ignore
221
253
 
222
- def endDocument(self): # noqa
223
- self._downstream.endDocument()
254
+ def endDocument(self) -> None: # noqa: ignore=N802
255
+ self._downstream.endDocument() # type: ignore
224
256
 
225
- def startPrefixMapping(self, prefix, uri): # pragma: no cover # noqa
226
- self._downstream.startPrefixMapping(prefix, uri)
257
+ def startPrefixMapping(self, prefix: str, uri: str) -> None: # noqa: ignore=N802
258
+ self._downstream.startPrefixMapping(prefix, uri) # type: ignore
227
259
 
228
- def endPrefixMapping(self, prefix): # pragma: no cover # noqa
229
- self._downstream.endPrefixMapping(prefix)
260
+ def endPrefixMapping(self, prefix: str) -> None: # noqa: ignore=N802
261
+ self._downstream.endPrefixMapping(prefix) # type: ignore
230
262
 
231
- def startElement(self, name, attrs): # noqa
263
+ def startElement(self, name: str, attrs: xml.sax.xmlreader.AttributesImpl) -> None: # noqa: ignore=N802
232
264
  if name == self.tag_name:
233
265
  self.level += 1
234
266
  if self.layers_path:
@@ -238,40 +270,40 @@ class _CapabilitiesFilter(XMLFilterBase):
238
270
  layer = _Layer(parent_layer.self_hidden) if len(self.layers_path) > 1 else _Layer()
239
271
  self.layers_path.append(layer)
240
272
 
241
- parent_layer.accumul.append(lambda: self._add_child(layer))
273
+ parent_layer.accumulator.append(lambda: self._add_child(layer))
242
274
  else:
243
275
  layer = _Layer()
244
276
  self.layers_path.append(layer)
245
277
  elif name == "Name" and self.layers_path:
246
278
  self.in_name = True
247
279
 
248
- self._do(lambda: self._downstream.startElement(name, attrs))
280
+ self._do(lambda: self._downstream.startElement(name, attrs)) # type: ignore
249
281
 
250
- def endElement(self, name): # noqa
251
- self._do(lambda: self._downstream.endElement(name))
282
+ def endElement(self, name: str) -> None: # noqa: ignore=N802
283
+ self._do(lambda: self._downstream.endElement(name)) # type: ignore
252
284
 
253
285
  if name == self.tag_name:
254
286
  self.level -= 1
255
287
  if self.level == 0 and not self.layers_path[0].hidden:
256
- for action in self.layers_path[0].accumul:
288
+ for action in self.layers_path[0].accumulator:
257
289
  self._complete_text_node()
258
290
  action()
259
291
  self.layers_path.pop()
260
292
  elif name == "Name":
261
293
  self.in_name = False
262
294
 
263
- def startElementNS(self, name, qname, attrs): # pragma: no cover # noqa
264
- self._do(lambda: self._downstream.startElementNS(name, qname, attrs))
295
+ def startElementNS(self, name: str, qname: str, attrs: Dict[str, str]) -> None: # noqa: ignore=N802
296
+ self._do(lambda: self._downstream.startElementNS(name, qname, attrs)) # type: ignore
265
297
 
266
- def endElementNS(self, name, qname): # pragma: no cover # noqa
267
- self._do(lambda: self._downstream.endElementNS(name, qname))
298
+ def endElementNS(self, name: str, qname: str) -> None: # noqa: ignore=N802
299
+ self._do(lambda: self._downstream.endElementNS(name, qname)) # type: ignore
268
300
 
269
- def _keep_layer(self, layer_name):
301
+ def _keep_layer(self, layer_name: str) -> bool:
270
302
  return (self.layers_blacklist is not None and layer_name not in self.layers_blacklist) or (
271
303
  self.layers_whitelist is not None and layer_name in self.layers_whitelist
272
304
  )
273
305
 
274
- def characters(self, content):
306
+ def characters(self, content: str) -> None:
275
307
  if self.in_name and self.layers_path and not self.layers_path[-1].self_hidden is True:
276
308
  layer_name = normalize_typename(content)
277
309
  if self._keep_layer(layer_name):
@@ -285,19 +317,20 @@ class _CapabilitiesFilter(XMLFilterBase):
285
317
 
286
318
  self._do(lambda: self._accumulator.append(content))
287
319
 
288
- def ignorableWhitespace(self, chars): # pragma: no cover # noqa
320
+ def ignorableWhitespace(self, chars: str) -> None: # noqa: ignore=N802
289
321
  self._do(lambda: self._accumulator.append(chars))
290
322
 
291
- def processingInstruction(self, target, data): # pragma: no cover # noqa
292
- self._do(lambda: self._downstream.processingInstruction(target, data))
323
+ def processingInstruction(self, target: str, data: str) -> None: # noqa: ignore=N802
324
+ self._do(lambda: self._downstream.processingInstruction(target, data)) # type: ignore
293
325
 
294
- def skippedEntity(self, name): # pragma: no cover # noqa
295
- self._downstream.skippedEntity(name)
326
+ def skippedEntity(self, name: str) -> None: # noqa: ignore=N802
327
+ self._downstream.skippedEntity(name) # type: ignore
296
328
 
297
329
 
298
- def normalize_tag(tag):
330
+ def normalize_tag(tag: str) -> str:
299
331
  """
300
- Drops the namespace from a tag and converts to lower case.
332
+ Drop the namespace from a tag and converts to lower case.
333
+
301
334
  e.g. '{https://....}TypeName' -> 'TypeName'
302
335
  """
303
336
  normalized = tag
@@ -307,9 +340,10 @@ def normalize_tag(tag):
307
340
  return normalized.lower()
308
341
 
309
342
 
310
- def normalize_typename(typename):
343
+ def normalize_typename(typename: str) -> str:
311
344
  """
312
- Drops the namespace from a type name and converts to lower case.
345
+ Drop the namespace from a type name and converts to lower case.
346
+
313
347
  e.g. 'tows:parks' -> 'parks'
314
348
  """
315
349
  normalized = typename
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2020, Camptocamp SA
1
+ # Copyright (c) 2020-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -28,10 +26,13 @@
28
26
  # either expressed or implied, of the FreeBSD Project.
29
27
 
30
28
  import re
29
+ from typing import Any, Dict
31
30
 
32
31
 
33
32
  class Normalize:
34
- def __init__(self, config):
33
+ """Normalize a text for the Full text search."""
34
+
35
+ def __init__(self, config: Dict[str, Any]) -> None:
35
36
  split = config.get("split_regex")
36
37
  self.split_re = re.compile(split) if split is not None else None
37
38
 
@@ -39,7 +40,7 @@ class Normalize:
39
40
  for search_regex, text in config.get("replace", {}).items():
40
41
  self.word_replace.append((re.compile(search_regex), text))
41
42
 
42
- def __call__(self, text):
43
+ def __call__(self, text: str) -> str:
43
44
  if self.split_re is not None:
44
45
  text = " ".join(self.split_re.split(text))
45
46
 
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  # Copyright (c) 2011-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
@@ -31,6 +29,7 @@
31
29
  import logging.config
32
30
  from typing import Any, Dict, List, Set, Union, cast
33
31
 
32
+ import pyramid.request
34
33
  from sqlalchemy.orm import joinedload
35
34
 
36
35
  from c2cgeoportal_commons.models import main, static
@@ -42,13 +41,13 @@ CACHE_REGION_OBJ = get_region("obj")
42
41
  CACHE_REGION = get_region("std")
43
42
 
44
43
 
45
- @CACHE_REGION_OBJ.cache_on_arguments()
44
+ @CACHE_REGION_OBJ.cache_on_arguments() # type: ignore
46
45
  def _get_role(name: str) -> Dict[str, Any]:
47
46
  from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
48
47
 
49
48
  role = (
50
- DBSession.query(static.Role)
51
- .filter(static.Role.name == name)
49
+ DBSession.query(main.Role)
50
+ .filter(main.Role.name == name)
52
51
  .options(joinedload(main.Role.functionalities))
53
52
  .one_or_none()
54
53
  )
@@ -56,19 +55,23 @@ def _get_role(name: str) -> Dict[str, Any]:
56
55
  return {"settings_functionalities": struct, "roles_functionalities": {name: struct}}
57
56
 
58
57
 
59
- def _user_to_struct(user):
58
+ def _user_to_struct(user: static.User) -> Dict[str, Any]:
60
59
  return {
61
60
  "settings_functionalities": _role_to_struct(user.settings_role),
62
61
  "roles_functionalities": {role.name: _role_to_struct(role) for role in user.roles},
63
62
  }
64
63
 
65
64
 
66
- def _role_to_struct(role):
65
+ def _role_to_struct(role: main.Role) -> List[Dict[str, Any]]:
67
66
  return [{"name": f.name, "value": f.value} for f in role.functionalities] if role else []
68
67
 
69
68
 
70
69
  def _get_db_functionality(
71
- name, user: Dict[str, Any], types, request, errors
70
+ name: str,
71
+ user: Dict[str, Any],
72
+ types: Dict[str, Dict[str, Any]],
73
+ request: pyramid.request.Request,
74
+ errors: Set[str],
72
75
  ) -> List[Union[str, int, float, bool, List[Any], Dict[str, Any]]]:
73
76
  if types.get(name, {}).get("single", False):
74
77
  values = [
@@ -91,16 +94,17 @@ def _get_db_functionality(
91
94
  return [r for r in values if r is not None]
92
95
 
93
96
 
94
- @CACHE_REGION_OBJ.cache_on_arguments()
95
- def _get_functionalities_type(request):
97
+ @CACHE_REGION_OBJ.cache_on_arguments() # type: ignore
98
+ def _get_functionalities_type(request: pyramid.request.Request) -> Dict[str, Dict[str, Any]]:
96
99
  return get_types_map(
97
100
  request.registry.settings.get("admin_interface", {}).get("available_functionalities", [])
98
101
  )
99
102
 
100
103
 
101
104
  def get_functionality(
102
- name, request, is_intranet_
105
+ name: str, request: pyramid.request.Request, is_intranet_: bool
103
106
  ) -> List[Union[str, int, float, bool, List[Any], Dict[str, Any]]]:
107
+ """Get all the functionality for the current user."""
104
108
  result: List[Union[str, int, float, bool, List[Any], Dict[str, Any]]] = []
105
109
  errors: Set[str] = set()
106
110
 
@@ -135,12 +139,13 @@ def get_functionality(
135
139
  errors,
136
140
  )
137
141
 
138
- if errors != set(): # pragma: no cover
142
+ if errors != set():
139
143
  LOG.error("\n".join(errors))
140
144
  return result
141
145
 
142
146
 
143
- def get_mapserver_substitution_params(request):
147
+ def get_mapserver_substitution_params(request: pyramid.request.Request) -> Dict[str, str]:
148
+ """Get the parameters used by the mapserver substitution."""
144
149
  params: Dict[str, str] = {}
145
150
  mss = get_functionality("mapserver_substitution", request, is_intranet(request))
146
151
  if mss:
@@ -149,13 +154,11 @@ def get_mapserver_substitution_params(request):
149
154
  index = s.find("=")
150
155
  if index > 0:
151
156
  attribute = "s_" + s[:index]
152
- # fmt: off
153
- value = s[index + 1:]
154
- # fmt: on
157
+ value = s[index + 1 :]
155
158
  if attribute in params:
156
159
  params[attribute] += "," + value
157
160
  else:
158
161
  params[attribute] = value
159
162
  else:
160
- LOG.warning("Mapserver Substitution '%s' does not " "respect pattern: <attribute>=<value>", s)
163
+ LOG.warning("Mapserver Substitution '%s' does not respect pattern: <attribute>=<value>", s)
161
164
  return params
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2013-2020, Camptocamp SA
1
+ # Copyright (c) 2013-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -29,16 +27,27 @@
29
27
 
30
28
 
31
29
  import re
30
+ from typing import Callable
31
+
32
+ import pyramid.registry
33
+ import pyramid.request
34
+ import pyramid.response
32
35
 
33
36
 
34
37
  class HeadersTween:
35
- def __init__(self, handler, registry):
38
+ """Add the header on all the application."""
39
+
40
+ def __init__(
41
+ self,
42
+ handler: Callable[[pyramid.request.Request], pyramid.response.Response],
43
+ registry: pyramid.registry.Registry,
44
+ ) -> None:
36
45
  self.handler = handler
37
46
  self.settings = [
38
47
  (re.compile(e["pattern"]), e["headers"]) for e in registry.settings["global_headers"]
39
48
  ]
40
49
 
41
- def __call__(self, request):
50
+ def __call__(self, request: pyramid.request.Request) -> pyramid.response.Response:
42
51
  response = self.handler(request)
43
52
 
44
53
  for pattern, headers in self.settings:
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2020, Camptocamp SA
1
+ # Copyright (c) 2020-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -29,11 +27,13 @@
29
27
 
30
28
 
31
29
  import os
30
+ from typing import List
32
31
 
33
32
  LOCALE_PATH = "/etc/geomapfish/locale/"
34
33
 
35
34
 
36
- def available_locale_names(path=LOCALE_PATH):
35
+ def available_locale_names(path: str = LOCALE_PATH) -> List[str]:
36
+ """Get the available locales."""
37
37
  if not os.path.exists(path):
38
38
  return []
39
39
  return [d for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))]