Skip to content

Commit 234494e

Browse files
committed
Initial ryhti import functionality.
- Added dialog for importing plan to Ryhti. - Displays validation errors on a list.
1 parent bc196cc commit 234494e

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed

arho_feature_template/core/lambda_service.py

+12
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
class LambdaService(QObject):
1616
jsons_received = pyqtSignal(dict, dict)
1717
validation_received = pyqtSignal(dict)
18+
post_received = pyqtSignal(dict)
1819
ActionAttribute = cast(QNetworkRequest.Attribute, QNetworkRequest.User + 1)
1920
ACTION_VALIDATE_PLANS = "validate_plans"
2021
ACTION_GET_PLANS = "get_plans"
22+
ACTION_POST_PLANS = "post_plans"
2123

2224
def __init__(self):
2325
super().__init__()
@@ -30,6 +32,9 @@ def serialize_plan(self, plan_id: str):
3032
def validate_plan(self, plan_id: str):
3133
self._send_request(action=self.ACTION_VALIDATE_PLANS, plan_id=plan_id)
3234

35+
def post_plan(self, plan_id: str):
36+
self._send_request(action=self.ACTION_POST_PLANS, plan_id=plan_id)
37+
3338
def _send_request(self, action: str, plan_id: str):
3439
"""Sends a request to the lambda function."""
3540
proxy_host, proxy_port, self.lambda_url = get_settings()
@@ -90,6 +95,9 @@ def _handle_reply(self, reply: QNetworkReply):
9095
self._process_json_reply(body)
9196
elif action == self.ACTION_VALIDATE_PLANS:
9297
self._process_validation_reply(body)
98+
elif action == self.ACTION_POST_PLANS:
99+
self.post_received.emit(body)
100+
# self._process_post_reply(body)
93101

94102
def _process_validation_reply(self, response_json: dict):
95103
"""Processes the validation reply from the lambda and emits a signal."""
@@ -98,6 +106,10 @@ def _process_validation_reply(self, response_json: dict):
98106

99107
self.validation_received.emit(validation_errors)
100108

109+
# def _process_post_reply(self, response_json: dict):
110+
# """Processes the post reply from the lambda and emits a signal."""
111+
# self.post_received.emit(response_json)
112+
101113
def _process_json_reply(self, response_json: dict):
102114
"""Processes the reply from the lambda and emits signal."""
103115
plan_id = get_active_plan_id()
+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
from __future__ import annotations
2+
3+
from importlib import resources
4+
from typing import TYPE_CHECKING
5+
6+
from qgis.PyQt.QtWidgets import QDialog, QProgressDialog, QListView, QMessageBox
7+
from qgis.PyQt.QtCore import Qt, QStringListModel
8+
from qgis.PyQt import uic
9+
10+
from arho_feature_template.core.lambda_service import LambdaService
11+
from arho_feature_template.utils.misc_utils import get_active_plan_id
12+
13+
if TYPE_CHECKING:
14+
from qgis.PyQt.QtWidgets import QListView
15+
16+
# Load the UI file
17+
ui_path = resources.files(__package__) / "post_plan.ui"
18+
FormClass, _ = uic.loadUiType(ui_path)
19+
20+
21+
class PostPlan(QDialog, FormClass): # type: ignore
22+
def __init__(self, parent=None) -> None:
23+
super().__init__(parent)
24+
self.setupUi(self)
25+
26+
# Initialize list model and assign to the list view
27+
self.validation_list_model: QStringListModel = QStringListModel()
28+
self.validation_list_view: QListView = self.validationListView
29+
self.validation_list_view.setModel(self.validation_list_model)
30+
31+
# Initialize buttons
32+
self.export_button = self.exportButton
33+
self.export_button.clicked.connect(self.post_plan)
34+
self.dialogButtonBox.rejected.connect(self.reject)
35+
36+
# Setup progress dialog (initially hidden)
37+
self.progress_dialog = QProgressDialog("Processing...", None, 0, 0, self)
38+
self.progress_dialog.setWindowModality(Qt.WindowModal)
39+
self.progress_dialog.setCancelButton(None)
40+
self.progress_dialog.setMinimumDuration(0)
41+
self.progress_dialog.hide()
42+
43+
def post_plan(self):
44+
"""Handles the 'Vie kaava' button logic."""
45+
print("Starting export...")
46+
47+
# Disable the button to prevent multiple clicks
48+
self.export_button.setEnabled(False)
49+
self.progress_dialog.show()
50+
51+
plan_id = get_active_plan_id()
52+
self.lambda_service = LambdaService()
53+
self.lambda_service.post_received.connect(self.handle_validation_errors)
54+
self.lambda_service.post_plan(plan_id)
55+
56+
def handle_validation_errors(self, post_json):
57+
"""Handles the Lambda response."""
58+
if not post_json:
59+
self.progress_dialog.hide()
60+
QMessageBox.critical(self, "Virhe", "Lambda palautti tyhjän vastauksen.")
61+
self.export_button.setEnabled(True)
62+
return
63+
64+
# Prepare errors and warnings for display
65+
new_errors = []
66+
validation_errors = post_json.get("ryhti_responses", {})
67+
for error_data in validation_errors.values():
68+
if isinstance(error_data, dict):
69+
# Get the errors
70+
errors = error_data.get("errors", [])
71+
for error in errors:
72+
rule_id = error.get("ruleId", "Tuntematon sääntö")
73+
message = error.get("message", "Ei viestiä")
74+
instance = error.get("instance", "Tuntematon instance")
75+
error_message = f"Validointivirhe - Sääntö: {rule_id}, Viesti: {message}, Instance: {instance}"
76+
new_errors.append(error_message)
77+
78+
# Get warnings
79+
warnings = error_data.get("warnings", [])
80+
new_errors.extend([f"Varoitus: {warning}" for warning in warnings])
81+
82+
# If no errors or warnings, display a success message
83+
if not new_errors:
84+
new_errors.append("Kaava on validi. Ei virheitä tai varoituksia havaittu.")
85+
86+
# Update the list view with errors and warnings
87+
self.validation_list_model.setStringList(new_errors)
88+
89+
# Hide progress dialog and re-enable the button
90+
self.progress_dialog.hide()
91+
self.export_button.setEnabled(True)
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<ui version="4.0">
2+
<class>PostPlan</class>
3+
<widget class="QDialog" name="PostPlanDialog">
4+
<property name="windowTitle">
5+
<string>Vie kaava</string>
6+
</property>
7+
<layout class="QVBoxLayout" name="mainLayout">
8+
<item>
9+
<layout class="QVBoxLayout" name="validationLayout">
10+
<item>
11+
<widget class="QLabel" name="label_validation">
12+
<property name="text">
13+
<string>Validation Results:</string>
14+
</property>
15+
</widget>
16+
</item>
17+
<item>
18+
<widget class="QListView" name="validationListView">
19+
<property name="sizePolicy">
20+
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
21+
<horstretch>0</horstretch>
22+
<verstretch>0</verstretch>
23+
</sizepolicy>
24+
</property>
25+
</widget>
26+
</item>
27+
</layout>
28+
</item>
29+
<item>
30+
<layout class="QHBoxLayout" name="bottomLayout">
31+
<item>
32+
<widget class="QPushButton" name="exportButton">
33+
<property name="text">
34+
<string>Vie kaava</string>
35+
</property>
36+
</widget>
37+
</item>
38+
<item>
39+
<spacer name="bottomSpacer">
40+
<property name="orientation">
41+
<enum>Qt::Horizontal</enum>
42+
</property>
43+
</spacer>
44+
</item>
45+
<item>
46+
<widget class="QDialogButtonBox" name="dialogButtonBox">
47+
<property name="orientation">
48+
<enum>Qt::Horizontal</enum>
49+
</property>
50+
<property name="standardButtons">
51+
<set>QDialogButtonBox::Cancel</set>
52+
</property>
53+
</widget>
54+
</item>
55+
</layout>
56+
</item>
57+
</layout>
58+
</widget>
59+
<resources/>
60+
<connections/>
61+
</ui>

arho_feature_template/plugin.py

+15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from arho_feature_template.core.plan_manager import PlanManager
1313
from arho_feature_template.gui.new_plan_regulation_group_form import NewPlanRegulationGroupForm
1414
from arho_feature_template.gui.plugin_settings import PluginSettings
15+
from arho_feature_template.gui.post_plan import PostPlan
1516
from arho_feature_template.gui.validation_dock import ValidationDock
1617
from arho_feature_template.qgis_plugin_tools.tools.custom_logging import setup_logger, teardown_logger
1718
from arho_feature_template.qgis_plugin_tools.tools.i18n import setup_translation
@@ -203,6 +204,15 @@ def initGui(self) -> None: # noqa N802
203204
status_tip="Tallenna aktiivinen kaava JSON muodossa",
204205
)
205206

207+
self.post_plan_action = self.add_action(
208+
text="Vie kaava",
209+
icon=QgsApplication.getThemeIcon("mActionSharingExport.svg"),
210+
triggered_callback=self.post_plan,
211+
add_to_menu=True,
212+
add_to_toolbar=True,
213+
status_tip="Vie kaava Ryhtiin",
214+
)
215+
206216
self.plugin_settings_action = self.add_action(
207217
text="Asetukset",
208218
triggered_callback=self.open_settings,
@@ -225,6 +235,11 @@ def serialize_plan(self):
225235
"""Serializes currently active plan."""
226236
self.plan_manager.get_plan_json()
227237

238+
def post_plan(self):
239+
"""Posts plan to Ryhti."""
240+
dialog = PostPlan()
241+
dialog.exec_()
242+
228243
def open_settings(self):
229244
"""Open the plugin settings dialog."""
230245
settings = PluginSettings()

0 commit comments

Comments
 (0)