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) 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
@@ -27,8 +25,6 @@
27
25
  # of the authors and should not be interpreted as representing official policies,
28
26
  # either expressed or implied, of the FreeBSD Project.
29
27
 
30
- # pylint: disable=no-member
31
-
32
28
 
33
29
  import argparse
34
30
  import logging
@@ -40,7 +36,8 @@ from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings, get_
40
36
  LOG = logging.getLogger(__name__)
41
37
 
42
38
 
43
- def main():
39
+ def main() -> None:
40
+ """Create and populate the database tables."""
44
41
  parser = argparse.ArgumentParser(description="Create and populate the database tables.")
45
42
  fill_arguments(parser)
46
43
  options = parser.parse_args()
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2011-2020, Camptocamp SA
1
+ # Copyright (c) 2011-2023, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -27,32 +25,20 @@
27
25
  # of the authors and should not be interpreted as representing official policies,
28
26
  # either expressed or implied, of the FreeBSD Project.
29
27
 
30
- # pylint: disable=no-member
31
-
32
28
 
33
29
  import argparse
34
30
  import sys
31
+ from typing import cast
35
32
 
36
33
  import transaction
37
34
 
38
35
  from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings, get_session
39
36
 
40
37
 
41
- def main():
42
- """
43
- Emergency user create and password reset script
44
- example, reset toto password to foobar:
45
- docker-compose exec geoportal manage-users --password=foobar toto
46
- example, create user foo with password bar and role admin:
47
- docker-compose exec geoportal manage-users --create --rolename=role_admin --password=bar foo
48
-
49
- to get the options list, do:
50
- docker-compose exec geoportal manage-users --help
51
- """
38
+ def get_argparser() -> argparse.ArgumentParser:
39
+ """Get the argument parser for this script."""
52
40
 
53
- usage = """Usage: %prog [options] USERNAME
54
-
55
- Reset a user password.
41
+ usage = """Reset a user password.
56
42
  The username is used as password if the password is not provided with the corresponding option.
57
43
  User can be created if it does not exist yet."""
58
44
 
@@ -67,12 +53,27 @@ User can be created if it does not exist yet."""
67
53
  )
68
54
  parser.add_argument("--email", "-e", default=None, help="The user email")
69
55
  parser.add_argument("user", help="The user")
56
+ return parser
57
+
58
+
59
+ def main() -> None:
60
+ """
61
+ Emergency user create and password reset script example.
62
+
63
+ Reset toto password to foobar: docker-compose
64
+ exec geoportal manage-users --password=foobar toto example, create user foo with password bar and role
65
+ admin: docker-compose exec geoportal manage-users --create --rolename=role_admin --password=bar foo.
66
+
67
+ to get the options list, do: docker-compose exec geoportal manage-users --help
68
+ """
69
+
70
+ parser = get_argparser()
70
71
  options = parser.parse_args()
71
72
  username = options.user
72
73
  settings = get_appsettings(options)
73
74
 
74
75
  with transaction.manager:
75
- sess = get_session(settings, transaction.manager)
76
+ session = get_session(settings, transaction.manager)
76
77
 
77
78
  # Must be done only once we have loaded the project config
78
79
  from c2cgeoportal_commons.models.main import Role # pylint: disable=import-outside-toplevel
@@ -81,13 +82,13 @@ User can be created if it does not exist yet."""
81
82
  print("\n")
82
83
 
83
84
  # Check that user exists
84
- query = sess.query(User).filter_by(username=username)
85
+ query = session.query(User).filter_by(username=username)
85
86
 
86
87
  result = query.count()
87
88
  if result == 0:
88
89
  if not options.create:
89
90
  # If doesn't exist and no -c option, throw error
90
- print("User {} does not exist in database".format(username))
91
+ print(f"User {username} does not exist in database")
91
92
  sys.exit(1)
92
93
  else:
93
94
  if options.password is None:
@@ -96,46 +97,40 @@ User can be created if it does not exist yet."""
96
97
  parser.error("The email is mandatory on user creation")
