c2cgeoportal-commons 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.
Potentially problematic release.
This version of c2cgeoportal-commons might be problematic. Click here for more details.
- c2cgeoportal_commons/alembic/env.py +14 -10
- c2cgeoportal_commons/alembic/main/028477929d13_add_technical_roles.py +2 -2
- c2cgeoportal_commons/alembic/main/04f05bfbb05e_remove_the_old_is_expanded_column.py +3 -1
- c2cgeoportal_commons/alembic/main/116b9b79fc4d_internal_and_external_layer_tables_.py +12 -12
- c2cgeoportal_commons/alembic/main/1418cb05921b_merge_1_6_and_master_branches.py +3 -1
- c2cgeoportal_commons/alembic/main/164ac0819a61_add_image_format_to_wmts_layer.py +2 -2
- c2cgeoportal_commons/alembic/main/166ff2dcc48d_create_database.py +2 -2
- c2cgeoportal_commons/alembic/main/16e43f8c0330_remove_old_metadata_column.py +2 -2
- c2cgeoportal_commons/alembic/main/1d5d4abfebd1_add_restricted_theme.py +2 -2
- c2cgeoportal_commons/alembic/main/1de20166b274_remove_v1_artifacts.py +2 -2
- c2cgeoportal_commons/alembic/main/20137477bd02_update_icons_url.py +2 -2
- c2cgeoportal_commons/alembic/main/21f11066f8ec_trigger_on_role_updates_user_in_static.py +2 -2
- c2cgeoportal_commons/alembic/main/22e6dfb556de_add_description_tree_.py +2 -2
- c2cgeoportal_commons/alembic/main/29f2a32859ec_merge_1_6_and_master_branches.py +3 -1
- c2cgeoportal_commons/alembic/main/2b8ed8c1df94_set_layergroup_treeitem_is_as_a_primary_.py +2 -2
- c2cgeoportal_commons/alembic/main/32527659d57b_move_exclude_properties_from_layerv1_to_.py +2 -2
- c2cgeoportal_commons/alembic/main/32b21aa1d0ed_merge_e004f76e951a_and_e004f76e951a_.py +3 -1
- c2cgeoportal_commons/alembic/main/338b57593823_remove_trigger_on_role_name_change.py +2 -2
- c2cgeoportal_commons/alembic/main/415746eb9f6_changes_for_v2.py +2 -2
- c2cgeoportal_commons/alembic/main/44c91d82d419_add_table_log.py +8 -6
- c2cgeoportal_commons/alembic/main/5109242131ce_add_column_time_widget.py +4 -3
- c2cgeoportal_commons/alembic/main/52916d8fde8b_add_sql_fields_to_vector_tiles.py +5 -3
- c2cgeoportal_commons/alembic/main/53ba1a68d5fe_add_theme_to_fulltextsearch.py +2 -2
- c2cgeoportal_commons/alembic/main/54645a535ad6_add_ordering_in_relation.py +2 -2
- c2cgeoportal_commons/alembic/main/56dc90838d90_fix_removing_layerv1.py +2 -2
- c2cgeoportal_commons/alembic/main/596ba21e3833_separate_local_internal.py +2 -2
- c2cgeoportal_commons/alembic/main/678f88c7ad5e_add_vector_tiles_layers_table.py +2 -2
- c2cgeoportal_commons/alembic/main/6a412d9437b1_rename_serverogc_to_ogcserver.py +2 -2
- c2cgeoportal_commons/alembic/main/6d87fdad275a_convert_metadata_to_the_right_case.py +2 -2
- c2cgeoportal_commons/alembic/main/7530011a66a7_trigger_on_role_updates_user_in_static.py +2 -2
- c2cgeoportal_commons/alembic/main/78fd093c8393_add_api_s_intrfaces.py +15 -10
- c2cgeoportal_commons/alembic/main/7d271f4527cd_add_layer_column_in_layerv1_table.py +2 -2
- c2cgeoportal_commons/alembic/main/809650bd04c3_add_dimension_field.py +2 -2
- c2cgeoportal_commons/alembic/main/8117bb9bba16_use_dimension_on_all_the_layers.py +2 -2
- c2cgeoportal_commons/alembic/main/87f8330ed64e_add_missing_delete_cascades.py +2 -2
- c2cgeoportal_commons/alembic/main/9268a1dffac0_add_trigger_to_be_able_to_correctly_.py +2 -2
- c2cgeoportal_commons/alembic/main/94db7e7e5b21_merge_2_2_and_master_branches.py +3 -1
- c2cgeoportal_commons/alembic/main/951ff84bd8ec_be_able_to_delete_a_wms_layer_in_sql.py +2 -2
- c2cgeoportal_commons/alembic/main/a00109812f89_add_field_layer_wms_valid.py +4 -4
- c2cgeoportal_commons/alembic/main/a4558f032d7d_add_support_of_cog_layers.py +74 -0
- c2cgeoportal_commons/alembic/main/a4f1aac9bda_merge_1_6_and_master_branches.py +3 -1
- c2cgeoportal_commons/alembic/main/b60f2a505f42_remame_uimetadata_to_metadata.py +2 -2
- c2cgeoportal_commons/alembic/main/b6b09f414fe8_sync_model_database.py +165 -0
- c2cgeoportal_commons/alembic/main/c75124553bf3_remove_deprecated_columns.py +2 -2
- c2cgeoportal_commons/alembic/main/d48a63b348f1_change_mapserver_url_for_docker.py +2 -2
- c2cgeoportal_commons/alembic/main/d8ef99bc227e_be_able_to_delete_a_linked_functionality.py +2 -2
- c2cgeoportal_commons/alembic/main/daf738d5bae4_merge_2_0_and_master_branches.py +3 -1
- c2cgeoportal_commons/alembic/main/dba87f2647f9_merge_2_2_on_2_3.py +3 -1
- c2cgeoportal_commons/alembic/main/e004f76e951a_add_missing_not_null.py +2 -2
- c2cgeoportal_commons/alembic/main/e7e03dedade3_put_the_default_wms_server_in_the_.py +2 -2
- c2cgeoportal_commons/alembic/main/e85afd327ab3_cascade_deletes_to_tsearch.py +2 -2
- c2cgeoportal_commons/alembic/main/ec82a8906649_add_missing_on_delete_cascade_on_layer_.py +2 -2
- c2cgeoportal_commons/alembic/main/ee25d267bf46_main_interface_desktop.py +2 -2
- c2cgeoportal_commons/alembic/main/eeb345672454_merge_2_4_and_master_branches.py +3 -1
- c2cgeoportal_commons/alembic/static/0c640a58a09a_add_opt_key_column.py +2 -2
- c2cgeoportal_commons/alembic/static/107b81f5b9fe_add_missing_delete_cascades.py +2 -2
- c2cgeoportal_commons/alembic/static/1857owc78a07_add_last_login_and_expiration_date.py +2 -2
- c2cgeoportal_commons/alembic/static/1da396a88908_move_user_table_to_static_schema.py +3 -3
- c2cgeoportal_commons/alembic/static/267b4c1bde2e_add_display_name_in_the_user_for_better_.py +62 -0
- c2cgeoportal_commons/alembic/static/3f89a7d71a5e_alter_column_url_to_remove_limitation.py +2 -2
- c2cgeoportal_commons/alembic/static/44c91d82d419_add_table_log.py +6 -4
- c2cgeoportal_commons/alembic/static/53d671b17b20_add_timezone_on_datetime_fields.py +2 -2
- c2cgeoportal_commons/alembic/static/5472fbc19f39_add_temp_password_column.py +2 -2
- c2cgeoportal_commons/alembic/static/76d72fb3fcb9_add_oauth2_pkce.py +3 -1
- c2cgeoportal_commons/alembic/static/7ef947f30f20_add_oauth2_tables.py +3 -1
- c2cgeoportal_commons/alembic/static/910b4ca53b68_sync_model_database.py +186 -0
- c2cgeoportal_commons/alembic/static/aa41e9613256_wip_add_openid_connect_support.py +64 -0
- c2cgeoportal_commons/alembic/static/ae5e88f35669_add_table_user_role.py +2 -2
- c2cgeoportal_commons/alembic/static/bd029dbfc11a_fill_tech_data_column.py +2 -2
- c2cgeoportal_commons/lib/email_.py +7 -7
- c2cgeoportal_commons/lib/literal.py +3 -3
- c2cgeoportal_commons/lib/url.py +15 -16
- c2cgeoportal_commons/models/__init__.py +15 -8
- c2cgeoportal_commons/models/main.py +296 -211
- c2cgeoportal_commons/models/sqlalchemy.py +10 -9
- c2cgeoportal_commons/models/static.py +125 -76
- c2cgeoportal_commons/testing/__init__.py +10 -6
- c2cgeoportal_commons/testing/initializedb.py +7 -6
- {c2cgeoportal_commons-2.8.1.181.dist-info → c2cgeoportal_commons-2.9rc2.dist-info}/METADATA +3 -9
- c2cgeoportal_commons-2.9rc2.dist-info/RECORD +88 -0
- {c2cgeoportal_commons-2.8.1.181.dist-info → c2cgeoportal_commons-2.9rc2.dist-info}/WHEEL +1 -1
- tests/conftest.py +1 -1
- c2cgeoportal_commons-2.8.1.181.dist-info/RECORD +0 -83
- {c2cgeoportal_commons-2.8.1.181.dist-info → c2cgeoportal_commons-2.9rc2.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2011-
|
|
1
|
+
# Copyright (c) 2011-2024, Camptocamp SA
|
|
2
2
|
# All rights reserved.
|
|
3
3
|
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
|
@@ -30,7 +30,8 @@ import enum
|
|
|
30
30
|
import logging
|
|
31
31
|
import os
|
|
32
32
|
import re
|
|
33
|
-
from
|
|
33
|
+
from datetime import datetime
|
|
34
|
+
from typing import Any, Literal, Optional, cast, get_args
|
|
34
35
|
|
|
35
36
|
import pyramid.request
|
|
36
37
|
import sqlalchemy.orm.base
|
|
@@ -40,24 +41,28 @@ from geoalchemy2.shape import to_shape
|
|
|
40
41
|
from papyrus.geo_interface import GeoInterface
|
|
41
42
|
from sqlalchemy import Column, ForeignKey, Table, UniqueConstraint, event
|
|
42
43
|
from sqlalchemy.ext.declarative import AbstractConcreteBase
|
|
43
|
-
from sqlalchemy.orm import Session, backref, relationship
|
|
44
|
+
from sqlalchemy.orm import Mapped, Session, backref, mapped_column, relationship
|
|
44
45
|
from sqlalchemy.schema import Index
|
|
45
46
|
from sqlalchemy.types import Boolean, DateTime, Enum, Integer, String, Unicode
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
import c2cgeoportal_commons.lib.literal
|
|
48
49
|
from c2cgeoportal_commons.lib.url import get_url2
|
|
49
50
|
from c2cgeoportal_commons.models import Base, _, cache_invalidate_cb
|
|
50
51
|
from c2cgeoportal_commons.models.sqlalchemy import JSONEncodedDict, TsVector
|
|
51
52
|
|
|
52
53
|
try:
|
|
54
|
+
import colander
|
|
53
55
|
from c2cgeoform import default_map_settings
|
|
54
56
|
from c2cgeoform.ext.colander_ext import Geometry as ColanderGeometry
|
|
55
57
|
from c2cgeoform.ext.deform_ext import MapWidget, RelationSelect2Widget
|
|
56
58
|
from colander import drop
|
|
57
59
|
from deform.widget import CheckboxWidget, HiddenWidget, SelectWidget, TextAreaWidget, TextInputWidget
|
|
60
|
+
|
|
61
|
+
colander_null = colander.null
|
|
58
62
|
except ModuleNotFoundError:
|
|
59
|
-
drop = None
|
|
63
|
+
drop = None # pylint: disable=invalid-name
|
|
60
64
|
default_map_settings = {"srid": 3857, "view": {"projection": "EPSG:3857"}}
|
|
65
|
+
colander_null = None # pylint: disable=invalid-name
|
|
61
66
|
|
|
62
67
|
class GenericClass:
|
|
63
68
|
"""Fallback class implementation."""
|
|
@@ -67,11 +72,11 @@ except ModuleNotFoundError:
|
|
|
67
72
|
|
|
68
73
|
CheckboxWidget = GenericClass
|
|
69
74
|
HiddenWidget = GenericClass
|
|
70
|
-
MapWidget = GenericClass
|
|
75
|
+
MapWidget = GenericClass # type: ignore[misc,assignment]
|
|
71
76
|
SelectWidget = GenericClass
|
|
72
77
|
TextAreaWidget = GenericClass
|
|
73
|
-
ColanderGeometry = GenericClass
|
|
74
|
-
RelationSelect2Widget = GenericClass
|
|
78
|
+
ColanderGeometry = GenericClass # type: ignore[misc,assignment]
|
|
79
|
+
RelationSelect2Widget = GenericClass # type: ignore[misc,assignment]
|
|
75
80
|
TextInputWidget = GenericClass
|
|
76
81
|
|
|
77
82
|
|
|
@@ -86,14 +91,16 @@ if os.environ.get("DEVELOPMENT", "0") == "1":
|
|
|
86
91
|
# information
|
|
87
92
|
sqlalchemy.orm.base.state_str = state_str
|
|
88
93
|
|
|
89
|
-
|
|
94
|
+
_LOG = logging.getLogger(__name__)
|
|
90
95
|
|
|
91
96
|
_schema: str = config["schema"] or "main"
|
|
92
97
|
_srid: int = cast(int, config["srid"]) or 3857
|
|
93
98
|
|
|
94
99
|
# Set some default values for the admin interface
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
conf = config.get_config()
|
|
101
|
+
assert conf is not None
|
|
102
|
+
_admin_config: dict[str, Any] = conf.get("admin_interface", {})
|
|
103
|
+
_map_config: dict[str, Any] = {**default_map_settings, **_admin_config.get("map", {})}
|
|
97
104
|
view_srid_match = re.match(r"EPSG:(\d+)", _map_config["view"]["projection"])
|
|
98
105
|
if "map_srid" not in _admin_config and view_srid_match is not None:
|
|
99
106
|
_admin_config["map_srid"] = view_srid_match.group(1)
|
|
@@ -103,22 +110,30 @@ class FullTextSearch(GeoInterface, Base): # type: ignore
|
|
|
103
110
|
"""The tsearch table representation."""
|
|
104
111
|
|
|
105
112
|
__tablename__ = "tsearch"
|
|
106
|
-
__table_args__ = (
|
|
113
|
+
__table_args__ = (
|
|
114
|
+
Index("tsearch_search_index", "ts", "public", "role_id", "interface_id", "lang"),
|
|
115
|
+
Index("tsearch_ts_idx", "ts", postgresql_using="gin"),
|
|
116
|
+
{"schema": _schema},
|
|
117
|
+
)
|
|
107
118
|
|
|
108
|
-
id =
|
|
109
|
-
label =
|
|
110
|
-
layer_name =
|
|
111
|
-
role_id =
|
|
119
|
+
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
120
|
+
label: Mapped[str] = mapped_column(Unicode)
|
|
121
|
+
layer_name: Mapped[str] = mapped_column(Unicode, nullable=True)
|
|
122
|
+
role_id: Mapped[int] = mapped_column(
|
|
123
|
+
Integer, ForeignKey(_schema + ".role.id", ondelete="CASCADE"), nullable=True
|
|
124
|
+
)
|
|
112
125
|
role = relationship("Role")
|
|
113
|
-
interface_id =
|
|
126
|
+
interface_id: Mapped[int] = mapped_column(
|
|
127
|
+
Integer, ForeignKey(_schema + ".interface.id", ondelete="CASCADE"), nullable=True
|
|
128
|
+
)
|
|
114
129
|
interface = relationship("Interface")
|
|
115
|
-
lang =
|
|
116
|
-
public =
|
|
117
|
-
ts =
|
|
118
|
-
the_geom =
|
|
119
|
-
params =
|
|
120
|
-
actions =
|
|
121
|
-
from_theme =
|
|
130
|
+
lang: Mapped[str] = mapped_column(String(2), nullable=True)
|
|
131
|
+
public: Mapped[bool] = mapped_column(Boolean, server_default="true")
|
|
132
|
+
ts = mapped_column(TsVector)
|
|
133
|
+
the_geom = mapped_column(Geometry("GEOMETRY", srid=_srid, spatial_index=False))
|
|
134
|
+
params = mapped_column(JSONEncodedDict, nullable=True)
|
|
135
|
+
actions = mapped_column(JSONEncodedDict, nullable=True)
|
|
136
|
+
from_theme: Mapped[bool] = mapped_column(Boolean, server_default="false")
|
|
122
137
|
|
|
123
138
|
def __str__(self) -> str:
|
|
124
139
|
return f"{self.label}[{self.id}]"
|
|
@@ -133,8 +148,10 @@ class Functionality(Base): # type: ignore
|
|
|
133
148
|
|
|
134
149
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
135
150
|
|
|
136
|
-
id
|
|
137
|
-
|
|
151
|
+
id: Mapped[int] = mapped_column(
|
|
152
|
+
Integer, primary_key=True, info={"colanderalchemy": {"widget": HiddenWidget()}}
|
|
153
|
+
)
|
|
154
|
+
name: Mapped[str] = mapped_column(
|
|
138
155
|
Unicode,
|
|
139
156
|
nullable=False,
|
|
140
157
|
info={
|
|
@@ -154,7 +171,7 @@ class Functionality(Base): # type: ignore
|
|
|
154
171
|
}
|
|
155
172
|
},
|
|
156
173
|
)
|
|
157
|
-
description =
|
|
174
|
+
description: Mapped[str | None] = mapped_column(
|
|
158
175
|
Unicode,
|
|
159
176
|
info={
|
|
160
177
|
"colanderalchemy": {
|
|
@@ -163,7 +180,7 @@ class Functionality(Base): # type: ignore
|
|
|
163
180
|
}
|
|
164
181
|
},
|
|
165
182
|
)
|
|
166
|
-
value =
|
|
183
|
+
value: Mapped[str] = mapped_column(
|
|
167
184
|
Unicode,
|
|
168
185
|
nullable=False,
|
|
169
186
|
info={
|
|
@@ -224,8 +241,10 @@ class Role(Base): # type: ignore
|
|
|
224
241
|
__colanderalchemy_config__ = {"title": _("Role"), "plural": _("Roles")}
|
|
225
242
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
226
243
|
|
|
227
|
-
id
|
|
228
|
-
|
|
244
|
+
id: Mapped[int] = mapped_column(
|
|
245
|
+
Integer, primary_key=True, info={"colanderalchemy": {"widget": HiddenWidget()}}
|
|
246
|
+
)
|
|
247
|
+
name: Mapped[str] = mapped_column(
|
|
229
248
|
Unicode,
|
|
230
249
|
unique=True,
|
|
231
250
|
nullable=False,
|
|
@@ -236,7 +255,7 @@ class Role(Base): # type: ignore
|
|
|
236
255
|
}
|
|
237
256
|
},
|
|
238
257
|
)
|
|
239
|
-
description =
|
|
258
|
+
description: Mapped[str | None] = mapped_column(
|
|
240
259
|
Unicode,
|
|
241
260
|
info={
|
|
242
261
|
"colanderalchemy": {
|
|
@@ -245,8 +264,8 @@ class Role(Base): # type: ignore
|
|
|
245
264
|
}
|
|
246
265
|
},
|
|
247
266
|
)
|
|
248
|
-
extent =
|
|
249
|
-
Geometry("POLYGON", srid=_srid),
|
|
267
|
+
extent = mapped_column(
|
|
268
|
+
Geometry("POLYGON", srid=_srid, spatial_index=False),
|
|
250
269
|
info={
|
|
251
270
|
"colanderalchemy": {
|
|
252
271
|
"title": _("Extent"),
|
|
@@ -275,8 +294,8 @@ class Role(Base): # type: ignore
|
|
|
275
294
|
self,
|
|
276
295
|
name: str = "",
|
|
277
296
|
description: str = "",
|
|
278
|
-
functionalities:
|
|
279
|
-
extent: Geometry = None,
|
|
297
|
+
functionalities: list[Functionality] | None = None,
|
|
298
|
+
extent: Geometry | None = None,
|
|
280
299
|
) -> None:
|
|
281
300
|
if functionalities is None:
|
|
282
301
|
functionalities = []
|
|
@@ -289,10 +308,10 @@ class Role(Base): # type: ignore
|
|
|
289
308
|
return f"{self.name}[{self.id}]>"
|
|
290
309
|
|
|
291
310
|
@property
|
|
292
|
-
def bounds(self) ->
|
|
311
|
+
def bounds(self) -> tuple[float, float, float, float] | None: # TODO
|
|
293
312
|
if self.extent is None:
|
|
294
313
|
return None
|
|
295
|
-
return cast(
|
|
314
|
+
return cast(tuple[float, float, float, float], to_shape(self.extent).bounds)
|
|
296
315
|
|
|
297
316
|
|
|
298
317
|
event.listen(Role.functionalities, "set", cache_invalidate_cb)
|
|
@@ -304,15 +323,17 @@ class TreeItem(Base): # type: ignore
|
|
|
304
323
|
"""The treeitem table representation."""
|
|
305
324
|
|
|
306
325
|
__tablename__ = "treeitem"
|
|
307
|
-
__table_args__:
|
|
326
|
+
__table_args__: tuple[Any, ...] | dict[str, Any] = (
|
|
308
327
|
UniqueConstraint("type", "name"),
|
|
309
328
|
{"schema": _schema},
|
|
310
329
|
)
|
|
311
|
-
item_type =
|
|
330
|
+
item_type: Mapped[str] = mapped_column(
|
|
331
|
+
"type", String(10), nullable=False, info={"colanderalchemy": {"exclude": True}}
|
|
332
|
+
)
|
|
312
333
|
__mapper_args__ = {"polymorphic_on": item_type}
|
|
313
334
|
|
|
314
|
-
id =
|
|
315
|
-
name =
|
|
335
|
+
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
336
|
+
name: Mapped[str] = mapped_column(
|
|
316
337
|
Unicode,
|
|
317
338
|
nullable=False,
|
|
318
339
|
info={
|
|
@@ -327,7 +348,7 @@ class TreeItem(Base): # type: ignore
|
|
|
327
348
|
}
|
|
328
349
|
},
|
|
329
350
|
)
|
|
330
|
-
description =
|
|
351
|
+
description: Mapped[str | None] = mapped_column(
|
|
331
352
|
Unicode,
|
|
332
353
|
info={
|
|
333
354
|
"colanderalchemy": {
|
|
@@ -339,7 +360,7 @@ class TreeItem(Base): # type: ignore
|
|
|
339
360
|
|
|
340
361
|
@property
|
|
341
362
|
# Better: def parents(self) -> List[TreeGroup]:
|
|
342
|
-
def parents(self) ->
|
|
363
|
+
def parents(self) -> list["TreeItem"]:
|
|
343
364
|
return [c.treegroup for c in self.parents_relation]
|
|
344
365
|
|
|
345
366
|
def is_in_interface(self, name: str) -> bool:
|
|
@@ -352,7 +373,7 @@ class TreeItem(Base): # type: ignore
|
|
|
352
373
|
|
|
353
374
|
return False
|
|
354
375
|
|
|
355
|
-
def get_metadata(self, name: str) ->
|
|
376
|
+
def get_metadata(self, name: str) -> list["Metadata"]:
|
|
356
377
|
return [metadata for metadata in self.metadatas if metadata.name == name]
|
|
357
378
|
|
|
358
379
|
def __init__(self, name: str = "") -> None:
|
|
@@ -375,11 +396,13 @@ class LayergroupTreeitem(Base): # type: ignore
|
|
|
375
396
|
__table_args__ = {"schema": _schema}
|
|
376
397
|
|
|
377
398
|
# required by formalchemy
|
|
378
|
-
id
|
|
379
|
-
|
|
380
|
-
|
|
399
|
+
id: Mapped[int] = mapped_column(
|
|
400
|
+
Integer, primary_key=True, info={"colanderalchemy": {"widget": HiddenWidget()}}
|
|
401
|
+
)
|
|
402
|
+
description: Mapped[str | None] = mapped_column(Unicode, info={"colanderalchemy": {"exclude": True}})
|
|
403
|
+
treegroup_id: Mapped[int] = mapped_column(
|
|
381
404
|
Integer,
|
|
382
|
-
ForeignKey(_schema + ".treegroup.id"),
|
|
405
|
+
ForeignKey(_schema + ".treegroup.id", name="treegroup_id_fkey"),
|
|
383
406
|
nullable=False,
|
|
384
407
|
info={"colanderalchemy": {"exclude": True}},
|
|
385
408
|
)
|
|
@@ -394,9 +417,9 @@ class LayergroupTreeitem(Base): # type: ignore
|
|
|
394
417
|
primaryjoin="LayergroupTreeitem.treegroup_id==TreeGroup.id",
|
|
395
418
|
info={"colanderalchemy": {"exclude": True}, "c2cgeoform": {"duplicate": False}},
|
|
396
419
|
)
|
|
397
|
-
treeitem_id =
|
|
420
|
+
treeitem_id: Mapped[int] = mapped_column(
|
|
398
421
|
Integer,
|
|
399
|
-
ForeignKey(_schema + ".treeitem.id"),
|
|
422
|
+
ForeignKey(_schema + ".treeitem.id", ondelete="CASCADE"),
|
|
400
423
|
nullable=False,
|
|
401
424
|
info={"colanderalchemy": {"widget": HiddenWidget()}},
|
|
402
425
|
)
|
|
@@ -413,10 +436,10 @@ class LayergroupTreeitem(Base): # type: ignore
|
|
|
413
436
|
primaryjoin="LayergroupTreeitem.treeitem_id==TreeItem.id",
|
|
414
437
|
info={"colanderalchemy": {"exclude": True}, "c2cgeoform": {"duplicate": False}},
|
|
415
438
|
)
|
|
416
|
-
ordering =
|
|
439
|
+
ordering: Mapped[int] = mapped_column(Integer, info={"colanderalchemy": {"widget": HiddenWidget()}})
|
|
417
440
|
|
|
418
441
|
def __init__(
|
|
419
|
-
self, group: Optional["TreeGroup"] = None, item:
|
|
442
|
+
self, group: Optional["TreeGroup"] = None, item: TreeItem | None = None, ordering: int = 0
|
|
420
443
|
) -> None:
|
|
421
444
|
self.treegroup = group
|
|
422
445
|
self.treeitem = item
|
|
@@ -436,14 +459,18 @@ class TreeGroup(TreeItem):
|
|
|
436
459
|
|
|
437
460
|
__tablename__ = "treegroup"
|
|
438
461
|
__table_args__ = {"schema": _schema}
|
|
439
|
-
__mapper_args__ = {"polymorphic_identity": "treegroup"} # needed for _identity_class
|
|
462
|
+
__mapper_args__ = {"polymorphic_identity": "treegroup"} # type: ignore[dict-item] # needed for _identity_class
|
|
440
463
|
|
|
441
|
-
id =
|
|
464
|
+
id: Mapped[int] = mapped_column(
|
|
465
|
+
Integer,
|
|
466
|
+
ForeignKey(_schema + ".treeitem.id", ondelete="CASCADE", name="treegroup_id_fkey"),
|
|
467
|
+
primary_key=True,
|
|
468
|
+
)
|
|
442
469
|
|
|
443
|
-
def _get_children(self) ->
|
|
470
|
+
def _get_children(self) -> list[TreeItem]:
|
|
444
471
|
return [c.treeitem for c in self.children_relation]
|
|
445
472
|
|
|
446
|
-
def _set_children(self, children:
|
|
473
|
+
def _set_children(self, children: list[TreeItem], order: bool = False) -> None:
|
|
447
474
|
"""
|
|
448
475
|
Set the current TreeGroup children TreeItem instances.
|
|
449
476
|
|
|
@@ -489,7 +516,7 @@ class LayerGroup(TreeGroup):
|
|
|
489
516
|
__colanderalchemy_config__ = {
|
|
490
517
|
"title": _("Layers group"),
|
|
491
518
|
"plural": _("Layers groups"),
|
|
492
|
-
"description": Literal(
|
|
519
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
493
520
|
_(
|
|
494
521
|
"""
|
|
495
522
|
<div class="help-block">
|
|
@@ -502,12 +529,12 @@ class LayerGroup(TreeGroup):
|
|
|
502
529
|
)
|
|
503
530
|
),
|
|
504
531
|
}
|
|
505
|
-
__mapper_args__ = {"polymorphic_identity": "group"}
|
|
532
|
+
__mapper_args__ = {"polymorphic_identity": "group"} # type: ignore[dict-item]
|
|
506
533
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
507
534
|
|
|
508
|
-
id =
|
|
535
|
+
id: Mapped[int] = mapped_column(
|
|
509
536
|
Integer,
|
|
510
|
-
ForeignKey(_schema + ".treegroup.id"),
|
|
537
|
+
ForeignKey(_schema + ".treegroup.id", ondelete="CASCADE"),
|
|
511
538
|
primary_key=True,
|
|
512
539
|
info={"colanderalchemy": {"missing": drop, "widget": HiddenWidget()}},
|
|
513
540
|
)
|
|
@@ -532,19 +559,19 @@ class Theme(TreeGroup):
|
|
|
532
559
|
__tablename__ = "theme"
|
|
533
560
|
__table_args__ = {"schema": _schema}
|
|
534
561
|
__colanderalchemy_config__ = {"title": _("Theme"), "plural": _("Themes")}
|
|
535
|
-
__mapper_args__ = {"polymorphic_identity": "theme"}
|
|
562
|
+
__mapper_args__ = {"polymorphic_identity": "theme"} # type: ignore[dict-item]
|
|
536
563
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
537
564
|
|
|
538
|
-
id =
|
|
565
|
+
id: Mapped[int] = mapped_column(
|
|
539
566
|
Integer,
|
|
540
|
-
ForeignKey(_schema + ".treegroup.id"),
|
|
567
|
+
ForeignKey(_schema + ".treegroup.id", ondelete="CASCADE"),
|
|
541
568
|
primary_key=True,
|
|
542
569
|
info={"colanderalchemy": {"missing": drop, "widget": HiddenWidget()}},
|
|
543
570
|
)
|
|
544
|
-
ordering =
|
|
571
|
+
ordering: Mapped[int] = mapped_column(
|
|
545
572
|
Integer, nullable=False, info={"colanderalchemy": {"title": _("Order"), "widget": HiddenWidget()}}
|
|
546
573
|
)
|
|
547
|
-
public =
|
|
574
|
+
public: Mapped[bool] = mapped_column(
|
|
548
575
|
Boolean,
|
|
549
576
|
default=True,
|
|
550
577
|
nullable=False,
|
|
@@ -555,12 +582,14 @@ class Theme(TreeGroup):
|
|
|
555
582
|
}
|
|
556
583
|
},
|
|
557
584
|
)
|
|
558
|
-
icon =
|
|
585
|
+
icon: Mapped[str] = mapped_column(
|
|
559
586
|
Unicode,
|
|
587
|
+
nullable=True,
|
|
560
588
|
info={
|
|
561
589
|
"colanderalchemy": {
|
|
562
590
|
"title": _("Icon"),
|
|
563
591
|
"description": _("The icon URL."),
|
|
592
|
+
"missing": "",
|
|
564
593
|
}
|
|
565
594
|
},
|
|
566
595
|
)
|
|
@@ -609,15 +638,15 @@ class Layer(TreeItem):
|
|
|
609
638
|
|
|
610
639
|
__tablename__ = "layer"
|
|
611
640
|
__table_args__ = {"schema": _schema}
|
|
612
|
-
__mapper_args__ = {"polymorphic_identity": "layer"} # needed for _identity_class
|
|
641
|
+
__mapper_args__ = {"polymorphic_identity": "layer"} # type: ignore[dict-item] # needed for _identity_class
|
|
613
642
|
|
|
614
|
-
id =
|
|
643
|
+
id: Mapped[int] = mapped_column(
|
|
615
644
|
Integer,
|
|
616
|
-
ForeignKey(_schema + ".treeitem.id"),
|
|
645
|
+
ForeignKey(_schema + ".treeitem.id", ondelete="CASCADE"),
|
|
617
646
|
primary_key=True,
|
|
618
647
|
info={"colanderalchemy": {"widget": HiddenWidget()}},
|
|
619
648
|
)
|
|
620
|
-
public =
|
|
649
|
+
public: Mapped[bool] = mapped_column(
|
|
621
650
|
Boolean,
|
|
622
651
|
default=True,
|
|
623
652
|
info={
|
|
@@ -627,7 +656,7 @@ class Layer(TreeItem):
|
|
|
627
656
|
}
|
|
628
657
|
},
|
|
629
658
|
)
|
|
630
|
-
geo_table =
|
|
659
|
+
geo_table: Mapped[str | None] = mapped_column(
|
|
631
660
|
Unicode,
|
|
632
661
|
info={
|
|
633
662
|
"colanderalchemy": {
|
|
@@ -636,8 +665,9 @@ class Layer(TreeItem):
|
|
|
636
665
|
}
|
|
637
666
|
},
|
|
638
667
|
)
|
|
639
|
-
exclude_properties =
|
|
668
|
+
exclude_properties: Mapped[str] = mapped_column(
|
|
640
669
|
Unicode,
|
|
670
|
+
nullable=True,
|
|
641
671
|
info={
|
|
642
672
|
"colanderalchemy": {
|
|
643
673
|
"title": _("Exclude properties"),
|
|
@@ -648,6 +678,7 @@ class Layer(TreeItem):
|
|
|
648
678
|
For enumerable attributes (foreign key), the column name should end with '_id'.
|
|
649
679
|
"""
|
|
650
680
|
),
|
|
681
|
+
"missing": "",
|
|
651
682
|
}
|
|
652
683
|
},
|
|
653
684
|
)
|
|
@@ -660,19 +691,27 @@ class Layer(TreeItem):
|
|
|
660
691
|
class DimensionLayer(Layer):
|
|
661
692
|
"""The intermediate class for the leyser with dimension."""
|
|
662
693
|
|
|
663
|
-
__mapper_args__ = {"polymorphic_identity": "dimensionlayer"} # needed for _identity_class
|
|
694
|
+
__mapper_args__ = {"polymorphic_identity": "dimensionlayer"} # type: ignore[dict-item] # needed for _identity_class
|
|
664
695
|
|
|
665
696
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
697
|
+
OGCServerType = Literal["mapserver", "qgisserver", "geoserver", "arcgis", "other"]
|
|
698
|
+
OGCSERVER_TYPE_MAPSERVER: OGCServerType = "mapserver"
|
|
699
|
+
OGCSERVER_TYPE_QGISSERVER: OGCServerType = "qgisserver"
|
|
700
|
+
OGCSERVER_TYPE_GEOSERVER: OGCServerType = "geoserver"
|
|
701
|
+
OGCSERVER_TYPE_ARCGIS: OGCServerType = "arcgis"
|
|
702
|
+
OGCSERVER_TYPE_OTHER: OGCServerType = "other"
|
|
671
703
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
704
|
+
|
|
705
|
+
OGCServerAuth = Literal["No auth", "Standard auth", "Geoserver auth", "Proxy"]
|
|
706
|
+
OGCSERVER_AUTH_NOAUTH: OGCServerAuth = "No auth"
|
|
707
|
+
OGCSERVER_AUTH_STANDARD: OGCServerAuth = "Standard auth"
|
|
708
|
+
OGCSERVER_AUTH_GEOSERVER: OGCServerAuth = "Geoserver auth"
|
|
709
|
+
OGCSERVER_AUTH_PROXY: OGCServerAuth = "Proxy"
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
ImageType = Literal["image/jpeg", "image/png"]
|
|
713
|
+
TimeMode = Literal["disabled", "value", "range"]
|
|
714
|
+
TimeWidget = Literal["slider", "datepicker"]
|
|
676
715
|
|
|
677
716
|
|
|
678
717
|
class OGCServer(Base): # type: ignore
|
|
@@ -683,7 +722,7 @@ class OGCServer(Base): # type: ignore
|
|
|
683
722
|
__colanderalchemy_config__ = {
|
|
684
723
|
"title": _("OGC Server"),
|
|
685
724
|
"plural": _("OGC Servers"),
|
|
686
|
-
"description": Literal(
|
|
725
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
687
726
|
_(
|
|
688
727
|
"""
|
|
689
728
|
<div class="help-block">
|
|
@@ -698,8 +737,10 @@ class OGCServer(Base): # type: ignore
|
|
|
698
737
|
),
|
|
699
738
|
}
|
|
700
739
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
701
|
-
id
|
|
702
|
-
|
|
740
|
+
id: Mapped[int] = mapped_column(
|
|
741
|
+
Integer, primary_key=True, info={"colanderalchemy": {"widget": HiddenWidget()}}
|
|
742
|
+
)
|
|
743
|
+
name: Mapped[str] = mapped_column(
|
|
703
744
|
Unicode,
|
|
704
745
|
nullable=False,
|
|
705
746
|
unique=True,
|
|
@@ -710,7 +751,7 @@ class OGCServer(Base): # type: ignore
|
|
|
710
751
|
}
|
|
711
752
|
},
|
|
712
753
|
)
|
|
713
|
-
description =
|
|
754
|
+
description: Mapped[str | None] = mapped_column(
|
|
714
755
|
Unicode,
|
|
715
756
|
info={
|
|
716
757
|
"colanderalchemy": {
|
|
@@ -719,7 +760,7 @@ class OGCServer(Base): # type: ignore
|
|
|
719
760
|
}
|
|
720
761
|
},
|
|
721
762
|
)
|
|
722
|
-
url =
|
|
763
|
+
url: Mapped[str] = mapped_column(
|
|
723
764
|
Unicode,
|
|
724
765
|
nullable=False,
|
|
725
766
|
info={
|
|
@@ -729,7 +770,7 @@ class OGCServer(Base): # type: ignore
|
|
|
729
770
|
}
|
|
730
771
|
},
|
|
731
772
|
)
|
|
732
|
-
url_wfs =
|
|
773
|
+
url_wfs: Mapped[str | None] = mapped_column(
|
|
733
774
|
Unicode,
|
|
734
775
|
info={
|
|
735
776
|
"colanderalchemy": {
|
|
@@ -738,15 +779,8 @@ class OGCServer(Base): # type: ignore
|
|
|
738
779
|
}
|
|
739
780
|
},
|
|
740
781
|
)
|
|
741
|
-
type =
|
|
742
|
-
Enum(
|
|
743
|
-
OGCSERVER_TYPE_MAPSERVER,
|
|
744
|
-
OGCSERVER_TYPE_QGISSERVER,
|
|
745
|
-
OGCSERVER_TYPE_GEOSERVER,
|
|
746
|
-
OGCSERVER_TYPE_ARCGIS,
|
|
747
|
-
OGCSERVER_TYPE_OTHER,
|
|
748
|
-
native_enum=False,
|
|
749
|
-
),
|
|
782
|
+
type: Mapped[OGCServerType] = mapped_column(
|
|
783
|
+
Enum(*get_args(OGCServerType), native_enum=False),
|
|
750
784
|
nullable=False,
|
|
751
785
|
info={
|
|
752
786
|
"colanderalchemy": {
|
|
@@ -754,56 +788,35 @@ class OGCServer(Base): # type: ignore
|
|
|
754
788
|
"description": _(
|
|
755
789
|
"The server type which is used to know which custom attribute will be used."
|
|
756
790
|
),
|
|
757
|
-
"widget": SelectWidget(
|
|
758
|
-
values=(
|
|
759
|
-
(OGCSERVER_TYPE_MAPSERVER, OGCSERVER_TYPE_MAPSERVER),
|
|
760
|
-
(OGCSERVER_TYPE_QGISSERVER, OGCSERVER_TYPE_QGISSERVER),
|
|
761
|
-
(OGCSERVER_TYPE_GEOSERVER, OGCSERVER_TYPE_GEOSERVER),
|
|
762
|
-
(OGCSERVER_TYPE_ARCGIS, OGCSERVER_TYPE_ARCGIS),
|
|
763
|
-
(OGCSERVER_TYPE_OTHER, OGCSERVER_TYPE_OTHER),
|
|
764
|
-
)
|
|
765
|
-
),
|
|
791
|
+
"widget": SelectWidget(values=list((e, e) for e in get_args(OGCServerType))),
|
|
766
792
|
}
|
|
767
793
|
},
|
|
768
794
|
)
|
|
769
|
-
image_type =
|
|
770
|
-
Enum(
|
|
795
|
+
image_type: Mapped[ImageType] = mapped_column(
|
|
796
|
+
Enum(*get_args(ImageType), native_enum=False),
|
|
771
797
|
nullable=False,
|
|
772
798
|
info={
|
|
773
799
|
"colanderalchemy": {
|
|
774
800
|
"title": _("Image type"),
|
|
775
801
|
"description": _("The MIME type of the images (e.g.: ``image/png``)."),
|
|
776
|
-
"widget": SelectWidget(values=((
|
|
802
|
+
"widget": SelectWidget(values=list((e, e) for e in get_args(ImageType))),
|
|
777
803
|
"column": 2,
|
|
778
804
|
}
|
|
779
805
|
},
|
|
780
806
|
)
|
|
781
|
-
auth =
|
|
782
|
-
Enum(
|
|
783
|
-
OGCSERVER_AUTH_NOAUTH,
|
|
784
|
-
OGCSERVER_AUTH_STANDARD,
|
|
785
|
-
OGCSERVER_AUTH_GEOSERVER,
|
|
786
|
-
OGCSERVER_AUTH_PROXY,
|
|
787
|
-
native_enum=False,
|
|
788
|
-
),
|
|
807
|
+
auth: Mapped[OGCServerAuth] = mapped_column(
|
|
808
|
+
Enum(*get_args(OGCServerAuth), native_enum=False),
|
|
789
809
|
nullable=False,
|
|
790
810
|
info={
|
|
791
811
|
"colanderalchemy": {
|
|
792
812
|
"title": _("Authentication type"),
|
|
793
813
|
"description": "The kind of authentication to use.",
|
|
794
|
-
"widget": SelectWidget(
|
|
795
|
-
values=(
|
|
796
|
-
(OGCSERVER_AUTH_NOAUTH, OGCSERVER_AUTH_NOAUTH),
|
|
797
|
-
(OGCSERVER_AUTH_STANDARD, OGCSERVER_AUTH_STANDARD),
|
|
798
|
-
(OGCSERVER_AUTH_GEOSERVER, OGCSERVER_AUTH_GEOSERVER),
|
|
799
|
-
(OGCSERVER_AUTH_PROXY, OGCSERVER_AUTH_PROXY),
|
|
800
|
-
)
|
|
801
|
-
),
|
|
814
|
+
"widget": SelectWidget(values=list((e, e) for e in get_args(OGCServerAuth))),
|
|
802
815
|
"column": 2,
|
|
803
816
|
}
|
|
804
817
|
},
|
|
805
818
|
)
|
|
806
|
-
wfs_support =
|
|
819
|
+
wfs_support: Mapped[bool] = mapped_column(
|
|
807
820
|
Boolean,
|
|
808
821
|
info={
|
|
809
822
|
"colanderalchemy": {
|
|
@@ -813,7 +826,7 @@ class OGCServer(Base): # type: ignore
|
|
|
813
826
|
}
|
|
814
827
|
},
|
|
815
828
|
)
|
|
816
|
-
is_single_tile =
|
|
829
|
+
is_single_tile: Mapped[bool] = mapped_column(
|
|
817
830
|
Boolean,
|
|
818
831
|
info={
|
|
819
832
|
"colanderalchemy": {
|
|
@@ -827,12 +840,12 @@ class OGCServer(Base): # type: ignore
|
|
|
827
840
|
def __init__(
|
|
828
841
|
self,
|
|
829
842
|
name: str = "",
|
|
830
|
-
description:
|
|
843
|
+
description: str | None = None,
|
|
831
844
|
url: str = "https://wms.example.com",
|
|
832
|
-
url_wfs:
|
|
833
|
-
type_:
|
|
834
|
-
image_type:
|
|
835
|
-
auth:
|
|
845
|
+
url_wfs: str | None = None,
|
|
846
|
+
type_: OGCServerType = OGCSERVER_TYPE_MAPSERVER,
|
|
847
|
+
image_type: ImageType = "image/png",
|
|
848
|
+
auth: OGCServerAuth = OGCSERVER_AUTH_STANDARD,
|
|
836
849
|
wfs_support: bool = True,
|
|
837
850
|
is_single_tile: bool = False,
|
|
838
851
|
) -> None:
|
|
@@ -850,14 +863,14 @@ class OGCServer(Base): # type: ignore
|
|
|
850
863
|
return self.name or ""
|
|
851
864
|
|
|
852
865
|
def url_description(self, request: pyramid.request.Request) -> str:
|
|
853
|
-
errors:
|
|
866
|
+
errors: set[str] = set()
|
|
854
867
|
url = get_url2(self.name, self.url, request, errors)
|
|
855
868
|
return url.url() if url else "\n".join(errors)
|
|
856
869
|
|
|
857
|
-
def url_wfs_description(self, request: pyramid.request.Request) ->
|
|
870
|
+
def url_wfs_description(self, request: pyramid.request.Request) -> str | None:
|
|
858
871
|
if not self.url_wfs:
|
|
859
872
|
return self.url_description(request)
|
|
860
|
-
errors:
|
|
873
|
+
errors: set[str] = set()
|
|
861
874
|
url = get_url2(self.name, self.url_wfs, request, errors)
|
|
862
875
|
return url.url() if url else "\n".join(errors)
|
|
863
876
|
|
|
@@ -870,7 +883,7 @@ class LayerWMS(DimensionLayer):
|
|
|
870
883
|
__colanderalchemy_config__ = {
|
|
871
884
|
"title": _("WMS Layer"),
|
|
872
885
|
"plural": _("WMS Layers"),
|
|
873
|
-
"description": Literal(
|
|
886
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
874
887
|
_(
|
|
875
888
|
"""
|
|
876
889
|
<div class="help-block">
|
|
@@ -886,15 +899,15 @@ class LayerWMS(DimensionLayer):
|
|
|
886
899
|
|
|
887
900
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
888
901
|
|
|
889
|
-
__mapper_args__ = {"polymorphic_identity": "l_wms"}
|
|
902
|
+
__mapper_args__ = {"polymorphic_identity": "l_wms"} # type: ignore[dict-item]
|
|
890
903
|
|
|
891
|
-
id =
|
|
904
|
+
id: Mapped[int] = mapped_column(
|
|
892
905
|
Integer,
|
|
893
906
|
ForeignKey(_schema + ".layer.id", ondelete="CASCADE"),
|
|
894
907
|
primary_key=True,
|
|
895
908
|
info={"colanderalchemy": {"missing": None, "widget": HiddenWidget()}},
|
|
896
909
|
)
|
|
897
|
-
ogc_server_id =
|
|
910
|
+
ogc_server_id: Mapped[int] = mapped_column(
|
|
898
911
|
Integer,
|
|
899
912
|
ForeignKey(_schema + ".ogc_server.id"),
|
|
900
913
|
nullable=False,
|
|
@@ -908,7 +921,7 @@ class LayerWMS(DimensionLayer):
|
|
|
908
921
|
}
|
|
909
922
|
},
|
|
910
923
|
)
|
|
911
|
-
layer =
|
|
924
|
+
layer: Mapped[str] = mapped_column(
|
|
912
925
|
Unicode,
|
|
913
926
|
nullable=False,
|
|
914
927
|
info={
|
|
@@ -926,7 +939,7 @@ class LayerWMS(DimensionLayer):
|
|
|
926
939
|
}
|
|
927
940
|
},
|
|
928
941
|
)
|
|
929
|
-
style =
|
|
942
|
+
style: Mapped[str | None] = mapped_column(
|
|
930
943
|
Unicode,
|
|
931
944
|
info={
|
|
932
945
|
"colanderalchemy": {
|
|
@@ -936,30 +949,34 @@ class LayerWMS(DimensionLayer):
|
|
|
936
949
|
}
|
|
937
950
|
},
|
|
938
951
|
)
|
|
939
|
-
valid =
|
|
952
|
+
valid: Mapped[bool] = mapped_column(
|
|
940
953
|
Boolean,
|
|
954
|
+
nullable=True,
|
|
941
955
|
info={
|
|
942
956
|
"colanderalchemy": {
|
|
943
957
|
"title": _("Valid"),
|
|
944
958
|
"description": _("The status reported by latest synchronization (readonly)."),
|
|
945
959
|
"column": 2,
|
|
946
960
|
"widget": CheckboxWidget(readonly=True),
|
|
961
|
+
"missing": colander_null,
|
|
947
962
|
}
|
|
948
963
|
},
|
|
949
964
|
)
|
|
950
|
-
invalid_reason =
|
|
965
|
+
invalid_reason: Mapped[str] = mapped_column(
|
|
951
966
|
Unicode,
|
|
967
|
+
nullable=True,
|
|
952
968
|
info={
|
|
953
969
|
"colanderalchemy": {
|
|
954
970
|
"title": _("Reason why I am not valid"),
|
|
955
971
|
"description": _("The reason for status reported by latest synchronization (readonly)."),
|
|
956
972
|
"column": 2,
|
|
957
973
|
"widget": TextInputWidget(readonly=True),
|
|
974
|
+
"missing": "",
|
|
958
975
|
}
|
|
959
976
|
},
|
|
960
977
|
)
|
|
961
|
-
time_mode =
|
|
962
|
-
Enum(
|
|
978
|
+
time_mode: Mapped[TimeMode] = mapped_column(
|
|
979
|
+
Enum(*get_args(TimeMode), native_enum=False),
|
|
963
980
|
default="disabled",
|
|
964
981
|
nullable=False,
|
|
965
982
|
info={
|
|
@@ -973,8 +990,8 @@ class LayerWMS(DimensionLayer):
|
|
|
973
990
|
}
|
|
974
991
|
},
|
|
975
992
|
)
|
|
976
|
-
time_widget =
|
|
977
|
-
Enum(
|
|
993
|
+
time_widget: Mapped[TimeWidget] = mapped_column(
|
|
994
|
+
Enum(*get_args(TimeWidget), native_enum=False),
|
|
978
995
|
default="slider",
|
|
979
996
|
nullable=False,
|
|
980
997
|
info={
|
|
@@ -1005,8 +1022,8 @@ class LayerWMS(DimensionLayer):
|
|
|
1005
1022
|
name: str = "",
|
|
1006
1023
|
layer: str = "",
|
|
1007
1024
|
public: bool = True,
|
|
1008
|
-
time_mode:
|
|
1009
|
-
time_widget:
|
|
1025
|
+
time_mode: TimeMode = "disabled",
|
|
1026
|
+
time_widget: TimeWidget = "slider",
|
|
1010
1027
|
) -> None:
|
|
1011
1028
|
super().__init__(name=name, public=public)
|
|
1012
1029
|
self.layer = layer
|
|
@@ -1014,7 +1031,7 @@ class LayerWMS(DimensionLayer):
|
|
|
1014
1031
|
self.time_widget = time_widget
|
|
1015
1032
|
|
|
1016
1033
|
@staticmethod
|
|
1017
|
-
def get_default(dbsession: Session) ->
|
|
1034
|
+
def get_default(dbsession: Session) -> DimensionLayer | None:
|
|
1018
1035
|
return cast(
|
|
1019
1036
|
Optional[DimensionLayer],
|
|
1020
1037
|
dbsession.query(LayerWMS).filter(LayerWMS.name == "wms-defaults").one_or_none(),
|
|
@@ -1029,7 +1046,7 @@ class LayerWMTS(DimensionLayer):
|
|
|
1029
1046
|
__colanderalchemy_config__ = {
|
|
1030
1047
|
"title": _("WMTS Layer"),
|
|
1031
1048
|
"plural": _("WMTS Layers"),
|
|
1032
|
-
"description": Literal(
|
|
1049
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
1033
1050
|
_(
|
|
1034
1051
|
"""
|
|
1035
1052
|
<div class="help-block">
|
|
@@ -1077,15 +1094,15 @@ class LayerWMTS(DimensionLayer):
|
|
|
1077
1094
|
),
|
|
1078
1095
|
}
|
|
1079
1096
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
1080
|
-
__mapper_args__ = {"polymorphic_identity": "l_wmts"}
|
|
1097
|
+
__mapper_args__ = {"polymorphic_identity": "l_wmts"} # type: ignore[dict-item]
|
|
1081
1098
|
|
|
1082
|
-
id =
|
|
1099
|
+
id: Mapped[int] = mapped_column(
|
|
1083
1100
|
Integer,
|
|
1084
|
-
ForeignKey(_schema + ".layer.id"),
|
|
1101
|
+
ForeignKey(_schema + ".layer.id", ondelete="CASCADE"),
|
|
1085
1102
|
primary_key=True,
|
|
1086
1103
|
info={"colanderalchemy": {"missing": None, "widget": HiddenWidget()}},
|
|
1087
1104
|
)
|
|
1088
|
-
url =
|
|
1105
|
+
url: Mapped[str] = mapped_column(
|
|
1089
1106
|
Unicode,
|
|
1090
1107
|
nullable=False,
|
|
1091
1108
|
info={
|
|
@@ -1096,7 +1113,7 @@ class LayerWMTS(DimensionLayer):
|
|
|
1096
1113
|
}
|
|
1097
1114
|
},
|
|
1098
1115
|
)
|
|
1099
|
-
layer =
|
|
1116
|
+
layer: Mapped[str] = mapped_column(
|
|
1100
1117
|
Unicode,
|
|
1101
1118
|
nullable=False,
|
|
1102
1119
|
info={
|
|
@@ -1107,18 +1124,21 @@ class LayerWMTS(DimensionLayer):
|
|
|
1107
1124
|
}
|
|
1108
1125
|
},
|
|
1109
1126
|
)
|
|
1110
|
-
style =
|
|
1127
|
+
style: Mapped[str] = mapped_column(
|
|
1111
1128
|
Unicode,
|
|
1129
|
+
nullable=True,
|
|
1112
1130
|
info={
|
|
1113
1131
|
"colanderalchemy": {
|
|
1114
1132
|
"title": _("Style"),
|
|
1115
1133
|
"description": _("The style to use; if not present, the default style is used."),
|
|
1116
1134
|
"column": 2,
|
|
1135
|
+
"missing": "",
|
|
1117
1136
|
}
|
|
1118
1137
|
},
|
|
1119
1138
|
)
|
|
1120
|
-
matrix_set =
|
|
1139
|
+
matrix_set: Mapped[str] = mapped_column(
|
|
1121
1140
|
Unicode,
|
|
1141
|
+
nullable=True,
|
|
1122
1142
|
info={
|
|
1123
1143
|
"colanderalchemy": {
|
|
1124
1144
|
"title": _("Matrix set"),
|
|
@@ -1127,16 +1147,17 @@ class LayerWMTS(DimensionLayer):
|
|
|
1127
1147
|
"left empty."
|
|
1128
1148
|
),
|
|
1129
1149
|
"column": 2,
|
|
1150
|
+
"missing": "",
|
|
1130
1151
|
}
|
|
1131
1152
|
},
|
|
1132
1153
|
)
|
|
1133
|
-
image_type =
|
|
1134
|
-
Enum(
|
|
1154
|
+
image_type: Mapped[ImageType] = mapped_column(
|
|
1155
|
+
Enum(*get_args(ImageType), native_enum=False),
|
|
1135
1156
|
nullable=False,
|
|
1136
1157
|
info={
|
|
1137
1158
|
"colanderalchemy": {
|
|
1138
1159
|
"title": _("Image type"),
|
|
1139
|
-
"description": Literal(
|
|
1160
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
1140
1161
|
_(
|
|
1141
1162
|
"""
|
|
1142
1163
|
The MIME type of the images (e.g.: <code>image/png</code>).
|
|
@@ -1144,17 +1165,17 @@ class LayerWMTS(DimensionLayer):
|
|
|
1144
1165
|
)
|
|
1145
1166
|
),
|
|
1146
1167
|
"column": 2,
|
|
1147
|
-
"widget": SelectWidget(values=((
|
|
1168
|
+
"widget": SelectWidget(values=list((e, e) for e in get_args(ImageType))),
|
|
1148
1169
|
}
|
|
1149
1170
|
},
|
|
1150
1171
|
)
|
|
1151
1172
|
|
|
1152
|
-
def __init__(self, name: str = "", public: bool = True, image_type:
|
|
1173
|
+
def __init__(self, name: str = "", public: bool = True, image_type: ImageType = "image/png") -> None:
|
|
1153
1174
|
super().__init__(name=name, public=public)
|
|
1154
1175
|
self.image_type = image_type
|
|
1155
1176
|
|
|
1156
1177
|
@staticmethod
|
|
1157
|
-
def get_default(dbsession: Session) ->
|
|
1178
|
+
def get_default(dbsession: Session) -> DimensionLayer | None:
|
|
1158
1179
|
return cast(
|
|
1159
1180
|
Optional[DimensionLayer],
|
|
1160
1181
|
dbsession.query(LayerWMTS).filter(LayerWMTS.name == "wmts-defaults").one_or_none(),
|
|
@@ -1190,6 +1211,58 @@ layer_ra = Table(
|
|
|
1190
1211
|
)
|
|
1191
1212
|
|
|
1192
1213
|
|
|
1214
|
+
class LayerCOG(Layer):
|
|
1215
|
+
"""The Cloud Optimized GeoTIFF layer table representation."""
|
|
1216
|
+
|
|
1217
|
+
__tablename__ = "layer_cog"
|
|
1218
|
+
__table_args__ = {"schema": _schema}
|
|
1219
|
+
__colanderalchemy_config__ = {
|
|
1220
|
+
"title": _("COG Layer"),
|
|
1221
|
+
"plural": _("COG Layers"),
|
|
1222
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
1223
|
+
_(
|
|
1224
|
+
"""
|
|
1225
|
+
<div class="help-block">
|
|
1226
|
+
<p>Definition of a <code>COG Layer</code> (COG for
|
|
1227
|
+
<a href="https://www.cogeo.org/">Cloud Optimized GeoTIFF</a>).</p>
|
|
1228
|
+
<p>Note: The layers named <code>cog-defaults</code> contains the values
|
|
1229
|
+
used when we create a new <code>COG layer</code>.</p>
|
|
1230
|
+
</div>
|
|
1231
|
+
"""
|
|
1232
|
+
)
|
|
1233
|
+
),
|
|
1234
|
+
}
|
|
1235
|
+
__c2cgeoform_config__ = {"duplicate": True}
|
|
1236
|
+
__mapper_args__ = {"polymorphic_identity": "l_cog"} # type: ignore[dict-item]
|
|
1237
|
+
|
|
1238
|
+
id: Mapped[int] = mapped_column(
|
|
1239
|
+
Integer,
|
|
1240
|
+
ForeignKey(_schema + ".layer.id"),
|
|
1241
|
+
primary_key=True,
|
|
1242
|
+
info={"colanderalchemy": {"missing": None, "widget": HiddenWidget()}},
|
|
1243
|
+
)
|
|
1244
|
+
url: Mapped[str] = mapped_column(
|
|
1245
|
+
Unicode,
|
|
1246
|
+
nullable=False,
|
|
1247
|
+
info={
|
|
1248
|
+
"colanderalchemy": {
|
|
1249
|
+
"title": _("URL"),
|
|
1250
|
+
"description": _("URL of the COG file."),
|
|
1251
|
+
"column": 2,
|
|
1252
|
+
}
|
|
1253
|
+
},
|
|
1254
|
+
)
|
|
1255
|
+
|
|
1256
|
+
@staticmethod
|
|
1257
|
+
def get_default(dbsession: Session) -> Layer | None:
|
|
1258
|
+
return dbsession.query(LayerCOG).filter(LayerCOG.name == "cog-defaults").one_or_none()
|
|
1259
|
+
|
|
1260
|
+
def url_description(self, request: pyramid.request.Request) -> str:
|
|
1261
|
+
errors: set[str] = set()
|
|
1262
|
+
url = get_url2(self.name, self.url, request, errors)
|
|
1263
|
+
return url.url() if url else "\n".join(errors)
|
|
1264
|
+
|
|
1265
|
+
|
|
1193
1266
|
class LayerVectorTiles(DimensionLayer):
|
|
1194
1267
|
"""The layer_vectortiles table representation."""
|
|
1195
1268
|
|
|
@@ -1198,7 +1271,7 @@ class LayerVectorTiles(DimensionLayer):
|
|
|
1198
1271
|
__colanderalchemy_config__ = {
|
|
1199
1272
|
"title": _("Vector Tiles Layer"),
|
|
1200
1273
|
"plural": _("Vector Tiles Layers"),
|
|
1201
|
-
"description": Literal(
|
|
1274
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
1202
1275
|
_(
|
|
1203
1276
|
"""
|
|
1204
1277
|
<div class="help-block">
|
|
@@ -1232,16 +1305,16 @@ class LayerVectorTiles(DimensionLayer):
|
|
|
1232
1305
|
|
|
1233
1306
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
1234
1307
|
|
|
1235
|
-
__mapper_args__ = {"polymorphic_identity": "l_mvt"}
|
|
1308
|
+
__mapper_args__ = {"polymorphic_identity": "l_mvt"} # type: ignore[dict-item]
|
|
1236
1309
|
|
|
1237
|
-
id =
|
|
1310
|
+
id: Mapped[int] = mapped_column(
|
|
1238
1311
|
Integer,
|
|
1239
1312
|
ForeignKey(_schema + ".layer.id"),
|
|
1240
1313
|
primary_key=True,
|
|
1241
1314
|
info={"colanderalchemy": {"missing": None, "widget": HiddenWidget()}},
|
|
1242
1315
|
)
|
|
1243
1316
|
|
|
1244
|
-
style =
|
|
1317
|
+
style: Mapped[str] = mapped_column(
|
|
1245
1318
|
Unicode,
|
|
1246
1319
|
nullable=False,
|
|
1247
1320
|
info={
|
|
@@ -1257,7 +1330,7 @@ class LayerVectorTiles(DimensionLayer):
|
|
|
1257
1330
|
},
|
|
1258
1331
|
)
|
|
1259
1332
|
|
|
1260
|
-
sql =
|
|
1333
|
+
sql: Mapped[str] = mapped_column(
|
|
1261
1334
|
Unicode,
|
|
1262
1335
|
nullable=True,
|
|
1263
1336
|
info={
|
|
@@ -1274,7 +1347,7 @@ class LayerVectorTiles(DimensionLayer):
|
|
|
1274
1347
|
},
|
|
1275
1348
|
)
|
|
1276
1349
|
|
|
1277
|
-
xyz =
|
|
1350
|
+
xyz: Mapped[str] = mapped_column(
|
|
1278
1351
|
Unicode,
|
|
1279
1352
|
nullable=True,
|
|
1280
1353
|
info={
|
|
@@ -1297,7 +1370,7 @@ class LayerVectorTiles(DimensionLayer):
|
|
|
1297
1370
|
self.sql = sql
|
|
1298
1371
|
|
|
1299
1372
|
@staticmethod
|
|
1300
|
-
def get_default(dbsession: Session) ->
|
|
1373
|
+
def get_default(dbsession: Session) -> DimensionLayer | None:
|
|
1301
1374
|
return cast(
|
|
1302
1375
|
Optional[DimensionLayer],
|
|
1303
1376
|
dbsession.query(LayerVectorTiles)
|
|
@@ -1306,7 +1379,7 @@ class LayerVectorTiles(DimensionLayer):
|
|
|
1306
1379
|
)
|
|
1307
1380
|
|
|
1308
1381
|
def style_description(self, request: pyramid.request.Request) -> str:
|
|
1309
|
-
errors:
|
|
1382
|
+
errors: set[str] = set()
|
|
1310
1383
|
url = get_url2(self.name, self.style, request, errors)
|
|
1311
1384
|
return url.url() if url else "\n".join(errors)
|
|
1312
1385
|
|
|
@@ -1318,9 +1391,11 @@ class RestrictionArea(Base): # type: ignore
|
|
|
1318
1391
|
__table_args__ = {"schema": _schema}
|
|
1319
1392
|
__colanderalchemy_config__ = {"title": _("Restriction area"), "plural": _("Restriction areas")}
|
|
1320
1393
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
1321
|
-
id
|
|
1394
|
+
id: Mapped[int] = mapped_column(
|
|
1395
|
+
Integer, primary_key=True, info={"colanderalchemy": {"widget": HiddenWidget()}}
|
|
1396
|
+
)
|
|
1322
1397
|
|
|
1323
|
-
name =
|
|
1398
|
+
name: Mapped[str] = mapped_column(
|
|
1324
1399
|
Unicode,
|
|
1325
1400
|
info={
|
|
1326
1401
|
"colanderalchemy": {
|
|
@@ -1329,7 +1404,7 @@ class RestrictionArea(Base): # type: ignore
|
|
|
1329
1404
|
}
|
|
1330
1405
|
},
|
|
1331
1406
|
)
|
|
1332
|
-
description =
|
|
1407
|
+
description: Mapped[str | None] = mapped_column(
|
|
1333
1408
|
Unicode,
|
|
1334
1409
|
info={
|
|
1335
1410
|
"colanderalchemy": {
|
|
@@ -1338,7 +1413,7 @@ class RestrictionArea(Base): # type: ignore
|
|
|
1338
1413
|
}
|
|
1339
1414
|
},
|
|
1340
1415
|
)
|
|
1341
|
-
readwrite =
|
|
1416
|
+
readwrite: Mapped[bool] = mapped_column(
|
|
1342
1417
|
Boolean,
|
|
1343
1418
|
default=False,
|
|
1344
1419
|
info={
|
|
@@ -1348,7 +1423,7 @@ class RestrictionArea(Base): # type: ignore
|
|
|
1348
1423
|
}
|
|
1349
1424
|
},
|
|
1350
1425
|
)
|
|
1351
|
-
area =
|
|
1426
|
+
area = mapped_column(
|
|
1352
1427
|
Geometry("POLYGON", srid=_srid),
|
|
1353
1428
|
info={
|
|
1354
1429
|
"colanderalchemy": {
|
|
@@ -1393,7 +1468,7 @@ class RestrictionArea(Base): # type: ignore
|
|
|
1393
1468
|
"colanderalchemy": {
|
|
1394
1469
|
"title": _("Layers"),
|
|
1395
1470
|
"exclude": True,
|
|
1396
|
-
"description": Literal(
|
|
1471
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
1397
1472
|
_(
|
|
1398
1473
|
"""
|
|
1399
1474
|
<div class="help-block">
|
|
@@ -1422,9 +1497,9 @@ class RestrictionArea(Base): # type: ignore
|
|
|
1422
1497
|
self,
|
|
1423
1498
|
name: str = "",
|
|
1424
1499
|
description: str = "",
|
|
1425
|
-
layers:
|
|
1426
|
-
roles:
|
|
1427
|
-
area: Geometry = None,
|
|
1500
|
+
layers: list[Layer] | None = None,
|
|
1501
|
+
roles: list[Role] | None = None,
|
|
1502
|
+
area: Geometry | None = None,
|
|
1428
1503
|
readwrite: bool = False,
|
|
1429
1504
|
) -> None:
|
|
1430
1505
|
if layers is None:
|
|
@@ -1478,8 +1553,10 @@ class Interface(Base): # type: ignore
|
|
|
1478
1553
|
__c2cgeoform_config__ = {"duplicate": True}
|
|
1479
1554
|
__colanderalchemy_config__ = {"title": _("Interface"), "plural": _("Interfaces")}
|
|
1480
1555
|
|
|
1481
|
-
id
|
|
1482
|
-
|
|
1556
|
+
id: Mapped[int] = mapped_column(
|
|
1557
|
+
Integer, primary_key=True, info={"colanderalchemy": {"widget": HiddenWidget()}}
|
|
1558
|
+
)
|
|
1559
|
+
name: Mapped[str] = mapped_column(
|
|
1483
1560
|
Unicode,
|
|
1484
1561
|
info={
|
|
1485
1562
|
"colanderalchemy": {
|
|
@@ -1488,7 +1565,7 @@ class Interface(Base): # type: ignore
|
|
|
1488
1565
|
}
|
|
1489
1566
|
},
|
|
1490
1567
|
)
|
|
1491
|
-
description =
|
|
1568
|
+
description: Mapped[str | None] = mapped_column(
|
|
1492
1569
|
Unicode,
|
|
1493
1570
|
info={
|
|
1494
1571
|
"colanderalchemy": {
|
|
@@ -1550,18 +1627,23 @@ class Metadata(Base): # type: ignore
|
|
|
1550
1627
|
"plural": _("Metadatas"),
|
|
1551
1628
|
}
|
|
1552
1629
|
|
|
1553
|
-
id
|
|
1554
|
-
|
|
1630
|
+
id: Mapped[int] = mapped_column(
|
|
1631
|
+
Integer, primary_key=True, info={"colanderalchemy": {"widget": HiddenWidget()}}
|
|
1632
|
+
)
|
|
1633
|
+
name: Mapped[str] = mapped_column(
|
|
1555
1634
|
Unicode,
|
|
1556
1635
|
info={
|
|
1557
1636
|
"colanderalchemy": {
|
|
1558
1637
|
"title": _("Name"),
|
|
1559
|
-
"description": Literal(
|
|
1638
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
1639
|
+
_("The type of <code>Metadata</code> we want to set.")
|
|
1640
|
+
),
|
|
1560
1641
|
}
|
|
1561
1642
|
},
|
|
1562
1643
|
)
|
|
1563
|
-
value =
|
|
1644
|
+
value: Mapped[str] = mapped_column(
|
|
1564
1645
|
Unicode,
|
|
1646
|
+
nullable=True,
|
|
1565
1647
|
info={
|
|
1566
1648
|
"colanderalchemy": {
|
|
1567
1649
|
"title": _("Value"),
|
|
@@ -1570,7 +1652,7 @@ class Metadata(Base): # type: ignore
|
|
|
1570
1652
|
}
|
|
1571
1653
|
},
|
|
1572
1654
|
)
|
|
1573
|
-
description =
|
|
1655
|
+
description: Mapped[str | None] = mapped_column(
|
|
1574
1656
|
Unicode,
|
|
1575
1657
|
info={
|
|
1576
1658
|
"colanderalchemy": {
|
|
@@ -1581,10 +1663,10 @@ class Metadata(Base): # type: ignore
|
|
|
1581
1663
|
},
|
|
1582
1664
|
)
|
|
1583
1665
|
|
|
1584
|
-
item_id =
|
|
1666
|
+
item_id: Mapped[int] = mapped_column(
|
|
1585
1667
|
"item_id",
|
|
1586
1668
|
Integer,
|
|
1587
|
-
ForeignKey(_schema + ".treeitem.id"),
|
|
1669
|
+
ForeignKey(_schema + ".treeitem.id", ondelete="CASCADE"),
|
|
1588
1670
|
nullable=False,
|
|
1589
1671
|
info={"colanderalchemy": {"exclude": True}, "c2cgeoform": {"duplicate": False}},
|
|
1590
1672
|
)
|
|
@@ -1598,7 +1680,7 @@ class Metadata(Base): # type: ignore
|
|
|
1598
1680
|
info={
|
|
1599
1681
|
"colanderalchemy": {
|
|
1600
1682
|
"title": _("Metadatas"),
|
|
1601
|
-
"description": Literal(
|
|
1683
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
1602
1684
|
_(
|
|
1603
1685
|
"""
|
|
1604
1686
|
<div class="help-block">
|
|
@@ -1631,7 +1713,7 @@ class Metadata(Base): # type: ignore
|
|
|
1631
1713
|
),
|
|
1632
1714
|
)
|
|
1633
1715
|
|
|
1634
|
-
def __init__(self, name: str = "", value: str = "", description:
|
|
1716
|
+
def __init__(self, name: str = "", value: str = "", description: str | None = None) -> None:
|
|
1635
1717
|
self.name = name
|
|
1636
1718
|
self.value = value
|
|
1637
1719
|
self.description = description
|
|
@@ -1655,8 +1737,10 @@ class Dimension(Base): # type: ignore
|
|
|
1655
1737
|
"plural": _("Dimensions"),
|
|
1656
1738
|
}
|
|
1657
1739
|
|
|
1658
|
-
id
|
|
1659
|
-
|
|
1740
|
+
id: Mapped[int] = mapped_column(
|
|
1741
|
+
Integer, primary_key=True, info={"colanderalchemy": {"widget": HiddenWidget()}}
|
|
1742
|
+
)
|
|
1743
|
+
name: Mapped[str] = mapped_column(
|
|
1660
1744
|
Unicode,
|
|
1661
1745
|
info={
|
|
1662
1746
|
"colanderalchemy": {
|
|
@@ -1665,8 +1749,9 @@ class Dimension(Base): # type: ignore
|
|
|
1665
1749
|
}
|
|
1666
1750
|
},
|
|
1667
1751
|
)
|
|
1668
|
-
value =
|
|
1752
|
+
value: Mapped[str] = mapped_column(
|
|
1669
1753
|
Unicode,
|
|
1754
|
+
nullable=True,
|
|
1670
1755
|
info={
|
|
1671
1756
|
"colanderalchemy": {
|
|
1672
1757
|
"title": _("Value"),
|
|
@@ -1674,7 +1759,7 @@ class Dimension(Base): # type: ignore
|
|
|
1674
1759
|
}
|
|
1675
1760
|
},
|
|
1676
1761
|
)
|
|
1677
|
-
field =
|
|
1762
|
+
field: Mapped[str | None] = mapped_column(
|
|
1678
1763
|
Unicode,
|
|
1679
1764
|
info={
|
|
1680
1765
|
"colanderalchemy": {
|
|
@@ -1685,7 +1770,7 @@ class Dimension(Base): # type: ignore
|
|
|
1685
1770
|
}
|
|
1686
1771
|
},
|
|
1687
1772
|
)
|
|
1688
|
-
description =
|
|
1773
|
+
description: Mapped[str | None] = mapped_column(
|
|
1689
1774
|
Unicode,
|
|
1690
1775
|
info={
|
|
1691
1776
|
"colanderalchemy": {
|
|
@@ -1696,7 +1781,7 @@ class Dimension(Base): # type: ignore
|
|
|
1696
1781
|
},
|
|
1697
1782
|
)
|
|
1698
1783
|
|
|
1699
|
-
layer_id =
|
|
1784
|
+
layer_id: Mapped[int] = mapped_column(
|
|
1700
1785
|
"layer_id",
|
|
1701
1786
|
Integer,
|
|
1702
1787
|
ForeignKey(_schema + ".layer.id"),
|
|
@@ -1713,7 +1798,7 @@ class Dimension(Base): # type: ignore
|
|
|
1713
1798
|
"colanderalchemy": {
|
|
1714
1799
|
"title": _("Dimensions"),
|
|
1715
1800
|
"exclude": True,
|
|
1716
|
-
"description": Literal(
|
|
1801
|
+
"description": c2cgeoportal_commons.lib.literal.Literal(
|
|
1717
1802
|
_(
|
|
1718
1803
|
"""
|
|
1719
1804
|
<div class="help-block">
|
|
@@ -1732,9 +1817,9 @@ class Dimension(Base): # type: ignore
|
|
|
1732
1817
|
self,
|
|
1733
1818
|
name: str = "",
|
|
1734
1819
|
value: str = "",
|
|
1735
|
-
layer:
|
|
1736
|
-
field:
|
|
1737
|
-
description:
|
|
1820
|
+
layer: str | None = None,
|
|
1821
|
+
field: str | None = None,
|
|
1822
|
+
description: str | None = None,
|
|
1738
1823
|
) -> None:
|
|
1739
1824
|
self.name = name
|
|
1740
1825
|
self.value = value
|
|
@@ -1767,8 +1852,8 @@ class AbstractLog(AbstractConcreteBase, Base): # type: ignore
|
|
|
1767
1852
|
"plural": _("Logs"),
|
|
1768
1853
|
}
|
|
1769
1854
|
|
|
1770
|
-
id =
|
|
1771
|
-
date =
|
|
1855
|
+
id: Mapped[int] = mapped_column(Integer, primary_key=True, info={"colanderalchemy": {}})
|
|
1856
|
+
date: Mapped[datetime] = mapped_column(
|
|
1772
1857
|
DateTime(timezone=True),
|
|
1773
1858
|
nullable=False,
|
|
1774
1859
|
info={
|
|
@@ -1777,7 +1862,7 @@ class AbstractLog(AbstractConcreteBase, Base): # type: ignore
|
|
|
1777
1862
|
}
|
|
1778
1863
|
},
|
|
1779
1864
|
)
|
|
1780
|
-
action =
|
|
1865
|
+
action: Mapped[LogAction] = mapped_column(
|
|
1781
1866
|
Enum(LogAction, native_enum=False),
|
|
1782
1867
|
nullable=False,
|
|
1783
1868
|
info={
|
|
@@ -1786,7 +1871,7 @@ class AbstractLog(AbstractConcreteBase, Base): # type: ignore
|
|
|
1786
1871
|
}
|
|
1787
1872
|
},
|
|
1788
1873
|
)
|
|
1789
|
-
element_type =
|
|
1874
|
+
element_type: Mapped[str] = mapped_column(
|
|
1790
1875
|
String(50),
|
|
1791
1876
|
nullable=False,
|
|
1792
1877
|
info={
|
|
@@ -1795,7 +1880,7 @@ class AbstractLog(AbstractConcreteBase, Base): # type: ignore
|
|
|
1795
1880
|
}
|
|
1796
1881
|
},
|
|
1797
1882
|
)
|
|
1798
|
-
element_id =
|
|
1883
|
+
element_id: Mapped[int] = mapped_column(
|
|
1799
1884
|
Integer,
|
|
1800
1885
|
nullable=False,
|
|
1801
1886
|
info={
|
|
@@ -1804,7 +1889,7 @@ class AbstractLog(AbstractConcreteBase, Base): # type: ignore
|
|
|
1804
1889
|
}
|
|
1805
1890
|
},
|
|
1806
1891
|
)
|
|
1807
|
-
element_name =
|
|
1892
|
+
element_name: Mapped[str] = mapped_column(
|
|
1808
1893
|
Unicode,
|
|
1809
1894
|
nullable=False,
|
|
1810
1895
|
info={
|
|
@@ -1813,7 +1898,7 @@ class AbstractLog(AbstractConcreteBase, Base): # type: ignore
|
|
|
1813
1898
|
}
|
|
1814
1899
|
},
|
|
1815
1900
|
)
|
|
1816
|
-
element_url_table =
|
|
1901
|
+
element_url_table: Mapped[str] = mapped_column(
|
|
1817
1902
|
Unicode,
|
|
1818
1903
|
nullable=False,
|
|
1819
1904
|
info={
|
|
@@ -1822,7 +1907,7 @@ class AbstractLog(AbstractConcreteBase, Base): # type: ignore
|
|
|
1822
1907
|
}
|
|
1823
1908
|
},
|
|
1824
1909
|
)
|
|
1825
|
-
username =
|
|
1910
|
+
username: Mapped[str] = mapped_column(
|
|
1826
1911
|
Unicode,
|
|
1827
1912
|
nullable=False,
|
|
1828
1913
|
info={
|