c2cgeoportal-geoportal 2.3.5.80__py3-none-any.whl → 2.9rc44__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 (198) hide show
  1. c2cgeoportal_geoportal/__init__.py +960 -0
  2. c2cgeoportal_geoportal/lib/__init__.py +256 -0
  3. c2cgeoportal_geoportal/lib/authentication.py +250 -0
  4. c2cgeoportal_geoportal/lib/bashcolor.py +46 -0
  5. c2cgeoportal_geoportal/lib/cacheversion.py +77 -0
  6. c2cgeoportal_geoportal/lib/caching.py +176 -0
  7. c2cgeoportal_geoportal/lib/check_collector.py +80 -0
  8. c2cgeoportal_geoportal/lib/checker.py +295 -0
  9. c2cgeoportal_geoportal/lib/common_headers.py +172 -0
  10. c2cgeoportal_geoportal/lib/dbreflection.py +266 -0
  11. c2cgeoportal_geoportal/lib/filter_capabilities.py +360 -0
  12. c2cgeoportal_geoportal/lib/fulltextsearch.py +50 -0
  13. c2cgeoportal_geoportal/lib/functionality.py +166 -0
  14. c2cgeoportal_geoportal/lib/headers.py +62 -0
  15. c2cgeoportal_geoportal/lib/i18n.py +38 -0
  16. c2cgeoportal_geoportal/lib/layers.py +132 -0
  17. c2cgeoportal_geoportal/lib/lingva_extractor.py +937 -0
  18. c2cgeoportal_geoportal/lib/loader.py +57 -0
  19. c2cgeoportal_geoportal/lib/metrics.py +117 -0
  20. c2cgeoportal_geoportal/lib/oauth2.py +1186 -0
  21. c2cgeoportal_geoportal/lib/oidc.py +304 -0
  22. c2cgeoportal_geoportal/lib/wmstparsing.py +353 -0
  23. c2cgeoportal_geoportal/lib/xsd.py +166 -0
  24. c2cgeoportal_geoportal/py.typed +0 -0
  25. c2cgeoportal_geoportal/resources.py +49 -0
  26. c2cgeoportal_geoportal/scaffolds/advance_create/ci/config.yaml +26 -0
  27. c2cgeoportal_geoportal/scaffolds/advance_create/cookiecutter.json +18 -0
  28. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.dockerignore +6 -0
  29. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.eslintrc.yaml +19 -0
  30. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml +30 -0
  31. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/Dockerfile +75 -0
  32. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/Makefile +6 -0
  33. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/alembic.ini +58 -0
  34. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/alembic.yaml +19 -0
  35. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/development.ini +121 -0
  36. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py +139 -0
  37. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/language_mapping +3 -0
  38. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/lingva-client.cfg +5 -0
  39. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/lingva-server.cfg +6 -0
  40. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/production.ini +38 -0
  41. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/requirements.txt +2 -0
  42. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/setup.py +25 -0
  43. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +41 -0
  44. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js +64 -0
  45. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.commons.js +11 -0
  46. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.config.js +22 -0
  47. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py +42 -0
  48. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py +10 -0
  49. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/dev.py +14 -0
  50. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py +8 -0
  51. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py +7 -0
  52. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/resources.py +11 -0
  53. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/api/index.js +12 -0
  54. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/js/{{cookiecutter.package}}module.js +25 -0
  55. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/subscribers.py +39 -0
  56. c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/views/__init__.py +0 -0
  57. c2cgeoportal_geoportal/scaffolds/advance_update/cookiecutter.json +18 -0
  58. c2cgeoportal_geoportal/scaffolds/advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile +121 -0
  59. c2cgeoportal_geoportal/scaffolds/create/cookiecutter.json +18 -0
  60. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.dockerignore +14 -0
  61. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.editorconfig +17 -0
  62. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/main.yaml +73 -0
  63. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/rebuild.yaml +50 -0
  64. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +66 -0
  65. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.gitignore +16 -0
  66. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.pre-commit-config.yaml +35 -0
  67. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierignore +1 -0
  68. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierrc.yaml +2 -0
  69. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Dockerfile +75 -0
  70. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +70 -0
  71. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/README.rst +29 -0
  72. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +179 -0
  73. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/config.yaml +22 -0
  74. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/docker-compose-check +25 -0
  75. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +2 -0
  76. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-db.yaml +24 -0
  77. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-lib.yaml +513 -0
  78. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-qgis.yaml +21 -0
  79. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.override.sample.yaml +65 -0
  80. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.yaml +121 -0
  81. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.default +102 -0
  82. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.project +69 -0
  83. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/vars.yaml +430 -0
  84. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/locale/en/LC_MESSAGES/{{cookiecutter.package}}_geoportal-client.po +6 -0
  85. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/desktop.css +0 -0
  86. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/iframe_api.css +0 -0
  87. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/mobile.css +0 -0
  88. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/banner_left.png +0 -0
  89. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/banner_right.png +0 -0
  90. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/blank.png +0 -0
  91. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-blue.png +0 -0
  92. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-gold.png +0 -0
  93. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker-green.png +0 -0
  94. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/images/markers/marker.png +0 -0
  95. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/robot.txt.tmpl +3 -0
  96. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/data/Readme.txt +69 -0
  97. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/data/TM_EUROPE_BORDERS-0.3.sql +70 -0
  98. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/demo.map.tmpl +224 -0
  99. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/Arial.ttf +0 -0
  100. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/Arialbd.ttf +0 -0
  101. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/Arialbi.ttf +0 -0
  102. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/Ariali.ttf +0 -0
  103. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/NotoSans-Bold.ttf +0 -0
  104. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/NotoSans-BoldItalic.ttf +0 -0
  105. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/NotoSans-Italic.ttf +0 -0
  106. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/NotoSans-Regular.ttf +0 -0
  107. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/Verdana.ttf +0 -0
  108. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/Verdanab.ttf +0 -0
  109. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/Verdanai.ttf +0 -0
  110. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts/Verdanaz.ttf +0 -0
  111. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/fonts.conf +12 -0
  112. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/mapserver.conf +16 -0
  113. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/mapserver.map.tmpl +87 -0
  114. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/tinyows.xml.tmpl +36 -0
  115. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A3_Landscape.jrxml +207 -0
  116. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A3_Portrait.jrxml +185 -0
  117. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A4_Landscape.jrxml +200 -0
  118. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A4_Portrait.jrxml +170 -0
  119. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/config.yaml.tmpl +175 -0
  120. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/legend.jrxml +109 -0
  121. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation.properties +4 -0
  122. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation_fr.properties +4 -0
  123. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/logo.png +0 -0
  124. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/north.svg +93 -0
  125. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/results.jrxml +25 -0
  126. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/project.yaml +18 -0
  127. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/pyproject.toml +7 -0
  128. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/qgisserver/pg_service.conf.tmpl +15 -0
  129. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/run_alembic.sh +11 -0
  130. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-backup +126 -0
  131. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +132 -0
  132. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/setup.cfg +7 -0
  133. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/spell-ignore-words.txt +5 -0
  134. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/__init__.py +0 -0
  135. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/test_app.py +78 -0
  136. c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tilegeneration/config.yaml.tmpl +195 -0
  137. c2cgeoportal_geoportal/scaffolds/update/cookiecutter.json +18 -0
  138. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/.upgrade.yaml +67 -0
  139. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +304 -0
  140. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py +48 -0
  141. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/.CONST_vars.yaml.swp +0 -0
  142. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/CONST_config-schema.yaml +927 -0
  143. c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/CONST_vars.yaml +1503 -0
  144. c2cgeoportal_geoportal/scripts/__init__.py +64 -0
  145. c2cgeoportal_geoportal/scripts/c2cupgrade.py +879 -0
  146. c2cgeoportal_geoportal/scripts/create_demo_theme.py +83 -0
  147. c2cgeoportal_geoportal/scripts/manage_users.py +140 -0
  148. c2cgeoportal_geoportal/scripts/pcreate.py +296 -0
  149. c2cgeoportal_geoportal/scripts/theme2fts.py +347 -0
  150. c2cgeoportal_geoportal/scripts/urllogin.py +81 -0
  151. c2cgeoportal_geoportal/templates/login.html +90 -0
  152. c2cgeoportal_geoportal/templates/notlogin.html +62 -0
  153. c2cgeoportal_geoportal/templates/testi18n.html +12 -0
  154. c2cgeoportal_geoportal/views/__init__.py +59 -0
  155. c2cgeoportal_geoportal/views/dev.py +57 -0
  156. c2cgeoportal_geoportal/views/dynamic.py +208 -0
  157. c2cgeoportal_geoportal/views/entry.py +174 -0
  158. c2cgeoportal_geoportal/views/fulltextsearch.py +189 -0
  159. c2cgeoportal_geoportal/views/geometry_processing.py +75 -0
  160. c2cgeoportal_geoportal/views/i18n.py +129 -0
  161. c2cgeoportal_geoportal/views/layers.py +713 -0
  162. c2cgeoportal_geoportal/views/login.py +684 -0
  163. c2cgeoportal_geoportal/views/mapserverproxy.py +234 -0
  164. c2cgeoportal_geoportal/views/memory.py +90 -0
  165. c2cgeoportal_geoportal/views/ogcproxy.py +120 -0
  166. c2cgeoportal_geoportal/views/pdfreport.py +245 -0
  167. c2cgeoportal_geoportal/views/printproxy.py +143 -0
  168. c2cgeoportal_geoportal/views/profile.py +192 -0
  169. c2cgeoportal_geoportal/views/proxy.py +261 -0
  170. c2cgeoportal_geoportal/views/raster.py +233 -0
  171. c2cgeoportal_geoportal/views/resourceproxy.py +73 -0
  172. c2cgeoportal_geoportal/views/shortener.py +152 -0
  173. c2cgeoportal_geoportal/views/theme.py +1322 -0
  174. c2cgeoportal_geoportal/views/tinyowsproxy.py +189 -0
  175. c2cgeoportal_geoportal/views/vector_tiles.py +83 -0
  176. {c2cgeoportal_geoportal-2.3.5.80.dist-info → c2cgeoportal_geoportal-2.9rc44.dist-info}/METADATA +21 -24
  177. c2cgeoportal_geoportal-2.9rc44.dist-info/RECORD +193 -0
  178. {c2cgeoportal_geoportal-2.3.5.80.dist-info → c2cgeoportal_geoportal-2.9rc44.dist-info}/WHEEL +1 -1
  179. c2cgeoportal_geoportal-2.9rc44.dist-info/entry_points.txt +28 -0
  180. c2cgeoportal_geoportal-2.9rc44.dist-info/top_level.txt +2 -0
  181. tests/__init__.py +100 -0
  182. tests/test_cachebuster.py +71 -0
  183. tests/test_caching.py +275 -0
  184. tests/test_checker.py +85 -0
  185. tests/test_decimaljson.py +47 -0
  186. tests/test_headerstween.py +64 -0
  187. tests/test_i18n.py +31 -0
  188. tests/test_init.py +193 -0
  189. tests/test_locale_negociator.py +69 -0
  190. tests/test_mapserverproxy_route_predicate.py +64 -0
  191. tests/test_raster.py +267 -0
  192. tests/test_wmstparsing.py +238 -0
  193. tests/xmlstr.py +103 -0
  194. c2cgeoportal_geoportal-2.3.5.80.dist-info/DESCRIPTION.rst +0 -8
  195. c2cgeoportal_geoportal-2.3.5.80.dist-info/RECORD +0 -7
  196. c2cgeoportal_geoportal-2.3.5.80.dist-info/entry_points.txt +0 -22
  197. c2cgeoportal_geoportal-2.3.5.80.dist-info/metadata.json +0 -1
  198. c2cgeoportal_geoportal-2.3.5.80.dist-info/top_level.txt +0 -1
