3333
3434from .ui_widgets .utils import get_url_status
3535
36- from .server_config_dialog import Ui_serverDialog
36+ from .server_config_dialog import Ui_serverDialog
3737
3838from .models .top_level .providers .records import ProviderTypes
3939from .ui_widgets .providers .NewProviderWindow import NewProviderWindow
7575except :
7676 pass
7777
78- headers = {
79- 'accept' : '*/*' ,
80- 'Content-Type' : 'application/json'
81- }
78+ headers = {"accept" : "*/*" , "Content-Type" : "application/json" }
79+
8280
8381def preprocess_for_json (d ):
8482 """Recursively converts datetime/date objects in a dict to ISO strings."""
@@ -90,35 +88,37 @@ def preprocess_for_json(d):
9088 return d .isoformat ()
9189 return d
9290
91+
9392class ServerConfigDialog (QDialog , Ui_serverDialog ):
9493 """
9594 Logic for the Server Configuration Dialog.
9695 Inherits from QDialog (functionality) and Ui_serverDialog (layout).
9796 """
97+
9898 def __init__ (self , parent = None ):
9999 super ().__init__ (parent )
100- self .setupUi (self ) # Builds the UI defined in Designer
101-
100+ self .setupUi (self ) # Builds the UI defined in Designer
101+
102102 # Optional: Set default values based on current config if needed
103103 # self.ServerHostlineEdit.setText("localhost")
104104
105- def get_server_data (self ):
105+ def get_server_url (self ):
106106 """
107107 Retrieve the server configuration data entered by the user.
108108 :return: A dictionary with 'host' and 'port' keys.
109109 """
110110 host = self .ServerHostlineEdit .text ()
111111 port = self .ServerSpinBox .value ()
112- protocol = ' http' if self .radioHttp .isChecked () else ' https'
113- return { 'host' : host , 'port' : port , 'protocol' : protocol }
112+ protocol = " http" if self .radioHttp .isChecked () else " https"
113+ return f" { protocol } :// { host } : { port } /admin/config"
114114
115115
116116# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer
117117FORM_CLASS , _ = uic .loadUiType (
118118 os .path .join (os .path .dirname (__file__ ), "pygeoapi_config_dialog_base.ui" )
119119)
120120
121-
121+
122122class PygeoapiConfigDialog (QtWidgets .QDialog , FORM_CLASS ):
123123
124124 config_data : ConfigData
@@ -183,17 +183,25 @@ def on_button_clicked(self, button):
183183
184184 # You can also check the standard button type
185185 if button == self .buttonBox .button (QDialogButtonBox .Save ):
186+ # proceed only if UI data inputs are valid
186187 if self ._set_validate_ui_data ()[0 ]:
187188
188189 if self .serverRadio .isChecked ():
190+ # check #1: show diff with "Procced" and "Cancel" options
191+ if not self ._diff_original_and_current_data ():
192+ return
193+
189194 self .server_config (save = True )
190195 else :
196+ # check #1: show diff with "Procced" and "Cancel" options
197+ if not self ._diff_original_and_current_data ():
198+ return
199+
191200 file_path , _ = QFileDialog .getSaveFileName (
192201 self , "Save File" , "" , "YAML Files (*.yml);;All Files (*)"
193202 )
194-
195- # before saving, show diff with "Procced" and "Cancel" options
196- if file_path and self ._diff_original_and_current_data ():
203+ # check #2: valid file path
204+ if file_path :
197205 self .save_to_file (file_path )
198206
199207 elif button == self .buttonBox .button (QDialogButtonBox .Open ):
@@ -213,14 +221,13 @@ def server_config(self, save):
213221
214222 dialog = ServerConfigDialog (self )
215223
216- if dialog .exec_ ():
217- data = dialog .get_server_data ()
218- url = f"{ data ['protocol' ]} ://{ data ['host' ]} :{ data ['port' ]} /admin/config"
219- if save == True :
224+ if dialog .exec_ ():
225+ url = dialog .get_server_url ()
226+ if save :
220227 self .push_to_server (url )
221228 else :
222- self .pull_from_server (url )
223-
229+ self .pull_from_server (url )
230+
224231 def push_to_server (self , url ):
225232
226233 QMessageBox .information (
@@ -240,8 +247,7 @@ def push_to_server(self, url):
240247 response = requests .put (url , headers = headers , json = processed_config_dict )
241248 response .raise_for_status ()
242249
243- QgsMessageLog .logMessage (
244- f"Success! Status Code: { response .status_code } " )
250+ QgsMessageLog .logMessage (f"Success! Status Code: { response .status_code } " )
245251
246252 QMessageBox .information (
247253 self ,
@@ -257,9 +263,8 @@ def push_to_server(self, url):
257263 f"An error occurred pulling the configuration from the server: { e } " ,
258264 )
259265
260-
261266 def pull_from_server (self , url ):
262-
267+
263268 QMessageBox .information (
264269 self ,
265270 "Information" ,
@@ -272,44 +277,18 @@ def pull_from_server(self, url):
272277 response = requests .get (url , headers = headers )
273278 response .raise_for_status ()
274279
275- QgsMessageLog .logMessage (
276- f"Success! Status Code: { response .status_code } " )
280+ QgsMessageLog .logMessage (f"Success! Status Code: { response .status_code } " )
277281
278282 QMessageBox .information (
279283 self ,
280284 "Information" ,
281285 f"Success! Status Code: { response .status_code } " ,
282286 )
283287
284- QgsMessageLog .logMessage (
285- f"Response: { response .text } " )
288+ QgsMessageLog .logMessage (f"Response: { response .text } " )
286289
287- data_dict = response .json ()
288-
289- self .config_data = ConfigData ()
290- self .config_data .set_data_from_yaml (data_dict )
291- self .ui_setter .set_ui_from_data ()
292-
293- # log messages about missing or mistyped values during deserialization
294- QgsMessageLog .logMessage (
295- f"Errors during deserialization: { self .config_data .error_message } "
296- )
297- QgsMessageLog .logMessage (
298- f"Default values used for missing YAML fields: { self .config_data .defaults_message } "
299- )
300-
301- # summarize all properties missing/overwitten with defaults
302- # atm, warning with the full list of properties
303- all_missing_props = self .config_data .all_missing_props
304- QgsMessageLog .logMessage (
305- f"All missing or replaced properties: { self .config_data .all_missing_props } "
306- )
307- if len (all_missing_props ) > 0 :
308- ReadOnlyTextDialog (
309- self ,
310- "Warning" ,
311- f"All missing or replaced properties (check logs for more details): { self .config_data .all_missing_props } " ,
312- ).exec_ ()
290+ data_dict = response .json ()
291+ self .update_config_data_and_ui (data_dict )
313292
314293 except requests .exceptions .RequestException as e :
315294 QgsMessageLog .logMessage (f"An error occurred: { e } " )
@@ -320,7 +299,6 @@ def pull_from_server(self, url):
320299 f"An error occurred pulling the configuration from the server: { e } " ,
321300 )
322301
323-
324302 def save_to_file (self , file_path ):
325303
326304 if file_path :
@@ -360,48 +338,53 @@ def open_file(self, file_name):
360338 # QApplication.setOverrideCursor(Qt.WaitCursor)
361339 with open (file_name , "r" , encoding = "utf-8" ) as file :
362340 file_content = file .read ()
341+ yaml_original_data_dict = yaml .safe_load (file_content )
342+
343+ self .update_config_data_and_ui (yaml_original_data_dict )
363344
364- # reset data
365- self .config_data = ConfigData ()
345+ except Exception as e :
346+ QMessageBox .warning (self , "Error" , f"Cannot open file:\n { str (e )} " )
347+ # finally:
348+ # QApplication.restoreOverrideCursor()
366349
367- # set data and .all_missing_props:
368- yaml_original_data = yaml .safe_load (file_content )
369- self .yaml_original_data = deepcopy (yaml_original_data )
350+ def update_config_data_and_ui (self , data_dict ):
351+ """Use the data from local file or local server to reset the ConfigData and UI."""
370352
371- self .config_data .set_data_from_yaml (yaml_original_data )
353+ # reset data
354+ self .config_data = ConfigData ()
372355
373- # set UI from data
374- self .ui_setter .set_ui_from_data ()
356+ # set data and .all_missing_props:
357+ self .yaml_original_data = deepcopy (data_dict )
358+ self .config_data .set_data_from_yaml (data_dict )
375359
376- # log messages about missing or mistyped values during deserialization
377- # try/except in case of running it from pytests
378- try :
379- QgsMessageLog .logMessage (
380- f"Errors during deserialization: { self .config_data .error_message } "
381- )
382- QgsMessageLog .logMessage (
383- f"Default values used for missing YAML fields: { self .config_data .defaults_message } "
384- )
360+ # set UI from data
361+ self .ui_setter .set_ui_from_data ()
385362
386- # summarize all properties missing/overwitten with defaults
387- # atm, warning with the full list of properties
388- QgsMessageLog .logMessage (
389- f"All missing or replaced properties: { self .config_data .all_missing_props } "
390- )
363+ # log messages about missing or mistyped values during deserialization
364+ # try/except in case of running it from pytests
365+ try :
366+ QgsMessageLog .logMessage (
367+ f"Errors during deserialization: { self .config_data .error_message } "
368+ )
369+ QgsMessageLog .logMessage (
370+ f"Default values used for missing YAML fields: { self .config_data .defaults_message } "
371+ )
391372
392- if len (self .config_data .all_missing_props ) > 0 :
393- ReadOnlyTextDialog (
394- self ,
395- "Warning" ,
396- f"All missing or replaced properties (check logs for more details): { self .config_data .all_missing_props } " ,
397- ).exec_ ()
398- except :
399- pass
373+ # summarize all properties missing/overwitten with defaults
374+ # atm, warning with the full list of properties
375+ all_missing_props = self .config_data .all_missing_props
376+ QgsMessageLog .logMessage (
377+ f"All missing or replaced properties: { all_missing_props } "
378+ )
400379
401- except Exception as e :
402- QMessageBox .warning (self , "Error" , f"Cannot open file:\n { str (e )} " )
403- # finally:
404- # QApplication.restoreOverrideCursor()
380+ if len (all_missing_props ) > 0 :
381+ ReadOnlyTextDialog (
382+ self ,
383+ "Warning" ,
384+ f"All missing or replaced properties (check logs for more details): { all_missing_props } " ,
385+ ).exec_ ()
386+ except :
387+ pass # QgsMessageLog import error in pytests, ignore
405388
406389 def _set_validate_ui_data (self ) -> tuple [bool , list ]:
407390 # Set and validate data from UI
0 commit comments