97
98
 
98
99
  # Get roles
99
- query_role = sess.query(Role).filter(Role.name == options.rolename)
100
+ query_role = session.query(Role).filter(Role.name == options.rolename)
100
101
 
101
102
  if query_role.count() == 0:
102
103
  # Role not found in db?
103
- print("Role matching {} does not exist in database".format(options.rolename))
104
+ print(f"Role matching {options.rolename} does not exist in database")
104
105
  sys.exit(1)
105
106
 
106
107
  role = query_role.first()
107
108
 
108
109
  user = User(
109
110
  username=username,
110
- password=options.password,
111
- email=options.email,
111
+ password=cast(str, options.password),
112
+ email=cast(str, options.email),
112
113
  settings_role=role,
113
114
  roles=[role],
114
115
  )
115
- sess.add(user)
116
-
117
- print(
118
- (
119
- "User {} created with password {} and role {}".format(
120
- username, options.password, options.rolename
121
- )
122
- )
123
- )
116
+ session.add(user)
117
+
118
+ print(f"User {username} created with password {options.password} and role {options.rolename}")
124
119
 
125
120
  else:
126
121
  # If user exists (assuming username are unique)
127
122
  user = query.first()
128
123
 
129
124
  if options.password is not None:
130
- print("Password set to: {}".format(options.password))
131
- user.password = "{}".format(options.password)
125
+ print(f"Password set to: {options.password}")
126
+ user.password = f"{options.password}"
132
127
 
133
128
  if options.email is not None:
134
129
  user.email = options.email
135
130
 
136
- sess.add(user)
131
+ session.add(user)
137
132
 
138
- print("Password reset for user {}".format(username))
133
+ print(f"Password reset for user {username}")
139
134
 
140
135
 
141
136
  if __name__ == "__main__":
