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.
- c2cgeoportal_admin/__init__.py +14 -6
- c2cgeoportal_admin/lib/{lingua_extractor.py → lingva_extractor.py} +6 -6
- c2cgeoportal_admin/lib/ogcserver_synchronizer.py +6 -5
- c2cgeoportal_admin/routes.py +12 -3
- c2cgeoportal_admin/schemas/dimensions.py +4 -2
- c2cgeoportal_admin/schemas/functionalities.py +9 -12
- c2cgeoportal_admin/schemas/interfaces.py +7 -3
- c2cgeoportal_admin/schemas/metadata.py +13 -13
- c2cgeoportal_admin/schemas/restriction_areas.py +5 -3
- c2cgeoportal_admin/schemas/roles.py +7 -3
- c2cgeoportal_admin/schemas/treegroup.py +14 -10
- c2cgeoportal_admin/schemas/treeitem.py +2 -2
- c2cgeoportal_admin/static/theme.css +3 -0
- c2cgeoportal_admin/views/dimension_layers.py +11 -7
- c2cgeoportal_admin/views/functionalities.py +25 -18
- c2cgeoportal_admin/views/interfaces.py +22 -15
- c2cgeoportal_admin/views/layer_groups.py +33 -20
- c2cgeoportal_admin/views/layers.py +12 -9
- c2cgeoportal_admin/views/layers_cog.py +135 -0
- c2cgeoportal_admin/views/layers_vectortiles.py +42 -27
- c2cgeoportal_admin/views/layers_wms.py +47 -32
- c2cgeoportal_admin/views/layers_wmts.py +46 -32
- c2cgeoportal_admin/views/layertree.py +9 -8
- c2cgeoportal_admin/views/logged_views.py +15 -12
- c2cgeoportal_admin/views/logs.py +9 -8
- c2cgeoportal_admin/views/oauth2_clients.py +26 -22
- c2cgeoportal_admin/views/ogc_servers.py +48 -34
- c2cgeoportal_admin/views/restriction_areas.py +29 -19
- c2cgeoportal_admin/views/roles.py +29 -19
- c2cgeoportal_admin/views/themes.py +35 -24
- c2cgeoportal_admin/views/themes_ordering.py +11 -11
- c2cgeoportal_admin/views/treeitems.py +13 -11
- c2cgeoportal_admin/views/users.py +37 -22
- c2cgeoportal_admin/widgets.py +3 -3
- {c2cgeoportal_admin-2.8.1.181.dist-info → c2cgeoportal_admin-2.9rc2.dist-info}/METADATA +3 -12
- {c2cgeoportal_admin-2.8.1.181.dist-info → c2cgeoportal_admin-2.9rc2.dist-info}/RECORD +48 -46
- {c2cgeoportal_admin-2.8.1.181.dist-info → c2cgeoportal_admin-2.9rc2.dist-info}/WHEEL +1 -1
- c2cgeoportal_admin-2.9rc2.dist-info/entry_points.txt +5 -0
- tests/__init__.py +13 -8
- tests/conftest.py +20 -10
- tests/test_layers_cog.py +243 -0
- tests/test_layers_vectortiles.py +2 -7
- tests/{test_lingua_extractor_config.py → test_lingva_extractor_config.py} +3 -3
- tests/test_logs.py +3 -4
- tests/test_oauth2_clients.py +3 -2
- tests/test_role.py +3 -2
- tests/test_user.py +8 -2
- c2cgeoportal_admin-2.8.1.181.dist-info/entry_points.txt +0 -6
- {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-
|
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
|
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))
|
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
|
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
|
103
|
+
return self._base_query()
|
89
104
|
|
90
|
-
@view_config(route_name="c2cgeoform_index", renderer="../templates/index.jinja2") # type: ignore
|
91
|
-
def index(self) ->
|
92
|
-
return super().index()
|
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) ->
|
96
|
-
return super().grid()
|
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) ->
|
99
|
-
actions:
|
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) ->
|
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"])
|
123
|
-
return super().edit()
|
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) ->
|
129
|
-
return super().save()
|
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) ->
|
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) ->
|
139
|
-
return super().duplicate()
|
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) ->
|
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-
|
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
|
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))
|
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
|
80
|
-
return super().
|
87
|
+
def _base_query(self) -> sqlalchemy.orm.query.Query[LayerWMTS]:
|
88
|
+
return super()._sub_query(self._request.dbsession.query(LayerWMTS).distinct())
|
81
89
|
|
82
|
-
|
83
|
-
|
84
|
-
|
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="
|
87
|
-
def
|
88
|
-
return super().
|
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
|
-
|
91
|
-
|
92
|
-
|
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) ->
|
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"])
|
115
|
-
return super().edit()
|
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) ->
|
121
|
-
return super().save()
|
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) ->
|
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) ->
|
131
|
-
return super().duplicate()
|
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) ->
|
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-
|
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
|
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) ->
|
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) ->
|
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:
|
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) ->
|
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) ->
|
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-
|
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
|
29
|
+
from typing import Generic, TypeVar
|
30
30
|
|
31
|
-
import
|
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
|
-
|
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) ->
|
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) ->
|
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
|
63
|
+
return response
|
64
64
|
|
65
65
|
def _create_log(
|
66
66
|
self,
|
67
67
|
action: LogAction,
|
68
|
-
obj: Base,
|
69
|
-
element_url_table:
|
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(
|
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),
|
c2cgeoportal_admin/views/logs.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2023-
|
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
|
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):
|
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-
|
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
|
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) ->
|
66
|
-
return super().index()
|
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) ->
|
70
|
-
return super().grid()
|
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) ->
|
76
|
-
return super().edit()
|
81
|
+
def view(self) -> ObjectResponse:
|
82
|
+
return super().edit()
|
77
83
|
|
78
|
-
@view_config( # type: ignore
|
79
|
-
|
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) ->
|
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) ->
|
92
|
-
return super().duplicate()
|
95
|
+
def duplicate(self) -> ObjectResponse:
|
96
|
+
return super().duplicate()
|