c2cgeoportal-geoportal 2.5.0.100__py2.py3-none-any.whl → 2.7.1.83__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 (224) hide show
  1. c2cgeoportal_geoportal/__init__.py +261 -130
  2. c2cgeoportal_geoportal/lib/__init__.py +72 -120
  3. c2cgeoportal_geoportal/lib/authentication.py +170 -21
  4. c2cgeoportal_geoportal/lib/bashcolor.py +17 -13
  5. c2cgeoportal_geoportal/lib/cacheversion.py +19 -11
  6. c2cgeoportal_geoportal/lib/caching.py +66 -160
  7. c2cgeoportal_geoportal/lib/check_collector.py +17 -10
  8. c2cgeoportal_geoportal/lib/checker.py +62 -64
  9. c2cgeoportal_geoportal/lib/common_headers.py +170 -0
  10. c2cgeoportal_geoportal/lib/dbreflection.py +70 -31
  11. c2cgeoportal_geoportal/lib/filter_capabilities.py +124 -96
  12. c2cgeoportal_geoportal/lib/fulltextsearch.py +50 -0
  13. c2cgeoportal_geoportal/lib/functionality.py +36 -21
  14. c2cgeoportal_geoportal/lib/headers.py +14 -5
  15. c2cgeoportal_geoportal/lib/i18n.py +39 -0
  16. c2cgeoportal_geoportal/lib/layers.py +29 -10
  17. c2cgeoportal_geoportal/lib/lingua_extractor.py +408 -211
  18. c2cgeoportal_geoportal/lib/loader.py +18 -16
  19. c2cgeoportal_geoportal/lib/metrics.py +29 -18
  20. c2cgeoportal_geoportal/lib/oauth2.py +1036 -0
  21. c2cgeoportal_geoportal/lib/wmstparsing.py +115 -90
  22. c2cgeoportal_geoportal/lib/xsd.py +29 -19
  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/+dot+prospector.yaml → advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml} +8 -4
  29. c2cgeoportal_geoportal/scaffolds/{create/geoportal/Dockerfile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Dockerfile} +24 -15
  30. c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/alembic.ini +1 -0
  31. c2cgeoportal_geoportal/scaffolds/{create/geoportal/alembic.yaml_tmpl → advance_create/{{cookiecutter.project}}/geoportal/alembic.yaml} +1 -1
  32. c2cgeoportal_geoportal/scaffolds/{create/geoportal/development.ini_tmpl → advance_create/{{cookiecutter.project}}/geoportal/development.ini} +34 -15
  33. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py +104 -0
  34. c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-client.cfg +1 -0
  35. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/production.ini +38 -0
  36. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/requirements.txt +2 -0
  37. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/setup.py +25 -0
  38. c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/tools/extract-messages.js +8 -6
  39. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/tsconfig.json +8 -0
  40. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +75 -0
  41. c2cgeoportal_geoportal/scaffolds/{create/geoportal/webpack.apps.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js} +31 -28
  42. c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.commons.js +3 -7
  43. c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.config.js +4 -4
  44. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py +47 -0
  45. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py +10 -0
  46. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/dev.py +14 -0
  47. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py +8 -0
  48. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py +7 -0
  49. c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/resources.py +4 -3
  50. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/api/index.js +12 -0
  51. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/js/{{cookiecutter.package}}module.js +25 -0
  52. c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/subscribers.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/subscribers.py} +3 -6
  53. c2cgeoportal_geoportal/scaffolds/advance_update/cookiecutter.json +18 -0
  54. c2cgeoportal_geoportal/scaffolds/{update/geoportal/CONST_Makefile_tmpl → advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile} +32 -20
  55. c2cgeoportal_geoportal/scaffolds/create/cookiecutter.json +18 -0
  56. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.dockerignore +14 -0
  57. c2cgeoportal_geoportal/scaffolds/create/{+dot+editorconfig → {{cookiecutter.project}}/.editorconfig} +4 -8
  58. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/main.yaml +43 -0
  59. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/rebuild.yaml +46 -0
  60. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +65 -0
  61. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.gitignore +16 -0
  62. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierignore +1 -0
  63. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierrc.yaml +2 -0
  64. c2cgeoportal_geoportal/scaffolds/create/{Dockerfile_tmpl → {{cookiecutter.project}}/Dockerfile} +34 -24
  65. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +14 -0
  66. c2cgeoportal_geoportal/scaffolds/create/{README.rst_tmpl → {{cookiecutter.project}}/README.rst} +4 -4
  67. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +158 -0
  68. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/config.yaml +25 -0
  69. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -0
  70. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-lib.yaml +474 -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} +43 -18
  73. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.default +82 -0
  74. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.project +60 -0
  75. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/vars.yaml +396 -0
  76. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/mobile.css +0 -0
  77. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-blue.png +0 -0
  78. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-gold.png +0 -0
  79. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-green.png +0 -0
  80. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker.png +0 -0
  81. c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/Readme.txt +1 -1
  82. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/demo.map.tmpl +224 -0
  83. c2cgeoportal_geoportal/scaffolds/create/{mapserver/mapserver.map.tmpl_tmpl → {{cookiecutter.project}}/mapserver/mapserver.map.tmpl} +7 -15
  84. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Landscape.jrxml +17 -9
  85. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Portrait.jrxml +17 -9
  86. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Landscape.jrxml +17 -9
  87. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Portrait.jrxml +17 -9
  88. c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/config.yaml.tmpl +30 -27
  89. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/legend.jrxml +109 -0
  90. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation.properties +4 -0
  91. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation_fr.properties +4 -0
  92. c2cgeoportal_geoportal/scaffolds/create/{project.yaml_tmpl → {{cookiecutter.project}}/project.yaml} +6 -6
  93. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/pyproject.toml +3 -0
  94. c2cgeoportal_geoportal/scaffolds/create/{qgisserver/pg_service.conf.tmpl_tmpl → {{cookiecutter.project}}/qgisserver/pg_service.conf.tmpl} +2 -2
  95. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-backup +107 -0
  96. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +111 -0
  97. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/setup.cfg +7 -0
  98. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/spell-ignore-words.txt +3 -0
  99. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tilegeneration/config.yaml.tmpl +195 -0
  100. c2cgeoportal_geoportal/scaffolds/update/cookiecutter.json +18 -0
  101. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/.upgrade.yaml +191 -0
  102. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +1153 -0
  103. c2cgeoportal_geoportal/scaffolds/update/{geoportal → {{cookiecutter.project}}/geoportal}/CONST_config-schema.yaml +99 -47
  104. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/CONST_vars.yaml +1412 -0
  105. c2cgeoportal_geoportal/scripts/__init__.py +17 -33
  106. c2cgeoportal_geoportal/scripts/c2cupgrade.py +295 -200
  107. c2cgeoportal_geoportal/scripts/create_demo_theme.py +5 -6
  108. c2cgeoportal_geoportal/scripts/manage_users.py +34 -37
  109. c2cgeoportal_geoportal/scripts/pcreate.py +312 -0
  110. c2cgeoportal_geoportal/scripts/theme2fts.py +92 -25
  111. c2cgeoportal_geoportal/scripts/urllogin.py +23 -17
  112. c2cgeoportal_geoportal/templates/login.html +88 -84
  113. c2cgeoportal_geoportal/templates/notlogin.html +62 -0
  114. c2cgeoportal_geoportal/templates/testi18n.html +6 -8
  115. c2cgeoportal_geoportal/views/__init__.py +23 -4
  116. c2cgeoportal_geoportal/views/dev.py +9 -7
  117. c2cgeoportal_geoportal/views/dynamic.py +70 -40
  118. c2cgeoportal_geoportal/views/entry.py +93 -24
  119. c2cgeoportal_geoportal/views/fulltextsearch.py +36 -29
  120. c2cgeoportal_geoportal/views/geometry_processing.py +15 -7
  121. c2cgeoportal_geoportal/views/i18n.py +91 -9
  122. c2cgeoportal_geoportal/views/layers.py +173 -134
  123. c2cgeoportal_geoportal/views/login.py +206 -87
  124. c2cgeoportal_geoportal/views/mapserverproxy.py +59 -35
  125. c2cgeoportal_geoportal/views/memory.py +13 -13
  126. c2cgeoportal_geoportal/views/ogcproxy.py +48 -30
  127. c2cgeoportal_geoportal/views/pdfreport.py +31 -27
  128. c2cgeoportal_geoportal/views/printproxy.py +67 -53
  129. c2cgeoportal_geoportal/views/profile.py +25 -24
  130. c2cgeoportal_geoportal/views/proxy.py +97 -68
  131. c2cgeoportal_geoportal/views/raster.py +47 -29
  132. c2cgeoportal_geoportal/views/resourceproxy.py +13 -11
  133. c2cgeoportal_geoportal/views/shortener.py +31 -24
  134. c2cgeoportal_geoportal/views/theme.py +475 -365
  135. c2cgeoportal_geoportal/views/tinyowsproxy.py +46 -39
  136. c2cgeoportal_geoportal/views/vector_tiles.py +80 -0
  137. {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/METADATA +16 -11
  138. c2cgeoportal_geoportal-2.7.1.83.dist-info/RECORD +185 -0
  139. {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/WHEEL +1 -1
  140. {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.dist-info}/entry_points.txt +3 -1
  141. tests/__init__.py +24 -3
  142. tests/test_cachebuster.py +1 -3
  143. tests/test_caching.py +19 -26
  144. tests/test_checker.py +2 -3
  145. tests/test_decimaljson.py +4 -4
  146. tests/test_headerstween.py +0 -3
  147. tests/test_i18n.py +31 -0
  148. tests/test_init.py +12 -27
  149. tests/test_locale_negociator.py +6 -6
  150. tests/test_mapserverproxy_route_predicate.py +0 -2
  151. tests/test_raster.py +18 -5
  152. tests/test_wmstparsing.py +7 -8
  153. c2cgeoportal_geoportal/scaffolds/__init__.py +0 -226
  154. c2cgeoportal_geoportal/scaffolds/create/+dot+dockerignore_tmpl +0 -11
  155. c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/ci.yaml_tmpl +0 -56
  156. c2cgeoportal_geoportal/scaffolds/create/+dot+gitignore_tmpl +0 -12
  157. c2cgeoportal_geoportal/scaffolds/create/build_tmpl +0 -144
  158. c2cgeoportal_geoportal/scaffolds/create/docker-compose-lib.yaml_tmpl +0 -302
  159. c2cgeoportal_geoportal/scaffolds/create/docker-compose.override.sample.yaml_tmpl +0 -54
  160. c2cgeoportal_geoportal/scaffolds/create/env.default_tmpl +0 -49
  161. c2cgeoportal_geoportal/scaffolds/create/env.project_tmpl +0 -39
  162. c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+dockerignore_tmpl +0 -5
  163. c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+eslintrc_tmpl +0 -19
  164. c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/__init__.py_tmpl +0 -48
  165. c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/models.py_tmpl +0 -10
  166. c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/images/favicon.ico +0 -0
  167. c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/robot.txt +0 -3
  168. c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static-ngeo/api/index.js_tmpl +0 -37
  169. c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static-ngeo/js/+package+module.js_tmpl +0 -22
  170. c2cgeoportal_geoportal/scaffolds/create/geoportal/production.ini_tmpl +0 -106
  171. c2cgeoportal_geoportal/scaffolds/create/geoportal/requirements.txt +0 -2
  172. c2cgeoportal_geoportal/scaffolds/create/geoportal/setup.py_tmpl +0 -18
  173. c2cgeoportal_geoportal/scaffolds/create/geoportal/tsconfig.json_tmpl +0 -9
  174. c2cgeoportal_geoportal/scaffolds/create/geoportal/vars.yaml_tmpl +0 -224
  175. c2cgeoportal_geoportal/scaffolds/create/geoportal/webpack.api.js_tmpl +0 -71
  176. c2cgeoportal_geoportal/scaffolds/create/mapserver/demo.map.tmpl_tmpl +0 -262
  177. c2cgeoportal_geoportal/scaffolds/create/mapserver/tinyows.xml +0 -36
  178. c2cgeoportal_geoportal/scaffolds/create/print/print-apps/+package+/config.yaml +0 -166
  179. c2cgeoportal_geoportal/scaffolds/create/print/print-apps/+package+/legend.jrxml +0 -27
  180. c2cgeoportal_geoportal/scaffolds/create/qgisserver/geomapfish.yaml.tmpl_tmpl +0 -29
  181. c2cgeoportal_geoportal/scaffolds/create/scripts/publish-docker +0 -124
  182. c2cgeoportal_geoportal/scaffolds/create/setup.cfg_tmpl +0 -3
  183. c2cgeoportal_geoportal/scaffolds/create/spell-ignore-words.txt +0 -1
  184. c2cgeoportal_geoportal/scaffolds/create/tilegeneration/config.yaml.tmpl_tmpl +0 -169
  185. c2cgeoportal_geoportal/scaffolds/create/yamllint.yaml +0 -11
  186. c2cgeoportal_geoportal/scaffolds/update/+dot+upgrade.yaml_tmpl +0 -171
  187. c2cgeoportal_geoportal/scaffolds/update/CONST_CHANGELOG.txt_tmpl +0 -64
  188. c2cgeoportal_geoportal/scaffolds/update/geoportal/CONST_vars.yaml_tmpl +0 -783
  189. c2cgeoportal_geoportal/templates/dynamic.js +0 -21
  190. c2cgeoportal_geoportal-2.5.0.100.dist-info/RECORD +0 -162
  191. tests/test_get_url.py +0 -96
  192. tests/test_lib.py +0 -77
  193. /c2cgeoportal_geoportal/{scaffolds/create/geoportal/+package+_geoportal/static/css/desktop.css → py.typed} +0 -0
  194. /c2cgeoportal_geoportal/scaffolds/{create/geoportal/Makefile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Makefile} +0 -0
  195. /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/language_mapping +0 -0
  196. /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-server.cfg +0 -0
  197. /c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/views/__init__.py +0 -0
  198. /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
  199. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/iframe_api.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/desktop.css} +0 -0
  200. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/mobile.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/iframe_api.css} +0 -0
  201. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_left.png +0 -0
  202. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_right.png +0 -0
  203. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/blank.png +0 -0
  204. /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/robot.txt.tmpl +0 -0
  205. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/TM_EUROPE_BORDERS-0.3.sql +0 -0
  206. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arial.ttf +0 -0
  207. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbd.ttf +0 -0
  208. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbi.ttf +0 -0
  209. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Ariali.ttf +0 -0
  210. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Bold.ttf +0 -0
  211. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-BoldItalic.ttf +0 -0
  212. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Italic.ttf +0 -0
  213. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Regular.ttf +0 -0
  214. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdana.ttf +0 -0
  215. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanab.ttf +0 -0
  216. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanai.ttf +0 -0
  217. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanaz.ttf +0 -0
  218. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts.conf +0 -0
  219. /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/tinyows.xml.tmpl +0 -0
  220. /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/logo.png +0 -0
  221. /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/north.svg +0 -0
  222. /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/results.jrxml +0 -0
  223. /c2cgeoportal_geoportal/scaffolds/create/{run_alembic.sh → {{cookiecutter.project}}/run_alembic.sh} +0 -0
  224. {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.83.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-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -28,30 +26,38 @@
28
26
  # either expressed or implied, of the FreeBSD Project.
29
27
 
30
28
 
31
- from argparse import ArgumentParser
32
29
  import gettext
33
30
  import os
34
31
  import sys
35
- from typing import Any, Dict, List, Set
32
+ from argparse import ArgumentParser, Namespace
33
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set
36
34
 
37
- from sqlalchemy import func
35
+ import pyramid.config
38
36
  import transaction
37
+ from sqlalchemy import func
38
+ from sqlalchemy.orm.session import Session
39
39
 
40
+ from c2cgeoportal_geoportal.lib.bashcolor import Color, colorize
41
+ from c2cgeoportal_geoportal.lib.fulltextsearch import Normalize
42
+ from c2cgeoportal_geoportal.lib.i18n import LOCALE_PATH
40
43
  from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings, get_session
41
44
 
45
+ if TYPE_CHECKING:
46
+ import c2cgeoportal_commons.models.main
47
+
42
48
 
43
- def main():
49
+ def get_argparser() -> ArgumentParser:
50
+ """Get the argument parser for this script."""
44
51
  parser = ArgumentParser(
45
52
  prog=sys.argv[0],
46
53
  add_help=True,
47
54
  description="Tool to fill the tsearch table (full-text search) from the theme information.",
48
55
  )
49
56
 
50
- locale_path_1 = os.path.join("{package}_geoportal", "locale", "")
51
- locale_path_2 = os.path.join("geoportal", locale_path_1)
52
- locale_path = locale_path_2 if os.path.exists("geoportal") else locale_path_1
53
57
  parser.add_argument(
54
- "--locale-folder", default=locale_path, help="The folder where the locale files are stored"
58
+ "--locale-folder",
59
+ default=LOCALE_PATH,
60
+ help=f"The folder where the locale files are stored (default is {LOCALE_PATH})",
55
61
  )
56
62
  parser.add_argument("--interfaces", action="append", help="the interfaces to export")
57
63
  parser.add_argument(
@@ -83,7 +89,13 @@ def main():
83
89
  )
84
90
  parser.add_argument("--package", help="the application package")
85
91
  fill_arguments(parser)
86
- options = parser.parse_args()
92
+ return parser
93
+
94
+
95
+ def main() -> None:
96
+ """Run the command."""
97
+
98
+ options = get_argparser().parse_args()
87
99
  settings = get_appsettings(options)
88
100
 
89
101
  with transaction.manager:
@@ -93,36 +105,52 @@ def main():
93
105
 
94
106
 
95
107
  class Import:
96
- def __init__(self, session, settings, options):
108
+ """
109
+ To import all the themes, layer groups and layers names into the full-text search table.
110
+
111
+ Done by interface and by language.
112
+ """
113
+
114
+ def __init__(self, session: Session, settings: pyramid.config.Configurator, options: Namespace):
97
115
  self.options = options
98
116
  self.imported: Set[Any] = set()
99
117
  package = settings["package"]
100
118
 
101
119
  self.fts_languages = settings["fulltextsearch"]["languages"]
102
120
  self.languages = settings["available_locale_names"]
121
+ self.fts_normalizer = Normalize(settings["fulltextsearch"])
122
+
123
+ fts_missing_langs = [lang for lang in self.languages if lang not in self.fts_languages]
124
+ if fts_missing_langs:
125
+ msg = f"Keys {fts_missing_langs} are missing in fulltextsearch languages configuration."
126
+ if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
127
+ print(colorize(msg, Color.RED))
128
+ self.languages = [lang for lang in self.languages if lang in self.fts_languages]
129
+ else:
130
+ raise KeyError(KeyError(msg))
103
131
 
104
132
  # must be done only once we have loaded the project config
105
133
  from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
106
134
  FullTextSearch,
107
135
  Interface,
108
- Theme,
109
136
  Role,
137
+ Theme,
110
138
  )
111
139
 
112
140
  self.session = session
113
- self.session.execute(FullTextSearch.__table__.delete().where(FullTextSearch.from_theme)) # noqa
141
+ self.session.execute(FullTextSearch.__table__.delete().where(FullTextSearch.from_theme))
114
142
 
115
143
  self._: Dict[str, gettext.NullTranslations] = {}
116
144
  for lang in self.languages:
117
145
  try:
118
146
  self._[lang] = gettext.translation(
119
- "{}_geoportal-client".format(package),
147
+ f"{package}_geoportal-client",
120
148
  options.locale_folder.format(package=package),
121
149
  [lang],
122
150
  )
123
151
  except OSError as e:
124
152
  self._[lang] = gettext.NullTranslations()
125
- print("Warning: {} (language: {})".format(e, lang))
153
+ print(f"Warning: {e} (language: {lang})")
126
154
 
127
155
  query = self.session.query(Interface)
128
156
  if options.interfaces is not None:
@@ -144,7 +172,13 @@ class Import:
144
172
  for theme in self.session.query(Theme).all():
145
173
  self._add_theme(theme, role)
146
174
 
147
- def _add_fts(self, item, interface, action, role):
175
+ def _add_fts(
176
+ self,
177
+ item: "c2cgeoportal_commons.models.main.TreeItem",
178
+ interface: "c2cgeoportal_commons.models.main.Interface",
179
+ action: str,
180
+ role: Optional["c2cgeoportal_commons.models.main.Role"],
181
+ ) -> None:
148
182
  from c2cgeoportal_commons.models.main import FullTextSearch # pylint: disable=import-outside-toplevel
149
183
 
150
184
  key = (
@@ -161,12 +195,22 @@ class Import:
161
195
  fts.interface = interface
162
196
  fts.lang = lang
163
197
  fts.public = role is None
164
- fts.ts = func.to_tsvector(self.fts_languages[lang], fts.label)
198
+ fts.ts = func.to_tsvector(
199
+ self.fts_languages[lang],
200
+ " ".join(
201
+ [self.fts_normalizer(self._[lang].gettext(item.name))]
202
+ + [v.strip() for m in item.get_metadata("searchAlias") for v in m.value.split(",")]
203
+ ),
204
+ )
165
205
  fts.actions = [{"action": action, "data": item.name}]
166
206
  fts.from_theme = True
167
207
  self.session.add(fts)
168
208
 
169
- def _add_theme(self, theme, role=None):
209
+ def _add_theme(
210
+ self,
211
+ theme: "c2cgeoportal_commons.models.main.Theme",
212
+ role: Optional["c2cgeoportal_commons.models.main.Role"] = None,
213
+ ) -> None:
170
214
  fill = False
171
215
  for interface in self.interfaces:
172
216
  if interface in theme.interfaces:
@@ -180,13 +224,29 @@ class Import:
180
224
  if role is None or theme.id not in self.public_theme[interface.id]:
181
225
  self._add_fts(theme, interface, "add_theme", role)
182
226
 
183
- def _add_block(self, group, interface, role):
227
+ def _add_block(
228
+ self,
229
+ group: "c2cgeoportal_commons.models.main.LayerGroup",
230
+ interface: "c2cgeoportal_commons.models.main.Interface",
231
+ role: Optional["c2cgeoportal_commons.models.main.Role"],
232
+ ) -> bool:
184
233
  return self._add_group(group, interface, self.options.blocks, role)
185
234
 
186
- def _add_folder(self, group, interface, role):
235
+ def _add_folder(
236
+ self,
237
+ group: "c2cgeoportal_commons.models.main.LayerGroup",
238
+ interface: "c2cgeoportal_commons.models.main.Interface",
239
+ role: Optional["c2cgeoportal_commons.models.main.Role"],
240
+ ) -> bool:
187
241
  return self._add_group(group, interface, self.options.folders, role)
188
242
 
189
- def _add_group(self, group, interface, export, role):
243
+ def _add_group(
244
+ self,
245
+ group: "c2cgeoportal_commons.models.main.LayerGroup",
246
+ interface: "c2cgeoportal_commons.models.main.Interface",
247
+ export: bool,
248
+ role: Optional["c2cgeoportal_commons.models.main.Role"],
249
+ ) -> bool:
190
250
  from c2cgeoportal_commons.models.main import LayerGroup # pylint: disable=import-outside-toplevel
191
251
 
192
252
  fill = False
@@ -206,13 +266,20 @@ class Import:
206
266
  return fill
207
267
 
208
268
  @staticmethod
209
- def _layer_visible(layer, role):
269
+ def _layer_visible(
270
+ layer: "c2cgeoportal_commons.models.main.Layer", role: "c2cgeoportal_commons.models.main.Role"
271
+ ) -> bool:
210
272
  for restrictionarea in layer.restrictionareas:
211
273
  if role in restrictionarea.roles:
212
274
  return True
213
275
  return False
214
276
 
215
- def _add_layer(self, layer, interface, role):
277
+ def _add_layer(
278
+ self,
279
+ layer: "c2cgeoportal_commons.models.main.Layer",
280
+ interface: "c2cgeoportal_commons.models.main.Interface",
281
+ role: Optional["c2cgeoportal_commons.models.main.Role"],
282
+ ) -> bool:
216
283
  if role is None:
217
284
  fill = layer.public and interface in layer.interfaces
218
285
  else:
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2012-2020, Camptocamp SA
1
+ # Copyright (c) 2012-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -30,45 +28,53 @@
30
28
  import argparse
31
29
  import binascii
32
30
  import json
33
- import os
34
31
  import sys
35
32
  import time
33
+ from typing import cast
36
34
 
37
35
  from Crypto.Cipher import AES # nosec
38
- import c2c.template
36
+ from Crypto.Cipher.ChaCha20_Poly1305 import ChaCha20Poly1305Cipher # nosec
37
+
38
+ from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings
39
39
 
40
40
 
41
- def create_token(aeskey, user, password, valid):
41
+ def create_token(aeskey: str, user: str, password: str, valid: bool) -> str:
42
+ """Create the authenticated URL token."""
42
43
  auth = {"u": user, "p": password, "t": int(time.time()) + valid * 3600 * 24}
43
44
 
44
45
  if aeskey is None:
45
46
  print("urllogin is not configured")
46
47
  sys.exit(1)
47
- cipher = AES.new(aeskey.encode("ascii"), AES.MODE_EAX)
48
+ cipher = cast(ChaCha20Poly1305Cipher, AES.new(aeskey.encode("ascii"), AES.MODE_EAX))
48
49
  data = json.dumps(auth)
49
50
  mod_len = len(data) % 16
50
51
  if mod_len != 0:
51
52
  data += "".join([" " for i in range(16 - mod_len)])
52
- ciphertext, tag = cipher.encrypt_and_digest(data.encode("utf-8")) # type: ignore
53
- return binascii.hexlify(cipher.nonce + tag + ciphertext).decode("ascii") # type: ignore
53
+ ciphertext, tag = cipher.encrypt_and_digest(data.encode("utf-8"))
54
+ return binascii.hexlify(cipher.nonce + tag + ciphertext).decode("ascii")
55
+
54
56
 
57
+ def get_argparser() -> argparse.ArgumentParser:
58
+ """Get the argument parser for this script."""
55
59
 
56
- def main():
57
60
  parser = argparse.ArgumentParser(description="Generate an auth token")
61
+ fill_arguments(parser)
58
62
  parser.add_argument("user", help="The username")
59
63
  parser.add_argument("password", help="The password")
60
64
  parser.add_argument("valid", type=int, default=1, nargs="?", help="Is valid for, in days")
65
+ return parser
66
+
67
+
68
+ def main() -> None:
69
+ """Run the command."""
61
70
 
62
- args = parser.parse_args()
63
- if os.path.exists("geoportal/config.yaml"):
64
- config = c2c.template.get_config("geoportal/config.yaml")
65
- else:
66
- config = c2c.template.get_config("config.yaml")
67
- urllogin = config.get("urllogin", {})
71
+ args = get_argparser().parse_args()
72
+ settings = get_appsettings(args)
73
+ urllogin = settings.get("urllogin", {})
68
74
  aeskey = urllogin.get("aes_key")
69
75
  auth_enc = create_token(aeskey, args.user, args.password, args.valid)
70
76
 
71
- print(("Use: auth={}".format(auth_enc)))
77
+ print(f"Use: auth={auth_enc}")
72
78
 
73
79
 
74
80
  if __name__ == "__main__":
@@ -1,86 +1,90 @@
1
- <!DOCTYPE HTML>
1
+ <!DOCTYPE html>
2
2
  <html lang="${lang}">
3
- <head>
4
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5
- <meta name="Content-Language" content="${lang}" />
6
- <title>${_('Login to Geoportal Application')}</title>
7
- <style>
8
- body {
9
- background: #444444;
10
- font-family: Helvetica, Arial, sans-serif;
11
- }
12
- * {
13
- padding: 0;
14
- margin: 0;
15
- }
16
- div#content {
17
- background: #F5F5EF;
18
- padding: 20px 30px;
19
- width: 330px;
20
- margin: 100px auto auto auto;
21
- -webkit-border-radius: 10px;
22
- border-radius: 10px;
23
- }
24
- td.field {
25
- padding-top: 20px;
26
- }
27
- td.field p {
28
- font-weight: bold;
29
- color: #444444;
30
- font-size: 80%;
31
- margin-bottom: 3px;
32
- }
33
- td.field input {
34
- -webkit-border-radius: 2px;
35
- border-radius: 2px;
36
- border: solid 1px #444444;
37
- padding: 3px 6px;
38
- font-size: 110%;
39
- width: 250px;
40
- }
41
- td.buttons {
42
- padding-top: 25px;
43
- padding-bottom: 20px;
44
- text-align: right;
45
- }
46
- td.buttons input {
47
- padding: 1px 6px;
48
- font-weight: bold;
49
- color: #444444;
50
- }
51
- </style>
52
- </head>
53
- <body>
54
- <div id="content">
55
- <form method="POST" id="loginForm" action="${request.route_url('login', _query=dict(came_from=came_from))}">
56
- <table style="margin-left: auto; margin-right: auto;">
57
- <tbody>
58
- <tr>
59
- <td class="field"><p>
60
- <label for="email">${_('Username')}</label></p>
61
- <input id="login" name="login" type="text">
62
- </td>
63
- </tr>
64
- <tr>
65
- <td class="field"><p>
66
- <label for="password">${_('Password')}</label></p>
67
- <input id="password" name="password" type="password">
68
- </td>
69
- </tr>
70
- % if two_fa:
71
- <tr>
72
- <td class="field">
73
- <p><label for="otp">${_('Authentication code')}</label></p>
74
- <input id="otp" name="otp" type="text" autocomplete="off">
75
- </td>
76
- </tr>
77
- % endif
78
- <tr>
79
- <td class="buttons"><input tabindex="4" value="${_('Login')}" type="submit"></td>
80
- </tr>
81
- </tbody>
82
- </table>
83
- </form>
84
- </div>
85
- </body>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5
+ <meta name="Content-Language" content="${lang}" />
6
+ <title>${_('Login to Geoportal Application')}</title>
7
+ <style>
8
+ body {
9
+ background: #444444;
10
+ font-family: Helvetica, Arial, sans-serif;
11
+ }
12
+ * {
13
+ padding: 0;
14
+ margin: 0;
15
+ }
16
+ div#content {
17
+ background: #f5f5ef;
18
+ padding: 20px 30px;
19
+ width: 330px;
20
+ margin: 100px auto auto auto;
21
+ -webkit-border-radius: 10px;
22
+ border-radius: 10px;
23
+ }
24
+ td.field {
25
+ padding-top: 20px;
26
+ }
27
+ td.field p {
28
+ font-weight: bold;
29
+ color: #444444;
30
+ font-size: 80%;
31
+ margin-bottom: 3px;
32
+ }
33
+ td.field input {
34
+ -webkit-border-radius: 2px;
35
+ border-radius: 2px;
36
+ border: solid 1px #444444;
37
+ padding: 3px 6px;
38
+ font-size: 110%;
39
+ width: 250px;
40
+ }
41
+ td.buttons {
42
+ padding-top: 25px;
43
+ padding-bottom: 20px;
44
+ text-align: right;
45
+ }
46
+ td.buttons input {
47
+ padding: 1px 6px;
48
+ font-weight: bold;
49
+ color: #444444;
50
+ }
51
+ </style>
52
+ </head>
53
+ <body>
54
+ <div id="content">
55
+ <form method="POST" id="loginForm" action="${request.route_url('login', _query=login_params)}">
56
+ <table style="margin-left: auto; margin-right: auto">
57
+ <tbody>
58
+ <tr>
59
+ <td class="field">
60
+ <p>
61
+ <label for="email">${_('Username')}</label>
62
+ </p>
63
+ <input id="login" name="login" type="text" />
64
+ </td>
65
+ </tr>
66
+ <tr>
67
+ <td class="field">
68
+ <p>
69
+ <label for="password">${_('Password')}</label>
70
+ </p>
71
+ <input id="password" name="password" type="password" />
72
+ </td>
73
+ </tr>
74
+ % if two_fa:
75
+ <tr>
76
+ <td class="field">
77
+ <p><label for="otp">${_('Authentication code')}</label></p>
78
+ <input id="otp" name="otp" type="text" autocomplete="off" />
79
+ </td>
80
+ </tr>
81
+ % endif
82
+ <tr>
83
+ <td class="buttons"><input tabindex="4" value="${_('Login')}" type="submit" /></td>
84
+ </tr>
85
+ </tbody>
86
+ </table>
87
+ </form>
88
+ </div>
89
+ </body>
86
90
  </html>
@@ -0,0 +1,62 @@
1
+ <!DOCTYPE html>
2
+ <html lang="${lang}">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5
+ <meta name="Content-Language" content="${lang}" />
6
+ <title>${_('Login to Geoportal Application')}</title>
7
+ <style>
8
+ body {
9
+ background: #444444;
10
+ font-family: Helvetica, Arial, sans-serif;
11
+ }
12
+ * {
13
+ padding: 0;
14
+ margin: 0;
15
+ }
16
+ div#content {
17
+ background: #f5f5ef;
18
+ padding: 20px 30px;
19
+ width: 330px;
20
+ margin: 100px auto auto auto;
21
+ -webkit-border-radius: 10px;
22
+ border-radius: 10px;
23
+ }
24
+ td.field {
25
+ padding-top: 20px;
26
+ }
27
+ td.field p {
28
+ font-weight: bold;
29
+ color: #444444;
30
+ font-size: 80%;
31
+ margin-bottom: 3px;
32
+ }
33
+ td.field input {
34
+ -webkit-border-radius: 2px;
35
+ border-radius: 2px;
36
+ border: solid 1px #444444;
37
+ padding: 3px 6px;
38
+ font-size: 110%;
39
+ width: 250px;
40
+ }
41
+ td.buttons {
42
+ padding-top: 25px;
43
+ padding-bottom: 20px;
44
+ text-align: right;
45
+ }
46
+ td.buttons input {
47
+ padding: 1px 6px;
48
+ font-weight: bold;
49
+ color: #444444;
50
+ }
51
+ </style>
52
+ </head>
53
+ <body>
54
+ <div id="content">
55
+ <p>
56
+ ${_('The user is not correctly initialized you should login in the main application and try '
57
+ 'again.')}
58
+ </p>
59
+ <p><a href="${request.route_url('base')}">${_('Main application')}</a></p>
60
+ </div>
61
+ </body>
62
+ </html>
@@ -1,14 +1,12 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
3
  <html xmlns="http://www.w3.org/1999/xhtml">
