c2cgeoportal-geoportal 2.5.0.100__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 (224) hide show
  1. c2cgeoportal_geoportal/__init__.py +261 -130
  2. c2cgeoportal_geoportal/lib/__init__.py +74 -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 +127 -97
  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 +102 -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 +162 -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 +67 -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 +110 -0
  96. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +114 -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 +1160 -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 +1410 -0
  105. c2cgeoportal_geoportal/scripts/__init__.py +18 -32
  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 +71 -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 +70 -54
  129. c2cgeoportal_geoportal/views/profile.py +25 -24
  130. c2cgeoportal_geoportal/views/proxy.py +100 -70
  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.156.dist-info}/METADATA +17 -11
  138. c2cgeoportal_geoportal-2.7.1.156.dist-info/RECORD +185 -0
  139. {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.156.dist-info}/WHEEL +1 -1
  140. {c2cgeoportal_geoportal-2.5.0.100.dist-info → c2cgeoportal_geoportal-2.7.1.156.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.156.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2011-2020, Camptocamp SA
1
+ # Copyright (c) 2011-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -32,17 +30,21 @@ import logging
32
30
  import os
33
31
  import subprocess
34
32
  from time import sleep
35
- from typing import Dict
33
+ from typing import Any, Dict, List, Mapping, Optional, Union, cast
36
34
  from urllib.parse import urljoin
37
35
 
38
36
  import c2cwsgiutils.health_check
37
+ import pyramid.config
38
+ import pyramid.request
39
39
  import requests
40
40
 
41
41
  LOG = logging.getLogger(__name__)
42
42
 
43
43
 
44
- def build_url(name, path, request, headers=None):
45
- """ Build an URL and headers for the checkers """
44
+ def build_url(
45
+ name: str, path: str, request: pyramid.request.Request, headers: Optional[Dict[str, str]] = None
46
+ ) -> Dict[str, Union[str, Dict[str, str]]]:
47
+ """Build an URL and headers for the checkers."""
46
48
  base_internal_url = request.registry.settings["checker"]["base_internal_url"]
47
49
  url = urljoin(base_internal_url, path)
48
50
 
@@ -55,7 +57,9 @@ def build_url(name, path, request, headers=None):
55
57
  return {"url": url, "headers": headers}
56
58
 
57
59
 
58
- def _build_headers(request, headers=None):
60
+ def _build_headers(
61
+ request: pyramid.request.Request, headers: Optional[Dict[str, str]] = None
62
+ ) -> Dict[str, str]:
59
63
  if headers is None:
60
64
  headers = {}
61
65
  headers["Cache-Control"] = "no-cache"
@@ -67,45 +71,43 @@ def _build_headers(request, headers=None):
67
71
  return headers
68
72
 
69
73
 
70
- def _routes(settings, health_check):
74
+ def _routes(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
71
75
  routes_settings = settings["routes"]
72
76
  for route in routes_settings["routes"]:
73
77
  if route.get("checker_name", route["name"]) not in routes_settings["disable"]:
74
78
  name = "checker_routes_" + route.get("checker_name", route["name"])
75
79
 
76
80
  class GetRequest:
77
- """
78
- Get the request information about the current route name
79
- """
81
+ """Get the request information about the current route name."""
80
82
 
81
- def __init__(self, route_name, type_):
83
+ def __init__(self, route_name: str, type_: str) -> None:
82
84
  self.route_name = route_name
83
85
  self.type = type_
84
86
 
85
- def __call__(self, request):
87
+ def __call__(self, request: pyramid.request.Request) -> Union[str, Dict[str, str]]:
86
88
  return build_url("route", request.route_path(self.route_name), request)[self.type]
87
89
 
88
90
  health_check.add_url_check(
89
- url=GetRequest(route["name"], "url"),
91
+ url=GetRequest(route["name"], "url"), # type: ignore
90
92
  name=name,
91
93
  params=route.get("params", None),
92
- headers=GetRequest(route["name"], "headers"),
94
+ headers=GetRequest(route["name"], "headers"), # type: ignore
93
95
  level=route["level"],
94
96
  timeout=30,
95
97
  )
96
98
 
97
99
 
98
- def _pdf3(settings, health_check):
100
+ def _pdf3(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
99
101
  print_settings = settings["print"]
100
102
  if "spec" not in print_settings:
101
103
  return
102
104
 
103
- def check(request):
105
+ def check(request: pyramid.request.Request) -> None:
104
106
  path = request.route_path("printproxy_report_create", format="pdf")
105
107
  url_headers = build_url("Check the printproxy request (create)", path, request)
106
108
 
107
109
  session = requests.session()
108
- resp = session.post(json=print_settings["spec"], timeout=30, **url_headers)
110
+ resp = session.post(json=print_settings["spec"], timeout=30, **url_headers) # type: ignore
109
111
  resp.raise_for_status()
110
112
 
111
113
  job = resp.json()
@@ -115,44 +117,44 @@ def _pdf3(settings, health_check):
115
117
  done = False
116
118
  while not done:
117
119
  sleep(1)
118
- resp = session.get(timeout=30, **url_headers)
120
+ resp = session.get(timeout=30, **url_headers) # type: ignore
119
121
  resp.raise_for_status()
120
122
 
121
123
  status = resp.json()
122
124
  if "error" in status:
123
- raise Exception("Failed to do the printing: {0!s}".format(status["error"]))
125
+ raise Exception(f"Failed to do the printing: {status['error']}")
124
126
  done = status["done"]
125
127
 
126
128
  path = request.route_path("printproxy_report_get", ref=job["ref"])
127
129
  url_headers = build_url("Check the printproxy pdf retrieve", path, request)
128
- resp = session.get(timeout=30, **url_headers)
130
+ resp = session.get(timeout=30, **url_headers) # type: ignore
129
131
  resp.raise_for_status()
130
132
 
131
133
  health_check.add_custom_check(name="checker_print", check_cb=check, level=print_settings["level"])
132
134
 
133
135
 
134
- def _fts(settings, health_check):
136
+ def _fts(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
135
137
  fts_settings = settings["fulltextsearch"]
136
138
  if fts_settings.get("disable", False):
137
139
  return
138
140
 
139
- def get_both(request):
141
+ def get_both(request: pyramid.request.Request) -> Dict[str, Union[str, Dict[str, str]]]:
140
142
  return build_url("Check the fulltextsearch", request.route_path("fulltextsearch"), request)
141
143
 
142
- def check(_request, response):
144
+ def check(_request: pyramid.request.Request, response: pyramid.response.Response) -> None:
143
145
  assert response.json()["features"], "No result"
144
146
 
145
147
  health_check.add_url_check(
146
148
  name="checker_fulltextsearch",
147
- url=lambda r: get_both(r)["url"],
148
- headers=lambda r: get_both(r)["headers"],
149
+ url=lambda r: get_both(r)["url"], # type: ignore
150
+ headers=lambda r: get_both(r)["headers"], # type: ignore
149
151
  params={"query": fts_settings["search"], "limit": "1"},
150
152
  check_cb=check,
151
153
  level=fts_settings["level"],
152
154
  )
153
155
 
154
156
 
155
- def _themes_errors(settings, health_check):
157
+ def _themes_errors(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
156
158
  from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
157
159
  from c2cgeoportal_commons.models.main import Interface # pylint: disable=import-outside-toplevel
158
160
 
@@ -160,7 +162,7 @@ def _themes_errors(settings, health_check):
160
162
  default_params = themes_settings.get("params", {})
161
163
  interfaces_settings = themes_settings["interfaces"]
162
164
 
163
- def check(request):
165
+ def check(request: pyramid.request.Request) -> None:
164
166
  path = request.route_path("themes")
165
167
  session = requests.session()
166
168
  for (interface,) in DBSession.query(Interface.name).all():
@@ -171,52 +173,51 @@ def _themes_errors(settings, health_check):
171
173
 
172
174
  interface_url_headers = build_url("checker_themes " + interface, path, request)
173
175
 
174
- response = session.get(params=params, timeout=120, **interface_url_headers)
176
+ response = session.get(params=params, timeout=120, **interface_url_headers) # type: ignore
175
177
  response.raise_for_status()
176
178
 
177
179
  result = response.json()
178
180
  if result["errors"]:
179
181
  raise c2cwsgiutils.health_check.JsonCheckException(
180
- "Interface '{}' has error in Theme.".format(interface), result["errors"]
182
+ f"Interface '{interface}' has error in Theme.", result["errors"]
181
183
  )
182
184
 
183
185
  health_check.add_custom_check(name="checker_themes", check_cb=check, level=themes_settings["level"])
184
186
 
185
187
 
186
- def _lang_files(global_settings, settings, health_check):
188
+ def _lang_files(
189
+ global_settings: Dict[str, Any],
190
+ settings: Dict[str, Any],
191
+ health_check: c2cwsgiutils.health_check.HealthCheck,
192
+ ) -> None:
187
193
  lang_settings = settings["lang"]
188
194
  available_locale_names = global_settings["available_locale_names"]
189
195
 
190
196
  default_name = global_settings["default_locale_name"]
191
- assert (
192
- default_name in available_locale_names
193
- ), "default_locale_name '{}' not in available_locale_names: {}".format(
194
- default_name, ", ".join(available_locale_names)
197
+ assert default_name in available_locale_names, (
198
+ f"default_locale_name '{default_name}' not in available_locale_names: "
199
+ f"{', '.join(available_locale_names)}"
195
200
  )
196
201
 
197
202
  for type_ in lang_settings.get("files", []):
198
203
  for lang in available_locale_names:
199
204
  if type_ == "ngeo":
200
- url = "/etc/geomapfish/static/{lang}.json"
205
+ url = f"/etc/geomapfish/static/{lang}.json"
201
206
  else:
202
- raise Exception(
203
- "Your language type value '%s' is not valid, " "available values [ngeo]" % type_
204
- )
207
+ raise Exception(f"Your language type value '{type_}' is not valid, available values [ngeo]")
205
208
 
206
- name = "checker_lang_{}_{}".format(type_, lang)
209
+ name = f"checker_lang_{type_}_{lang}"
207
210
 
208
211
  class GetRequest:
209
- """
210
- Get the request information about the current route name
211
- """
212
+ """Get the request information about the current route name."""
212
213
 
213
- def __init__(self, name, url, lang, type_):
214
+ def __init__(self, name: str, url: str, lang: str, type_: str) -> None:
214
215
  self.name = name
215
216
  self.url = url
216
217
  self.lang = lang
217
218
  self.type = type_
218
219
 
219
- def __call__(self, request):
220
+ def __call__(self, request: pyramid.request.Request) -> Union[str, Mapping[str, str]]:
220
221
  return build_url(
221
222
  self.name,
222
223
  request.static_path(
@@ -227,27 +228,27 @@ def _lang_files(global_settings, settings, health_check):
227
228
 
228
229
  health_check.add_url_check(
229
230
  name=name,
230
- url=GetRequest(name, url, lang, "url"),
231
- headers=GetRequest(name, url, lang, "headers"),
231
+ url=GetRequest(name, url, lang, "url"), # type: ignore
232
+ headers=GetRequest(name, url, lang, "headers"), # type: ignore
232
233
  level=lang_settings["level"],
233
234
  )
234
235
 
235
236
 
236
- def _phantomjs(settings, health_check):
237
+ def _phantomjs(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
237
238
  phantomjs_settings = settings["phantomjs"]
238
239
  for route in phantomjs_settings["routes"]:
239
240
  if route.get("checker_name", route["name"]) in phantomjs_settings["disable"]:
240
241
  continue
241
242
 
242
243
  class _Check:
243
- def __init__(self, route):
244
+ def __init__(self, route: Dict[str, Any]) -> None:
244
245
  self.route = route
245
246
 
246
- def __call__(self, request):
247
+ def __call__(self, request: pyramid.request.Request) -> None:
247
248
  path = request.route_path(self.route["name"], _query=self.route.get("params", {}))
248
- url = build_url("Check", path, request)["url"]
249
+ url: str = cast(str, build_url("Check", path, request)["url"])
249
250
 
250
- cmd = ["node", "/usr/bin/check-example.js", url]
251
+ cmd: List[str] = ["node", "/usr/bin/check-example.js", url]
251
252
  env = dict(os.environ)
252
253
  for name, value in self.route.get("environment", {}).items():
253
254
  if isinstance(value, (list, dict)):
@@ -260,26 +261,23 @@ def _phantomjs(settings, health_check):
260
261
  subprocess.check_output(cmd, env=env, timeout=70)
261
262
  except subprocess.CalledProcessError as exception:
262
263
  raise Exception(
263
- "{} exit with code: {}\n{}".format(
264
- " ".join(exception.cmd), exception.returncode, exception.output.decode("utf-8")
265
- )
266
- )
264
+ f"{' '.join(exception.cmd)} exit with code: {exception.returncode}\n"
265
+ f"{exception.output.decode('utf-8')[:10000]}"
266
+ ) from exception
267
267
  except subprocess.TimeoutExpired as exception:
268
268
  raise Exception(
269
- """Timeout:
270
- command: {}
269
+ f"""Timeout:
270
+ command: {' '.join(exception.cmd)}
271
271
  output:
272
- {}""".format(
273
- " ".join(exception.cmd), exception.output.decode("utf-8")
274
- )
275
- )
272
+ {exception.output.decode('utf-8')}"""
273
+ ) from exception
276
274
 
277
275
  name = "checker_phantomjs_" + route.get("checker_name", route["name"])
278
276
  health_check.add_custom_check(name=name, check_cb=_Check(route), level=route["level"])
279
277
 
280
278
 
281
- def init(config, health_check):
282
- """ Init the ckeckers """
279
+ def init(config: pyramid.config.Configurator, health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
280
+ """Initialize the checkers."""
283
281
  global_settings = config.get_settings()
284
282
  if "checker" not in global_settings:
285
283
  return
@@ -0,0 +1,170 @@
1
+ # Copyright (c) 2012-2021, Camptocamp SA
2
+ # All rights reserved.
3
+
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+
7
+ # 1. Redistributions of source code must retain the above copyright notice, this
8
+ # list of conditions and the following disclaimer.
9
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ # this list of conditions and the following disclaimer in the documentation
11
+ # and/or other materials provided with the distribution.
12
+
13
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
+
24
+ # The views and conclusions contained in the software and documentation are those
25
+ # of the authors and should not be interpreted as representing official policies,
26
+ # either expressed or implied, of the FreeBSD Project.
27
+
28
+
29
+ import logging
30
+ from enum import Enum
31
+ from typing import Any, Dict, List, Optional, cast
32
+
33
+ import pyramid.request
34
+ import pyramid.response
35
+
36
+ from c2cgeoportal_geoportal.lib import is_intranet
37
+
38
+ _LOG = logging.getLogger(__name__)
39
+
40
+
41
+ class Cache(Enum):
42
+ """Enumeration for the possible cache values."""
43
+
44
+ # For responses that do not depend on authentication
45
+ PUBLIC = 0
46
+ # For responses that do not depends on authentication
47
+ # We use a small cache (e.g. 10s) instead of no cache to protect the service against too high traffic.
48
+ PUBLIC_NO = 1
49
+ # For responses that can depend on authentication
50
+ PRIVATE = 2
51
+ # See PUBLIC_NO and PRIVATE
52
+ PRIVATE_NO = 3
53
+
54
+
55
+ CORS_METHODS = "HEAD, GET, POST, PUT, DELETE"
56
+
57
+
58
+ def _set_cors_headers(
59
+ request: pyramid.request.Request,
60
+ response: pyramid.response.Response,
61
+ service_name: str,
62
+ service_headers_settings: Dict[str, Any],
63
+ credentials: bool,
64
+ ) -> None:
65
+ """Handle CORS requests, as specified in https://www.w3.org/TR/cors/."""
66
+ response.vary = (response.vary or ()) + ("Origin",)
67
+
68
+ if "Origin" not in request.headers:
69
+ return # Not a CORS request if this header is missing
70
+ origin = request.headers["Origin"]
71
+
72
+ if request.method == "OPTIONS" and "Access-Control-Request-Method" not in request.headers:
73
+ _LOG.warning("CORS preflight query missing the Access-Control-Request-Method header")
74
+ return
75
+
76
+ allowed_origins = cast(List[str], service_headers_settings.get("access_control_allow_origin", []))
77
+ if origin not in allowed_origins:
78
+ if "*" in allowed_origins:
79
+ origin = "*"
80
+ credentials = False # Force no credentials
81
+ else:
82
+ _LOG.warning("CORS query not allowed for origin=%s, service=%s", origin, service_name)
83
+ return
84
+
85
+ response.headers.update(
86
+ {"Access-Control-Allow-Origin": origin, "Access-Control-Allow-Methods": CORS_METHODS}
87
+ )
88
+
89
+ max_age = service_headers_settings.get("access_control_max_age", 3600)
90
+ response.headers["Access-Control-Max-Age"] = str(max_age)
91
+
92
+ if credentials:
93
+ response.headers["Access-Control-Allow-Credentials"] = "true"
94
+
95
+ if request.method != "OPTIONS":
96
+ return
97
+
98
+ response.cache_control.max_age = max_age
99
+
100
+ if not service_headers_settings or "access_control_allow_origin" not in service_headers_settings:
101
+ _LOG.warning("CORS query not configured for service=%s", service_name)
102
+ return
103
+
104
+ requested_headers = request.headers.get("Access-Control-Request-Headers", False)
105
+ if requested_headers:
106
+ # For the moment, we allow all requested headers
107
+ response.headers["Access-Control-Allow-Headers"] = requested_headers
108
+
109
+ # If we start using headers in responses, we'll have to add
110
+ # Access-Control-Expose-Headers
111
+
112
+
113
+ def _set_common_headers(
114
+ request: pyramid.request.Request,
115
+ response: pyramid.response.Response,
116
+ service_headers_settings: Dict[str, Dict[str, str]],
117
+ cache: Cache,
118
+ content_type: Optional[str],
119
+ ) -> pyramid.response.Response:
120
+ """Set the common headers."""
121
+
122
+ response.headers.update(service_headers_settings.get("headers", {}))
123
+
124
+ if cache in (Cache.PRIVATE, Cache.PRIVATE_NO):
125
+ response.vary = (response.vary or ()) + ("Cookie",)
126
+
127
+ maxage = (
128
+ service_headers_settings.get("cache_control_max_age", 3600)
129
+ if cache in (Cache.PUBLIC, Cache.PRIVATE)
130
+ else service_headers_settings.get("cache_control_max_age_nocache", 10)
131
+ )
132
+ response.cache_control.max_age = maxage
133
+ if maxage == 0:
134
+ response.cache_control.no_cache = True
135
+ response.cache_control.no_store = True
136
+ elif cache in (Cache.PUBLIC, Cache.PUBLIC_NO):
137
+ response.cache_control.public = True
138
+ elif cache in (Cache.PRIVATE, Cache.PRIVATE_NO):
139
+ if hasattr(request, "user") and request.user is not None or is_intranet(request):
140
+ response.cache_control.private = True
141
+ else:
142
+ response.cache_control.public = True
143
+ else:
144
+ raise Exception("Invalid cache type")
145
+
146
+ if content_type is not None:
147
+ response.content_type = content_type
148
+
149
+ return response
150
+
151
+
152
+ def set_common_headers(
153
+ request: pyramid.request.Request,
154
+ service_name: str,
155
+ cache: Cache,
156
+ response: pyramid.response.Response = None,
157
+ credentials: bool = True,
158
+ content_type: Optional[str] = None,
159
+ ) -> pyramid.response.Response:
160
+ """Set the common headers."""
161
+ if response is None:
162
+ response = request.response
163
+
164
+ headers_settings = request.registry.settings.get("headers", {})
165
+ service_headers_settings = headers_settings.get(service_name, {})
166
+
167
+ _set_cors_headers(request, response, service_name, service_headers_settings, credentials)
168
+ if request.method == "OPTIONS":
169
+ return response
170
+ return _set_common_headers(request, response, service_headers_settings, cache, content_type)