@@ -0,0 +1,83 @@
1
+ # Copyright (c) 2011-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 argparse
30
+ import logging
31
+
32
+ import transaction
33
+
34
+ from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings, get_session
35
+
36
+ _LOG = logging.getLogger(__name__)
37
+
38
+
39
+ def main() -> None:
40
+ """Create and populate the database tables."""
41
+ parser = argparse.ArgumentParser(description="Create and populate the database tables.")
42
+ fill_arguments(parser)
43
+ options = parser.parse_args()
44
+ settings = get_appsettings(options)
45
+
46
+ with transaction.manager:
47
+ session = get_session(settings, transaction.manager)
48
+
49
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
50
+ Interface,
51
+ LayerGroup,
52
+ LayerWMS,
53
+ OGCServer,
54
+ Theme,
55
+ )
56
+
57
+ interfaces = session.query(Interface).all()
58
+ ogc_jpeg = session.query(OGCServer).filter(OGCServer.name == "MapServer_JPEG").one()
59
+ session.delete(ogc_jpeg)
60
+
61
+ ogc_server_mapserver = session.query(OGCServer).filter(OGCServer.name == "MapServer").one()
62
+
63
+ layer_borders = LayerWMS("Borders", "borders")
64
+ layer_borders.interfaces = interfaces
65
+ layer_borders.ogc_server = ogc_server_mapserver
66
+ layer_density = LayerWMS("Density", "density")
67
+ layer_density.interfaces = interfaces
68
+ layer_density.ogc_server = ogc_server_mapserver
69
+
70
+ group_mapserver = LayerGroup("MapServer")
71
+ group_mapserver.children = [layer_borders, layer_density]
72
+
73
+ theme = Theme("Demo")
74
+ theme.children = [group_mapserver]
75
+ theme.interfaces = interfaces
76
+
77
+ session.add(theme)
78
+
79
+ print("Successfully added the demo theme")
80
+
81
+
82
+ if __name__ == "__main__":
83
+ main()
@@ -0,0 +1,140 @@
1
+ # Copyright (c) 2011-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 argparse
30
+ import sys
31
+ from typing import cast
32
+
33
+ import transaction
34
+
35
+ from c2cgeoportal_geoportal.scripts import fill_arguments, get_appsettings, get_session
36
+
37
+
38
+ def get_argparser() -> argparse.ArgumentParser:
39
+ """Get the argument parser for this script."""
40
+
41
+ usage = """Reset a user password.
42
+ The username is used as password if the password is not provided with the corresponding option.
43
+ User can be created if it does not exist yet."""
44
+
45
+ parser = argparse.ArgumentParser(description=usage)
46
+ fill_arguments(parser)
47
+ parser.add_argument("--password", "-p", help="Set password (if not set, username is used as password")
48
+ parser.add_argument(
49
+ "--create", "-c", action="store_true", default=False, help="Create user if it does not already exist"
50
+ )
51
+ parser.add_argument(
52
+ "--rolename", "-r", default="role_admin", help="The role name which must exist in the database"
53
+ )
54
+ parser.add_argument("--email", "-e", default=None, help="The user email")
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()
71
+ options = parser.parse_args()
72
+ username = options.user
73
+ settings = get_appsettings(options)
74
+
75
+ with transaction.manager:
76
+ session = get_session(settings, transaction.manager)
77
+
78
+ # Must be done only once we have loaded the project config
79
+ from c2cgeoportal_commons.models.main import Role # pylint: disable=import-outside-toplevel
80
+ from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel
81
+
82
+ print("\n")
83
+
84
+ # Check that user exists
85
+ query = session.query(User).filter_by(username=username)
86
+
87
+ result = query.count()
88
+ if result == 0:
89
+ if not options.create:
90
+ # If doesn't exist and no -c option, throw error
91
+ print(f"User {username} does not exist in database")
92
+ sys.exit(1)
93
+ else:
94
+ if options.password is None:
95
+ parser.error("The password is mandatory on user creation")
96
+ if options.email is None:
97
+ parser.error("The email is mandatory on user creation")
98
+
99
+ # Get roles
100
+ query_role = session.query(Role).filter(Role.name == options.rolename)
101
+
102
+ if query_role.count() == 0:
103
+ # Role not found in db?
104
+ print(f"Role matching {options.rolename} does not exist in database")
105
+ sys.exit(1)
106
+
107
+ role = query_role.first()
108
+ assert role is not None
109
+
110
+ user = User(
111
+ username=username,
112
+ password=cast(str, options.password),
113
+ email=cast(str, options.email),
114
+ settings_role=role,
115
+ roles=[role],
116
+ )
117
+ session.add(user)
118
+
119
+ print(f"User {username} created with password {options.password} and role {options.rolename}")
120
+
121
+ else:
122
+ # If user exists (assuming username are unique)
123
+ first_user = query.first()
124
+ assert first_user is not None
125
+ user = first_user
126
+
127
+ if options.password is not None:
128
+ print(f"Password set to: {options.password}")
129
+ user.password = f"{options.password}"
130
+
131
+ if options.email is not None:
132
+ user.email = options.email
133
+
134
+ session.add(user)
135
+
136
+ print(f"Password reset for user {username}")
137
+
138
+
139
+ if __name__ == "__main__":
140
+ main()
@@ -0,0 +1,296 @@
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 os
30
+ import re
31
+ import subprocess
32
+ import sys
33
+ from argparse import ArgumentParser
34
+ from typing import Any, Union, cast
35
+
36
+ import pkg_resources
37
+ import pyproj
38
+ import yaml
39
+ from cookiecutter.log import configure_logger
40
+ from cookiecutter.main import cookiecutter
41
+
42
+ _bad_chars_re = re.compile("[^a-zA-Z0-9_]")
43
+ SCAFFOLDS_DIR = pkg_resources.resource_filename("c2cgeoportal_geoportal", "scaffolds")
44
+
45
+
46
+ def get_argparser() -> ArgumentParser:
47
+ """Get the argument parser for this script."""
48
+
49
+ parser = ArgumentParser(
50
+ prog=sys.argv[0],
51
+ add_help=True,
52
+ description="Wrapper around cookiecutter that create appropriated context.",
53
+ )
54
+ parser.add_argument(
55
+ "-s",
56
+ "--scaffold",
57
+ dest="scaffold_names",
58
+ action="append",
59
+ help=("Add a scaffold to the create process " "(multiple -s args accepted)"),
60
+ )
61
+ parser.add_argument(
62
+ "-l",
63
+ "--list",
64
+ dest="list",
65
+ action="store_true",
66
+ help="List all available scaffold names",
67
+ )
68
+ parser.add_argument(
69
+ "--package-name",
70
+ dest="package_name",
71
+ action="store",
72
+ help="Package name to use. The name provided is "
73
+ "assumed to be a valid Python package name, and "
74
+ "will not be validated. By default the package "
75
+ "name is derived from the value of "
76
+ "output_directory.",
77
+ )
78
+ parser.add_argument(
79
+ "--overwrite",
80
+ dest="overwrite",
81
+ action="store_true",
82
+ help="Always overwrite",
83
+ )
84
+ parser.add_argument(
85
+ "output_directory",
86
+ nargs="?",
87
+ default=None,
88
+ help="The directory where the project will be " "created.",
89
+ )
90
+ return parser
91
+
92
+
93
+ def main() -> int:
94
+ """Entry point to run PCreateCommand."""
95
+ command = PCreateCommand(sys.argv)
96
+ try:
97
+ return command.run()
98
+ except KeyboardInterrupt: # pragma: no cover
99
+ return 1
100
+
101
+
102
+ class PCreateCommand:
103
+ """
104
+ Wrapper around cookiecutter with appropriated context creator for our scaffolds.
105
+
106
+ This is a port of Pyramid 1 PCreateCommand using cookiecutter as a backend.
107
+ """
108
+
109
+ def __init__(self, argv: list[str], quiet: bool = False) -> None:
110
+ self.quiet = quiet
111
+ self.parser = get_argparser()
112
+ self.args = self.parser.parse_args(argv[1:])
113
+ self.scaffolds = self.all_scaffolds()
114
+
115
+ def run(self) -> int:
116
+ if self.args.list:
117
+ return self.show_scaffolds()
118
+ if not self.args.scaffold_names and not self.args.output_directory:
119
+ if not self.quiet: # pragma: no cover
120
+ self.parser.print_help()
121
+ self.out("")
122
+ self.show_scaffolds()
123
+ return 2
124
+
125
+ return self.render_scaffolds()
126
+
127
+ @property
128
+ def output_path(self) -> str:
129
+ return cast(str, os.path.abspath(os.path.normpath(self.args.output_directory)))
130
+
131
+ def render_scaffolds(self) -> int:
132
+ verbose = True
133
+ debug_file = None
134
+ configure_logger(stream_level="DEBUG" if verbose else "INFO", debug_file=debug_file)
135
+
136
+ context = self.get_context()
137
+
138
+ for scaffold_name in self.args.scaffold_names:
139
+ # Needed to be backward compatible for the `test-upgrade init` command
140
+ if scaffold_name.startswith("c2cgeoportal_"):
141
+ scaffold_name = scaffold_name[len("c2cgeoportal_") :]
142
+ self.out(f"Rendering scaffold: {scaffold_name}")
143
+ cookiecutter(
144
+ template=os.path.join(SCAFFOLDS_DIR, scaffold_name),
145
+ extra_context=context,
146
+ no_input=True,
147
+ overwrite_if_exists=self.args.overwrite,
148
+ output_dir=os.path.dirname(self.output_path),
149
+ )
150
+ return 0
151
+
152
+ def show_scaffolds(self) -> int:
153
+ scaffolds = sorted(self.scaffolds)
154
+ if scaffolds:
155
+ self.out("Available scaffolds:")
156
+ for scaffold in scaffolds:
157
+ self.out(f" {scaffold}")
158
+ else:
159
+ self.out("No scaffolds available")
160
+ return 0
161
+
162
+ @staticmethod
163
+ def all_scaffolds() -> list[str]:
164
+ return os.listdir(SCAFFOLDS_DIR)
165
+
166
+ def out(self, msg: str) -> None:
167
+ if not self.quiet:
168
+ print(msg)
169
+
170
+ def get_context(self) -> dict[str, str | int]:
171
+ output_dir = self.output_path
172
+ project_name = os.path.basename(output_dir)
173
+ if self.args.package_name is None:
174
+ pkg_name = _bad_chars_re.sub("", project_name.lower().replace("-", "_"))
175
+ else:
176
+ pkg_name = self.args.package_name
177
+
178
+ context: dict[str, str | int] = {
179
+ "project": project_name,
180
+ "package": pkg_name,
181
+ "authtkt_secret": gen_authtkt_secret(),
182
+ }
183
+ context.update(self.read_project_file())
184
+ if os.environ.get("CI") == "true":
185
+ context["authtkt_secret"] = ( # nosec
186
+ "io7heoDui8xaikie1rushaeGeiph8Bequei6ohchaequob6viejei0xooWeuvohf"
187
+ )
188
+
189
+ self.get_var(context, "srid", "Spatial Reference System Identifier (e.g. 2056): ", int)
190
+ srid = cast(int, context["srid"])
191
+ extent = self.epsg2bbox(srid)
192
+ self.get_var(
193
+ context,
194
+ "extent",
195
+ (
196
+ f"Extent (minx miny maxx maxy): in EPSG: {srid} projection, default is "
197
+ f"[{extent[0]} {extent[1]} {extent[2]} {extent[3]}]: "
198
+ if extent
199
+ else f"Extent (minx miny maxx maxy): in EPSG: {srid} projection: "
200
+ ),
201
+ )
202
+ match = re.match(
203
+ r"([\d.]+)[,; ] *([\d.]+)[,; ] *([\d.]+)[,; ] *([\d.]+)",
204
+ cast(str, context["extent"]),
205
+ )
206
+ if match is not None:
207
+ extent = [match.group(n + 1) for n in range(4)]
208
+ assert extent is not None
209
+ context["extent"] = ",".join(extent)
210
+ context["extent_mapserver"] = " ".join(extent)
211
+
212
+ if context["package"] == "site":
213
+ raise ValueError(
214
+ "Sorry, you may not name your package 'site'. "
215
+ "The package name 'site' has a special meaning in "
216
+ "Python. Please name it anything except 'site'."
217
+ )
218
+
219
+ package_logger = context["package"]
220
+ if package_logger == "root":
221
+ # Rename the app logger in the rare case a project
222
+ # is named "root"
223
+ package_logger = "app"
224
+ context["package_logger"] = package_logger
225
+ context["geomapfish_version"] = os.environ["VERSION"]
226
+ # Used in the Docker files to shoos the version of the build image
227
+ context["geomapfish_version_tag"] = "GEOMAPFISH_VERSION"
228
+ context["geomapfish_version_tag_env"] = "${GEOMAPFISH_VERSION}"
229
+ geomapfish_major_version_tag = (
230
+ "GEOMAPFISH_VERSION"
231
+ if context.get("unsafe_long_version", False)
232
+ else "GEOMAPFISH_MAIN_MINOR_VERSION"
233
+ )
234
+ # Used in the Docker files to shoos the version of the run image
235
+ context["geomapfish_major_version_tag"] = geomapfish_major_version_tag
236
+ context["geomapfish_major_version_tag_env"] = "${" + geomapfish_major_version_tag + "}"
237
+ context["geomapfish_main_version"] = os.environ["MAJOR_VERSION"]
238
+ context["geomapfish_main_version_dash"] = os.environ["MAJOR_VERSION"].replace(".", "-")
239
+ context["geomapfish_main_minor_version"] = os.environ["MAJOR_MINOR_VERSION"]
240
+
241
+ return context
242
+
243
+ def read_project_file(self) -> dict[str, str | int]:
244
+ project_file = os.path.join(self.output_path, "project.yaml")
245
+ if os.path.exists(project_file):
246
+ with open(project_file, encoding="utf8") as f:
247
+ project = yaml.safe_load(f)
248
+ return cast(dict[str, Union[str, int]], project.get("template_vars", {}))
249
+ else:
250
+ return {}
251
+
252
+ @staticmethod
253
+ def get_var(
254
+ context: dict[str, Any],
255
+ name: str,
256
+ prompt: str,
257
+ type_: type[Any] | None = None,
258
+ ) -> None:
259
+ if name.upper() in os.environ and os.environ[name.upper()] != "":
260
+ value = os.environ.get(name.upper())
261
+ else:
262
+ value = context.get(name)
263
+
264
+ if value is None:
265
+ value = input(prompt).strip()
266
+
267
+ if type_ is not None and not isinstance(value, type_):
268
+ try:
269
+ value = type_(value)
270
+ except ValueError:
271
+ print(f"The attribute {name}={value} is not a {type_}")
272
+ sys.exit(1)
273
+
274
+ context[name] = value
275
+
276
+ @staticmethod
277
+ def epsg2bbox(srid: int) -> list[str] | None:
278
+ try:
279
+ crs = pyproj.CRS.from_epsg(srid)
280
+ assert crs.area_of_use is not None
281
+ transformer = pyproj.Transformer.from_crs(4326, crs)
282
+ c1 = transformer.transform(crs.area_of_use.bounds[1], crs.area_of_use.bounds[0])
283
+ c2 = transformer.transform(crs.area_of_use.bounds[3], crs.area_of_use.bounds[2])
284
+ return [c1[0], c1[1], c2[0], c2[1]]
285
+ except Exception as exception: # pylint: disable=broad-exception-caught
286
+ print(f"Unexpected error: {str(exception)}")
287
+ return None
288
+
289
+
290
+ def gen_authtkt_secret() -> str:
291
+ """Generate a random authtkt secret."""
292
+ return subprocess.run(["pwgen", "64"], stdout=subprocess.PIPE, check=True).stdout.decode().strip()
293
+
294
+
295
+ if __name__ == "__main__": # pragma: no cover
296
+ sys.exit(main() or 0)