From ca852cf1e80f69888aa94a5b6ee95ae0730439a4 Mon Sep 17 00:00:00 2001 From: Germap Date: Fri, 17 May 2024 23:54:33 -0500 Subject: [PATCH] Add proper Windows location for pg_service.conf (#29) * Add proper Windows location for pg_service.conf (namely, at %APPDATA%/postgresql/.pg_service.conf) and avoid the ~/.pg_service.conf for Windows, since clients like QGIS won't go there to find the file * Use the lib to get the proper Windows file path * Improve 'pg_service.conf location' section in README, adding a paragraph on QGIS connections using the service file --- README.md | 4 +-- .../core/pg_service_parser_wrapper.py | 15 ++++---- pg_service_parser/gui/dlg_pg_service.py | 35 +++++++++++-------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 8b1916e..b144ae6 100755 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ This plugin is distributed under the [GNU GPL v3 license](https://github.com/ope ### pg_service.conf location -If your `pg_service.conf` file is located at `/home/YOUR_USER/.pg_service.conf` (on Linux) or at `%HOMEPATH%\.pg_service.conf` (on Windows), then you are done! The plugin will read your file directly. +If your `pg_service.conf` file is located at `/home/YOUR_USER/.pg_service.conf` (on Linux) or at `%APPDATA%\postgresql\.pg_service.conf` (on Windows), then you are done! The plugin will read your file directly. If that's not the case, i.e., if your `pg_service.conf` file is not in the aforementioned locations, you can still set the `PGSERVICEFILE` environment variable pointing to your `pg_service.conf` file path before using the plugin. - +Clients like QGIS will directly read your `pg_service.conf` file from any of these locations and you'll be able to use any service from this file in the `New Connection` dialog (see [QGIS docs](https://docs.qgis.org/latest/en/docs/user_manual/managing_data_source/opening_data.html#creating-a-stored-connection)). ### Edit PG service entries diff --git a/pg_service_parser/core/pg_service_parser_wrapper.py b/pg_service_parser/core/pg_service_parser_wrapper.py index 66be49d..d22ccdc 100644 --- a/pg_service_parser/core/pg_service_parser_wrapper.py +++ b/pg_service_parser/core/pg_service_parser_wrapper.py @@ -8,28 +8,28 @@ def conf_path() -> Path: return pgserviceparser.conf_path() -def service_names(conf_file_path: Optional[str] = None) -> List[str]: +def service_names(conf_file_path: Optional[Path] = None) -> List[str]: return pgserviceparser.service_names(conf_file_path) -def add_new_service(service_name: str, conf_file_path: Optional[str] = None) -> bool: +def add_new_service(service_name: str, conf_file_path: Optional[Path] = None) -> bool: return create_service(service_name, {}, conf_file_path) -def service_config(service_name: str, conf_file_path: Optional[str] = None) -> dict: +def service_config(service_name: str, conf_file_path: Optional[Path] = None) -> dict: return pgserviceparser.service_config(service_name, conf_file_path) def write_service( service_name: str, settings: dict, - conf_file_path: Optional[str] = None, + conf_file_path: Optional[Path] = None, ): pgserviceparser.write_service(service_name, settings, conf_file_path) def create_service( - service_name: str, settings: dict, conf_file_path: Optional[str] = None + service_name: str, settings: dict, conf_file_path: Optional[Path] = None ) -> bool: config = pgserviceparser.full_config(conf_file_path) if service_name in config: @@ -40,15 +40,14 @@ def create_service( config.write(f) if service_name in config: - if settings: - pgserviceparser.write_service(service_name, settings) + pgserviceparser.write_service(service_name, settings, conf_file_path) return True return False def copy_service_settings( - source_service_name: str, target_service_name: str, conf_file_path: Optional[str] = None + source_service_name: str, target_service_name: str, conf_file_path: Optional[Path] = None ): settings = pgserviceparser.service_config(source_service_name, conf_file_path) config = pgserviceparser.full_config(conf_file_path) diff --git a/pg_service_parser/gui/dlg_pg_service.py b/pg_service_parser/gui/dlg_pg_service.py index 689df51..ecf3f75 100644 --- a/pg_service_parser/gui/dlg_pg_service.py +++ b/pg_service_parser/gui/dlg_pg_service.py @@ -33,11 +33,11 @@ def __init__(self, parent): # Flag to handle initialization of new files self.__new_empty_file = False - conf_file_path = conf_path() - self.__initialize_dialog(conf_file_path) + self.__conf_file_path = conf_path() + self.__initialize_dialog() - def __initialize_dialog(self, conf_file_path): - if not conf_file_path.exists(): + def __initialize_dialog(self): + if not self.__conf_file_path.exists(): self.btnCreateServiceFile.setIcon(QgsApplication.getThemeIcon("/mActionNewPage.svg")) self.btnCreateServiceFile.clicked.connect(self.__create_file_clicked) self.lblConfFile.setText("Config file not found!") @@ -55,7 +55,7 @@ def __initialize_dialog(self, conf_file_path): self.btnAddSettings.setIcon(QgsApplication.getThemeIcon("/symbologyAdd.svg")) self.btnRemoveSetting.setIcon(QgsApplication.getThemeIcon("/symbologyRemove.svg")) - self.txtConfFile.setText(str(conf_file_path)) + self.txtConfFile.setText(str(self.__conf_file_path)) self.lblWarning.setVisible(False) self.lblConfFile.setText("Config file path found at ") self.lblConfFile.setToolTip("") @@ -85,13 +85,12 @@ def __create_file_clicked(self): dlg = ServiceNameDialog(self) dlg.exec_() if dlg.result() == QDialog.Accepted: - path = conf_path() - Path.touch(path) + Path.touch(self.__conf_file_path) add_new_service(dlg.service_name) # Set flag to get a template after some initialization self.__new_empty_file = True - self.__initialize_dialog(path) + self.__initialize_dialog() @pyqtSlot(bool) def __update_target_controls(self, checked): @@ -106,7 +105,7 @@ def __source_service_changed(self, index): current_text = current_text if self.cboSourceService.currentText() != current_text else "" self.cboTargetService.clear() - self.cboTargetService.addItems([""] + service_names()) + self.cboTargetService.addItems([""] + service_names(self.__conf_file_path)) model = self.cboTargetService.model() item = model.item(index + 1) # Account for the first (empty) item @@ -119,7 +118,7 @@ def __initialize_copy_services(self): self.cboSourceService.blockSignals(True) # Avoid triggering custom slot while clearing self.cboSourceService.clear() self.cboSourceService.blockSignals(False) - self.cboSourceService.addItems(service_names()) + self.cboSourceService.addItems(service_names(self.__conf_file_path)) self.cboSourceService.setCurrentText(current_text) def __initialize_edit_services(self): @@ -128,7 +127,7 @@ def __initialize_edit_services(self): self.cboEditService.blockSignals(True) # Avoid triggering custom slot while clearing self.cboEditService.clear() self.cboEditService.blockSignals(False) - self.cboEditService.addItems(service_names()) + self.cboEditService.addItems(service_names(self.__conf_file_path)) self.cboEditService.setCurrentText(current_text) @pyqtSlot() @@ -138,7 +137,7 @@ def __copy_service(self): if not self.txtNewService.text().strip(): self.bar.pushInfo("PG service", "Enter a service name and try again.") return - elif self.txtNewService.text().strip() in service_names(): + elif self.txtNewService.text().strip() in service_names(self.__conf_file_path): self.bar.pushWarning( "PG service", "Service name '{}' already exists! Change it and try again.".format( @@ -157,7 +156,9 @@ def __copy_service(self): else self.txtNewService.text().strip() ) - copy_service_settings(self.cboSourceService.currentText(), target_service) + copy_service_settings( + self.cboSourceService.currentText(), target_service, self.__conf_file_path + ) self.bar.pushSuccess("PG service", f"PG service copied to '{target_service}'!") if self.radCreate.isChecked(): self.__initialize_copy_services() # Reflect the newly added service @@ -192,7 +193,9 @@ def __edit_service_changed(self, index): self.cboEditService.blockSignals(False) return - self.__edit_model = ServiceConfigModel(target_service, service_config(target_service)) + self.__edit_model = ServiceConfigModel( + target_service, service_config(target_service, self.__conf_file_path) + ) self.tblServiceConfig.setModel(self.__edit_model) self.__edit_model.is_dirty_changed.connect(self.btnUpdateService.setEnabled) self.btnUpdateService.setDisabled(True) @@ -242,7 +245,9 @@ def __update_service_clicked(self): return target_service = self.cboEditService.currentText() - write_service(target_service, self.__edit_model.service_config()) + write_service( + target_service, self.__edit_model.service_config(), self.__conf_file_path + ) self.bar.pushSuccess("PG service", f"PG service '{target_service}' updated!") self.__edit_model.set_not_dirty() else: