c2cgeoportal-admin 2.5.0.100__py3-none-any.whl → 2.7.1.156__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 (91) hide show
  1. c2cgeoportal_admin/__init__.py +19 -12
  2. c2cgeoportal_admin/lib/__init__.py +0 -0
  3. c2cgeoportal_admin/lib/lingua_extractor.py +77 -0
  4. c2cgeoportal_admin/lib/ogcserver_synchronizer.py +409 -0
  5. c2cgeoportal_admin/py.typed +0 -0
  6. c2cgeoportal_admin/routes.py +18 -10
  7. c2cgeoportal_admin/schemas/dimensions.py +13 -11
  8. c2cgeoportal_admin/schemas/functionalities.py +63 -22
  9. c2cgeoportal_admin/schemas/interfaces.py +23 -19
  10. c2cgeoportal_admin/schemas/metadata.py +121 -47
  11. c2cgeoportal_admin/schemas/restriction_areas.py +22 -20
  12. c2cgeoportal_admin/schemas/roles.py +8 -6
  13. c2cgeoportal_admin/schemas/treegroup.py +84 -18
  14. c2cgeoportal_admin/schemas/treeitem.py +2 -3
  15. c2cgeoportal_admin/static/layertree.css +26 -4
  16. c2cgeoportal_admin/static/navbar.css +59 -36
  17. c2cgeoportal_admin/static/theme.css +48 -11
  18. c2cgeoportal_admin/subscribers.py +3 -3
  19. c2cgeoportal_admin/templates/404.jinja2 +23 -0
  20. c2cgeoportal_admin/templates/edit.jinja2 +23 -0
  21. c2cgeoportal_admin/templates/home.jinja2 +23 -0
  22. c2cgeoportal_admin/templates/index.jinja2 +23 -0
  23. c2cgeoportal_admin/templates/layertree.jinja2 +55 -11
  24. c2cgeoportal_admin/templates/layout.jinja2 +23 -0
  25. c2cgeoportal_admin/templates/navigation_navbar.jinja2 +56 -0
  26. c2cgeoportal_admin/templates/ogcserver_synchronize.jinja2 +90 -0
  27. c2cgeoportal_admin/templates/widgets/child.pt +35 -3
  28. c2cgeoportal_admin/templates/widgets/children.pt +121 -92
  29. c2cgeoportal_admin/templates/widgets/dimension.pt +23 -0
  30. c2cgeoportal_admin/templates/widgets/dimensions.pt +23 -0
  31. c2cgeoportal_admin/templates/widgets/functionality_fields.pt +51 -0
  32. c2cgeoportal_admin/templates/widgets/layer_fields.pt +23 -0
  33. c2cgeoportal_admin/templates/widgets/layer_group_fields.pt +23 -0
  34. c2cgeoportal_admin/templates/widgets/layer_v1_fields.pt +23 -0
  35. c2cgeoportal_admin/templates/widgets/metadata.pt +30 -1
  36. c2cgeoportal_admin/templates/widgets/metadatas.pt +23 -0
  37. c2cgeoportal_admin/templates/widgets/ogcserver_fields.pt +23 -0
  38. c2cgeoportal_admin/templates/widgets/restriction_area_fields.pt +25 -9
  39. c2cgeoportal_admin/templates/widgets/role_fields.pt +52 -25
  40. c2cgeoportal_admin/templates/widgets/theme_fields.pt +23 -0
  41. c2cgeoportal_admin/templates/widgets/user_fields.pt +23 -0
  42. c2cgeoportal_admin/views/dimension_layers.py +7 -6
  43. c2cgeoportal_admin/views/functionalities.py +31 -5
  44. c2cgeoportal_admin/views/home.py +5 -5
  45. c2cgeoportal_admin/views/interfaces.py +8 -8
  46. c2cgeoportal_admin/views/layer_groups.py +9 -11
  47. c2cgeoportal_admin/views/layers.py +8 -7
  48. c2cgeoportal_admin/views/layers_vectortiles.py +30 -10
  49. c2cgeoportal_admin/views/layers_wms.py +45 -37
  50. c2cgeoportal_admin/views/layers_wmts.py +39 -33
  51. c2cgeoportal_admin/views/layertree.py +34 -26
  52. c2cgeoportal_admin/views/oauth2_clients.py +89 -0
  53. c2cgeoportal_admin/views/ogc_servers.py +130 -27
  54. c2cgeoportal_admin/views/restriction_areas.py +50 -8
  55. c2cgeoportal_admin/views/roles.py +60 -8
  56. c2cgeoportal_admin/views/themes.py +15 -14
  57. c2cgeoportal_admin/views/themes_ordering.py +38 -18
  58. c2cgeoportal_admin/views/treeitems.py +12 -11
  59. c2cgeoportal_admin/views/users.py +7 -5
  60. c2cgeoportal_admin/widgets.py +79 -28
  61. {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.7.1.156.dist-info}/METADATA +16 -11
  62. c2cgeoportal_admin-2.7.1.156.dist-info/RECORD +92 -0
  63. {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.7.1.156.dist-info}/WHEEL +1 -1
  64. c2cgeoportal_admin-2.7.1.156.dist-info/entry_points.txt +5 -0
  65. tests/__init__.py +23 -18
  66. tests/conftest.py +4 -15
  67. tests/test_edit_url.py +16 -18
  68. tests/test_functionalities.py +23 -10
  69. tests/test_interface.py +8 -8
  70. tests/test_layer_groups.py +15 -23
  71. tests/test_layers_vectortiles.py +16 -20
  72. tests/test_layers_wms.py +37 -75
  73. tests/test_layers_wmts.py +20 -24
  74. tests/test_layertree.py +107 -100
  75. tests/test_learn.py +1 -1
  76. tests/test_lingua_extractor_config.py +66 -0
  77. tests/test_main.py +4 -2
  78. tests/test_metadatas.py +79 -70
  79. tests/test_oauth2_clients.py +157 -0
  80. tests/test_ogc_servers.py +51 -7
  81. tests/test_restriction_areas.py +81 -17
  82. tests/test_role.py +110 -76
  83. tests/test_themes.py +44 -37
  84. tests/test_themes_ordering.py +1 -1
  85. tests/test_treegroup.py +2 -2
  86. tests/test_user.py +31 -64
  87. tests/themes_ordering.py +1 -1
  88. c2cgeoportal_admin/templates/navigation_vertical.jinja2 +0 -10
  89. c2cgeoportal_admin-2.5.0.100.dist-info/RECORD +0 -84
  90. c2cgeoportal_admin-2.5.0.100.dist-info/entry_points.txt +0 -3
  91. {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.7.1.156.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2017-2020, Camptocamp SA
1
+ # Copyright (c) 2017-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -29,7 +27,9 @@
29
27
 
30
28
 
31
29
  from functools import partial
30
+ from typing import Any, Dict, List, Optional
32
31
 
32
+ import sqlalchemy
33
33
  from c2cgeoform.schema import GeoFormSchemaNode
34
34
  from c2cgeoform.views.abstract_views import ItemAction, ListField
35
35
  from deform.widget import FormWidget
@@ -40,7 +40,7 @@ from zope.sqlalchemy import mark_changed
40
40
  from c2cgeoportal_admin import _
41
41
  from c2cgeoportal_admin.schemas.dimensions import dimensions_schema_node
42
42
  from c2cgeoportal_admin.schemas.interfaces import interfaces_schema_node
43
- from c2cgeoportal_admin.schemas.metadata import metadatas_schema_node
43
+ from c2cgeoportal_admin.schemas.metadata import metadata_schema_node
44
44
  from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node
45
45
  from c2cgeoportal_admin.schemas.treeitem import parent_id_node
46
46
  from c2cgeoportal_admin.views.dimension_layers import DimensionLayerViews
@@ -49,29 +49,33 @@ from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, LayerWMTS, OG
49
49
  _list_field = partial(ListField, LayerWMS)
50
50
 
51
51
  base_schema = GeoFormSchemaNode(LayerWMS, widget=FormWidget(fields_template="layer_fields"))
52
- base_schema.add(dimensions_schema_node.clone())
53
- base_schema.add(metadatas_schema_node.clone())
54
- base_schema.add(interfaces_schema_node.clone())
55
- base_schema.add(restrictionareas_schema_node.clone())
52
+ base_schema.add(dimensions_schema_node(LayerWMS.dimensions))
53
+ base_schema.add(metadata_schema_node(LayerWMS.metadatas, LayerWMS))
54
+ base_schema.add(interfaces_schema_node(LayerWMS.interfaces))
55
+ base_schema.add(restrictionareas_schema_node(LayerWMS.restrictionareas))
56
56
  base_schema.add_unique_validator(LayerWMS.name, LayerWMS.id)
57
- base_schema.add(parent_id_node(LayerGroup))
57
+ base_schema.add(parent_id_node(LayerGroup)) # type: ignore
58
58
 
59
59
 
60
60
  @view_defaults(match_param="table=layers_wms")
61
61
  class LayerWmsViews(DimensionLayerViews):
62
+ """The WMS layer administration view."""
63
+
62
64
  _list_fields = (
63
65
  DimensionLayerViews._list_fields
64
66
  + [
65
- _list_field("layer"),
66
- _list_field("style"),
67
- _list_field("time_mode"),
68
- _list_field("time_widget"),
69
67
  _list_field(
70
68
  "ogc_server",
71
69
  renderer=lambda layer_wms: layer_wms.ogc_server.name,
72
70
  sort_column=OGCServer.name,
73
71
  filter_column=OGCServer.name,
74
72
  ),
73
+ _list_field("layer"),
74
+ _list_field("style"),
75
+ _list_field("valid", label="Valid"),
76
+ _list_field("invalid_reason", visible=False),
77
+ _list_field("time_mode"),
78
+ _list_field("time_widget"),
75
79
  ]
76
80
  + DimensionLayerViews._extra_list_fields
77
81
  )
@@ -79,20 +83,20 @@ class LayerWmsViews(DimensionLayerViews):
79
83
  _model = LayerWMS
80
84
  _base_schema = base_schema
81
85
 
82
- def _base_query(self, query=None):
86
+ def _base_query(self, query: Optional[sqlalchemy.orm.query.Query] = None) -> sqlalchemy.orm.query.Query:
83
87
  del query
84
88
  return super()._base_query(self._request.dbsession.query(LayerWMS).distinct().outerjoin("ogc_server"))
85
89
 
86
- @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2")
87
- def index(self):
88
- return super().index()
90
+ @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2") # type: ignore
91
+ def index(self) -> Dict[str, Any]:
92
+ return super().index() # type: ignore
89
93
 
90
- @view_config(route_name="c2cgeoform_grid", renderer="fast_json")
91
- def grid(self):
92
- return super().grid()
94
+ @view_config(route_name="c2cgeoform_grid", renderer="fast_json") # type: ignore
95
+ def grid(self) -> Dict[str, Any]:
96
+ return super().grid() # type: ignore
93
97
 
94
- def _item_actions(self, item, readonly=False):
95
- actions = super()._item_actions(item, readonly)
98
+ def _item_actions(self, item: LayerWMS, readonly: bool = False) -> List[ItemAction]:
99
+ actions: List[ItemAction] = super()._item_actions(item, readonly)
96
100
  if inspect(item).persistent:
97
101
  actions.insert(
98
102
  next((i for i, v in enumerate(actions) if v.name() == "delete")),
@@ -107,31 +111,35 @@ class LayerWmsViews(DimensionLayerViews):
107
111
  )
108
112
  return actions
109
113
 
110
- @view_config(route_name="c2cgeoform_item", request_method="GET", renderer="../templates/edit.jinja2")
111
- def view(self):
114
+ @view_config( # type: ignore
115
+ route_name="c2cgeoform_item", request_method="GET", renderer="../templates/edit.jinja2"
116
+ )
117
+ def view(self) -> Dict[str, Any]:
112
118
  if self._is_new():
113
119
  dbsession = self._request.dbsession
114
120
  default_wms = LayerWMS.get_default(dbsession)
115
121
  if default_wms:
116
- return self.copy(default_wms, excludes=["name", "layer"])
117
- return super().edit()
122
+ return self.copy(default_wms, excludes=["name", "layer"]) # type: ignore
123
+ return super().edit() # type: ignore
118
124
 
119
- @view_config(route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2")
120
- def save(self):
121
- return super().save()
125
+ @view_config( # type: ignore
126
+ route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2"
127
+ )
128
+ def save(self) -> Dict[str, Any]:
129
+ return super().save() # type: ignore
122
130
 
123
- @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json")
124
- def delete(self):
125
- return super().delete()
131
+ @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore
132
+ def delete(self) -> Dict[str, Any]:
133
+ return super().delete() # type: ignore
126
134
 
127
- @view_config(
135
+ @view_config( # type: ignore
128
136
  route_name="c2cgeoform_item_duplicate", request_method="GET", renderer="../templates/edit.jinja2"
129
137
  )
130
- def duplicate(self):
131
- return super().duplicate()
138
+ def duplicate(self) -> Dict[str, Any]:
139
+ return super().duplicate() # type: ignore
132
140
 
133
- @view_config(route_name="convert_to_wmts", request_method="POST", renderer="fast_json")
134
- def convert_to_wmts(self):
141
+ @view_config(route_name="convert_to_wmts", request_method="POST", renderer="fast_json") # type: ignore
142
+ def convert_to_wmts(self) -> Dict[str, Any]:
135
143
  src = self._get_object()
136
144
  dbsession = self._request.dbsession
137
145
  default_wmts = LayerWMTS.get_default(dbsession)
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2017-2020, Camptocamp SA
1
+ # Copyright (c) 2017-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -29,7 +27,9 @@
29
27
 
30
28
 
31
29
  from functools import partial
30
+ from typing import Any, Dict, List, Optional
32
31
 
32
+ import sqlalchemy
33
33
  from c2cgeoform.schema import GeoFormSchemaNode
34
34
  from c2cgeoform.views.abstract_views import ItemAction, ListField
35
35
  from deform.widget import FormWidget
@@ -40,7 +40,7 @@ from zope.sqlalchemy import mark_changed
40
40
  from c2cgeoportal_admin import _
41
41
  from c2cgeoportal_admin.schemas.dimensions import dimensions_schema_node
42
42
  from c2cgeoportal_admin.schemas.interfaces import interfaces_schema_node
43
- from c2cgeoportal_admin.schemas.metadata import metadatas_schema_node
43
+ from c2cgeoportal_admin.schemas.metadata import metadata_schema_node
44
44
  from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node
45
45
  from c2cgeoportal_admin.schemas.treeitem import parent_id_node
46
46
  from c2cgeoportal_admin.views.dimension_layers import DimensionLayerViews
@@ -49,16 +49,18 @@ from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, LayerWMTS, OG
49
49
  _list_field = partial(ListField, LayerWMTS)
50
50
 
51
51
  base_schema = GeoFormSchemaNode(LayerWMTS, widget=FormWidget(fields_template="layer_fields"))
52
- base_schema.add(dimensions_schema_node.clone())
53
- base_schema.add(metadatas_schema_node.clone())
54
- base_schema.add(interfaces_schema_node.clone())
55
- base_schema.add(restrictionareas_schema_node.clone())
52
+ base_schema.add(dimensions_schema_node(LayerWMTS.dimensions))
53
+ base_schema.add(metadata_schema_node(LayerWMTS.metadatas, LayerWMTS))
54
+ base_schema.add(interfaces_schema_node(LayerWMTS.interfaces))
55
+ base_schema.add(restrictionareas_schema_node(LayerWMTS.restrictionareas))
56
56
  base_schema.add_unique_validator(LayerWMTS.name, LayerWMTS.id)
57
- base_schema.add(parent_id_node(LayerGroup))
57
+ base_schema.add(parent_id_node(LayerGroup)) # type: ignore
58
58
 
59
59
 
60
60
  @view_defaults(match_param="table=layers_wmts")
61
61
  class LayerWmtsViews(DimensionLayerViews):
62
+ """The WMTS layer administration view."""
63
+
62
64
  _list_fields = (
63
65
  DimensionLayerViews._list_fields
64
66
  + [
@@ -74,19 +76,19 @@ class LayerWmtsViews(DimensionLayerViews):
74
76
  _model = LayerWMTS
75
77
  _base_schema = base_schema
76
78
 
77
- def _base_query(self, query=None):
79
+ def _base_query(self, query: Optional[sqlalchemy.orm.query.Query] = None) -> sqlalchemy.orm.query.Query:
78
80
  return super()._base_query(self._request.dbsession.query(LayerWMTS).distinct())
79
81
 
80
- @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2")
81
- def index(self):
82
- return super().index()
82
+ @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2") # type: ignore
83
+ def index(self) -> Dict[str, Any]:
84
+ return super().index() # type: ignore
83
85
 
84
- @view_config(route_name="c2cgeoform_grid", renderer="fast_json")
85
- def grid(self):
86
- return super().grid()
86
+ @view_config(route_name="c2cgeoform_grid", renderer="fast_json") # type: ignore
87
+ def grid(self) -> Dict[str, Any]:
88
+ return super().grid() # type: ignore
87
89
 
88
- def _item_actions(self, item, readonly=False):
89
- actions = super()._item_actions(item, readonly)
90
+ def _item_actions(self, item: LayerWMTS, readonly: bool = False) -> List[ItemAction]:
91
+ actions: List[ItemAction] = super()._item_actions(item, readonly)
90
92
  if inspect(item).persistent:
91
93
  actions.insert(
92
94
  next((i for i, v in enumerate(actions) if v.name() == "delete")),
@@ -101,31 +103,35 @@ class LayerWmtsViews(DimensionLayerViews):
101
103
  )
102
104
  return actions
103
105
 
104
- @view_config(route_name="c2cgeoform_item", request_method="GET", renderer="../templates/edit.jinja2")
105
- def view(self):
106
+ @view_config( # type: ignore
107
+ route_name="c2cgeoform_item", request_method="GET", renderer="../templates/edit.jinja2"
108
+ )
109
+ def view(self) -> Dict[str, Any]:
106
110
  if self._is_new():
107
111
  dbsession = self._request.dbsession
108
112
  default_wmts = LayerWMTS.get_default(dbsession)
109
113
  if default_wmts:
110
- return self.copy(default_wmts, excludes=["name", "layer"])
111
- return super().edit()
114
+ return self.copy(default_wmts, excludes=["name", "layer"]) # type: ignore
115
+ return super().edit() # type: ignore
112
116
 
113
- @view_config(route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2")
114
- def save(self):
115
- return super().save()
117
+ @view_config( # type: ignore
118
+ route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2"
119
+ )
120
+ def save(self) -> Dict[str, Any]:
121
+ return super().save() # type: ignore
116
122
 
117
- @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json")
118
- def delete(self):
119
- return super().delete()
123
+ @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore
124
+ def delete(self) -> Dict[str, Any]:
125
+ return super().delete() # type: ignore
120
126
 
121
- @view_config(
127
+ @view_config( # type: ignore
122
128
  route_name="c2cgeoform_item_duplicate", request_method="GET", renderer="../templates/edit.jinja2"
123
129
  )
124
- def duplicate(self):
125
- return super().duplicate()
130
+ def duplicate(self) -> Dict[str, Any]:
131
+ return super().duplicate() # type: ignore
126
132
 
127
- @view_config(route_name="convert_to_wms", request_method="POST", renderer="fast_json")
128
- def convert_to_wms(self):
133
+ @view_config(route_name="convert_to_wms", request_method="POST", renderer="fast_json") # type: ignore
134
+ def convert_to_wms(self) -> Dict[str, Any]:
129
135
  src = self._get_object()
130
136
  dbsession = self._request.dbsession
131
137
  default_wms = LayerWMS.get_default(dbsession)
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # Copyright (c) 2017-2020, Camptocamp SA
1
+ # Copyright (c) 2017-2021, Camptocamp SA
4
2
  # All rights reserved.
5
3
 
6
4
  # Redistribution and use in source and binary forms, with or without
@@ -28,13 +26,16 @@
28
26
  # either expressed or implied, of the FreeBSD Project.
29
27
 
30
28
 
29
+ from typing import Any, Dict, List, Optional
30
+
31
+ import pyramid.request
31
32
  from c2cgeoform.views.abstract_views import ItemAction
32
33
  from pyramid.httpexceptions import HTTPNotFound
33
34
  from pyramid.view import view_config, view_defaults
34
35
  from translationstring import TranslationStringFactory
35
36
 
36
37
  from c2cgeoportal_admin import _
37
- from c2cgeoportal_commons.models.main import LayergroupTreeitem, Theme, TreeItem
38
+ from c2cgeoportal_commons.models.main import Interface, Layer, LayergroupTreeitem, Theme, TreeItem
38
39
 
39
40
  itemtypes_tables = {
40
41
  "theme": "themes",
@@ -46,30 +47,37 @@ itemtypes_tables = {
46
47
 
47
48
  @view_defaults(match_param=("application=admin"))
48
49
  class LayerTreeViews:
49
- def __init__(self, request):
50
+ """The layer tree administration view."""
51
+
52
+ def __init__(self, request: pyramid.request.Request):
50
53
  self._request = request
51
54
  self._dbsession = request.dbsession
52
55
 
53
- @view_config(route_name="layertree", renderer="../templates/layertree.jinja2")
54
- def index(self):
56
+ @view_config(route_name="layertree", renderer="../templates/layertree.jinja2") # type: ignore
57
+ def index(self) -> Dict[str, int]:
55
58
  node_limit = self._request.registry.settings["admin_interface"].get("layer_tree_max_nodes")
56
59
  limit_exceeded = self._dbsession.query(LayergroupTreeitem).count() < node_limit
57
- return {"limit_exceeded": limit_exceeded}
60
+ return {"limit_exceeded": limit_exceeded, "interfaces": self._dbsession.query(Interface).all()}
58
61
 
59
- @view_config(route_name="layertree_children", renderer="fast_json")
60
- def children(self):
62
+ @view_config(route_name="layertree_children", renderer="fast_json") # type: ignore
63
+ def children(self) -> List[Dict[str, Any]]:
64
+ interface = self._request.params.get("interface", None)
61
65
  group_id = self._request.params.get("group_id", None)
62
66
  path = self._request.params.get("path", "")
63
67
 
64
- client_tsf = TranslationStringFactory("{}-client".format(self._request.registry.package_name))
68
+ client_tsf = TranslationStringFactory(f"{self._request.registry.package_name}-client")
65
69
 
66
70
  if group_id is None:
67
71
  items = self._dbsession.query(Theme).order_by(Theme.ordering)
72
+ if interface is not None:
73
+ items = items.join(Theme.interfaces).filter(Interface.name == interface)
74
+
68
75
  else:
69
76
  items = (
70
77
  self._dbsession.query(TreeItem)
71
78
  .join(TreeItem.parents_relation)
72
79
  .filter(LayergroupTreeitem.treegroup_id == group_id)
80
+ .order_by(LayergroupTreeitem.ordering)
73
81
  )
74
82
 
75
83
  return [
@@ -79,14 +87,17 @@ class LayerTreeViews:
79
87
  "name": item.name,
80
88
  "translated_name": self._request.localizer.translate(client_tsf(item.name)),
81
89
  "description": item.description,
82
- "path": "{}_{}".format(path, item.id),
90
+ "path": f"{path}_{item.id}",
83
91
  "parent_path": path,
84
92
  "actions": [action.to_dict(self._request) for action in self._item_actions(item, group_id)],
85
93
  }
86
94
  for item in items
95
+ if interface is None
96
+ or not isinstance(item, Layer)
97
+ or interface in [interface.name for interface in item.interfaces]
87
98
  ]
88
99
 
89
- def _item_actions(self, item, parent_id=None):
100
+ def _item_actions(self, item: TreeItem, parent_id: Optional[int] = None) -> List[ItemAction]:
90
101
  actions = []
91
102
  actions.append(
92
103
  ItemAction(
@@ -105,9 +116,8 @@ class LayerTreeViews:
105
116
  name="new_layer_group",
106
117
  label=_("New layer group"),
107
118
  icon="glyphicon glyphicon-plus",
108
- url="{}?parent_id={}".format(
109
- self._request.route_url("c2cgeoform_item", table="layer_groups", id="new"), item.id
110
- ),
119
+ url=f"{self._request.route_url('c2cgeoform_item', table='layer_groups', id='new')}?"
120
+ f"parent_id={item.id}",
111
121
  )
112
122
  )
113
123
 
@@ -117,9 +127,8 @@ class LayerTreeViews:
117
127
  name="new_layer_wms",
118
128
  label=_("New WMS layer"),
119
129
  icon="glyphicon glyphicon-plus",
120
- url="{}?parent_id={}".format(
121
- self._request.route_url("c2cgeoform_item", table="layers_wms", id="new"), item.id
122
- ),
130
+ url=f"{self._request.route_url('c2cgeoform_item', table='layers_wms', id='new')}?"
131
+ f"parent_id={item.id}",
123
132
  )
124
133
  )
125
134
 
@@ -128,9 +137,8 @@ class LayerTreeViews:
128
137
  name="new_layer_wmts",
129
138
  label=_("New WMTS layer"),
130
139
  icon="glyphicon glyphicon-plus",
131
- url="{}?parent_id={}".format(
132
- self._request.route_url("c2cgeoform_item", table="layers_wmts", id="new"), item.id
133
- ),
140
+ url=f"{self._request.route_url('c2cgeoform_item', table='layers_wmts', id='new')}?"
141
+ f"parent_id={item.id}",
134
142
  )
135
143
  )
136
144
 
@@ -170,8 +178,8 @@ class LayerTreeViews:
170
178
 
171
179
  return actions
172
180
 
173
- @view_config(route_name="layertree_unlink", request_method="DELETE", renderer="fast_json")
174
- def unlink(self):
181
+ @view_config(route_name="layertree_unlink", request_method="DELETE", renderer="fast_json") # type: ignore
182
+ def unlink(self) -> Dict[str, Any]:
175
183
  group_id = self._request.matchdict.get("group_id")
176
184
  item_id = self._request.matchdict.get("item_id")
177
185
  link = (
@@ -186,8 +194,8 @@ class LayerTreeViews:
186
194
  self._request.dbsession.flush()
187
195
  return {"success": True, "redirect": self._request.route_url("layertree")}
188
196
 
189
- @view_config(route_name="layertree_delete", request_method="DELETE", renderer="fast_json")
190
- def delete(self):
197
+ @view_config(route_name="layertree_delete", request_method="DELETE", renderer="fast_json") # type: ignore
198
+ def delete(self) -> Dict[str, Any]:
191
199
  item_id = self._request.matchdict.get("item_id")
192
200
  item = self._request.dbsession.query(TreeItem).get(item_id)
193
201
  if item is None:
@@ -0,0 +1,89 @@
1
+ # Copyright (c) 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
+ from functools import partial
30
+ from typing import Any, Dict
31
+
32
+ from c2cgeoform.schema import GeoFormSchemaNode
33
+ from c2cgeoform.views.abstract_views import AbstractViews, ListField
34
+ from pyramid.view import view_config, view_defaults
35
+
36
+ from c2cgeoportal_commons.models.static import OAuth2Client
37
+
38
+ _list_field = partial(ListField, OAuth2Client)
39
+
40
+ base_schema = GeoFormSchemaNode(OAuth2Client)
41
+ base_schema.add_unique_validator(OAuth2Client.client_id, OAuth2Client.id)
42
+
43
+
44
+ @view_defaults(match_param="table=oauth2_clients")
45
+ class OAuth2ClientViews(AbstractViews): # type: ignore
46
+ """The oAuth2 client administration view."""
47
+
48
+ _list_fields = [
49
+ _list_field("id"),
50
+ _list_field("client_id"),
51
+ _list_field("secret"),
52
+ _list_field("redirect_uri"),
53
+ ]
54
+ _id_field = "id"
55
+ _model = OAuth2Client
56
+ _base_schema = base_schema
57
+
58
+ def _base_query(self):
59
+ return self._request.dbsession.query(OAuth2Client)
60
+
61
+ @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2") # type: ignore
62
+ def index(self) -> Dict[str, Any]:
63
+ return super().index() # type: ignore
64
+
65
+ @view_config(route_name="c2cgeoform_grid", renderer="fast_json") # type: ignore
66
+ def grid(self) -> Dict[str, Any]:
67
+ return super().grid() # type: ignore
68
+
69
+ @view_config( # type: ignore
70
+ route_name="c2cgeoform_item", request_method="GET", renderer="../templates/edit.jinja2"
71
+ )
72
+ def view(self) -> Dict[str, Any]:
73
+ return super().edit() # type: ignore
74
+
75
+ @view_config( # type: ignore
76
+ route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2"
77
+ )
78
+ def save(self) -> Dict[str, Any]:
79
+ return super().save() # type: ignore
80
+
81
+ @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore
82
+ def delete(self) -> Dict[str, Any]:
83
+ return super().delete() # type: ignore
84
+
85
+ @view_config( # type: ignore
86
+ route_name="c2cgeoform_item_duplicate", request_method="GET", renderer="../templates/edit.jinja2"
87
+ )
88
+ def duplicate(self) -> Dict[str, Any]:
89
+ return super().duplicate() # type: ignore