@@ -0,0 +1,312 @@
1
+ # Copyright (c) 2021-2024, 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 json
30
+ import os
31
+ import re
32
+ import subprocess
33
+ import sys
34
+ from argparse import ArgumentParser
35
+ from typing import Any, Dict, List, Optional, Type, Union, cast
36
+
37
+ import pkg_resources
38
+ import requests
39
+ import yaml
40
+ from cookiecutter.log import configure_logger
41
+ from cookiecutter.main import cookiecutter
42
+
43
+ _bad_chars_re = re.compile("[^a-zA-Z0-9_]")
44
+ SCAFFOLDS_DIR = pkg_resources.resource_filename("c2cgeoportal_geoportal", "scaffolds")
45
+
46
+
47
+ def get_argparser() -> ArgumentParser:
48
+ """Get the argument parser for this script."""
49
+
50
+ parser = ArgumentParser(
51
+ prog=sys.argv[0],
52
+ add_help=True,
53
+ description="Wrapper around cookiecutter that create appropriated context.",
54
+ )
55
+ parser.add_argument(
56
+ "-s",
57
+ "--scaffold",
58
+ dest="scaffold_names",
59
+ action="append",
60
+ help=("Add a scaffold to the create process " "(multiple -s args accepted)"),
61
+ )
62
+ parser.add_argument(
63
+ "-l",
64
+ "--list",
65
+ dest="list",
66
+ action="store_true",
67
+ help="List all available scaffold names",
68
+ )
69
+ parser.add_argument(
70
+ "--package-name",
71
+ dest="package_name",
72
+ action="store",
73
+ help="Package name to use. The name provided is "
74
+ "assumed to be a valid Python package name, and "
75
+ "will not be validated. By default the package "
76
+ "name is derived from the value of "
77
+ "output_directory.",
78
+ )
79
+ parser.add_argument(
80
+ "--overwrite",
81
+ dest="overwrite",
82
+ action="store_true",
83
+ help="Always overwrite",
84
+ )
85
+ parser.add_argument(
86
+ "output_directory",
87
+ nargs="?",
88
+ default=None,
89
+ help="The directory where the project will be " "created.",
90
+ )
91
+ return parser
92
+
93
+
94
+ def main() -> int:
95
+ """Entry point to run PCreateCommand."""
96
+ command = PCreateCommand(sys.argv)
97
+ try:
98
+ return command.run()
99
+ except KeyboardInterrupt: # pragma: no cover
100
+ return 1
101
+
102
+
103
+ class PCreateCommand:
104
+ """
105
+ Wrapper around cookiecutter with appropriated context creator for our scaffolds.
106
+
107
+ This is a port of Pyramid 1 PCreateCommand using cookiecutter as a backend.
108
+ """
109
+
110
+ def __init__(self, argv: List[str], quiet: bool = False) -> None:
111
+ self.quiet = quiet
112
+ self.parser = get_argparser()
113
+ self.args = self.parser.parse_args(argv[1:])
114
+ self.scaffolds = self.all_scaffolds()
115
+
116
+ def run(self) -> int:
117
+ if self.args.list:
118
+ return self.show_scaffolds()
119
+ if not self.args.scaffold_names and not self.args.output_directory:
120
+ if not self.quiet: # pragma: no cover
121
+ self.parser.print_help()
122
+ self.out("")
123
+ self.show_scaffolds()
124
+ return 2
125
+
126
+ return self.render_scaffolds()
127
+
128
+ @property
129
+ def output_path(self) -> str:
130
+ return cast(str, os.path.abspath(os.path.normpath(self.args.output_directory)))
131
+
132
+ def render_scaffolds(self) -> int:
133
+ verbose = True
134
+ debug_file = None
135
+ configure_logger(stream_level="DEBUG" if verbose else "INFO", debug_file=debug_file)
136
+
137
+ context = self.get_context()
138
+
139
+ for scaffold_name in self.args.scaffold_names:
140
+ # Needed to be backward compatible for the `test-upgrade init` command
141
+ if scaffold_name.startswith("c2cgeoportal_"):
142
+ scaffold_name = scaffold_name[len("c2cgeoportal_") :]
143
+ self.out(f"Rendering scaffold: {scaffold_name}")
144
+ cookiecutter(
145
+ template=os.path.join(SCAFFOLDS_DIR, scaffold_name),
146
+ extra_context=context,
147
+ no_input=True,
148
+ overwrite_if_exists=self.args.overwrite,
149
+ output_dir=os.path.dirname(self.output_path),
150
+ )
151
+ return 0
152
+
153
+ def show_scaffolds(self) -> int:
154
+ scaffolds = sorted(self.scaffolds)
155
+ if scaffolds:
156
+ self.out("Available scaffolds:")
157
+ for scaffold in scaffolds:
158
+ self.out(f" {scaffold}")
159
+ else:
160
+ self.out("No scaffolds available")
161
+ return 0
162
+
163
+ @staticmethod
164
+ def all_scaffolds() -> List[str]:
165
+ return os.listdir(SCAFFOLDS_DIR)
166
+
167
+ def out(self, msg: str) -> None:
168
+ if not self.quiet:
169
+ print(msg)
170
+
171
+ def get_context(self) -> Dict[str, Union[str, int]]:
172
+ output_dir = self.output_path
173
+ project_name = os.path.basename(output_dir)
174
+ if self.args.package_name is None:
175
+ pkg_name = _bad_chars_re.sub("", project_name.lower().replace("-", "_"))
176
+ else:
177
+ pkg_name = self.args.package_name
178
+
179
+ context: Dict[str, Union[str, int]] = {
180
+ "project": project_name,
181
+ "package": pkg_name,
182
+ "authtkt_secret": gen_authtkt_secret(),
183
+ }
184
+ context.update(self.read_project_file())
185
+ if os.environ.get("CI") == "true":
186
+ context["authtkt_secret"] = ( # nosec
187
+ "io7heoDui8xaikie1rushaeGeiph8Bequei6ohchaequob6viejei0xooWeuvohf"
188
+ )
189
+
190
+ self.get_var(context, "srid", "Spatial Reference System Identifier (e.g. 2056): ", int)
191
+ srid = cast(int, context["srid"])
192
+ extent = self.epsg2bbox(srid)
193
+ self.get_var(
194
+ context,
195
+ "extent",
196
+ (
197
+ f"Extent (minx miny maxx maxy): in EPSG: {srid} projection, default is "
198
+ f"[{extent[0]} {extent[1]} {extent[2]} {extent[3]}]: "
199
+ if extent
200
+ else f"Extent (minx miny maxx maxy): in EPSG: {srid} projection: "
201
+ ),
202
+ )
203
+ match = re.match(
204
+ r"([\d.]+)[,; ] *([\d.]+)[,; ] *([\d.]+)[,; ] *([\d.]+)",
205
+ cast(str, context["extent"]),
206
+ )
207
+ if match is not None:
208
+ extent = [match.group(n + 1) for n in range(4)]
209
+ assert extent is not None
210
+ context["extent"] = ",".join(extent)
211
+ context["extent_mapserver"] = " ".join(extent)
212
+
213
+ if context["package"] == "site":
214
+ raise ValueError(
215
+ "Sorry, you may not name your package 'site'. "
216
+ "The package name 'site' has a special meaning in "
217
+ "Python. Please name it anything except 'site'."
218
+ )
219
+
220
+ package_logger = context["package"]
221
+ if package_logger == "root":
222
+ # Rename the app logger in the rare case a project
223
+ # is named "root"
224
+ package_logger = "app"
225
+ context["package_logger"] = package_logger
226
+ context["geomapfish_version"] = os.environ["VERSION"]
227
+ # Used in the Docker files to shoos the version of the build image
228
+ context["geomapfish_version_tag"] = "GEOMAPFISH_VERSION"
229
+ context["geomapfish_version_tag_env"] = "${GEOMAPFISH_VERSION}"
230
+ geomapfish_major_version_tag = (
231
+ "GEOMAPFISH_VERSION"
232
+ if context.get("unsafe_long_version", False)
233
+ else "GEOMAPFISH_MAIN_MINOR_VERSION"
234
+ )
235
+ # Used in the Docker files to shoos the version of the run image
236
+ context["geomapfish_major_version_tag"] = geomapfish_major_version_tag
237
+ context["geomapfish_major_version_tag_env"] = "${" + geomapfish_major_version_tag + "}"
238
+ context["geomapfish_main_version"] = os.environ["MAJOR_VERSION"]
239
+ context["geomapfish_main_version_dash"] = os.environ["MAJOR_VERSION"].replace(".", "-")
240
+ context["geomapfish_main_minor_version"] = os.environ["MAJOR_MINOR_VERSION"]
241
+
242
+ return context
243
+
244
+ def read_project_file(self) -> Dict[str, Union[str, int]]:
245
+ project_file = os.path.join(self.output_path, "project.yaml")
246
+ if os.path.exists(project_file):
247
+ with open(project_file, encoding="utf8") as f:
248
+ project = yaml.safe_load(f)
249
+ return cast(Dict[str, Union[str, int]], project.get("template_vars", {}))
250
+ else:
251
+ return {}
252
+
253
+ @staticmethod
254
+ def get_var(
255
+ context: Dict[str, Any],
256
+ name: str,
257
+ prompt: str,
258
+ type_: Optional[Type[Any]] = None,
259
+ ) -> None:
260
+ if name.upper() in os.environ and os.environ[name.upper()] != "":
261
+ value = os.environ.get(name.upper())
262
+ else:
263
+ value = context.get(name)
264
+
265
+ if value is None:
266
+ value = input(prompt).strip()
267
+
268
+ if type_ is not None and not isinstance(value, type_):
269
+ try:
270
+ value = type_(value)
271
+ except ValueError:
272
+ print(f"The attribute {name}={value} is not a {type_}")
273
+ sys.exit(1)
274
+
275
+ context[name] = value
276
+
277
+ @staticmethod
278
+ def epsg2bbox(srid: int) -> Optional[List[str]]:
279
+ try:
280
+ r = requests.get(f"https://epsg.io/?format=json&q={srid}")
281
+ bbox = r.json()["results"][0]["bbox"]
282
+ r = requests.get(
283
+ "https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[1]},{bbox[0]}".format(
284
+ srid=srid, bbox=bbox
285
+ )
286
+ )
287
+ r1 = r.json()[0]
288
+ r = requests.get(
289
+ "https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[3]},{bbox[2]}".format(
290
+ srid=srid, bbox=bbox
291
+ )
292
+ )
293
+ r2 = r.json()[0]
294
+ return [r1["x"], r2["y"], r2["x"], r1["y"]]
295
+ except requests.RequestException:
296
+ print("Failed to establish a connection to epsg.io.")
297
+ except json.JSONDecodeError:
298
+ print("epsg.io doesn't return a correct json.")
299
+ except IndexError:
300
+ print("Unable to get the bbox")
301
+ except Exception as exception:
302
+ print(f"unexpected error: {str(exception)}")
303
+ return None
304
+
305
+
306
+ def gen_authtkt_secret() -> str:
307
+ """Generate a random authtkt secret."""
308
+ return subprocess.run(["pwgen", "64"], stdout=subprocess.PIPE, check=True).stdout.decode().strip()
309
+
310
+
311
+ if __name__ == "__main__": # pragma: no cover
312
+ sys.exit(main() or 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
@@ -31,19 +29,25 @@
31
29
  import gettext
32
30
  import os
33
31
  import sys
34
- from argparse import ArgumentParser
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
 
35
+ import pyramid.config
37
36
  import transaction
38
37
  from sqlalchemy import func
38
+ from sqlalchemy.orm.session import Session
39
39
 
40
- from c2cgeoportal_geoportal.lib.bashcolor import RED, colorize
40
+ from c2cgeoportal_geoportal.lib.bashcolor import Color, colorize
41
41
  from c2cgeoportal_geoportal.lib.fulltextsearch import Normalize
42
42
  from c2cgeoportal_geoportal.lib.i18n import LOCALE_PATH
43
43
  from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings, get_session
44
44
 
45
+ if TYPE_CHECKING:
46
+ import c2cgeoportal_commons.models.main
47
+
45
48
 
46
- def main():
49
+ def get_argparser() -> ArgumentParser:
50
+ """Get the argument parser for this script."""
47
51
  parser = ArgumentParser(
48
52
  prog=sys.argv[0],
49
53
  add_help=True,
@@ -53,7 +57,7 @@ def main():
53
57
  parser.add_argument(
54
58
  "--locale-folder",
55
59
  default=LOCALE_PATH,
56
- help="The folder where the locale files are stored (default to {})".format(LOCALE_PATH),
60
+ help=f"The folder where the locale files are stored (default is {LOCALE_PATH})",
57
61
  )
58
62
  parser.add_argument("--interfaces", action="append", help="the interfaces to export")
59
63
  parser.add_argument(
@@ -85,7 +89,13 @@ def main():
85
89
  )
86
90
  parser.add_argument("--package", help="the application package")
87
91
  fill_arguments(parser)
88
- options = parser.parse_args()
92
+ return parser
93
+
94
+
95
+ def main() -> None:
96
+ """Run the command."""
97
+
98
+ options = get_argparser().parse_args()
89
99
  settings = get_appsettings(options)
90
100
 
91
101
  with transaction.manager:
@@ -95,7 +105,13 @@ def main():
95
105
 
96
106
 
97
107
  class Import:
98
- 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):
99
115
  self.options = options
100
116
  self.imported: Set[Any] = set()
101
117
  package = settings["package"]
@@ -106,9 +122,9 @@ class Import:
106
122
 
107
123
  fts_missing_langs = [lang for lang in self.languages if lang not in self.fts_languages]
108
124
  if fts_missing_langs:
109
- msg = "Keys {} are missing in fulltextsearch languages configuration.".format(fts_missing_langs)
125
+ msg = f"Keys {fts_missing_langs} are missing in fulltextsearch languages configuration."
110
126
  if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
111
- print(colorize(msg, RED))
127
+ print(colorize(msg, Color.RED))
112
128
  self.languages = [lang for lang in self.languages if lang in self.fts_languages]
113
129
  else:
114
130
  raise KeyError(KeyError(msg))
@@ -122,19 +138,19 @@ class Import:
122
138
  )