6
- <head>
7
- <meta charset="UTF-8">
4
+ <head>
5
+ <meta charset="UTF-8" />
8
6
  <title>${title}</title>
9
- </head>
10
- <body>
7
+ </head>
8
+ <body>
11
9
  <h1>${title}</h1>
12
10
  <p>${_('my translation test')}</p>
13
- </body>
11
+ </body>
14
12
  </html>
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- # Copyright (c) 2011-2020, Camptocamp SA
3
+ # Copyright (c) 2011-2021, Camptocamp SA
4
4
  # All rights reserved.
5
5
 
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -27,17 +27,36 @@
27
27
  # of the authors and should not be interpreted as representing official policies,
28
28
  # either expressed or implied, of the FreeBSD Project.
29
29
 
30
+ from typing import Dict, List
30
31
 
32
+ import pyramid.config
33
+ import pyramid.request
31
34
  from pyramid.httpexceptions import HTTPFound
32
35
 
33
36
 
34
- def add_ending_slash(request):
37
+ def add_ending_slash(request: pyramid.request.Request) -> HTTPFound:
38
+ """Add an ending slash view."""
35
39
  return HTTPFound(location=request.path + "/")
36
40
 
37
41
 
38
- def add_redirect(config, name, from_, to):
39
- def redirect_view(request):
42
+ def add_redirect(config: pyramid.config.Configurator, name: str, from_: str, to: str) -> None:
43
+ """Add a redirect view."""
44
+
45
+ def redirect_view(request: pyramid.request.Request) -> HTTPFound:
40
46
  return HTTPFound(location=request.route_url(to))
