xmas-app 0.9.0__py3-none-any.whl → 0.10.0__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.
- xmas_app/form.py +3 -1
- xmas_app/main.py +21 -46
- xmas_app/settings.py +4 -0
- {xmas_app-0.9.0.dist-info → xmas_app-0.10.0.dist-info}/METADATA +9 -7
- {xmas_app-0.9.0.dist-info → xmas_app-0.10.0.dist-info}/RECORD +8 -8
- {xmas_app-0.9.0.dist-info → xmas_app-0.10.0.dist-info}/WHEEL +0 -0
- {xmas_app-0.9.0.dist-info → xmas_app-0.10.0.dist-info}/entry_points.txt +0 -0
- {xmas_app-0.9.0.dist-info → xmas_app-0.10.0.dist-info}/licenses/LICENSE +0 -0
xmas_app/form.py
CHANGED
|
@@ -710,7 +710,9 @@ class ModelForm:
|
|
|
710
710
|
ui.select(
|
|
711
711
|
options,
|
|
712
712
|
label=prop_info["typename"],
|
|
713
|
-
on_change=self._set_stylesheetId_and_schriftinhalt
|
|
713
|
+
on_change=self._set_stylesheetId_and_schriftinhalt
|
|
714
|
+
if self.editable
|
|
715
|
+
else None,
|
|
714
716
|
multiple=prop_info["list"],
|
|
715
717
|
clearable=prop_info["nullable"],
|
|
716
718
|
validation=None
|
xmas_app/main.py
CHANGED
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
|
-
import pydantic
|
|
4
|
-
import pydantic_core
|
|
5
|
-
from nicegui.observables import ObservableSet
|
|
6
|
-
from xplan_tools.util import get_geometry_type_from_wkt
|
|
7
|
-
|
|
8
|
-
from xmas_app.schema import ErrorDetail, ErrorResponse, SplitPayload, SplitSuccess
|
|
9
|
-
from xmas_app.split_service import PlanSplitService, SplitValidationError
|
|
10
|
-
|
|
11
|
-
os.environ["PGGSSENCMODE"] = "disable"
|
|
12
|
-
os.environ["PGSSLMODE"] = "disable"
|
|
13
|
-
|
|
14
1
|
import asyncio
|
|
15
2
|
import importlib
|
|
16
3
|
import inspect
|
|
@@ -24,8 +11,15 @@ from tempfile import NamedTemporaryFile
|
|
|
24
11
|
from typing import Any, Literal
|
|
25
12
|
from uuid import uuid4
|
|
26
13
|
|
|
14
|
+
import pydantic
|
|
15
|
+
import pydantic_core
|
|
16
|
+
from nicegui.observables import ObservableSet
|
|
27
17
|
from pydantic import ValidationError
|
|
28
18
|
from starlette.applications import Starlette
|
|
19
|
+
from xplan_tools.util import get_geometry_type_from_wkt
|
|
20
|
+
|
|
21
|
+
from xmas_app.schema import ErrorDetail, ErrorResponse, SplitPayload, SplitSuccess
|
|
22
|
+
from xmas_app.split_service import PlanSplitService, SplitValidationError
|
|
29
23
|
|
|
30
24
|
log_dir = Path(__file__).parent / "logs"
|
|
31
25
|
log_dir.mkdir(exist_ok=True)
|
|
@@ -43,19 +37,6 @@ if not logger.handlers:
|
|
|
43
37
|
logger.addHandler(fh)
|
|
44
38
|
logger.debug(f"Writing logs to {log_file}")
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
# ui.timer(
|
|
48
|
-
# 1.0,
|
|
49
|
-
# lambda: (
|
|
50
|
-
# print("bindings:", len(binding.bindings)),
|
|
51
|
-
# print("a. links:", len(binding.active_links)),
|
|
52
|
-
# print("b. props:", len(binding.bindable_properties)),
|
|
53
|
-
# print(
|
|
54
|
-
# "c. link elements:", "\n".join([str(link) for link in binding.active_links])
|
|
55
|
-
# ),
|
|
56
|
-
# ),
|
|
57
|
-
# )
|
|
58
|
-
|
|
59
40
|
from fastapi import APIRouter, HTTPException, Request, status
|
|
60
41
|
from nicegui import app, run, ui
|
|
61
42
|
from nicegui.events import ClickEventArguments, ValueChangeEventArguments
|
|
@@ -170,7 +151,7 @@ async def plan_tree(
|
|
|
170
151
|
tree.update()
|
|
171
152
|
|
|
172
153
|
app.storage.client["user_agent"] = request.headers.get("user-agent", None)
|
|
173
|
-
qgis = app.storage.client["user_agent"]
|
|
154
|
+
qgis = app.storage.client["user_agent"].startswith(settings.qgis_plugin_name)
|
|
174
155
|
if qgis:
|
|
175
156
|
ui.add_head_html('<script src="qrc:///qtwebchannel/qwebchannel.js"></script>')
|
|
176
157
|
|
|
@@ -244,23 +225,17 @@ async def plan_tree(
|
|
|
244
225
|
if feature.get_geom_wkt():
|
|
245
226
|
ui.button("Zum Feature springen").on(
|
|
246
227
|
"click",
|
|
247
|
-
lambda e,
|
|
248
|
-
e, str(origin), str(target)
|
|
249
|
-
),
|
|
228
|
+
lambda e, target=target: highlight_feature(e, str(target)),
|
|
250
229
|
)
|
|
251
230
|
|
|
252
231
|
ui.button("Feature selektieren").on(
|
|
253
232
|
"click",
|
|
254
|
-
lambda e,
|
|
255
|
-
e, str(origin), str(target)
|
|
256
|
-
),
|
|
233
|
+
lambda e, target=target: select_feature(e, str(target)),
|
|
257
234
|
)
|
|
258
235
|
|
|
259
236
|
ui.button("Attributformular öffnen").on(
|
|
260
237
|
"click",
|
|
261
|
-
lambda e,
|
|
262
|
-
e, str(origin), str(target)
|
|
263
|
-
),
|
|
238
|
+
lambda e, target=target: show_attribute_form(e, str(target)),
|
|
264
239
|
)
|
|
265
240
|
|
|
266
241
|
# ui.button(
|
|
@@ -308,12 +283,12 @@ async def plan_tree(
|
|
|
308
283
|
return
|
|
309
284
|
action_dialog.open()
|
|
310
285
|
|
|
311
|
-
async def highlight_feature(e: ClickEventArguments,
|
|
286
|
+
async def highlight_feature(e: ClickEventArguments, target: str):
|
|
312
287
|
logger.debug("highlight_feature called")
|
|
313
288
|
try:
|
|
314
289
|
logger.info("Sending highlight_feature to QWebChannel handler")
|
|
315
290
|
ui.run_javascript(f"""new QWebChannel(qt.webChannelTransport, function (channel) {{
|
|
316
|
-
channel.objects.handler.highlight_feature("{
|
|
291
|
+
channel.objects.handler.highlight_feature("{target}")
|
|
317
292
|
}});""")
|
|
318
293
|
except Exception as ex:
|
|
319
294
|
logger.error(
|
|
@@ -322,12 +297,12 @@ async def plan_tree(
|
|
|
322
297
|
finally:
|
|
323
298
|
e.sender.props(remove="loading")
|
|
324
299
|
|
|
325
|
-
async def show_attribute_form(e: ClickEventArguments,
|
|
300
|
+
async def show_attribute_form(e: ClickEventArguments, target: str):
|
|
326
301
|
logger.debug("show_attribute_form called")
|
|
327
302
|
try:
|
|
328
303
|
logger.info("Sending show_attribute_form to QWebChannel handler")
|
|
329
304
|
ui.run_javascript(f"""new QWebChannel(qt.webChannelTransport, function (channel) {{
|
|
330
|
-
channel.objects.handler.show_attribute_form("{
|
|
305
|
+
channel.objects.handler.show_attribute_form("{target}")
|
|
331
306
|
}});""")
|
|
332
307
|
except Exception as ex:
|
|
333
308
|
logger.error(
|
|
@@ -336,12 +311,12 @@ async def plan_tree(
|
|
|
336
311
|
finally:
|
|
337
312
|
e.sender.props(remove="loading")
|
|
338
313
|
|
|
339
|
-
async def select_feature(e: ClickEventArguments,
|
|
314
|
+
async def select_feature(e: ClickEventArguments, target: str):
|
|
340
315
|
logger.debug("highlight_feature called")
|
|
341
316
|
try:
|
|
342
317
|
logger.info("Sending select_feature to QWebChannel handler")
|
|
343
318
|
ui.run_javascript(f"""new QWebChannel(qt.webChannelTransport, function (channel) {{
|
|
344
|
-
channel.objects.handler.select_feature("{
|
|
319
|
+
channel.objects.handler.select_feature("{target}")
|
|
345
320
|
}});""")
|
|
346
321
|
except Exception as ex:
|
|
347
322
|
logger.error(f"Exception while select_feature called: {ex}", exc_info=True)
|
|
@@ -397,7 +372,7 @@ async def plan_tree(
|
|
|
397
372
|
nodes,
|
|
398
373
|
on_select=show_menu,
|
|
399
374
|
tick_strategy=None,
|
|
400
|
-
).props("accordion")
|
|
375
|
+
).props("accordion no-transition")
|
|
401
376
|
|
|
402
377
|
notification.spinner = False
|
|
403
378
|
notification.type = "positive"
|
|
@@ -434,7 +409,7 @@ async def plans(
|
|
|
434
409
|
ui.dropdown_button.default_props("flat square no-caps")
|
|
435
410
|
ui.select.default_props("square filled dense")
|
|
436
411
|
app.storage.client["user_agent"] = request.headers.get("user-agent", None)
|
|
437
|
-
qgis = app.storage.client["user_agent"]
|
|
412
|
+
qgis = app.storage.client["user_agent"].startswith(settings.qgis_plugin_name)
|
|
438
413
|
if qgis:
|
|
439
414
|
ui.add_head_html('<script src="qrc:///qtwebchannel/qwebchannel.js"></script>')
|
|
440
415
|
|
|
@@ -865,7 +840,7 @@ async def feature(
|
|
|
865
840
|
app.storage.client["parent_id"] = parentId
|
|
866
841
|
app.storage.client["user_agent"] = request.headers.get("user-agent", None)
|
|
867
842
|
|
|
868
|
-
qgis = app.storage.client["user_agent"]
|
|
843
|
+
qgis = app.storage.client["user_agent"].startswith(settings.qgis_plugin_name)
|
|
869
844
|
|
|
870
845
|
ui.colors(
|
|
871
846
|
# primary=f"{'#f0f0f0' if qgis else 'rgb(157 157 156)'}",
|
|
@@ -1059,7 +1034,7 @@ def get_associations(
|
|
|
1059
1034
|
|
|
1060
1035
|
app.storage.client["user_agent"] = request.headers.get("user-agent", None)
|
|
1061
1036
|
|
|
1062
|
-
qgis = app.storage.client["user_agent"]
|
|
1037
|
+
qgis = app.storage.client["user_agent"].startswith(settings.qgis_plugin_name)
|
|
1063
1038
|
|
|
1064
1039
|
feature_data = {}
|
|
1065
1040
|
|
xmas_app/settings.py
CHANGED
|
@@ -2,7 +2,9 @@ import os
|
|
|
2
2
|
from typing import Any, Dict, List, Literal, Optional, TypedDict
|
|
3
3
|
|
|
4
4
|
from pydantic import HttpUrl
|
|
5
|
+
from pydantic_extra_types.semver import _VersionPydanticAnnotation
|
|
5
6
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
7
|
+
from semver import Version
|
|
6
8
|
from xplan_tools.interface.db import DBRepository
|
|
7
9
|
|
|
8
10
|
|
|
@@ -52,6 +54,8 @@ class Settings(BaseSettings):
|
|
|
52
54
|
codelist_repo: HttpUrl = HttpUrl(
|
|
53
55
|
"https://registry.gdi-de.org/codelist/de.xleitstelle.xplanung"
|
|
54
56
|
)
|
|
57
|
+
qgis_plugin_name: str = "XMAS-Plugin"
|
|
58
|
+
qgis_plugin_min_version: _VersionPydanticAnnotation = Version(major=0, minor=9)
|
|
55
59
|
|
|
56
60
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
|
|
57
61
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xmas-app
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Summary: The XLeitstelle model-driven application schema app.
|
|
5
5
|
License: EUPL-1.2-or-later
|
|
6
6
|
License-File: LICENSE
|
|
@@ -13,10 +13,11 @@ Classifier: License :: OSI Approved :: European Union Public Licence 1.2 (EUPL 1
|
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
15
|
Requires-Dist: nicegui (>=2.20,<3.0)
|
|
16
|
+
Requires-Dist: pydantic-extra-types[semver]
|
|
16
17
|
Requires-Dist: pydantic-settings (>=2.0,<3.0)
|
|
17
18
|
Requires-Dist: xplan-tools (>=1.10.3)
|
|
18
19
|
Project-URL: Homepage, https://gitlab.opencode.de/xleitstelle/xmas-app
|
|
19
|
-
Project-URL: Issues, https://gitlab.opencode.de/xleitstelle/
|
|
20
|
+
Project-URL: Issues, https://gitlab.opencode.de/xleitstelle/xmas-app/-/issues
|
|
20
21
|
Description-Content-Type: text/markdown
|
|
21
22
|
|
|
22
23
|
# XMAS-App
|
|
@@ -106,7 +107,7 @@ pixi shell
|
|
|
106
107
|
then run
|
|
107
108
|
|
|
108
109
|
```shell
|
|
109
|
-
|
|
110
|
+
xmas-app
|
|
110
111
|
```
|
|
111
112
|
|
|
112
113
|
### Optional: batch import test data to the database using xplan-tools
|
|
@@ -125,10 +126,11 @@ done
|
|
|
125
126
|
(on Windows:):
|
|
126
127
|
```cmd
|
|
127
128
|
for %f in (*.gml) do xplan-tools convert "%f" postgresql://postgres:postgres@127.0.0.1:55432/postgres
|
|
128
|
-
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## License
|
|
129
132
|
|
|
130
|
-
|
|
133
|
+
The code in this repository is licensed under the [EUPL-1.2-or-later](https://joinup.ec.europa.eu/collection/eupl)
|
|
131
134
|
|
|
132
|
-
|
|
133
|
-
This does not affect production deployments, which can use secure defaults.
|
|
135
|
+
© [XLeitstelle](https://xleitstelle.de), 2025
|
|
134
136
|
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
xmas_app/db.py,sha256=dHU8_xDsH2WduEMrYs0spY55hLlN5Xv12tRb8lHAado,7139
|
|
2
2
|
xmas_app/db_uow.py,sha256=usvqo1bO4dQnMbiub5PyQAAgu8Af-HYAJTsFNYS3Le0,761
|
|
3
|
-
xmas_app/form.py,sha256=
|
|
4
|
-
xmas_app/main.py,sha256=
|
|
3
|
+
xmas_app/form.py,sha256=fO-7Fwl3TCEQIlZYrbathPIZ1iBIk7nkVLnLaN5vDbM,70954
|
|
4
|
+
xmas_app/main.py,sha256=cjRi56mVcWdmKb_CCW61GRuMSDidQbJlM6OEiKvwIB8,49937
|
|
5
5
|
xmas_app/models/crud.py,sha256=p_NkUXAo9UkUPUPh2yPtuWoUnP2yMONjxgPaMmgkhzw,411
|
|
6
6
|
xmas_app/pygeoapi/config.yaml,sha256=lmb08zXk8-dB0sh_4EQ1enVBIqgBI-v6QcoIiHyH3N8,7992
|
|
7
7
|
xmas_app/pygeoapi/openapi.yaml,sha256=h4J4kYugyNVMFjL_C2CLcntELgIkGh0N4VzpPf8u_tE,40650
|
|
8
8
|
xmas_app/pygeoapi/provider.py,sha256=uKHK_Hsqale1C2pNRKYpyka9GnNHYvGBmbzfcSi05NE,25109
|
|
9
9
|
xmas_app/schema.py,sha256=3P-i14caMqydGsxNw6SOAcanEg1Qr4qxqciAow1aCUM,1507
|
|
10
10
|
xmas_app/services/crud.py,sha256=qY6d_bXKSNN-6lID8h7vVeYAvwOb8A6JkhZpaWLRIE8,2464
|
|
11
|
-
xmas_app/settings.py,sha256=
|
|
11
|
+
xmas_app/settings.py,sha256=oxVrJArZNOQCMBM72Iv0YGBkRUbGSArBxsl26SgaJPg,2537
|
|
12
12
|
xmas_app/split_service.py,sha256=Ag_Ix2vMgT04OsQ0DIGK7WFKQlbktmmTqWlESO2ZgVs,26701
|
|
13
13
|
xmas_app/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
xmas_app/util/codelist.py,sha256=7qdiaKQLm38TA7WuAfizmdXd_AjJVZ-tnAFpQg4vdeA,1951
|
|
15
|
-
xmas_app-0.
|
|
16
|
-
xmas_app-0.
|
|
17
|
-
xmas_app-0.
|
|
18
|
-
xmas_app-0.
|
|
19
|
-
xmas_app-0.
|
|
15
|
+
xmas_app-0.10.0.dist-info/METADATA,sha256=QsglqnmJkp760bffaZFnj7gG6StKlnAI5hVVqytwEVk,5315
|
|
16
|
+
xmas_app-0.10.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
17
|
+
xmas_app-0.10.0.dist-info/entry_points.txt,sha256=uve2b0hgPbVfiD047-hOI6_dD97ZytvCPWk7HsN9Xng,53
|
|
18
|
+
xmas_app-0.10.0.dist-info/licenses/LICENSE,sha256=b8nnCcy_4Nd_v_okJ6mDKCvi64jkexzbSfIag7TR5mU,13827
|
|
19
|
+
xmas_app-0.10.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|