123
139
 
124
140
  self.session = session
125
- self.session.execute(FullTextSearch.__table__.delete().where(FullTextSearch.from_theme)) # noqa
141
+ self.session.execute(FullTextSearch.__table__.delete().where(FullTextSearch.from_theme))
126
142
 
127
143
  self._: Dict[str, gettext.NullTranslations] = {}
128
144
  for lang in self.languages:
129
145
  try:
130
146
  self._[lang] = gettext.translation(
131
- "{}_geoportal-client".format(package),
147
+ f"{package}_geoportal-client",
132
148
  options.locale_folder.format(package=package),
133
149
  [lang],
134
150
  )
135
151
  except OSError as e:
136
152
  self._[lang] = gettext.NullTranslations()
137
- print("Warning: {} (language: {})".format(e, lang))
153
+ print(f"Warning: {e} (language: {lang})")
138
154
 
139
155
  query = self.session.query(Interface)
140
156
  if options.interfaces is not None:
@@ -156,7 +172,13 @@ class Import:
156
172
  for theme in self.session.query(Theme).all():
157
173
  self._add_theme(theme, role)
158
174
 
159
- 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:
160
182
  from c2cgeoportal_commons.models.main import FullTextSearch # pylint: disable=import-outside-toplevel
161
183
 
162
184
  key = (
@@ -177,14 +199,18 @@ class Import:
177
199
  self.fts_languages[lang],
178
200
  " ".join(
179
201
  [self.fts_normalizer(self._[lang].gettext(item.name))]
180
- + [v.strip() for m in item.get_metadatas("searchAlias") for v in m.value.split(",")]
202
+ + [v.strip() for m in item.get_metadata("searchAlias") for v in m.value.split(",")]
181
203
  ),
182
204
  )