41
47
 
42
48
  config.add_route(name, from_, request_method="GET")
43
49
  config.add_view(redirect_view, route_name=name)
50
+
51
+
52
+ def restrict_headers(headers: Dict[str, str], whitelist: List[str], blacklist: List[str]) -> Dict[str, str]:
53
+ """
54
+ Filter headers with a whitelist then a blacklist.
55
+
56
+ Some default pyramid headers will be added back by pyramid.
57
+ """
58
+ if len(whitelist) > 0:
59
+ headers = {key: value for key, value in headers.items() if key in whitelist}
60
+
61
+ headers = {key: value for key, value in headers.items() if key not in blacklist}
62
+ return headers
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2011-2020, Camptocamp SA
1
+ # Copyright (c) 2011-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -31,25 +29,29 @@
31
29
  import logging
32
30
  import re
33
31
 
32
+ import pyramid.request
33
+ import pyramid.response
34
34
  from pyramid.httpexceptions import HTTPFound
35
35
  from pyramid.view import view_config
36
36
 
37
+ from c2cgeoportal_commons.lib.url import Url
37
38
  from c2cgeoportal_geoportal.views.proxy import Proxy
38
39
 
39
40
  logger = logging.getLogger(__name__)
40
41
 
41
42
 
42
43
  class Dev(Proxy):
44
+ """All the development views."""
43
45
 
44
46
  THEME_RE = re.compile(r"/theme/.*$")
45
47
 
46
- def __init__(self, request):
48
+ def __init__(self, request: pyramid.request.Request):
47
49
  super().__init__(request)
48
50
  self.dev_url = self.request.registry.settings["devserver_url"]
49
51
 
50
- @view_config(route_name="dev")
51
- def dev(self):
52
+ @view_config(route_name="dev") # type: ignore
53
+ def dev(self) -> pyramid.response.Response:
52
54
  path = self.THEME_RE.sub("", self.request.path_info)
53
55
  if self.request.path.endswith("/dynamic.js"):
54
56
  return HTTPFound(location=self.request.route_url("dynamic", _query=self.request.params))
55
- return self._proxy_response("dev", "{}/{}".format(self.dev_url.rstrip("/"), path.lstrip("/")))
57
+ return self._proxy_response("dev", Url(f"{self.dev_url.rstrip('/')}/{path.lstrip('/')}"))