diff --git a/mslib/msui/autoplot_dockwidget.py b/mslib/msui/autoplot_dockwidget.py index 0e8edf28b..fd348e222 100644 --- a/mslib/msui/autoplot_dockwidget.py +++ b/mslib/msui/autoplot_dockwidget.py @@ -47,7 +47,7 @@ class AutoplotDockWidget(QWidget, Ui_AutoplotDockWidget): autoplot_treewidget_item_selected = QtCore.pyqtSignal(str, str) update_op_flight_treewidget = QtCore.pyqtSignal(str, str) - def __init__(self, parent=None, parent2=None, view=None, config_settings=None): + def __init__(self, parent=None, parent2=None, view=None, config_settings=None, last_save_directory=None): super().__init__() self.setupUi(self) @@ -70,6 +70,7 @@ def __init__(self, parent=None, parent2=None, view=None, config_settings=None): self.intv = "" self.refresh_sig(config_settings) + self.last_save_directory = last_save_directory or os.path.expanduser("~") parent.refresh_signal_send.connect(lambda: self.refresh_sig(config_settings)) @@ -178,7 +179,7 @@ def download_plots_cli(self, config_settings): view = "linear" # Create the configuration path - config_path = os.path.join(const.MSUI_CONFIG_PATH, "mssautoplot.json") + config_path = os.path.join(self.last_save_directory, "mssautoplot.json") # Save the config settings to the file if config_path: @@ -268,7 +269,7 @@ def configure_from_path(self, parent, config_settings): options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( - self, "Select .json Config File", const.MSUI_CONFIG_PATH, "JSON Files (*.json)", options=options) + self, "Select .json Config File", self.last_save_directory, "JSON Files (*.json)", options=options) if fileName != "": self.cpath = fileName @@ -288,7 +289,7 @@ def configure_from_path(self, parent, config_settings): self.resize_treewidgets() def add_to_treewidget(self, parent, parent2, config_settings, treewidget, flight, sections, vertical, filename, - itime, vtime, url, layer, styles, level): + itime, vtime, url, layer, styles, level): if treewidget.objectName() == "autoplotTreeWidget": if self.autoplotSecsTreeWidget.topLevelItemCount() == 0: QMessageBox.information( @@ -302,7 +303,9 @@ def add_to_treewidget(self, parent, parent2, config_settings, treewidget, flight flight = "" else: if filename != parent2.mscolab.active_operation_name: - filename += ".ftml" + filename = os.path.join(self.last_save_directory, filename + ".ftml") + else: + filename = os.path.join(self.last_save_directory, filename + ".ftml") item = QTreeWidgetItem([flight, sections, vertical, filename, itime, vtime]) self.autoplotTreeWidget.addTopLevelItem(item) self.autoplotTreeWidget.setCurrentItem(item) @@ -330,13 +333,15 @@ def add_to_treewidget(self, parent, parent2, config_settings, treewidget, flight self.resize_treewidgets() def update_treewidget(self, parent, parent2, config_settings, treewidget, flight, sections, vertical, filename, - itime, vtime, url, layer, styles, level): + itime, vtime, url, layer, styles, level): if flight.startswith("new flight track"): filename = "" flight = "" else: if filename != parent2.mscolab.active_operation_name: - filename += ".ftml" + filename = os.path.join(self.last_save_directory, filename + ".ftml") + else: + filename = os.path.join(self.last_save_directory, filename + ".ftml") if treewidget.objectName() == "autoplotTreeWidget": selected_item = self.autoplotTreeWidget.currentItem() selected_item.setText(0, flight) @@ -501,7 +506,7 @@ def update_config_file(self, config_settings): file_path, _ = QFileDialog.getSaveFileName( self, "Save JSON File", - const.MSUI_CONFIG_PATH, + self.last_save_directory, "JSON Files (*.json);;All Files (*)", options=options ) diff --git a/mslib/msui/msui_mainwindow.py b/mslib/msui/msui_mainwindow.py index b1a8ba9f6..f705ea7d8 100644 --- a/mslib/msui/msui_mainwindow.py +++ b/mslib/msui/msui_mainwindow.py @@ -939,7 +939,8 @@ def create_view(self, _type, model): active_flighttrack=self.active_flight_track, mscolab_server_url=self.mscolab.mscolab_server_url, token=self.mscolab.token, tutorial_mode=self.tutorial_mode, - config_settings=self.config_for_gui) + config_settings=self.config_for_gui, + last_save_directory=self.last_save_directory) view_window.refresh_signal_emit.connect(self.refresh_signal_connect.emit) view_window.mpl.resize(layout['topview'][0], layout['topview'][1]) if layout["immutable"]: diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index f892da606..d9e30b3c1 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -228,7 +228,7 @@ class MSUITopViewWindow(MSUIMplViewWindow, ui.Ui_TopViewWindow): def __init__(self, parent=None, mainwindow=None, model=None, _id=None, active_flighttrack=None, mscolab_server_url=None, token=None, config_settings=None, - tutorial_mode=False): + tutorial_mode=False, last_save_directory=None): """ Set up user interface, connect signal/slots. """ @@ -262,6 +262,7 @@ def __init__(self, parent=None, mainwindow=None, model=None, _id=None, # Store active flighttrack waypoint model self.active_flighttrack = active_flighttrack + self.last_save_directory = last_save_directory # Stores active mscolab operation id self.active_op_id = mainwindow.mscolab.active_op_id @@ -439,7 +440,8 @@ def openTool(self, index, parent=None, config_settings=None): elif index == AUTOPLOT: title = "Autoplot (Top View)" widget = apd.AutoplotDockWidget(parent=self, parent2=parent, - view="Top View", config_settings=config_settings) + view="Top View", config_settings=config_settings, + last_save_directory=self.last_save_directory) widget.treewidget_item_selected.connect( lambda url, layer, style, level: self.tree_item_select(url, layer, style, level)) widget.autoplot_treewidget_item_selected.connect( diff --git a/mslib/utils/mssautoplot.py b/mslib/utils/mssautoplot.py index 3220eae88..73eea79dd 100644 --- a/mslib/utils/mssautoplot.py +++ b/mslib/utils/mssautoplot.py @@ -108,8 +108,7 @@ def load_from_operation(op_name, msc_url, msc_auth_password, username, password) msc_auth = ("mscolab", msc_auth_password) session.auth = msc_auth session.headers.update({'x-test': 'true'}) - # ToDp fix config_loader it gets a list of two times the entry - response = session.get(urljoin(msc_url, 'status'), timeout=tuple(config_loader(dataset="MSCOLAB_timeout")[0])) + response = session.get(urljoin(msc_url, 'status'), timeout=tuple(config_loader(dataset="MSCOLAB_timeout"))) session.close() if response.status_code == 401: logging.error("Error", 'Server authentication data were incorrect.') @@ -119,8 +118,7 @@ def load_from_operation(op_name, msc_url, msc_auth_password, username, password) session.headers.update({'x-test': 'true'}) url = urljoin(msc_url, "token") try: - # ToDp fix config_loader it gets a list of two times the entry - response = session.post(url, data=data, timeout=tuple(config_loader(dataset="MSCOLAB_timeout")[0])) + response = session.post(url, data=data, timeout=tuple(config_loader(dataset="MSCOLAB_timeout"))) response.raise_for_status() except requests.exceptions.RequestException as ex: logging.error("unexpected error: %s %s %s", type(ex), url, ex) @@ -158,7 +156,7 @@ def get_xml_data(msc_url, token, op_id): "op_id": op_id } url = urljoin(msc_url, "get_operation_by_id") - r = requests.get(url, data=data) + r = requests.get(url, data=data, timeout=tuple(config_loader(dataset="MSCOLAB_timeout"))) if r.text != "False": xml_content = json.loads(r.text)["content"] return xml_content @@ -187,7 +185,7 @@ def get_op_id(msc_url, token, op_name): "skip_archived": skip_archived } url = urljoin(msc_url, "operations") - r = requests.get(url, data=data) + r = requests.get(url, data=data, timeout=tuple(config_loader(dataset="MSCOLAB_timeout"))) if r.text != "False": _json = json.loads(r.text) operations = _json["operations"] @@ -218,6 +216,9 @@ def __init__(self, cpath, msc_url=None, msc_auth_password=None, username=None, p flight = self.config["automated_plotting_flights"][0][0] section = self.config["automated_plotting_flights"][0][1] filename = self.config["automated_plotting_flights"][0][3] + config_dir = os.path.dirname(os.path.expanduser(cpath)) + if filename and not os.path.isabs(filename): + filename = os.path.join(config_dir, filename) if self.__class__.__name__ == "TopViewPlotting": try: self.params = get_projection_params(self.config["predefined_map_sections"][section]["CRS"].lower()) @@ -234,14 +235,11 @@ def __init__(self, cpath, msc_url=None, msc_auth_password=None, username=None, p if filename != "" and filename == flight: self.read_operation(flight, msc_url, msc_auth_password, username, password) elif filename != "": - # Todo add the dir to the file in the mssautoplot.json - dirpath = "./" - file_path = os.path.join(dirpath, filename) - exists = os.path.exists(file_path) - if not exists: - print("Filename {} doesn't exist".format(filename)) - self.pdlg.close() - raise SystemExit("Filename {} doesn't exist".format(filename)) + if not os.path.exists(filename): + print(f"FTML file {filename} does not exist") + if self.pdlg: + self.pdlg.close() + raise SystemExit(f"FTML file {filename} does not exist") self.read_ftml(filename) def setup(self): @@ -589,42 +587,55 @@ def draw(self, flight, section, vertical, filename, init_time, time, url, layer, @click.option('--stime', default="", help='Starting time for downloading multiple plots with a fixed interval.') @click.option('--etime', default="", help='Ending time for downloading multiple plots with a fixed interval.') @click.option('--raw', default=False, help='Saves the raw image with its projection in topview') +@click.option('--ftml-path', default="", help='Override the FTML file path from the configuration.') @click.pass_context -def main(ctx, cpath, view, ftrack, itime, vtime, intv, stime, etime, raw): +def main(ctx, cpath, view, ftrack, itime, vtime, intv, stime, etime, raw, ftml_path): pdlg = None def close_process_dialog(pdlg): pdlg.close() if ctx.obj is not None: - # ToDo find a simpler solution, on a split of the package, QT is expensive for such a progressbar pdlg = QProgressDialog("Downloading images", "Cancel", 0, 10, parent=ctx.obj) pdlg.setMinimumDuration(0) pdlg.repaint() pdlg.canceled.connect(lambda: close_process_dialog(pdlg)) pdlg.setWindowModality(Qt.WindowModal) - pdlg.setAutoReset(True) # Close dialog automatically when reaching max value - pdlg.setAutoClose(True) # Automatically close when value reaches maximum - pdlg.setValue(0) # Initial progress value - - # Set window flags to ensure visibility and modality + pdlg.setAutoReset(True) + pdlg.setAutoClose(True) + pdlg.setValue(0) pdlg.setWindowFlags(pdlg.windowFlags() | Qt.CustomizeWindowHint | Qt.WindowTitleHint) - pdlg.setValue(0) conf.read_config_file(path=cpath) config = conf.config_loader() - # flight_name = config["automated_plotting_flights"][0][0] - # file = config["automated_plotting_flights"][0][3] + if ftml_path: + # Override the FTML file path in the configuration + if not os.path.exists(ftml_path): + print(f"Provided FTML file path {ftml_path} does not exist") + if ctx.obj is not None: + pdlg.close() + raise SystemExit(f"Provided FTML file path {ftml_path} does not exist") + config["automated_plotting_flights"][0][3] = ftml_path + if ctx.obj is not None: pdlg.setValue(1) msc_url = config["mscolab_server_url"] - msc_auth_password = mslib.utils.auth.get_password_from_keyring(service_name=f"MSCOLAB_AUTH_{msc_url}", - username="mscolab") - msc_username = config["MSS_auth"][msc_url] - msc_password = mslib.utils.auth.get_password_from_keyring(service_name=msc_url, username=msc_username) + try: + msc_auth_password = mslib.utils.auth.get_password_from_keyring(service_name=f"MSCOLAB_AUTH_{msc_url}", + username="mscolab") + except KeyError: + msc_auth_password = None + + try: + msc_username = config["MSS_auth"][msc_url] + except KeyError: + msc_username = None + msc_password = None + if msc_username is not None: + msc_password = mslib.utils.auth.get_password_from_keyring(service_name=msc_url, username=msc_username) # Choose view (top or side) if view == "top":