183
205
  fts.actions = [{"action": action, "data": item.name}]
184
206
  fts.from_theme = True
185
207
  self.session.add(fts)
186
208
 
187
- 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:
188
214
  fill = False
189
215
  for interface in self.interfaces:
190
216
  if interface in theme.interfaces:
@@ -198,13 +224,29 @@ class Import:
198
224
  if role is None or theme.id not in self.public_theme[interface.id]:
199
225
  self._add_fts(theme, interface, "add_theme", role)
200
226
 
201
- 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:
202
233
  return self._add_group(group, interface, self.options.blocks, role)
203
234
 
204
- 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:
205
241
  return self._add_group(group, interface, self.options.folders, role)
206
242
 
207
- 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:
208
250
  from c2cgeoportal_commons.models.main import LayerGroup # pylint: disable=import-outside-toplevel
209
251
 
210
252
  fill = False
@@ -224,13 +266,20 @@ class Import:
224
266
  return fill
225
267
 
226
268
  @staticmethod
227
- def _layer_visible(layer, role):
269
+ def _layer_visible(
270
+ layer: "c2cgeoportal_commons.models.main.Layer", role: "c2cgeoportal_commons.models.main.Role"
271
+ ) -> bool:
228
272
  for restrictionarea in layer.restrictionareas:
229
273
  if role in restrictionarea.roles:
230
274
  return True
231
275
  return False
232
276
 
233
- 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:
234
283
  if role is None:
235
284
  fill = layer.public and interface in layer.interfaces
236
285
  else: