c2cgeoportal-admin 2.7.1.156__py3-none-any.whl → 2.8.1.180__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 +16 -1
- c2cgeoportal_admin/lib/ogcserver_synchronizer.py +4 -4
- c2cgeoportal_admin/routes.py +3 -1
- c2cgeoportal_admin/schemas/metadata.py +1 -1
- c2cgeoportal_admin/schemas/treegroup.py +2 -2
- c2cgeoportal_admin/templates/404.jinja2 +18 -2
- c2cgeoportal_admin/templates/widgets/metadata.pt +1 -1
- c2cgeoportal_admin/views/__init__.py +29 -0
- c2cgeoportal_admin/views/functionalities.py +4 -3
- c2cgeoportal_admin/views/interfaces.py +4 -3
- c2cgeoportal_admin/views/layer_groups.py +1 -1
- c2cgeoportal_admin/views/layers_wms.py +5 -3
- c2cgeoportal_admin/views/layers_wmts.py +5 -3
- c2cgeoportal_admin/views/layertree.py +2 -2
- c2cgeoportal_admin/views/logged_views.py +80 -0
- c2cgeoportal_admin/views/logs.py +90 -0
- c2cgeoportal_admin/views/oauth2_clients.py +9 -6
- c2cgeoportal_admin/views/ogc_servers.py +66 -12
- c2cgeoportal_admin/views/restriction_areas.py +4 -3
- c2cgeoportal_admin/views/roles.py +4 -3
- c2cgeoportal_admin/views/themes.py +1 -1
- c2cgeoportal_admin/views/treeitems.py +4 -3
- c2cgeoportal_admin/views/users.py +7 -4
- c2cgeoportal_admin/widgets.py +2 -2
- {c2cgeoportal_admin-2.7.1.156.dist-info → c2cgeoportal_admin-2.8.1.180.dist-info}/METADATA +13 -7
- c2cgeoportal_admin-2.8.1.180.dist-info/RECORD +95 -0
- {c2cgeoportal_admin-2.7.1.156.dist-info → c2cgeoportal_admin-2.8.1.180.dist-info}/entry_points.txt +1 -0
- tests/__init__.py +2 -3
- tests/test_edit_url.py +0 -1
- tests/test_functionalities.py +29 -4
- tests/test_home.py +0 -1
- tests/test_interface.py +27 -4
- tests/test_layer_groups.py +45 -11
- tests/test_layers_vectortiles.py +33 -8
- tests/test_layers_wms.py +43 -10
- tests/test_layers_wmts.py +33 -8
- tests/test_layertree.py +0 -1
- tests/test_left_menu.py +0 -1
- tests/test_lingua_extractor_config.py +1 -3
- tests/test_logs.py +103 -0
- tests/test_metadatas.py +0 -1
- tests/test_oauth2_clients.py +35 -7
- tests/test_ogc_servers.py +65 -27
- tests/test_restriction_areas.py +28 -3
- tests/test_role.py +33 -8
- tests/test_themes.py +33 -6
- tests/test_themes_ordering.py +0 -1
- tests/test_user.py +33 -4
- tests/themes_ordering.py +0 -1
- c2cgeoportal_admin-2.7.1.156.dist-info/RECORD +0 -92
- {c2cgeoportal_admin-2.7.1.156.dist-info → c2cgeoportal_admin-2.8.1.180.dist-info}/WHEEL +0 -0
- {c2cgeoportal_admin-2.7.1.156.dist-info → c2cgeoportal_admin-2.8.1.180.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2017-
|
1
|
+
# Copyright (c) 2017-2023, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -26,29 +26,36 @@
|
|
26
26
|
# either expressed or implied, of the FreeBSD Project.
|
27
27
|
|
28
28
|
|
29
|
+
import logging
|
30
|
+
import threading
|
29
31
|
from functools import partial
|
30
|
-
from typing import Any, Dict, List, cast
|
32
|
+
from typing import Any, Dict, List, Union, cast
|
31
33
|
|
34
|
+
import requests
|
32
35
|
from c2cgeoform.schema import GeoFormSchemaNode
|
33
36
|
from c2cgeoform.views.abstract_views import AbstractViews, ItemAction, ListField, UserMessage
|
34
37
|
from deform.widget import FormWidget
|
35
|
-
from pyramid.httpexceptions import
|
38
|
+
from pyramid.httpexceptions import HTTPFound
|
36
39
|
from pyramid.view import view_config, view_defaults
|
37
40
|
from sqlalchemy import inspect
|
38
41
|
|
39
42
|
from c2cgeoportal_admin import _
|
40
43
|
from c2cgeoportal_admin.lib.ogcserver_synchronizer import OGCServerSynchronizer
|
44
|
+
from c2cgeoportal_admin.views.logged_views import LoggedViews
|
41
45
|
from c2cgeoportal_commons.lib.literal import Literal
|
42
|
-
from c2cgeoportal_commons.models
|
46
|
+
from c2cgeoportal_commons.models import cache_invalidate_cb
|
47
|
+
from c2cgeoportal_commons.models.main import LogAction, OGCServer
|
43
48
|
|
44
49
|
_list_field = partial(ListField, OGCServer)
|
45
50
|
|
46
51
|
base_schema = GeoFormSchemaNode(OGCServer, widget=FormWidget(fields_template="ogcserver_fields"))
|
47
52
|
base_schema.add_unique_validator(OGCServer.name, OGCServer.id)
|
48
53
|
|
54
|
+
LOG = logging.getLogger(__name__)
|
55
|
+
|
49
56
|
|
50
57
|
@view_defaults(match_param="table=ogc_servers")
|
51
|
-
class OGCServerViews(
|
58
|
+
class OGCServerViews(LoggedViews):
|
52
59
|
"""The OGC server administration view."""
|
53
60
|
|
54
61
|
_list_fields = [
|
@@ -84,10 +91,7 @@ class OGCServerViews(AbstractViews): # type: ignore
|
|
84
91
|
return super().grid() # type: ignore
|
85
92
|
|
86
93
|
def schema(self) -> GeoFormSchemaNode:
|
87
|
-
|
88
|
-
obj = self._get_object()
|
89
|
-
except HTTPNotFound:
|
90
|
-
obj = None
|
94
|
+
obj = self._get_object()
|
91
95
|
|
92
96
|
schema = self._base_schema.clone()
|
93
97
|
schema["url"].description = Literal(
|
@@ -107,6 +111,22 @@ class OGCServerViews(AbstractViews): # type: ignore
|
|
107
111
|
def _item_actions(self, item: OGCServer, readonly: bool = False) -> List[Any]:
|
108
112
|
actions = cast(List[Any], super()._item_actions(item, readonly))
|
109
113
|
if inspect(item).persistent:
|
114
|
+
actions.insert(
|
115
|
+
next((i for i, v in enumerate(actions) if v.name() == "delete")),
|
116
|
+
ItemAction(
|
117
|
+
name="clear-cache",
|
118
|
+
label=_("Clear the cache"),
|
119
|
+
icon="glyphicon glyphicon-hdd",
|
120
|
+
url=self._request.route_url(
|
121
|
+
"ogc_server_clear_cache",
|
122
|
+
id=getattr(item, self._id_field),
|
123
|
+
_query={
|
124
|
+
"came_from": self._request.current_route_url(),
|
125
|
+
},
|
126
|
+
),
|
127
|
+
confirmation=_("The current changes will be lost."),
|
128
|
+
),
|
129
|
+
)
|
110
130
|
actions.insert(
|
111
131
|
next((i for i, v in enumerate(actions) if v.name() == "delete")),
|
112
132
|
ItemAction(
|
@@ -127,8 +147,11 @@ class OGCServerViews(AbstractViews): # type: ignore
|
|
127
147
|
@view_config( # type: ignore
|
128
148
|
route_name="c2cgeoform_item", request_method="POST", renderer="../templates/edit.jinja2"
|
129
149
|
)
|
130
|
-
def save(self) -> Dict[str, Any]:
|
131
|
-
|
150
|
+
def save(self) -> Union[HTTPFound, Dict[str, Any]]:
|
151
|
+
result: Union[HTTPFound, Dict[str, Any]] = super().save()
|
152
|
+
if isinstance(result, HTTPFound):
|
153
|
+
self._update_cache(self._obj)
|
154
|
+
return result
|
132
155
|
|
133
156
|
@view_config(route_name="c2cgeoform_item", request_method="DELETE", renderer="fast_json") # type: ignore
|
134
157
|
def delete(self) -> Dict[str, Any]:
|
@@ -143,7 +166,9 @@ class OGCServerViews(AbstractViews): # type: ignore
|
|
143
166
|
_query=[("msg_col", "cannot_delete")],
|
144
167
|
),
|
145
168
|
}
|
146
|
-
|
169
|
+
result: Dict[str, Any] = super().delete()
|
170
|
+
cache_invalidate_cb()
|
171
|
+
return result
|
147
172
|
|
148
173
|
@view_config( # type: ignore
|
149
174
|
route_name="c2cgeoform_item_duplicate", request_method="GET", renderer="../templates/edit.jinja2"
|
@@ -176,16 +201,45 @@ class OGCServerViews(AbstractViews): # type: ignore
|
|
176
201
|
force_ordering=force_ordering,
|
177
202
|
clean=clean,
|
178
203
|
)
|
204
|
+
|
179
205
|
if "check" in self._request.params:
|
180
206
|
synchronizer.check_layers()
|
207
|
+
|
181
208
|
elif "dry-run" in self._request.params:
|
182
209
|
synchronizer.synchronize(dry_run=True)
|
210
|
+
|
183
211
|
elif "synchronize" in self._request.params:
|
184
212
|
synchronizer.synchronize()
|
213
|
+
|
214
|
+
self._create_log(LogAction.SYNCHRONIZE, obj)
|
215
|
+
|
185
216
|
return {
|
186
217
|
"ogcserver": obj,
|
187
218
|
"success": True,
|
188
219
|
"report": synchronizer.report(),
|
189
220
|
}
|
190
221
|
|
222
|
+
self._update_cache(obj)
|
223
|
+
|
191
224
|
return {}
|
225
|
+
|
226
|
+
def _update_cache(self, ogc_server: OGCServer) -> None:
|
227
|
+
try:
|
228
|
+
ogc_server_id = ogc_server.id
|
229
|
+
|
230
|
+
def update_cache() -> None:
|
231
|
+
response = requests.get(
|
232
|
+
self._request.route_url(
|
233
|
+
"ogc_server_clear_cache",
|
234
|
+
id=ogc_server_id,
|
235
|
+
_query={
|
236
|
+
"came_from": self._request.current_route_url(),
|
237
|
+
},
|
238
|
+
)
|
239
|
+
)
|
240
|
+
if not response.ok:
|
241
|
+
LOG.error("Error while cleaning the OGC server cache:\n%s", response.text)
|
242
|
+
|
243
|
+
threading.Thread(target=update_cache).start()
|
244
|
+
except Exception:
|
245
|
+
LOG.error("Error on cleaning the OGC server cache", exc_info=True)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2017-
|
1
|
+
# Copyright (c) 2017-2023, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -30,13 +30,14 @@ from functools import partial
|
|
30
30
|
|
31
31
|
import colander
|
32
32
|
from c2cgeoform.schema import GeoFormManyToManySchemaNode, GeoFormSchemaNode
|
33
|
-
from c2cgeoform.views.abstract_views import
|
33
|
+
from c2cgeoform.views.abstract_views import ListField
|
34
34
|
from deform.widget import FormWidget
|
35
35
|
from pyramid.view import view_config, view_defaults
|
36
36
|
from sqlalchemy.orm import subqueryload
|
37
37
|
|
38
38
|
from c2cgeoportal_admin.schemas.roles import roles_schema_node
|
39
39
|
from c2cgeoportal_admin.schemas.treegroup import treeitem_edit_url
|
40
|
+
from c2cgeoportal_admin.views.logged_views import LoggedViews
|
40
41
|
from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget
|
41
42
|
from c2cgeoportal_commons.models.main import Layer, RestrictionArea
|
42
43
|
|
@@ -87,7 +88,7 @@ base_schema.add(
|
|
87
88
|
|
88
89
|
|
89
90
|
@view_defaults(match_param="table=restriction_areas")
|
90
|
-
class RestrictionAreaViews(
|
91
|
+
class RestrictionAreaViews(LoggedViews):
|
91
92
|
"""The restriction area administration view."""
|
92
93
|
|
93
94
|
_list_fields = [
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2017-
|
1
|
+
# Copyright (c) 2017-2023, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -30,13 +30,14 @@ from functools import partial
|
|
30
30
|
|
31
31
|
import colander
|
32
32
|
from c2cgeoform.schema import GeoFormManyToManySchemaNode, GeoFormSchemaNode
|
33
|
-
from c2cgeoform.views.abstract_views import
|
33
|
+
from c2cgeoform.views.abstract_views import ListField
|
34
34
|
from deform.widget import FormWidget
|
35
35
|
from pyramid.view import view_config, view_defaults
|
36
36
|
from sqlalchemy.orm import subqueryload
|
37
37
|
|
38
38
|
from c2cgeoportal_admin.schemas.functionalities import functionalities_schema_node
|
39
39
|
from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node
|
40
|
+
from c2cgeoportal_admin.views.logged_views import LoggedViews
|
40
41
|
from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget
|
41
42
|
from c2cgeoportal_commons.models.main import Role
|
42
43
|
from c2cgeoportal_commons.models.static import User
|
@@ -99,7 +100,7 @@ base_schema["users"].children[0].description = ""
|
|
99
100
|
|
100
101
|
|
101
102
|
@view_defaults(match_param="table=roles")
|
102
|
-
class RoleViews(
|
103
|
+
class RoleViews(LoggedViews):
|
103
104
|
"""The roles administration view."""
|
104
105
|
|
105
106
|
_list_fields = [
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2017-
|
1
|
+
# Copyright (c) 2017-2023, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -29,17 +29,18 @@
|
|
29
29
|
from functools import partial
|
30
30
|
|
31
31
|
import sqlalchemy
|
32
|
-
from c2cgeoform.views.abstract_views import
|
32
|
+
from c2cgeoform.views.abstract_views import ListField
|
33
33
|
from pyramid.view import view_config
|
34
34
|
from sqlalchemy.orm import subqueryload
|
35
35
|
from sqlalchemy.sql.functions import concat
|
36
36
|
|
37
|
+
from c2cgeoportal_admin.views.logged_views import LoggedViews
|
37
38
|
from c2cgeoportal_commons.models.main import LayergroupTreeitem, Metadata, TreeGroup, TreeItem
|
38
39
|
|
39
40
|
_list_field = partial(ListField, TreeItem)
|
40
41
|
|
41
42
|
|
42
|
-
class TreeItemViews(
|
43
|
+
class TreeItemViews(LoggedViews):
|
43
44
|
"""The admin tree item view."""
|
44
45
|
|
45
46
|
_list_fields = [
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2017-
|
1
|
+
# Copyright (c) 2017-2023, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -29,7 +29,7 @@
|
|
29
29
|
from functools import partial
|
30
30
|
|
31
31
|
from c2cgeoform.schema import GeoFormSchemaNode
|
32
|
-
from c2cgeoform.views.abstract_views import
|
32
|
+
from c2cgeoform.views.abstract_views import ListField
|
33
33
|
from deform.widget import FormWidget
|
34
34
|
from passwordgenerator import pwgenerator
|
35
35
|
from pyramid.httpexceptions import HTTPFound
|
@@ -37,9 +37,10 @@ from pyramid.view import view_config, view_defaults
|
|
37
37
|
from sqlalchemy.orm import aliased, subqueryload
|
38
38
|
|
39
39
|
from c2cgeoportal_admin.schemas.roles import roles_schema_node
|
40
|
+
from c2cgeoportal_admin.views.logged_views import LoggedViews
|
40
41
|
from c2cgeoportal_commons.lib.email_ import send_email_config
|
41
42
|
from c2cgeoportal_commons.models.main import Role
|
42
|
-
from c2cgeoportal_commons.models.static import User
|
43
|
+
from c2cgeoportal_commons.models.static import Log, User
|
43
44
|
|
44
45
|
_list_field = partial(ListField, User)
|
45
46
|
|
@@ -51,7 +52,7 @@ settings_role = aliased(Role)
|
|
51
52
|
|
52
53
|
|
53
54
|
@view_defaults(match_param="table=users")
|
54
|
-
class UserViews(
|
55
|
+
class UserViews(LoggedViews):
|
55
56
|
"""The admin user view."""
|
56
57
|
|
57
58
|
_list_fields = [
|
@@ -76,6 +77,8 @@ class UserViews(AbstractViews): # type: ignore
|
|
76
77
|
_id_field = "id"
|
77
78
|
_model = User
|
78
79
|
_base_schema = base_schema
|
80
|
+
_log_model = Log
|
81
|
+
_name_field = "username"
|
79
82
|
|
80
83
|
def _base_query(self):
|
81
84
|
return (
|
c2cgeoportal_admin/widgets.py
CHANGED
@@ -90,11 +90,11 @@ class ChildWidget(MappingWidget): # type: ignore
|
|
90
90
|
model = TreeItem
|
91
91
|
label_field = "name"
|
92
92
|
|
93
|
-
def icon_class(self, child: Any) -> Optional[str]: # pylint: disable=
|
93
|
+
def icon_class(self, child: Any) -> Optional[str]: # pylint: disable=useless-return
|
94
94
|
del child
|
95
95
|
return None
|
96
96
|
|
97
|
-
def edit_url( # pylint: disable=
|
97
|
+
def edit_url( # pylint: disable=useless-return
|
98
98
|
self, request: pyramid.request.Request, child: Any
|
99
99
|
) -> Optional[str]:
|
100
100
|
del request
|
@@ -1,11 +1,13 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: c2cgeoportal-admin
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.8.1.180
|
4
4
|
Summary: c2cgeoportal admin
|
5
5
|
Home-page: https://github.com/camptocamp/c2cgeoportal/
|
6
6
|
Author: Camptocamp
|
7
7
|
Author-email: info@camptocamp.com
|
8
|
+
License: UNKNOWN
|
8
9
|
Keywords: web gis geoportail c2cgeoportal geocommune pyramid
|
10
|
+
Platform: UNKNOWN
|
9
11
|
Classifier: Development Status :: 6 - Mature
|
10
12
|
Classifier: Environment :: Web Environment
|
11
13
|
Classifier: Framework :: Pyramid
|
@@ -18,23 +20,25 @@ Classifier: Programming Language :: Python :: 3.8
|
|
18
20
|
Classifier: Topic :: Scientific/Engineering :: GIS
|
19
21
|
Classifier: Typing :: Typed
|
20
22
|
Description-Content-Type: text/markdown
|
23
|
+
Requires-Dist: babel (>=2.9.1)
|
21
24
|
Requires-Dist: c2cgeoform
|
22
25
|
Requires-Dist: c2cwsgiutils
|
26
|
+
Requires-Dist: certifi (>=2022.12.7)
|
23
27
|
Requires-Dist: colander
|
24
28
|
Requires-Dist: deform
|
29
|
+
Requires-Dist: idna (>=3.7)
|
25
30
|
Requires-Dist: passwordgenerator
|
31
|
+
Requires-Dist: pygments (>=2.15.0)
|
26
32
|
Requires-Dist: pyproj
|
27
33
|
Requires-Dist: pyramid
|
28
34
|
Requires-Dist: pyramid-debugtoolbar
|
29
35
|
Requires-Dist: pyramid-jinja2
|
30
36
|
Requires-Dist: pyramid-tm
|
37
|
+
Requires-Dist: requests (>=2.32.0)
|
31
38
|
Requires-Dist: sqlalchemy
|
32
|
-
Requires-Dist: zope.event
|
33
39
|
Requires-Dist: translationstring
|
34
|
-
Requires-Dist:
|
35
|
-
Requires-Dist:
|
36
|
-
Requires-Dist: setuptools (>=65.5.1)
|
37
|
-
Requires-Dist: requests (>=2.31.0)
|
40
|
+
Requires-Dist: urllib3 (>=1.26.17)
|
41
|
+
Requires-Dist: zope.event
|
38
42
|
|
39
43
|
# c2cgeoportal admin interface
|
40
44
|
|
@@ -47,4 +51,6 @@ make preparedev
|
|
47
51
|
make serve
|
48
52
|
```
|
49
53
|
|
50
|
-
Now open http://localhost:8888/ in your favorite browser.
|
54
|
+
Now open http://localhost:8888/admin/ in your favorite browser.
|
55
|
+
|
56
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
c2cgeoportal_admin/__init__.py,sha256=uuW2AC81qIXn7bH7MLHzf9fhEK4liGg3Zi-TosyzKNs,5478
|
2
|
+
c2cgeoportal_admin/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
c2cgeoportal_admin/routes.py,sha256=tgLP5uKhgX80a2gLCpu6C92UtmqwVkOkmJ-tPxEP3QE,4712
|
4
|
+
c2cgeoportal_admin/subscribers.py,sha256=P1CaccDTpuxrWak_gMN2qBurz3OrAZ6aZ1LA7P3avu8,2430
|
5
|
+
c2cgeoportal_admin/widgets.py,sha256=bjMlC4mqx_bAjzIzzu-zqdQ7bc6tVo7mKOMbpmbeN38,6108
|
6
|
+
c2cgeoportal_admin/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
c2cgeoportal_admin/lib/lingua_extractor.py,sha256=Dw4vo46TcUnJ7vvxgFezPYidfEdL2pHJUM0qxAaJ1KE,3380
|
8
|
+
c2cgeoportal_admin/lib/ogcserver_synchronizer.py,sha256=Px9SzBAv5qDTtF1xu6IRzr1u77TA8eAC3cjgI0Rxgks,15515
|
9
|
+
c2cgeoportal_admin/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
+
c2cgeoportal_admin/schemas/dimensions.py,sha256=rPMEuIdGiVGS5e0xqXUu-COVKlrWg9rpp-xe-8aHbOQ,2290
|
11
|
+
c2cgeoportal_admin/schemas/functionalities.py,sha256=AptqKn2oyy74qivzihNfeNvmaDILsl36bSoJdSNXh9Y,3941
|
12
|
+
c2cgeoportal_admin/schemas/interfaces.py,sha256=0NCRDZOqbw7Bwj-l3GNsVwYDHck4F0q1fCSo1kTYoOY,2578
|
13
|
+
c2cgeoportal_admin/schemas/metadata.py,sha256=EOr9hWYBPBJ3iaUmPFgtWnBaNWadX0g9UQ0eeJ6N84E,8991
|
14
|
+
c2cgeoportal_admin/schemas/restriction_areas.py,sha256=48hFUgFznl_1bYsl490YSXLbXfjCY_f6gURQtB_7eIk,2598
|
15
|
+
c2cgeoportal_admin/schemas/roles.py,sha256=4JJrgZNKsj_wru_YGOWxZTEXGVm0hahbAkYf2aePGzI,2507
|
16
|
+
c2cgeoportal_admin/schemas/treegroup.py,sha256=8_aDM5xhtT7m-amaccEgH8T5O-SoRtFYIcGZ01VwHr0,7036
|
17
|
+
c2cgeoportal_admin/schemas/treeitem.py,sha256=qnjrLd2LD7NCBjXqzw7aRn83cw_hYZbepJdLzOz0rBk,2117
|
18
|
+
c2cgeoportal_admin/static/layertree.css,sha256=tk54KGW0yRRmdrY35gOCZG3qTsqWtGNEwvBYPQKhaVs,3177
|
19
|
+
c2cgeoportal_admin/static/navbar.css,sha256=QIaAQsb4n17OfwdKEQdmNDVPCP23Yu-oGW4xsSaHyW0,2307
|
20
|
+
c2cgeoportal_admin/static/theme.css,sha256=eHtBEJcBtDhyZJvCKNxE5hgril0VpLtcDKfNFdgCSVw,2025
|
21
|
+
c2cgeoportal_admin/templates/404.jinja2,sha256=KSpqCNFwv37rKSmX6kL_VvCnn5egcT1eRD6kIKwWx34,1807
|
22
|
+
c2cgeoportal_admin/templates/edit.jinja2,sha256=rkBQiz0JZdL7VDq8XrhRLTv6JaiFt_QB8CwP3NMHWQY,1302
|
23
|
+
c2cgeoportal_admin/templates/home.jinja2,sha256=WDQwmBGMZxsiOLw9YeYPLuca_mjjntjrTh529euzd1o,1516
|
24
|
+
c2cgeoportal_admin/templates/index.jinja2,sha256=HPgilbqh5dv-yc_T_bc1hV2DEtV2wD617_aAERC2VSk,2005
|
25
|
+
c2cgeoportal_admin/templates/layertree.jinja2,sha256=1ys5XDY3nb4gAu8JazkwSFeJUdGRadT7WaBuvin_hYg,9830
|
26
|
+
c2cgeoportal_admin/templates/layout.jinja2,sha256=KCDwATUYBu-ZXv7ijo0S0PlTmKtU-JxW8gMhvPA_kAE,4105
|
27
|
+
c2cgeoportal_admin/templates/navigation_navbar.jinja2,sha256=XzVQDpo3ClIiRxWf5eDULHZi9u-veYOmndiE_Twqxog,4166
|
28
|
+
c2cgeoportal_admin/templates/ogcserver_synchronize.jinja2,sha256=rdQfbHBzrV5VUq5TC97QR7pv8bRvrdKaUUZpnQyldoE,4327
|
29
|
+
c2cgeoportal_admin/templates/widgets/child.pt,sha256=JjxI0oVADhS3SoFgg0iN8P4ca1I_UGr7fWRp3wpZXsE,2159
|
30
|
+
c2cgeoportal_admin/templates/widgets/children.pt,sha256=0TPpatvmZcU2TxbcZMjDz8VQcLGtoHkuDJ-eAGvjXho,6625
|
31
|
+
c2cgeoportal_admin/templates/widgets/dimension.pt,sha256=1BXmE7s9JpzaJSHAQEtZk0DHB11pQ4FNQPaG_4c8CYo,2627
|
32
|
+
c2cgeoportal_admin/templates/widgets/dimensions.pt,sha256=LjWjsgdcFYZxpB_30-3NOfvq5KYkKTu49F-P-r9d5Jg,1211
|
33
|
+
c2cgeoportal_admin/templates/widgets/functionality_fields.pt,sha256=8TvwXCmQOtYFkiqsa4AHFUYsWk92LLnthz8bDrLmMBc,1969
|
34
|
+
c2cgeoportal_admin/templates/widgets/layer_fields.pt,sha256=RJBYt8ji6YQp9ZaNZJD-caLgy856a6rzlKSMnuZWphw,3223
|
35
|
+
c2cgeoportal_admin/templates/widgets/layer_group_fields.pt,sha256=xnqIqFjPPan81OqLwKeDnvNtlhEvYss6h2J9txH5neE,2459
|
36
|
+
c2cgeoportal_admin/templates/widgets/layer_v1_fields.pt,sha256=w-MujUevHWmnOkOTbbvES6alDoL_UO1eiMj8SCxcQEY,3956
|
37
|
+
c2cgeoportal_admin/templates/widgets/metadata.pt,sha256=P8noHX8YAv3m6EGh0IDUJCFsyeZDX88HtlqOWab8DAU,3735
|
38
|
+
c2cgeoportal_admin/templates/widgets/metadatas.pt,sha256=ErgAH0DA94MO7gqEJ2iZdQ9LRptP2YKH78yze-jdl2Q,1476
|
39
|
+
c2cgeoportal_admin/templates/widgets/ogcserver_fields.pt,sha256=x0bDmgrnj9SA6RCVpg3k2lTkkXPkuBFPKMScDgDeyGU,1724
|
40
|
+
c2cgeoportal_admin/templates/widgets/restriction_area_fields.pt,sha256=pZVE0KcitAF7HXc3ZlniLr0QwSD05TOhlgieLUR1i7Q,1731
|
41
|
+
c2cgeoportal_admin/templates/widgets/role_fields.pt,sha256=gVd9eRYaqw8fGmZauqEUS_Igmyxaa71qcmdC1KUx5nY,2623
|
42
|
+
c2cgeoportal_admin/templates/widgets/theme_fields.pt,sha256=68G1Ya8-Dc6pCeP-taQ0ofCIpnY_v0rouazkFhfQflU,3083
|
43
|
+
c2cgeoportal_admin/templates/widgets/user_fields.pt,sha256=twmajhUYL1xa47Eu-iATKifNPA5lu3SGpqdKajH6gL8,1753
|
44
|
+
c2cgeoportal_admin/views/__init__.py,sha256=jtI6CdoXJwizznjwb8ClYySgq4kbwhTIJYutSw89PAw,683
|
45
|
+
c2cgeoportal_admin/views/dimension_layers.py,sha256=jupwqX_kO37ukcWE-SsO290JdKENEmfoYxk4sRWb25Y,2598
|
46
|
+
c2cgeoportal_admin/views/functionalities.py,sha256=4oZYgs2_M0Usb3GBi40gCP6XvTbR-1PhCDZXiBnhsuk,4031
|
47
|
+
c2cgeoportal_admin/views/home.py,sha256=h_hJWIKpzJeSmXl58J0nvZdEg7avSYOOVUEEnlV-r0k,1943
|
48
|
+
c2cgeoportal_admin/views/interfaces.py,sha256=gzIRrd4D64iSH7NVaR-9oQh8-iMzjZOW5QfTfpQeYU4,3494
|
49
|
+
c2cgeoportal_admin/views/layer_groups.py,sha256=Zcdr26jyo4ZZw7sr6hYOjo6PuI9-StQ5KQ7OlIxSEtY,3956
|
50
|
+
c2cgeoportal_admin/views/layers.py,sha256=xjvcRvKVpeD-LRuVwE8PGkDT-Kih9ADX0beEDcOP1bE,3039
|
51
|
+
c2cgeoportal_admin/views/layers_vectortiles.py,sha256=lREdMc7bo2TVqdf-s6MzNXZoauReqFS_K-Hng49NUT4,4932
|
52
|
+
c2cgeoportal_admin/views/layers_wms.py,sha256=Kpgr-eWME9zxahkf-re1w6wkToKBqyInmqd_DHhj9Kc,8040
|
53
|
+
c2cgeoportal_admin/views/layers_wmts.py,sha256=HNZalKLLhPF7aXLxuFP07yr9-MGnJTg-CVD-GeokvMM,7815
|
54
|
+
c2cgeoportal_admin/views/layertree.py,sha256=plb5fL9vTaSe9EFp8VmUWl5iD9FuiQ-3TuStKAGjIKo,8587
|
55
|
+
c2cgeoportal_admin/views/logged_views.py,sha256=_XHoIl7Lw3SV_1T0c0JUeIhkluzNnjNrSUgimfk993E,3169
|
56
|
+
c2cgeoportal_admin/views/logs.py,sha256=I4ZnfNtBZmriDLIzLpLiX5HPm3Y1UvIQehemPbC2rL0,3616
|
57
|
+
c2cgeoportal_admin/views/oauth2_clients.py,sha256=lfMSwZW7pybQx3PR1btRY7XFLfx1TOx7ooVgllOqK-s,3798
|
58
|
+
c2cgeoportal_admin/views/ogc_servers.py,sha256=nGTs_pDr2knS_NAakqvxmjZE2ulrWxn2puWA_uNqgaY,9412
|
59
|
+
c2cgeoportal_admin/views/restriction_areas.py,sha256=uzfQQVRFCP-OCg1sdGzQCTkO35C1H8DZNMWIquFQqRw,5578
|
60
|
+
c2cgeoportal_admin/views/roles.py,sha256=VP0OEsW2_l99YnxGO5mdOkvPBs4Hs3nyRSbetIKtx14,5887
|
61
|
+
c2cgeoportal_admin/views/themes.py,sha256=mxpf56KXwCKG5tCYgV7xgPtQqlCU67iOBOLB7cHD-Hc,5710
|
62
|
+
c2cgeoportal_admin/views/themes_ordering.py,sha256=NYN3I2tDwLW5E4G-695DwV0dCbHUAObWVFYZ8Bir1-o,5590
|
63
|
+
c2cgeoportal_admin/views/treeitems.py,sha256=C-vjScmb_HI5QOowx3MGZBJqAHDkGTG90vshPG7FvgA,3889
|
64
|
+
c2cgeoportal_admin/views/users.py,sha256=sXCgVluLLnbbQTG8Q7tmaVfnEcHj5fBiHFCG7owVp1w,5439
|
65
|
+
tests/__init__.py,sha256=oo8kqGfoSh8AV0HhTqQfC0izcIQ8ZQPkNmONSEUUby4,9556
|
66
|
+
tests/conftest.py,sha256=ah7JmR2epDZul2rmMH5wuUzkSpXIjm8dd-cgGjK6_k0,2119
|
67
|
+
tests/test_edit_url.py,sha256=Mo_Vo5xvdpPasfjvhQUif5F3nKVpJ6GQJ_x_Hj5VNY8,4494
|
68
|
+
tests/test_functionalities.py,sha256=tGQbEsQWjr_oExI3vWhLIioxylDaoUaOfEas42YPw50,5191
|
69
|
+
tests/test_home.py,sha256=oWsKaWqRicNpUdaca54YvLIBRaGYnsXlv_Tjqv7guEQ,425
|
70
|
+
tests/test_interface.py,sha256=z1jpRzW0R2e9BJWWurE-j-YkG5yhorn7h1XRIauUQ7A,5669
|
71
|
+
tests/test_layer_groups.py,sha256=bisbaDY0SiyBc0rexYajbcvfdDt8Kux6VqXIEBLSULM,12191
|
72
|
+
tests/test_layers_vectortiles.py,sha256=PpnR8wJyRcsByPTOrrtltQUYzzQ0qRzQM2no1z1rLgU,10404
|
73
|
+
tests/test_layers_wms.py,sha256=ynqO1cnXk2ZbSXR3l9hp0IyG8PMXbmR4eyubnwRvRfU,19494
|
74
|
+
tests/test_layers_wmts.py,sha256=7zye_pZ_e0RyJdoT8oeHKPoYJMKWfTg0K8lEgMIu77Q,12181
|
75
|
+
tests/test_layertree.py,sha256=Dxe10OwuilQ-AEgVIDU4Ns9U6PQ4kPWTxwItdBE7nSg,11335
|
76
|
+
tests/test_learn.py,sha256=gQwe-Bim0eihZH0rbBWDn6_rIBxvQD_lyu9MlOljupM,2307
|
77
|
+
tests/test_left_menu.py,sha256=xnlv5sD0k3wpCChKCnbpYRN0TA895pg8k6wVvjf99-4,919
|
78
|
+
tests/test_lingua_extractor_config.py,sha256=vAfunJ4tVuqTJg4xinPwlB0EvA4sYhjY_iDBfMq8EW4,2495
|
79
|
+
tests/test_logs.py,sha256=sUBC61rCSIfg9HBavhT6c0QPmPYUnEfDm91bUaUF4Q8,3147
|
80
|
+
tests/test_main.py,sha256=_gUdMrMMAEzvGIf1QwkoHQkd0eBACz05ycTidCHP5Ao,365
|
81
|
+
tests/test_metadatas.py,sha256=bVNxvZRKNRMmjQGr7Al1d4H85EjEaoesRpxytyld4Fw,12088
|
82
|
+
tests/test_oauth2_clients.py,sha256=-aowsa2Dw77lxzuBb9ULW4iEJSB9yut-eYGP7YptT0M,7000
|
83
|
+
tests/test_ogc_servers.py,sha256=DGSMVIzYnw3bJT53VFGuPYIPMPCyHJDb5ZPJj1VM3Bo,8204
|
84
|
+
tests/test_restriction_areas.py,sha256=5VhO9ZvtFQPy1kVFm96Mh_vf1LCI5oeIdl0dfvS6JD8,9003
|
85
|
+
tests/test_role.py,sha256=eD7dXwP7RjCg14T9ncTfJuMUU4caY9yW3l5ka-gtCd4,12776
|
86
|
+
tests/test_themes.py,sha256=uhzHe2TbuNoLnL4VdYATPnOqtnZWWPKsvUTq6GUxwiU,16207
|
87
|
+
tests/test_themes_ordering.py,sha256=T4Esr0C3EN5UdeEyYLa4ePvEn-bx3RNPkGBK3lDFoBo,2243
|
88
|
+
tests/test_treegroup.py,sha256=Plv119G4TWlurWLE7Z1mWGeHHPScK_fWKcDmDzMUlIU,576
|
89
|
+
tests/test_user.py,sha256=xD0yoJa_babVK69hHQzDkTs6wRWBMXFGD8k0-DfOd-4,12814
|
90
|
+
tests/themes_ordering.py,sha256=UdydcRIzWC6RRnTMfl2JM_250DHuAhGC7rijHqfy7lk,1342
|
91
|
+
c2cgeoportal_admin-2.8.1.180.dist-info/METADATA,sha256=4IZ5Bu5mH3ErjEWDbuTwu1xItrt3UDnOtbtmZXLYQxQ,1597
|
92
|
+
c2cgeoportal_admin-2.8.1.180.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
93
|
+
c2cgeoportal_admin-2.8.1.180.dist-info/entry_points.txt,sha256=kz-7AnYsbtK04jTpGUtcOeu2NbQiXW3CQV3AjyC32tw,165
|
94
|
+
c2cgeoportal_admin-2.8.1.180.dist-info/top_level.txt,sha256=DgcTJgTvpJUB8HqwYB14PdLBPAOAFk0B8oqnSTFoAU4,25
|
95
|
+
c2cgeoportal_admin-2.8.1.180.dist-info/RECORD,,
|
tests/__init__.py
CHANGED
@@ -54,7 +54,6 @@ def factory_build_layers(layer_builder, dbsession, add_dimension=True):
|
|
54
54
|
|
55
55
|
layers = []
|
56
56
|
for i in range(0, 25):
|
57
|
-
|
58
57
|
layer = layer_builder(i)
|
59
58
|
|
60
59
|
if add_dimension:
|
@@ -90,7 +89,6 @@ def factory_build_layers(layer_builder, dbsession, add_dimension=True):
|
|
90
89
|
|
91
90
|
|
92
91
|
class AbstractViewsTests:
|
93
|
-
|
94
92
|
_prefix = None # url prefix (index view url). Example: /users
|
95
93
|
|
96
94
|
def get(self, test_app, path="", locale="en", status=200, **kwargs):
|
@@ -120,7 +118,8 @@ class AbstractViewsTests:
|
|
120
118
|
)
|
121
119
|
actions = resp.html.select_one('th[data-field="actions"]')
|
122
120
|
assert "false" == actions.attrs["data-sortable"]
|
123
|
-
|
121
|
+
if new is not False:
|
122
|
+
assert 1 == len(list(filter(lambda x: next(x.stripped_strings) == new, resp.html.findAll("a"))))
|
124
123
|
|
125
124
|
def check_search(self, test_app, search="", offset=0, limit=10, sort="", order="", total=None):
|
126
125
|
json = test_app.post(
|
tests/test_edit_url.py
CHANGED
tests/test_functionalities.py
CHANGED
@@ -31,7 +31,6 @@ def functionality_test_data(dbsession, transact, settings):
|
|
31
31
|
|
32
32
|
@pytest.mark.usefixtures("functionality_test_data", "test_app")
|
33
33
|
class TestFunctionality(AbstractViewsTests):
|
34
|
-
|
35
34
|
_prefix = "/admin/functionalities"
|
36
35
|
|
37
36
|
def test_index_rendering(self, test_app):
|
@@ -53,7 +52,7 @@ class TestFunctionality(AbstractViewsTests):
|
|
53
52
|
self.check_search(test_app, "default_basemap", total=1)
|
54
53
|
|
55
54
|
def test_submit_new(self, dbsession, test_app):
|
56
|
-
from c2cgeoportal_commons.models.main import Functionality
|
55
|
+
from c2cgeoportal_commons.models.main import Functionality, Log, LogAction
|
57
56
|
|
58
57
|
resp = test_app.post(
|
59
58
|
"/admin/functionalities/new",
|
@@ -66,7 +65,17 @@ class TestFunctionality(AbstractViewsTests):
|
|
66
65
|
).group(1)
|
67
66
|
assert functionality.name == "new_name"
|
68
67
|
|
69
|
-
|
68
|
+
log = dbsession.query(Log).one()
|
69
|
+
assert log.date != None
|
70
|
+
assert log.action == LogAction.INSERT
|
71
|
+
assert log.element_type == "functionality"
|
72
|
+
assert log.element_id == functionality.id
|
73
|
+
assert log.element_name == functionality.name
|
74
|
+
assert log.username == "test_user"
|
75
|
+
|
76
|
+
def test_edit(self, test_app, functionality_test_data, dbsession):
|
77
|
+
from c2cgeoportal_commons.models.main import Log, LogAction
|
78
|
+
|
70
79
|
functionality = functionality_test_data["functionalities"][0]
|
71
80
|
resp = test_app.get(f"/admin/functionalities/{functionality.id}", status=200)
|
72
81
|
form = resp.form
|
@@ -77,14 +86,30 @@ class TestFunctionality(AbstractViewsTests):
|
|
77
86
|
assert form.submit().status_int == 302
|
78
87
|
assert functionality.description == "new_description"
|
79
88
|
|
89
|
+
log = dbsession.query(Log).one()
|
90
|
+
assert log.date != None
|
91
|
+
assert log.action == LogAction.UPDATE
|
92
|
+
assert log.element_type == "functionality"
|
93
|
+
assert log.element_id == functionality.id
|
94
|
+
assert log.element_name == functionality.name
|
95
|
+
assert log.username == "test_user"
|
96
|
+
|
80
97
|
def test_delete(self, test_app, functionality_test_data, dbsession):
|
81
|
-
from c2cgeoportal_commons.models.main import Functionality
|
98
|
+
from c2cgeoportal_commons.models.main import Functionality, Log, LogAction
|
82
99
|
|
83
100
|
functionality = functionality_test_data["functionalities"][0]
|
84
101
|
deleted_id = functionality.id
|
85
102
|
test_app.delete(f"/admin/functionalities/{deleted_id}", status=200)
|
86
103
|
assert dbsession.query(Functionality).get(deleted_id) is None
|
87
104
|
|
105
|
+
log = dbsession.query(Log).one()
|
106
|
+
assert log.date != None
|
107
|
+
assert log.action == LogAction.DELETE
|
108
|
+
assert log.element_type == "functionality"
|
109
|
+
assert log.element_id == functionality.id
|
110
|
+
assert log.element_name == functionality.name
|
111
|
+
assert log.username == "test_user"
|
112
|
+
|
88
113
|
def test_duplicate(self, functionality_test_data, test_app, dbsession):
|
89
114
|
from c2cgeoportal_commons.models.main import Functionality
|
90
115
|
|
tests/test_home.py
CHANGED
tests/test_interface.py
CHANGED
@@ -45,7 +45,6 @@ def interface_test_data(dbsession, transact):
|
|
45
45
|
|
46
46
|
@pytest.mark.usefixtures("interface_test_data", "test_app")
|
47
47
|
class TestInterface(AbstractViewsTests):
|
48
|
-
|
49
48
|
_prefix = "/admin/interfaces"
|
50
49
|
|
51
50
|
def test_index_rendering(self, test_app):
|
@@ -82,7 +81,7 @@ class TestInterface(AbstractViewsTests):
|
|
82
81
|
self.check_search(test_app, "interface_0", total=1)
|
83
82
|
|
84
83
|
def test_submit_new(self, dbsession, test_app):
|
85
|
-
from c2cgeoportal_commons.models.main import Interface
|
84
|
+
from c2cgeoportal_commons.models.main import Interface, Log, LogAction
|
86
85
|
|
87
86
|
resp = test_app.post(
|
88
87
|
"/admin/interfaces/new", {"name": "new_name", "description": "new description"}, status=302
|
@@ -94,8 +93,16 @@ class TestInterface(AbstractViewsTests):
|
|
94
93
|
).group(1)
|
95
94
|
assert interface.name == "new_name"
|
96
95
|
|
96
|
+
log = dbsession.query(Log).one()
|
97
|
+
assert log.date != None
|
98
|
+
assert log.action == LogAction.INSERT
|
99
|
+
assert log.element_type == "interface"
|
100
|
+
assert log.element_id == interface.id
|
101
|
+
assert log.element_name == interface.name
|
102
|
+
assert log.username == "test_user"
|
103
|
+
|
97
104
|
def test_edit(self, test_app, interface_test_data, dbsession):
|
98
|
-
from c2cgeoportal_commons.models.main import Interface
|
105
|
+
from c2cgeoportal_commons.models.main import Interface, Log, LogAction
|
99
106
|
|
100
107
|
interface = interface_test_data["interfaces"][0]
|
101
108
|
descriptions = "{}, {}".format(
|
@@ -110,13 +117,29 @@ class TestInterface(AbstractViewsTests):
|
|
110
117
|
assert form.submit().status_int == 302
|
111
118
|
assert len(dbsession.query(Interface).filter(Interface.description == descriptions).all()) == 1
|
112
119
|
|
120
|
+
log = dbsession.query(Log).one()
|
121
|
+
assert log.date != None
|
122
|
+
assert log.action == LogAction.UPDATE
|
123
|
+
assert log.element_type == "interface"
|
124
|
+
assert log.element_id == interface.id
|
125
|
+
assert log.element_name == interface.name
|
126
|
+
assert log.username == "test_user"
|
127
|
+
|
113
128
|
def test_delete(self, test_app, interface_test_data, dbsession):
|
114
|
-
from c2cgeoportal_commons.models.main import Interface
|
129
|
+
from c2cgeoportal_commons.models.main import Interface, Log, LogAction
|
115
130
|
|
116
131
|
interface = interface_test_data["interfaces"][0]
|
117
132
|
test_app.delete(f"/admin/interfaces/{interface.id}", status=200)
|
118
133
|
assert len(dbsession.query(Interface).filter(Interface.id == interface.id).all()) == 0
|
119
134
|
|
135
|
+
log = dbsession.query(Log).one()
|
136
|
+
assert log.date != None
|
137
|
+
assert log.action == LogAction.DELETE
|
138
|
+
assert log.element_type == "interface"
|
139
|
+
assert log.element_id == interface.id
|
140
|
+
assert log.element_name == interface.name
|
141
|
+
assert log.username == "test_user"
|
142
|
+
|
120
143
|
def test_duplicate(self, interface_test_data, test_app):
|
121
144
|
interface = interface_test_data["interfaces"][3]
|
122
145
|
resp = test_app.get(f"/admin/interfaces/{interface.id}/duplicate", status=200)
|