c2cgeoportal-admin 2.8.1.181__py3-none-any.whl → 2.9rc2__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 (49) hide show
  1. c2cgeoportal_admin/__init__.py +14 -6
  2. c2cgeoportal_admin/lib/{lingua_extractor.py → lingva_extractor.py} +6 -6
  3. c2cgeoportal_admin/lib/ogcserver_synchronizer.py +6 -5
  4. c2cgeoportal_admin/routes.py +12 -3
  5. c2cgeoportal_admin/schemas/dimensions.py +4 -2
  6. c2cgeoportal_admin/schemas/functionalities.py +9 -12
  7. c2cgeoportal_admin/schemas/interfaces.py +7 -3
  8. c2cgeoportal_admin/schemas/metadata.py +13 -13
  9. c2cgeoportal_admin/schemas/restriction_areas.py +5 -3
  10. c2cgeoportal_admin/schemas/roles.py +7 -3
  11. c2cgeoportal_admin/schemas/treegroup.py +14 -10
  12. c2cgeoportal_admin/schemas/treeitem.py +2 -2
  13. c2cgeoportal_admin/static/theme.css +3 -0
  14. c2cgeoportal_admin/views/dimension_layers.py +11 -7
  15. c2cgeoportal_admin/views/functionalities.py +25 -18
  16. c2cgeoportal_admin/views/interfaces.py +22 -15
  17. c2cgeoportal_admin/views/layer_groups.py +33 -20
  18. c2cgeoportal_admin/views/layers.py +12 -9
  19. c2cgeoportal_admin/views/layers_cog.py +135 -0
  20. c2cgeoportal_admin/views/layers_vectortiles.py +42 -27
  21. c2cgeoportal_admin/views/layers_wms.py +47 -32
  22. c2cgeoportal_admin/views/layers_wmts.py +46 -32
  23. c2cgeoportal_admin/views/layertree.py +9 -8
  24. c2cgeoportal_admin/views/logged_views.py +15 -12
  25. c2cgeoportal_admin/views/logs.py +9 -8
  26. c2cgeoportal_admin/views/oauth2_clients.py +26 -22
  27. c2cgeoportal_admin/views/ogc_servers.py +48 -34
  28. c2cgeoportal_admin/views/restriction_areas.py +29 -19
  29. c2cgeoportal_admin/views/roles.py +29 -19
  30. c2cgeoportal_admin/views/themes.py +35 -24
  31. c2cgeoportal_admin/views/themes_ordering.py +11 -11
  32. c2cgeoportal_admin/views/treeitems.py +13 -11
  33. c2cgeoportal_admin/views/users.py +37 -22
  34. c2cgeoportal_admin/widgets.py +3 -3
  35. {c2cgeoportal_admin-2.8.1.181.dist-info → c2cgeoportal_admin-2.9rc2.dist-info}/METADATA +3 -12
  36. {c2cgeoportal_admin-2.8.1.181.dist-info → c2cgeoportal_admin-2.9rc2.dist-info}/RECORD +48 -46
  37. {c2cgeoportal_admin-2.8.1.181.dist-info → c2cgeoportal_admin-2.9rc2.dist-info}/WHEEL +1 -1
  38. c2cgeoportal_admin-2.9rc2.dist-info/entry_points.txt +5 -0
  39. tests/__init__.py +13 -8
  40. tests/conftest.py +20 -10
  41. tests/test_layers_cog.py +243 -0
  42. tests/test_layers_vectortiles.py +2 -7
  43. tests/{test_lingua_extractor_config.py → test_lingva_extractor_config.py} +3 -3
  44. tests/test_logs.py +3 -4
  45. tests/test_oauth2_clients.py +3 -2
  46. tests/test_role.py +3 -2
  47. tests/test_user.py +8 -2
  48. c2cgeoportal_admin-2.8.1.181.dist-info/entry_points.txt +0 -6
  49. {c2cgeoportal_admin-2.8.1.181.dist-info → c2cgeoportal_admin-2.9rc2.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2017-2023, Camptocamp SA
1
+ # Copyright (c) 2017-2024, Camptocamp SA
2
2
  # All rights reserved.
3
3
 
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -27,11 +27,19 @@
27
27
 
28
28
 
29
29
  from functools import partial
30
- from typing import Any, Dict, List, Optional
31
30
 
32
31
  import sqlalchemy
32
+ from c2cgeoform import JSONDict
33
33
  from c2cgeoform.schema import GeoFormSchemaNode
34
- from c2cgeoform.views.abstract_views import ItemAction, ListField
34
+ from c2cgeoform.views.abstract_views import (
35
+ DeleteResponse,
36
+ GridResponse,
37
+ IndexResponse,
38
+ ItemAction,
39
+ ListField,
40
+ ObjectResponse,
41
+ SaveResponse,
42
+ )
35
43
  from deform.widget import FormWidget
36
44
  from pyramid.view import view_config, view_defaults
37
45
  from sqlalchemy import delete, insert, inspect, update
@@ -54,15 +62,15 @@ base_schema.add(metadata_schema_node(LayerWMS.metadatas, LayerWMS))
54
62
  base_schema.add(interfaces_schema_node(LayerWMS.interfaces))
55
63
  base_schema.add(restrictionareas_schema_node(LayerWMS.restrictionareas))
56
64
  base_schema.add_unique_validator(LayerWMS.name, LayerWMS.id)
57
- base_schema.add(parent_id_node(LayerGroup)) # type: ignore
65
+ base_schema.add(parent_id_node(LayerGroup))
58
66
 
59
67
 
60
68
  @view_defaults(match_param="table=layers_wms")
61
- class LayerWmsViews(DimensionLayerViews):
69
+ class LayerWmsViews(DimensionLayerViews[LayerWMS]):
62
70
  """The WMS layer administration view."""
63
71
 
64
72
  _list_fields = (
65
- DimensionLayerViews._list_fields
73
+ DimensionLayerViews._list_fields # pylint: disable=protected-access
66
74
  + [
67
75
  _list_field(
68
76
  "ogc_server",
@@ -77,27 +85,34 @@ class LayerWmsViews(DimensionLayerViews):
77
85
  _list_field("time_mode"),
78
86
  _list_field("time_widget"),
79
87
  ]
80
- + DimensionLayerViews._extra_list_fields
88
+ + DimensionLayerViews._extra_list_fields # pylint: disable=protected-access
81
89
  )
82
90
  _id_field = "id"
83
91
  _model = LayerWMS
84
92
  _base_schema = base_schema
85
93
 
86
- def _base_query(self, query: Optional[sqlalchemy.orm.query.Query] = None) -> sqlalchemy.orm.query.Query:
94
+ def _base_query(self) -> sqlalchemy.orm.query.Query[LayerWMS]:
95
+ return super()._sub_query(
96
+ self._request.dbsession.query(LayerWMS, OGCServer.name).distinct().outerjoin(LayerWMS.ogc_server)
97
+ )
98
+
99
+ def _sub_query(
100
+ self, query: sqlalchemy.orm.query.Query[LayerWMS] | None
101
+ ) -> sqlalchemy.orm.query.Query[LayerWMS]:
87
102
  del query
88
- return super()._base_query(self._request.dbsession.query(LayerWMS).distinct().outerjoin("ogc_server"))
103
+ return self._base_query()
89
104
 
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
105
+ @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2") # type: ignore[misc]
106
+ def index(self) -> IndexResponse:
107
+ return super().index()
93
108
 
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
109
+ @view_config(route_name="c2cgeoform_grid", renderer="fast_json") # type: ignore[misc]
110
+ def grid(self) -> GridResponse:
111
+ return super().grid()
97
112
 
98
- def _item_actions(self, item: LayerWMS, readonly: bool = False) -> List[ItemAction]:
99
- actions: List[ItemAction] = super()._item_actions(item, readonly)
100
- if inspect(item).persistent:
113
+ def _item_actions(self, item: LayerWMS, readonly: bool = False) -> list[ItemAction]:
114
+ actions: list[ItemAction] = super()._item_actions(item, readonly)
115
+ if inspect(item).persistent: # type: ignore[attr-defined]
101
116
  actions.insert(
102
117
  next((i for i, v in enumerate(actions) if v.name() == "delete")),
103
118
  ItemAction(
@@ -111,35 +126,35 @@ class LayerWmsViews(DimensionLayerViews):
111
126
  )
112
127
  return actions
113
128
 
114
- @view_config( # type: ignore
129
+ @view_config( # type: ignore[misc]
115
130
  route_name="c2cgeoform_item", request_method="GET", renderer="../templates/edit.jinja2"
116
131
  )
117
- def view(self) -> Dict[str, Any]:
132
+ def view(self) -> ObjectResponse:
118
133
  if self._is_new():
119
134
  dbsession = self._request.dbsession
120
135
  default_wms = LayerWMS.get_default(dbsession)
121
136
  if default_wms:
122
- return self.copy(default_wms, excludes=["name", "layer"]) # type: ignore
123
- return super().edit() # type: ignore
137
+ return self.copy(default_wms, excludes=["name", "layer"])
138
+ return super().edit()
124
139
 
125
- @view_config( # type: ignore
140
+ @view_config( # type: ignore[misc]
126
141
  route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2"
127
142
  )
128
- def save(self) -> Dict[str, Any]:
129
- return super().save() # type: ignore
143
+ def save(self) -> SaveResponse:
144
+ return super().save()
130
145
 
131
- @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore
132
- def delete(self) -> Dict[str, Any]:
146
+ @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore[misc]
147
+ def delete(self) -> DeleteResponse:
133
148
  return super().delete()
134
149
 
135
- @view_config( # type: ignore
150
+ @view_config( # type: ignore[misc]
136
151
  route_name="c2cgeoform_item_duplicate", request_method="GET", renderer="../templates/edit.jinja2"
137
152
  )
138
- def duplicate(self) -> Dict[str, Any]:
139
- return super().duplicate() # type: ignore
153
+ def duplicate(self) -> ObjectResponse:
154
+ return super().duplicate()
140
155
 
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]:
156
+ @view_config(route_name="convert_to_wmts", request_method="POST", renderer="fast_json") # type: ignore[misc]
157
+ def convert_to_wmts(self) -> JSONDict:
143
158
  src = self._get_object()
144
159
  dbsession = self._request.dbsession
145
160
  default_wmts = LayerWMTS.get_default(dbsession)
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2017-2023, Camptocamp SA
1
+ # Copyright (c) 2017-2024, Camptocamp SA
2
2
  # All rights reserved.
3
3
 
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -27,11 +27,19 @@
27
27
 
28
28
 
29
29
  from functools import partial
30
- from typing import Any, Dict, List, Optional
31
30
 
32
31
  import sqlalchemy
32
+ from c2cgeoform import JSONDict
33
33
  from c2cgeoform.schema import GeoFormSchemaNode
34
- from c2cgeoform.views.abstract_views import ItemAction, ListField
34
+ from c2cgeoform.views.abstract_views import (
35
+ DeleteResponse,
36
+ GridResponse,
37
+ IndexResponse,
38
+ ItemAction,
39
+ ListField,
40
+ ObjectResponse,
41
+ SaveResponse,
42
+ )
35
43
  from deform.widget import FormWidget
36
44
  from pyramid.view import view_config, view_defaults
37
45
  from sqlalchemy import delete, insert, inspect, update
@@ -54,15 +62,15 @@ base_schema.add(metadata_schema_node(LayerWMTS.metadatas, LayerWMTS))
54
62
  base_schema.add(interfaces_schema_node(LayerWMTS.interfaces))
55
63
  base_schema.add(restrictionareas_schema_node(LayerWMTS.restrictionareas))
56
64
  base_schema.add_unique_validator(LayerWMTS.name, LayerWMTS.id)
57
- base_schema.add(parent_id_node(LayerGroup)) # type: ignore
65
+ base_schema.add(parent_id_node(LayerGroup))
58
66
 
59
67
 
60
68
  @view_defaults(match_param="table=layers_wmts")
61
- class LayerWmtsViews(DimensionLayerViews):
69
+ class LayerWmtsViews(DimensionLayerViews[LayerWMTS]):
62
70
  """The WMTS layer administration view."""
63
71
 
64
72
  _list_fields = (
65
- DimensionLayerViews._list_fields
73
+ DimensionLayerViews._list_fields # pylint: disable=protected-access
66
74
  + [
67
75
  _list_field("url"),
68
76
  _list_field("layer"),
@@ -70,26 +78,32 @@ class LayerWmtsViews(DimensionLayerViews):
70
78
  _list_field("matrix_set"),
71
79
  _list_field("image_type"),
72
80
  ]
73
- + DimensionLayerViews._extra_list_fields
81
+ + DimensionLayerViews._extra_list_fields # pylint: disable=protected-access
74
82
  )
75
83
  _id_field = "id"
76
84
  _model = LayerWMTS
77
85
  _base_schema = base_schema
78
86
 
79
- def _base_query(self, query: Optional[sqlalchemy.orm.query.Query] = None) -> sqlalchemy.orm.query.Query:
80
- return super()._base_query(self._request.dbsession.query(LayerWMTS).distinct())
87
+ def _base_query(self) -> sqlalchemy.orm.query.Query[LayerWMTS]:
88
+ return super()._sub_query(self._request.dbsession.query(LayerWMTS).distinct())
81
89
 
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
90
+ def _sub_query(
91
+ self, query: sqlalchemy.orm.query.Query[LayerWMTS]
92
+ ) -> sqlalchemy.orm.query.Query[LayerWMTS]:
93
+ del query
94
+ return self._base_query()
85
95
 
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
96
+ @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2") # type: ignore[misc]
97
+ def index(self) -> IndexResponse:
98
+ return super().index()
89
99
 
90
- def _item_actions(self, item: LayerWMTS, readonly: bool = False) -> List[ItemAction]:
91
- actions: List[ItemAction] = super()._item_actions(item, readonly)
92
- if inspect(item).persistent:
100
+ @view_config(route_name="c2cgeoform_grid", renderer="fast_json") # type: ignore[misc]
101
+ def grid(self) -> GridResponse:
102
+ return super().grid()
103
+
104
+ def _item_actions(self, item: LayerWMTS, readonly: bool = False) -> list[ItemAction]:
105
+ actions: list[ItemAction] = super()._item_actions(item, readonly)
106
+ if inspect(item).persistent: # type: ignore[attr-defined]
93
107
  actions.insert(
94
108
  next((i for i, v in enumerate(actions) if v.name() == "delete")),
95
109
  ItemAction(
@@ -103,35 +117,35 @@ class LayerWmtsViews(DimensionLayerViews):
103
117
  )
104
118
  return actions
105
119
 
106
- @view_config( # type: ignore
120
+ @view_config( # type: ignore[misc]
107
121
  route_name="c2cgeoform_item", request_method="GET", renderer="../templates/edit.jinja2"
108
122
  )
109
- def view(self) -> Dict[str, Any]:
123
+ def view(self) -> ObjectResponse:
110
124
  if self._is_new():
111
125
  dbsession = self._request.dbsession
112
126
  default_wmts = LayerWMTS.get_default(dbsession)
113
127
  if default_wmts:
114
- return self.copy(default_wmts, excludes=["name", "layer"]) # type: ignore
115
- return super().edit() # type: ignore
128
+ return self.copy(default_wmts, excludes=["name", "layer"])
129
+ return super().edit()
116
130
 
117
- @view_config( # type: ignore
131
+ @view_config( # type: ignore[misc]
118
132
  route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2"
119
133
  )
120
- def save(self) -> Dict[str, Any]:
121
- return super().save() # type: ignore
134
+ def save(self) -> SaveResponse:
135
+ return super().save()
122
136
 
123
- @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore
124
- def delete(self) -> Dict[str, Any]:
137
+ @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore[misc]
138
+ def delete(self) -> DeleteResponse:
125
139
  return super().delete()
126
140
 
127
- @view_config( # type: ignore
141
+ @view_config( # type: ignore[misc]
128
142
  route_name="c2cgeoform_item_duplicate", request_method="GET", renderer="../templates/edit.jinja2"
129
143
  )
130
- def duplicate(self) -> Dict[str, Any]:
131
- return super().duplicate() # type: ignore
144
+ def duplicate(self) -> ObjectResponse:
145
+ return super().duplicate()
132
146
 
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]:
147
+ @view_config(route_name="convert_to_wms", request_method="POST", renderer="fast_json") # type: ignore[misc]
148
+ def convert_to_wms(self) -> JSONDict:
135
149
  src = self._get_object()
136
150
  dbsession = self._request.dbsession
137
151
  default_wms = LayerWMS.get_default(dbsession)
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2017-2023, Camptocamp SA
1
+ # Copyright (c) 2017-2024, Camptocamp SA
2
2
  # All rights reserved.
3
3
 
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -26,10 +26,10 @@
26
26
  # either expressed or implied, of the FreeBSD Project.
27
27
 
28
28
 
29
- from typing import Any, Dict, List, Optional
29
+ from typing import Any
30
30
 
31
31
  import pyramid.request
32
- from c2cgeoform.views.abstract_views import ItemAction
32
+ from c2cgeoform.views.abstract_views import DeleteResponse, ItemAction
33
33
  from pyramid.httpexceptions import HTTPNotFound
34
34
  from pyramid.view import view_config, view_defaults
35
35
  from translationstring import TranslationStringFactory
@@ -42,6 +42,7 @@ itemtypes_tables = {
42
42
  "group": "layer_groups",
43
43
  "l_wms": "layers_wms",
44
44
  "l_wmts": "layers_wmts",
45
+ "l_cog": "layers_cog",
45
46
  }
46
47
 
47
48
 
@@ -54,13 +55,13 @@ class LayerTreeViews:
54
55
  self._dbsession = request.dbsession
55
56
 
56
57
  @view_config(route_name="layertree", renderer="../templates/layertree.jinja2") # type: ignore
57
- def index(self) -> Dict[str, int]:
58
+ def index(self) -> dict[str, int]:
58
59
  node_limit = self._request.registry.settings["admin_interface"].get("layer_tree_max_nodes")
59
60
  limit_exceeded = self._dbsession.query(LayergroupTreeitem).count() < node_limit
60
61
  return {"limit_exceeded": limit_exceeded, "interfaces": self._dbsession.query(Interface).all()}
61
62
 
62
63
  @view_config(route_name="layertree_children", renderer="fast_json") # type: ignore
63
- def children(self) -> List[Dict[str, Any]]:
64
+ def children(self) -> list[dict[str, Any]]:
64
65
  interface = self._request.params.get("interface", None)
65
66
  group_id = self._request.params.get("group_id", None)
66
67
  path = self._request.params.get("path", "")
@@ -97,7 +98,7 @@ class LayerTreeViews:
97
98
  or interface in [interface.name for interface in item.interfaces]
98
99
  ]
99
100
 
100
- def _item_actions(self, item: TreeItem, parent_id: Optional[int] = None) -> List[ItemAction]:
101
+ def _item_actions(self, item: TreeItem, parent_id: int | None = None) -> list[ItemAction]:
101
102
  actions = []
102
103
  actions.append(
103
104
  ItemAction(
@@ -179,7 +180,7 @@ class LayerTreeViews:
179
180
  return actions
180
181
 
181
182
  @view_config(route_name="layertree_unlink", request_method="DELETE", renderer="fast_json") # type: ignore
182
- def unlink(self) -> Dict[str, Any]:
183
+ def unlink(self) -> dict[str, Any]:
183
184
  group_id = self._request.matchdict.get("group_id")
184
185
  item_id = self._request.matchdict.get("item_id")
185
186
  link = (
@@ -195,7 +196,7 @@ class LayerTreeViews:
195
196
  return {"success": True, "redirect": self._request.route_url("layertree")}
196
197
 
197
198
  @view_config(route_name="layertree_delete", request_method="DELETE", renderer="fast_json") # type: ignore
198
- def delete(self) -> Dict[str, Any]:
199
+ def delete(self) -> DeleteResponse:
199
200
  item_id = self._request.matchdict.get("item_id")
200
201
  item = self._request.dbsession.query(TreeItem).get(item_id)
201
202
  if item is None:
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023-2023, Camptocamp SA
1
+ # Copyright (c) 2023-2024, Camptocamp SA
2
2
  # All rights reserved.
3
3
 
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -26,25 +26,25 @@
26
26
  # either expressed or implied, of the FreeBSD Project.
27
27
 
28
28
  import datetime
29
- from typing import Any, Dict, Optional, Union
29
+ from typing import Generic, TypeVar
30
30
 
31
- import pytz
32
- from c2cgeoform.views.abstract_views import AbstractViews
31
+ from c2cgeoform.views.abstract_views import AbstractViews, DeleteResponse, SaveResponse
33
32
  from pyramid.httpexceptions import HTTPFound
34
33
 
35
34
  from c2cgeoportal_commons.models import Base
36
35
  from c2cgeoportal_commons.models.main import Log, LogAction
37
36
 
37
+ _T = TypeVar("_T", bound=Log)
38
38
 
39
- class LoggedViews(AbstractViews): # type: ignore
39
+
40
+ class LoggedViews(AbstractViews[_T], Generic[_T]):
40
41
  """Extension of AbstractViews which log actions in a table."""
41
42
 
42
43
  _log_model = Log # main.Log or static.Log
43
44
  _name_field = "name"
44
45
 
45
- def save(self) -> Union[HTTPFound, Dict[str, Any]]:
46
+ def save(self) -> SaveResponse:
46
47
  response = super().save()
47
-
48
48
  if isinstance(response, HTTPFound):
49
49
  self._create_log(
50
50
  action=LogAction.INSERT if self._is_new() else LogAction.UPDATE,
@@ -53,23 +53,26 @@ class LoggedViews(AbstractViews): # type: ignore
53
53
 
54
54
  return response
55
55
 
56
- def delete(self) -> Dict[str, Any]:
56
+ def delete(self) -> DeleteResponse:
57
57
  obj = self._get_object()
58
58
 
59
59
  response = super().delete()
60
60
 
61
61
  self._create_log(LogAction.DELETE, obj)
62
62
 
63
- return response # type: ignore
63
+ return response
64
64
 
65
65
  def _create_log(
66
66
  self,
67
67
  action: LogAction,
68
- obj: Base,
69
- element_url_table: Optional[str] = None,
68
+ obj: Base, # type: ignore[valid-type]
69
+ element_url_table: str | None = None,
70
70
  ) -> None:
71
+ assert self._model is not None
72
+ assert self._name_field is not None
73
+ assert self._id_field is not None
71
74
  log = self._log_model(
72
- date=datetime.datetime.now(pytz.utc),
75
+ date=datetime.datetime.now(datetime.timezone.utc),
73
76
  action=action,
74
77
  element_type=self._model.__tablename__,
75
78
  element_id=getattr(obj, self._id_field),
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023-2023, Camptocamp SA
1
+ # Copyright (c) 2023-2024, Camptocamp SA
2
2
  # All rights reserved.
3
3
 
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,8 @@
27
27
 
28
28
  from functools import partial
29
29
 
30
- from c2cgeoform.views.abstract_views import AbstractViews, ItemAction, ListField
30
+ from c2cgeoform import JSONDict
31
+ from c2cgeoform.views.abstract_views import AbstractViews, GridResponse, IndexResponse, ItemAction, ListField
31
32
  from pyramid.view import view_config, view_defaults
32
33
 
33
34
  from c2cgeoportal_commons.models import _
@@ -37,7 +38,7 @@ _list_field = partial(ListField, AbstractLog)
37
38
 
38
39
 
39
40
  @view_defaults(match_param="table=logs")
40
- class LogViews(AbstractViews): # type: ignore
41
+ class LogViews(AbstractViews[AbstractLog]):
41
42
  """The theme administration view."""
42
43
 
43
44
  # We pass labels explicitly because actually we are not able to get info
@@ -56,18 +57,18 @@ class LogViews(AbstractViews): # type: ignore
56
57
  _id_field = "id"
57
58
  _model = AbstractLog
58
59
 
59
- @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2")
60
- def index(self):
60
+ @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2") # type: ignore[misc]
61
+ def index(self) -> IndexResponse:
61
62
  return super().index()
62
63
 
63
- @view_config(route_name="c2cgeoform_grid", renderer="fast_json")
64
- def grid(self):
64
+ @view_config(route_name="c2cgeoform_grid", renderer="fast_json") # type: ignore[misc]
65
+ def grid(self) -> GridResponse:
65
66
  return super().grid()
66
67
 
67
68
  def _grid_actions(self):
68
69
  return []
69
70
 
70
- def _grid_item_actions(self, item):
71
+ def _grid_item_actions(self, item: AbstractLog) -> JSONDict:
71
72
  element_url = self._request.route_url(
72
73
  "c2cgeoform_item",
73
74
  table=item.element_url_table,
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2021-2023, Camptocamp SA
1
+ # Copyright (c) 2021-2024, Camptocamp SA
2
2
  # All rights reserved.
3
3
 
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -27,10 +27,16 @@
27
27
 
28
28
 
29
29
  from functools import partial
30
- from typing import Any, Dict
31
30
 
32
31
  from c2cgeoform.schema import GeoFormSchemaNode
33
- from c2cgeoform.views.abstract_views import ListField
32
+ from c2cgeoform.views.abstract_views import (
33
+ DeleteResponse,
34
+ GridResponse,
35
+ IndexResponse,
36
+ ListField,
37
+ ObjectResponse,
38
+ SaveResponse,
39
+ )
34
40
  from pyramid.view import view_config, view_defaults
35
41
 
36
42
  from c2cgeoportal_admin.views.logged_views import LoggedViews
@@ -43,7 +49,7 @@ base_schema.add_unique_validator(OAuth2Client.client_id, OAuth2Client.id)
43
49
 
44
50
 
45
51
  @view_defaults(match_param="table=oauth2_clients")
46
- class OAuth2ClientViews(LoggedViews):
52
+ class OAuth2ClientViews(LoggedViews[OAuth2Client]):
47
53
  """The oAuth2 client administration view."""
48
54
 
49
55
  _list_fields = [
@@ -61,32 +67,30 @@ class OAuth2ClientViews(LoggedViews):
61
67
  def _base_query(self):
62
68
  return self._request.dbsession.query(OAuth2Client)
63
69
 
64
- @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2") # type: ignore
65
- def index(self) -> Dict[str, Any]:
66
- return super().index() # type: ignore
70
+ @view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2") # type: ignore[misc]
71
+ def index(self) -> IndexResponse:
72
+ return super().index()
67
73
 
68
- @view_config(route_name="c2cgeoform_grid", renderer="fast_json") # type: ignore
69
- def grid(self) -> Dict[str, Any]:
70
- return super().grid() # type: ignore
74
+ @view_config(route_name="c2cgeoform_grid", renderer="fast_json") # type: ignore[misc]
75
+ def grid(self) -> GridResponse:
76
+ return super().grid()
71
77
 
72
- @view_config( # type: ignore
78
+ @view_config( # type: ignore[misc]
73
79
  route_name="c2cgeoform_item", request_method="GET", renderer="../templates/edit.jinja2"
74
80
  )
75
- def view(self) -> Dict[str, Any]:
76
- return super().edit() # type: ignore
81
+ def view(self) -> ObjectResponse:
82
+ return super().edit()
77
83
 
78
- @view_config( # type: ignore
79
- route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2"
80
- )
81
- def save(self) -> Dict[str, Any]:
84
+ @view_config(route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2") # type: ignore[misc]
85
+ def save(self) -> SaveResponse:
82
86
  return super().save()
83
87
 
84
- @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore
85
- def delete(self) -> Dict[str, Any]:
88
+ @view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore[misc]
89
+ def delete(self) -> DeleteResponse:
86
90
  return super().delete()
87
91
 
88
- @view_config( # type: ignore
92
+ @view_config( # type: ignore[misc]
89
93
  route_name="c2cgeoform_item_duplicate", request_method="GET", renderer="../templates/edit.jinja2"
90
94
  )
91
- def duplicate(self) -> Dict[str, Any]:
92
- return super().duplicate() # type: ignore
95
+ def duplicate(self) -> ObjectResponse:
96
+ return super().duplicate()