Skip to content

Commit 119e6d4

Browse files
committed
Save None for empty texts
1 parent 641b23b commit 119e6d4

File tree

3 files changed

+56
-30
lines changed

3 files changed

+56
-30
lines changed

arho_feature_template/core/models.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from arho_feature_template.exceptions import ConfigSyntaxError
1313
from arho_feature_template.project.layers.code_layers import AdditionalInformationTypeLayer, UndergroundTypeLayer
1414
from arho_feature_template.qgis_plugin_tools.tools.resources import resources_path
15-
from arho_feature_template.utils.misc_utils import LANGUAGE, get_layer_by_name, iface
15+
from arho_feature_template.utils.misc_utils import deserialize_localized_text, get_layer_by_name, iface
1616

1717
if TYPE_CHECKING:
1818
from datetime import datetime
@@ -246,8 +246,8 @@ class RegulationConfig:
246246

247247
id: str
248248
regulation_code: str
249-
name: str
250-
description: str
249+
name: str | None
250+
description: str | None
251251
status: str
252252
level: int
253253
parent_id: str | None
@@ -268,8 +268,8 @@ def from_feature(cls, feature: QgsFeature) -> RegulationConfig:
268268
return cls(
269269
id=feature["id"],
270270
regulation_code=feature["value"],
271-
name=feature["name"].get(LANGUAGE) if feature["name"] else None,
272-
description=feature["description"].get(LANGUAGE) if feature["description"] else None,
271+
name=deserialize_localized_text(feature["name"]),
272+
description=deserialize_localized_text(feature["description"]),
273273
status=feature["status"],
274274
level=feature["level"],
275275
parent_id=feature["parent_id"],
@@ -287,8 +287,8 @@ class AdditionalInformationConfig:
287287
# From layer
288288
id: str
289289
additional_information_type: str
290-
name: str
291-
description: str
290+
name: str | None
291+
description: str | None
292292
status: str
293293
level: int
294294
parent_id: str | None
@@ -344,8 +344,8 @@ def initialize(cls, config_fp: Path = ADDITIONAL_INFORMATION_CONFIG_PATH) -> Add
344344
ai_config = AdditionalInformationConfig(
345345
id=feature["id"],
346346
additional_information_type=ai_code,
347-
name=feature["name"].get(LANGUAGE) if feature["name"] else None,
348-
description=feature["description"].get(LANGUAGE) if feature["description"] else None,
347+
name=deserialize_localized_text(feature["name"]),
348+
description=deserialize_localized_text(feature["description"]),
349349
status=feature["status"],
350350
level=feature["level"],
351351
parent_id=feature["parent_id"],

arho_feature_template/project/layers/plan_layers.py

+31-20
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@
2323
from arho_feature_template.exceptions import FeatureNotFoundError, LayerEditableError, LayerNotFoundError
2424
from arho_feature_template.project.layers import AbstractLayer
2525
from arho_feature_template.project.layers.code_layers import PlanRegulationTypeLayer
26-
from arho_feature_template.utils.misc_utils import LANGUAGE, get_active_plan_id, iface
26+
from arho_feature_template.utils.misc_utils import (
27+
deserialize_localized_text,
28+
get_active_plan_id,
29+
iface,
30+
serialize_localized_text,
31+
)
2732

2833
logger = logging.getLogger(__name__)
2934

@@ -78,8 +83,8 @@ def feature_from_model(cls, model: Plan) -> QgsFeature:
7883

7984
feature = cls.initialize_feature_from_model(model)
8085
feature.setGeometry(model.geom)
81-
feature["name"] = {LANGUAGE: model.name if model.name else None}
82-
feature["description"] = {LANGUAGE: model.description if model.description else None}
86+
feature["name"] = serialize_localized_text(model.name)
87+
feature["description"] = serialize_localized_text(model.description)
8388
feature["permanent_plan_identifier"] = model.permanent_plan_identifier
8489
feature["record_number"] = model.record_number
8590
feature["producers_plan_identifier"] = model.producers_plan_identifier
@@ -98,8 +103,8 @@ def model_from_feature(cls, feature: QgsFeature) -> Plan:
98103
]
99104
return Plan(
100105
geom=feature.geometry(),
101-
name=feature["name"].get(LANGUAGE) if feature["name"] else None,
102-
description=feature["description"].get(LANGUAGE) if feature["description"] else None,
106+
name=deserialize_localized_text(feature["name"]),
107+
description=deserialize_localized_text(feature["description"]),
103108
permanent_plan_identifier=feature["permanent_plan_identifier"],
104109
record_number=feature["record_number"],
105110
producers_plan_identifier=feature["producers_plan_identifier"],
@@ -122,7 +127,9 @@ def model_from_feature(cls, feature: QgsFeature) -> Plan:
122127
@classmethod
123128
def get_plan_name(cls, plan_id: str) -> str:
124129
attribute_value = cls.get_attribute_value_by_another_attribute_value("name", "id", plan_id)
125-
return attribute_value.get(LANGUAGE, "Nimetön") if attribute_value else "Nimetön"
130+
name = deserialize_localized_text(attribute_value)
131+
132+
return name or "Nimetön"
126133

127134

128135
class PlanFeatureLayer(AbstractPlanLayer):
@@ -134,9 +141,9 @@ def feature_from_model(cls, model: PlanFeature, plan_id: str | None = None) -> Q
134141

135142
feature = cls.initialize_feature_from_model(model)
136143
feature.setGeometry(model.geom)
137-
feature["name"] = {LANGUAGE: model.name if model.name else None}
144+
feature["name"] = serialize_localized_text(model.name)
138145
feature["type_of_underground_id"] = model.type_of_underground_id
139-
feature["description"] = {LANGUAGE: model.description if model.description else None}
146+
feature["description"] = serialize_localized_text(model.description)
140147
feature["plan_id"] = plan_id if plan_id else get_active_plan_id()
141148

142149
return feature
@@ -151,8 +158,8 @@ def model_from_feature(cls, feature: QgsFeature) -> PlanFeature:
151158
geom=feature.geometry(),
152159
type_of_underground_id=feature["type_of_underground_id"],
153160
layer_name=cls.get_from_project().name(),
154-
name=feature["name"].get(LANGUAGE) if feature["name"] else None,
155-
description=feature["description"].get(LANGUAGE),
161+
name=deserialize_localized_text(feature["name"]),
162+
description=deserialize_localized_text(feature["description"]),
156163
regulation_groups=[
157164
RegulationGroupLayer.model_from_feature(feat) for feat in regulation_group_features if feat is not None
158165
],
@@ -195,7 +202,7 @@ def feature_from_model(cls, model: RegulationGroup, plan_id: str | None = None)
195202
feature = cls.initialize_feature_from_model(model)
196203

197204
feature["short_name"] = model.short_name if model.short_name else None
198-
feature["name"] = {LANGUAGE: model.name if model.name else None}
205+
feature["name"] = serialize_localized_text(model.name)
199206
feature["type_of_plan_regulation_group_id"] = model.type_code_id
200207
feature["plan_id"] = plan_id if plan_id else get_active_plan_id()
201208
feature["id"] = model.id_ if model.id_ else feature["id"]
@@ -205,7 +212,7 @@ def feature_from_model(cls, model: RegulationGroup, plan_id: str | None = None)
205212
def model_from_feature(cls, feature: QgsFeature) -> RegulationGroup:
206213
return RegulationGroup(
207214
type_code_id=feature["type_of_plan_regulation_group_id"],
208-
name=feature["name"].get(LANGUAGE) if feature["name"] else None,
215+
name=deserialize_localized_text(feature["name"]),
209216
short_name=feature["short_name"],
210217
color_code=None,
211218
group_number=None,
@@ -313,11 +320,11 @@ def attribute_value_model_from_feature(feature: QgsFeature) -> AttributeValue:
313320
numeric_range_min=feature["numeric_range_min"],
314321
numeric_range_max=feature["numeric_range_max"],
315322
unit=feature["unit"],
316-
text_value=feature["text_value"].get(LANGUAGE) if feature["text_value"] else None,
323+
text_value=deserialize_localized_text(feature["text_value"]),
317324
text_syntax=feature["text_syntax"],
318325
code_list=feature["code_list"],
319326
code_value=feature["code_value"],
320-
code_title=feature["code_title"].get(LANGUAGE) if feature["code_title"] else None,
327+
code_title=deserialize_localized_text(feature["code_title"]),
321328
height_reference_point=feature["height_reference_point"],
322329
)
323330

@@ -330,11 +337,11 @@ def update_feature_from_attribute_value_model(value: AttributeValue | None, feat
330337
feature["numeric_range_min"] = value.numeric_range_min
331338
feature["numeric_range_max"] = value.numeric_range_max
332339
feature["unit"] = value.unit
333-
feature["text_value"] = {LANGUAGE: value.text_value if value.text_value else None}
340+
feature["text_value"] = serialize_localized_text(value.text_value)
334341
feature["text_syntax"] = value.text_syntax
335342
feature["code_list"] = value.code_list
336343
feature["code_value"] = value.code_value
337-
feature["code_title"] = {LANGUAGE: value.code_title if value.code_title else None}
344+
feature["code_title"] = serialize_localized_text(value.code_title)
338345
feature["height_reference_point"] = value.height_reference_point
339346

340347

@@ -428,7 +435,7 @@ class PlanPropositionLayer(AbstractPlanLayer):
428435
def feature_from_model(cls, model: Proposition) -> QgsFeature:
429436
feature = cls.initialize_feature_from_model(model)
430437

431-
feature["text_value"] = {LANGUAGE: model.value if model.value else None}
438+
feature["text_value"] = serialize_localized_text(model.value)
432439
feature["plan_regulation_group_id"] = model.regulation_group_id
433440
feature["ordering"] = model.proposition_number
434441
feature["plan_theme_id"] = model.theme_id
@@ -438,8 +445,12 @@ def feature_from_model(cls, model: Proposition) -> QgsFeature:
438445

439446
@classmethod
440447
def model_from_feature(cls, feature: QgsFeature) -> Proposition:
448+
proposition_value = deserialize_localized_text(feature["text_value"])
449+
if not proposition_value:
450+
msg = "Proposition value cannot be empty."
451+
raise ValueError(msg)
441452
return Proposition(
442-
value=feature["text_value"].get(LANGUAGE) if feature["text_value"] else None,
453+
value=proposition_value,
443454
regulation_group_id=feature["plan_regulation_group_id"],
444455
proposition_number=feature["ordering"],
445456
theme_id=feature["plan_theme_id"],
@@ -468,7 +479,7 @@ class DocumentLayer(AbstractPlanLayer):
468479
def feature_from_model(cls, model: Document) -> QgsFeature:
469480
feature = cls.initialize_feature_from_model(model)
470481

471-
feature["name"] = {LANGUAGE: model.name if model.name else None}
482+
feature["name"] = serialize_localized_text(model.name)
472483
feature["url"] = model.url
473484
feature["type_of_document_id"] = model.type_of_document_id
474485
feature["decision"] = model.decision
@@ -487,7 +498,7 @@ def feature_from_model(cls, model: Document) -> QgsFeature:
487498
@classmethod
488499
def model_from_feature(cls, feature: QgsFeature) -> Document:
489500
return Document(
490-
name=feature["name"].get(LANGUAGE) if feature["name"] else None,
501+
name=deserialize_localized_text(feature["name"]),
491502
url=feature["url"],
492503
type_of_document_id=feature["type_of_document_id"],
493504
decision=feature["decision"],

arho_feature_template/utils/misc_utils.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import os
44
from contextlib import suppress
5-
from typing import TYPE_CHECKING, cast
5+
from typing import TYPE_CHECKING, Any, cast
66

77
from qgis.core import QgsExpressionContextUtils, QgsProject, QgsVectorLayer
88
from qgis.PyQt.QtCore import QSettings, pyqtBoundSignal
@@ -113,3 +113,18 @@ def disconnect_signal(signal: pyqtBoundSignal) -> None:
113113
"""
114114
with suppress(TypeError):
115115
signal.disconnect()
116+
117+
118+
def serialize_localized_text(text: str | None) -> dict[str, str] | None:
119+
if isinstance(text, str):
120+
text = text.strip()
121+
if text:
122+
return {LANGUAGE: text}
123+
return None
124+
125+
126+
def deserialize_localized_text(text_value: dict[str, str] | None | Any) -> str | None:
127+
text = None
128+
if isinstance(text_value, dict):
129+
text = text_value.get(LANGUAGE)
130+
return text

0 commit comments

Comments
 (0)