From a06f12f269c9c18fdb78b8a64fb619b751454a54 Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Fri, 30 Aug 2024 15:23:39 +0200 Subject: [PATCH 01/12] remove the conda/mamba based updater. Show in About a new version available. --- mslib/mscolab/app/__init__.py | 6 +- mslib/mscolab/mscolab.py | 12 --- mslib/msui/msui.py | 12 --- mslib/msui/msui_mainwindow.py | 7 +- mslib/msui/qt5/ui_about_dialog.py | 47 +++++----- mslib/msui/qt5/ui_mainwindow.py | 5 +- mslib/msui/qt5/ui_updater_dialog.py | 65 -------------- mslib/msui/ui/ui_about_dialog.ui | 43 +++++---- mslib/msui/ui/ui_mainwindow.ui | 1 - mslib/msui/ui/ui_updater_dialog.ui | 107 ---------------------- mslib/msui/updater.py | 81 ----------------- mslib/mswms/app/__init__.py | 5 +- mslib/mswms/mswms.py | 12 --- mslib/utils/qt.py | 54 ----------- mslib/utils/release_info.py | 75 ++++++++++++++++ tests/_test_msui/test_updater.py | 135 ---------------------------- 16 files changed, 139 insertions(+), 528 deletions(-) delete mode 100644 mslib/msui/qt5/ui_updater_dialog.py delete mode 100644 mslib/msui/ui/ui_updater_dialog.ui delete mode 100644 mslib/msui/updater.py create mode 100644 mslib/utils/release_info.py delete mode 100644 tests/_test_msui/test_updater.py diff --git a/mslib/mscolab/app/__init__.py b/mslib/mscolab/app/__init__.py index 9cf33a150..d62301ba2 100644 --- a/mslib/mscolab/app/__init__.py +++ b/mslib/mscolab/app/__init__.py @@ -25,6 +25,7 @@ """ import os +import logging from flask_migrate import Migrate @@ -33,7 +34,10 @@ from flask import Flask, url_for from mslib.mscolab.conf import mscolab_settings from flask_sqlalchemy import SQLAlchemy -from mslib.utils import prefix_route +from mslib.utils import prefix_route, release_info + + +logging.debug(release_info.check_for_new_release()) DOCS_SERVER_PATH = os.path.dirname(os.path.abspath(mslib.__file__)) diff --git a/mslib/mscolab/mscolab.py b/mslib/mscolab/mscolab.py index b0a79969d..7b2258eb2 100644 --- a/mslib/mscolab/mscolab.py +++ b/mslib/mscolab/mscolab.py @@ -41,7 +41,6 @@ add_all_users_to_all_operations, delete_user from mslib.mscolab.utils import create_files from mslib.utils import setup_logging -from mslib.utils.qt import Worker, Updater def handle_start(args): @@ -353,7 +352,6 @@ def handle_sso_metadata_init(repo_exists): def main(): parser = argparse.ArgumentParser() parser.add_argument("-v", "--version", help="show version", action="store_true", default=False) - parser.add_argument("--update", help="Updates MSS to the newest version", action="store_true", default=False) subparsers = parser.add_subparsers(help='Available actions', dest='action') @@ -403,16 +401,6 @@ def main(): except git.exc.InvalidGitRepositoryError: repo_exists = False - updater = Updater() - if args.update: - updater.on_update_available.connect(lambda old, new: updater.update_mss()) - updater.on_log_update.connect(lambda s: print(s.replace("\n", ""))) - updater.on_status_update.connect(lambda s: print(s.replace("\n", ""))) - updater.run() - while Worker.workers: - list(Worker.workers)[0].wait() - sys.exit() - if args.action == "start": handle_start(args) diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index 0a4c4108e..b15bab1aa 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -42,7 +42,6 @@ from mslib.msui import constants from mslib.utils import setup_logging from mslib.msui.icons import icons -from mslib.utils.qt import Worker, Updater from mslib.utils.config import read_config_file from PyQt5 import QtGui, QtCore, QtWidgets @@ -62,7 +61,6 @@ def main(tutorial_mode=False): parser.add_argument("--debug", help="show debugging log messages on console", action="store_true", default=False) parser.add_argument("--logfile", help="Specify logfile location. Set to empty string to disable.", action="store", default=os.path.join(constants.MSUI_CONFIG_PATH, "msui.log")) - parser.add_argument("--update", help="Updates MSS to the newest version", action="store_true", default=False) args = parser.parse_args() @@ -74,16 +72,6 @@ def main(tutorial_mode=False): print("Version:", __version__) sys.exit() - if args.update: - updater = Updater() - updater.on_update_available.connect(lambda old, new: updater.update_mss()) - updater.on_log_update.connect(lambda s: print(s.replace("\n", ""))) - updater.on_status_update.connect(lambda s: print(s.replace("\n", ""))) - updater.run() - while Worker.workers: - list(Worker.workers)[0].wait() - sys.exit() - setup_logging(args) logging.info("MSS Version: %s", __version__) diff --git a/mslib/msui/msui_mainwindow.py b/mslib/msui/msui_mainwindow.py index f1ec9768b..983bd6350 100644 --- a/mslib/msui/msui_mainwindow.py +++ b/mslib/msui/msui_mainwindow.py @@ -46,11 +46,11 @@ from mslib.msui import flighttrack as ft from mslib.msui import tableview, topview, sideview, linearview from mslib.msui import constants, editor, mscolab -from mslib.msui.updater import UpdaterUI from mslib.plugins.io.csv import load_from_csv, save_to_csv from mslib.msui.icons import icons, python_powered from mslib.utils.qt import get_open_filenames, get_save_filename, show_popup from mslib.utils.config import read_config_file, config_loader +from mslib.utils import release_info from PyQt5 import QtGui, QtCore, QtWidgets from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas @@ -408,6 +408,7 @@ def __init__(self, parent=None): super().__init__(parent) self.setupUi(self) self.lblVersion.setText(f"Version: {__version__}") + self.lblNewVersion.setText(f"{release_info.check_for_new_release()}") self.milestone_url = f'https://github.com/Open-MSS/MSS/issues?q=is%3Aclosed+milestone%3A{__version__[:-1]}' self.lblChanges.setText(f'New Features and Changes') blub = QtGui.QPixmap(python_powered()) @@ -532,10 +533,6 @@ def __init__(self, mscolab_data_dir=None, tutorial_mode=False, *args): self.mscolab.signal_render_new_permission.connect( lambda op_id, path: self.signal_render_new_permission.emit(op_id, path)) - # Don't start the updater during a test run of msui - if "pytest" not in sys.modules: - self.updater = UpdaterUI(self) - self.actionUpdater.triggered.connect(self.updater.show) self.openOperationsGb.hide() def bring_main_window_to_front(self): diff --git a/mslib/msui/qt5/ui_about_dialog.py b/mslib/msui/qt5/ui_about_dialog.py index 32d6a9f15..46725b0ff 100644 --- a/mslib/msui/qt5/ui_about_dialog.py +++ b/mslib/msui/qt5/ui_about_dialog.py @@ -2,9 +2,10 @@ # Form implementation generated from reading ui file 'ui_about_dialog.ui' # -# Created by: PyQt5 UI code generator 5.12.3 +# Created by: PyQt5 UI code generator 5.15.9 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets @@ -13,7 +14,7 @@ class Ui_AboutMSUIDialog(object): def setupUi(self, AboutMSUIDialog): AboutMSUIDialog.setObjectName("AboutMSUIDialog") - AboutMSUIDialog.resize(1052, 600) + AboutMSUIDialog.resize(1052, 771) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -82,6 +83,9 @@ def setupUi(self, AboutMSUIDialog): self.lblChanges.setObjectName("lblChanges") self.horizontalLayout_2.addWidget(self.lblChanges) self.verticalLayout_2.addLayout(self.horizontalLayout_2) + self.lblNewVersion = QtWidgets.QLabel(AboutMSUIDialog) + self.lblNewVersion.setObjectName("lblNewVersion") + self.verticalLayout_2.addWidget(self.lblNewVersion) spacerItem2 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) self.verticalLayout_2.addItem(spacerItem2) self.lblLicense = QtWidgets.QLabel(AboutMSUIDialog) @@ -109,7 +113,7 @@ def setupUi(self, AboutMSUIDialog): self.verticalLayout.addLayout(self.verticalLayout_2) self.retranslateUi(AboutMSUIDialog) - self.btOK.clicked.connect(AboutMSUIDialog.accept) + self.btOK.clicked.connect(AboutMSUIDialog.accept) # type: ignore QtCore.QMetaObject.connectSlotsByName(AboutMSUIDialog) def retranslateUi(self, AboutMSUIDialog): @@ -120,25 +124,26 @@ def retranslateUi(self, AboutMSUIDialog): self.textBrowser.setHtml(_translate("AboutMSUIDialog", "\n" "\n" -"

Please read the reference documentation:

\n" -"


\n" -"

Bauer, R., Grooß, J.-U., Ungermann, J., Bär, M., Geldenhuys, M., and Hoffmann, L.: The Mission Support

\n" -"

System (MSS v7.0.4) and its use in planning for the SouthTRAC aircraft campaign, Geosci.

\n" -"

Model Dev., 15, 8983–8997, https://doi.org/10.5194/gmd-15-8983-2022, 2022.

\n" -"


\n" -"


\n" -"

Rautenhaus, M., Bauer, G., and Doernbrack, A.: A web service based tool to plan

\n" -"

atmospheric research flights, Geosci. Model Dev., 5,55-71, https://doi.org/10.5194/gmd-5-55-2012, 2012.

\n" -"


\n" -"

and the paper\'s Supplement (which includes a tutorial) before using the application. The documents are available at:

\n" -"


\n" -"

* http://www.geosci-model-dev.net/5/55/2012/gmd-5-55-2012.pdf

\n" -"

* http://www.geosci-model-dev.net/5/55/2012/gmd-5-55-2012-supplement.pdf

\n" -"

\n" -"

When using this software, please be so kind and acknowledge its use by citing the above mentioned reference documentation in publications, presentations, reports, etc. that you create. Thank you very much.

")) +"\n" +"

Please read the reference documentation:

\n" +"


\n" +"

Bauer, R., Grooß, J.-U., Ungermann, J., Bär, M., Geldenhuys, M., and Hoffmann, L.: The Mission Support

\n" +"

System (MSS v7.0.4) and its use in planning for the SouthTRAC aircraft campaign, Geosci.

\n" +"

Model Dev., 15, 8983–8997, https://doi.org/10.5194/gmd-15-8983-2022, 2022.

\n" +"


\n" +"


\n" +"

Rautenhaus, M., Bauer, G., and Doernbrack, A.: A web service based tool to plan

\n" +"

atmospheric research flights, Geosci. Model Dev., 5,55-71, https://doi.org/10.5194/gmd-5-55-2012, 2012.

\n" +"


\n" +"

and the paper\'s Supplement (which includes a tutorial) before using the application. The documents are available at:

\n" +"


\n" +"

* http://www.geosci-model-dev.net/5/55/2012/gmd-5-55-2012.pdf

\n" +"

* http://www.geosci-model-dev.net/5/55/2012/gmd-5-55-2012-supplement.pdf

\n" +"

\n" +"

When using this software, please be so kind and acknowledge its use by citing the above mentioned reference documentation in publications, presentations, reports, etc. that you create. Thank you very much.

")) self.lblVersion.setText(_translate("AboutMSUIDialog", "Version: --VERSION--")) self.lblChanges.setText(_translate("AboutMSUIDialog", "Changes: --CHANGES--")) + self.lblNewVersion.setText(_translate("AboutMSUIDialog", "Check for new Version: --NEW VERSION--")) self.lblLicense.setText(_translate("AboutMSUIDialog", "License: Apache License Version 2.0")) self.lblCopyright.setText(_translate("AboutMSUIDialog", "Copyright 2008-2014: Deutsches Zentrum fuer Luft- und Raumfahrt e.V.\n" "Copyright 2011-2014: Marc Rautenhaus\n" diff --git a/mslib/msui/qt5/ui_mainwindow.py b/mslib/msui/qt5/ui_mainwindow.py index 2b8056f50..ae68dfe21 100644 --- a/mslib/msui/qt5/ui_mainwindow.py +++ b/mslib/msui/qt5/ui_mainwindow.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'mslib/msui/ui/ui_mainwindow.ui' +# Form implementation generated from reading ui file 'ui_mainwindow.ui' # -# Created by: PyQt5 UI code generator 5.15.7 +# Created by: PyQt5 UI code generator 5.15.9 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. @@ -253,7 +253,6 @@ def setupUi(self, MSUIMainWindow): self.menuFile.addAction(self.actionQuit) self.menuHelp.addAction(self.actionShortcuts) self.menuHelp.addAction(self.actionMSColabHelp) - self.menuHelp.addAction(self.actionUpdater) self.menuHelp.addAction(self.actionOnlineHelp) self.menuHelp.addAction(self.actionAboutMSUI) self.menuHelp.addAction(self.actionSearch) diff --git a/mslib/msui/qt5/ui_updater_dialog.py b/mslib/msui/qt5/ui_updater_dialog.py deleted file mode 100644 index bf60607af..000000000 --- a/mslib/msui/qt5/ui_updater_dialog.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'ui_updater_dialog.ui' -# -# Created by: PyQt5 UI code generator 5.12.3 -# -# WARNING! All changes made in this file will be lost! - - -from PyQt5 import QtCore, QtGui, QtWidgets - - -class Ui_Updater(object): - def setupUi(self, Updater): - Updater.setObjectName("Updater") - Updater.setWindowModality(QtCore.Qt.NonModal) - Updater.resize(854, 338) - self.verticalLayout = QtWidgets.QVBoxLayout(Updater) - self.verticalLayout.setObjectName("verticalLayout") - self.horizontalLayout = QtWidgets.QHBoxLayout() - self.horizontalLayout.setObjectName("horizontalLayout") - self.labelVersion = QtWidgets.QLabel(Updater) - self.labelVersion.setObjectName("labelVersion") - self.horizontalLayout.addWidget(self.labelVersion) - self.btUpdate = QtWidgets.QPushButton(Updater) - self.btUpdate.setEnabled(False) - self.btUpdate.setObjectName("btUpdate") - self.horizontalLayout.addWidget(self.btUpdate) - self.btRestart = QtWidgets.QPushButton(Updater) - self.btRestart.setEnabled(False) - self.btRestart.setObjectName("btRestart") - self.horizontalLayout.addWidget(self.btRestart) - spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.horizontalLayout.addItem(spacerItem) - self.label = QtWidgets.QLabel(Updater) - self.label.setOpenExternalLinks(True) - self.label.setObjectName("label") - self.horizontalLayout.addWidget(self.label) - self.verticalLayout.addLayout(self.horizontalLayout) - self.statusLabel = QtWidgets.QLabel(Updater) - self.statusLabel.setObjectName("statusLabel") - self.verticalLayout.addWidget(self.statusLabel) - self.output = QtWidgets.QPlainTextEdit(Updater) - font = QtGui.QFont() - font.setFamily("Sans Serif") - font.setStyleStrategy(QtGui.QFont.PreferDefault) - self.output.setFont(font) - self.output.setLineWrapMode(QtWidgets.QPlainTextEdit.NoWrap) - self.output.setReadOnly(True) - self.output.setPlainText("") - self.output.setCenterOnScroll(False) - self.output.setObjectName("output") - self.verticalLayout.addWidget(self.output) - - self.retranslateUi(Updater) - QtCore.QMetaObject.connectSlotsByName(Updater) - - def retranslateUi(self, Updater): - _translate = QtCore.QCoreApplication.translate - Updater.setWindowTitle(_translate("Updater", "Updater")) - self.labelVersion.setText(_translate("Updater", "Newest Version: x.x.x")) - self.btUpdate.setText(_translate("Updater", "Update")) - self.btRestart.setText(_translate("Updater", "Restart MSUI")) - self.label.setText(_translate("Updater", "

Manual update instructions

")) - self.statusLabel.setText(_translate("Updater", "Nothing to do")) diff --git a/mslib/msui/ui/ui_about_dialog.ui b/mslib/msui/ui/ui_about_dialog.ui index c82ba442f..484e6912f 100644 --- a/mslib/msui/ui/ui_about_dialog.ui +++ b/mslib/msui/ui/ui_about_dialog.ui @@ -7,7 +7,7 @@ 0 0 1052 - 600 + 771 @@ -139,23 +139,23 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Please read the reference documentation:</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Bauer, R., Grooß, J.-U., Ungermann, J., Bär, M., Geldenhuys, M., and Hoffmann, L.: The Mission Support</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">System (MSS v7.0.4) and its use in planning for the SouthTRAC aircraft campaign, Geosci.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Model Dev., 15, 8983–8997, https://doi.org/10.5194/gmd-15-8983-2022, 2022.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Rautenhaus, M., Bauer, G., and Doernbrack, A.: A web service based tool to plan</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">atmospheric research flights, Geosci. Model Dev., 5,55-71, https://doi.org/10.5194/gmd-5-55-2012, 2012.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">and the paper's Supplement (which includes a tutorial) before using the application. The documents are available at:</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> * http://www.geosci-model-dev.net/5/55/2012/gmd-5-55-2012.pdf</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> * http://www.geosci-model-dev.net/5/55/2012/gmd-5-55-2012-supplement.pdf</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> When using this software, please be so kind and acknowledge its use by citing the above mentioned reference documentation in publications, presentations, reports, etc. that you create. Thank you very much.</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Please read the reference documentation:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Bauer, R., Grooß, J.-U., Ungermann, J., Bär, M., Geldenhuys, M., and Hoffmann, L.: The Mission Support</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">System (MSS v7.0.4) and its use in planning for the SouthTRAC aircraft campaign, Geosci.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Model Dev., 15, 8983–8997, https://doi.org/10.5194/gmd-15-8983-2022, 2022.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Rautenhaus, M., Bauer, G., and Doernbrack, A.: A web service based tool to plan</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">atmospheric research flights, Geosci. Model Dev., 5,55-71, https://doi.org/10.5194/gmd-5-55-2012, 2012.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">and the paper's Supplement (which includes a tutorial) before using the application. The documents are available at:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;"> * http://www.geosci-model-dev.net/5/55/2012/gmd-5-55-2012.pdf</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;"> * http://www.geosci-model-dev.net/5/55/2012/gmd-5-55-2012-supplement.pdf</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;"> </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;"> When using this software, please be so kind and acknowledge its use by citing the above mentioned reference documentation in publications, presentations, reports, etc. that you create. Thank you very much.</span></p></body></html> @@ -193,6 +193,13 @@ p, li { white-space: pre-wrap; } + + + + Check for new Version: --NEW VERSION-- + + + diff --git a/mslib/msui/ui/ui_mainwindow.ui b/mslib/msui/ui/ui_mainwindow.ui index 9f6209063..737992ff4 100644 --- a/mslib/msui/ui/ui_mainwindow.ui +++ b/mslib/msui/ui/ui_mainwindow.ui @@ -403,7 +403,6 @@ Double click a operation to activate and view its description. - diff --git a/mslib/msui/ui/ui_updater_dialog.ui b/mslib/msui/ui/ui_updater_dialog.ui deleted file mode 100644 index 611b55719..000000000 --- a/mslib/msui/ui/ui_updater_dialog.ui +++ /dev/null @@ -1,107 +0,0 @@ - - - Updater - - - Qt::NonModal - - - - 0 - 0 - 854 - 338 - - - - Updater - - - - - - - - Newest Version: x.x.x - - - - - - - false - - - Update - - - - - - - false - - - Restart MSUI - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p><a href="https://mss.readthedocs.io/en/stable/installation.html#install"><span style=" text-decoration: underline; color:#0000ff;">Manual update instructions</span></a></p></body></html> - - - true - - - - - - - - - Nothing to do - - - - - - - - Sans Serif - PreferDefault - - - - QPlainTextEdit::NoWrap - - - true - - - - - - false - - - - - - - - diff --git a/mslib/msui/updater.py b/mslib/msui/updater.py deleted file mode 100644 index b33822e94..000000000 --- a/mslib/msui/updater.py +++ /dev/null @@ -1,81 +0,0 @@ -""" - mslib.msui.updater - ~~~~~~~~~~~~~~~~~~~ - - This UI interface for the updater util, handles detection of an outdated mss version and automatic updating. - - This file is part of MSS. - - :copyright: Copyright 2021 May Bär - :copyright: Copyright 2021-2024 by the MSS team, see AUTHORS. - :license: APACHE-2.0, see LICENSE for details. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" -import logging - -from PyQt5 import QtCore, QtWidgets, QtGui - -from mslib.utils.qt import Updater -from mslib.msui.qt5 import ui_updater_dialog -from mslib import __version__ - - -class UpdaterUI(QtWidgets.QDialog, ui_updater_dialog.Ui_Updater): - """ - Checks for a newer versions of MSS and installs it. - Only works if conda is installed and MSS isn't inside a git repo. - """ - on_update_available = QtCore.pyqtSignal([str, str]) - - def __init__(self, parent=None): - super().__init__(parent) - self.setupUi(self) - self.hide() - self.labelVersion.setText(f"Newest Version: {__version__}") - self.updater = None - try: - self.updater = Updater() - except ModuleNotFoundError as ex: - # https://github.com/Open-MSS/MSS/issues/1409#issuecomment-1200946622 - logging.error("unexpected error in updater: %s %s in version: %s", type(ex), ex, __version__) - - if self.updater is not None: - monospace = QtGui.QFont("non-existent") - monospace.setStyleHint(QtGui.QFont.Monospace) - self.output.setFont(monospace) - self.updater.on_log_update.connect(lambda s: (self.output.insertPlainText(s), - self.output.verticalScrollBar().setSliderPosition( - self.output.verticalScrollBar().maximum()))) - self.updater.on_status_update.connect(self.statusLabel.setText) - self.updater.on_update_available.connect(self.notify_on_update) - self.updater.on_update_finished.connect(lambda: self.btRestart.setEnabled(True)) - self.btUpdate.clicked.connect(lambda: (self.updater.update_mss(), self.btUpdate.setEnabled(False))) - self.btRestart.clicked.connect(self.updater._restart_msui) - self.updater.run() - - def notify_on_update(self, old, new): - """ - Asks the user if they want to update MSS - """ - self.btUpdate.setEnabled(True) - self.labelVersion.setText(f"Newest Version: {new}") - if not self.updater.is_git_env: - ret = QtWidgets.QMessageBox.information( - self, "Mission Support System", - f"MSS can be updated from {old} to {new}\nDo you want to update?", - QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, - QtWidgets.QMessageBox.No) - if ret == QtWidgets.QMessageBox.Yes: - self.show() - self.btUpdate.click() diff --git a/mslib/mswms/app/__init__.py b/mslib/mswms/app/__init__.py index dd7885619..1f8eadcd8 100644 --- a/mslib/mswms/app/__init__.py +++ b/mslib/mswms/app/__init__.py @@ -25,11 +25,14 @@ """ import os +import logging import mslib from flask import Flask, url_for from mslib.mswms.gallery_builder import STATIC_LOCATION -from mslib.utils import prefix_route +from mslib.utils import prefix_route, release_info + +logging.debug(release_info.check_for_new_release()) DOCS_SERVER_PATH = os.path.dirname(os.path.abspath(mslib.__file__)) diff --git a/mslib/mswms/mswms.py b/mslib/mswms/mswms.py index 987d6a7a2..b73fe9d5b 100644 --- a/mslib/mswms/mswms.py +++ b/mslib/mswms/mswms.py @@ -31,7 +31,6 @@ from mslib import __version__ from mslib.utils import setup_logging -from mslib.utils.qt import Updater, Worker from mslib.mswms.wms import app as application @@ -45,7 +44,6 @@ def main(): parser.add_argument("--debug", help="show debugging log messages on console", action="store_true", default=False) parser.add_argument("--logfile", help="If set to a name log output goes to that file", dest="logfile", default=None) - parser.add_argument("--update", help="Updates MSS to the newest version", action="store_true", default=False) subparsers = parser.add_subparsers(help='Available actions', dest='action') gallery = subparsers.add_parser("gallery", help="Subcommands surrounding the gallery") @@ -87,16 +85,6 @@ def main(): print("Version:", __version__) sys.exit() - updater = Updater() - if args.update: - updater.on_update_available.connect(lambda old, new: updater.update_mss()) - updater.on_log_update.connect(lambda s: print(s.replace("\n", ""))) - updater.on_status_update.connect(lambda s: print(s.replace("\n", ""))) - updater.run() - while Worker.workers: - list(Worker.workers)[0].wait() - sys.exit() - setup_logging(args) # keep the import after the version check. This creates all layers. diff --git a/mslib/utils/qt.py b/mslib/utils/qt.py index 8503b80c4..ee6af70f3 100644 --- a/mslib/utils/qt.py +++ b/mslib/utils/qt.py @@ -420,60 +420,6 @@ def create(function, on_success=None, on_failure=None, start=True): worker.start() return worker - @staticmethod - def _update_gui(): - """ - Iterate through all windows and update them. - Useful for when a thread modifies the GUI. - Happens automatically at the end of a Worker. - """ - for window in QtWidgets.QApplication.allWindows(): - window.requestUpdate() - - -class Updater(QtCore.QObject): - """ - Checks for a newer versions of MSS and provide functions to install it asynchronously. - Only works if conda is installed. - """ - on_update_available = QtCore.pyqtSignal([str, str]) - on_update_finished = QtCore.pyqtSignal() - on_log_update = QtCore.pyqtSignal([str]) - on_status_update = QtCore.pyqtSignal([str]) - - def __init__(self, parent=None): - super().__init__(parent) - self.is_git_env = False - self.new_version = None - self.old_version = None - # we are using the installer version of the env - self.conda_prefix = os.getenv("CONDA_PREFIX") - if self.conda_prefix is not None: - self.command = os.path.join(self.conda_prefix, 'bin', "conda") - mamba_cmd = os.path.join(self.conda_prefix, 'bin', 'mamba') - # Check if mamba is installed in the env - try: - subprocess.run([mamba_cmd], startupinfo=subprocess_startupinfo(), - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - self.command = mamba_cmd - except FileNotFoundError: - pass - else: - self.command = "conda" - - # pyqtSignals don't work without an application eventloop running - if QtCore.QCoreApplication.startingUp(): - self.on_update_available = NonQtCallback() - self.on_update_finished = NonQtCallback() - self.on_log_update = NonQtCallback() - self.on_status_update = NonQtCallback() - - def run(self): - """ - Starts the updater process - """ - Worker.create(self._check_version) - def _check_version(self): """ Checks if conda search has a newer version of MSS diff --git a/mslib/utils/release_info.py b/mslib/utils/release_info.py new file mode 100644 index 000000000..d7e1d57f5 --- /dev/null +++ b/mslib/utils/release_info.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +""" + + mslib.utils.release_info + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Shows by an github API call informations about the latests release + + This file is part of MSS. + + :copyright: Copyright 2024 Reimar Bauer + :license: APACHE-2.0, see LICENSE for details. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import datetime +import requests + +from mslib.version import __version__ as installed_version + + +def get_latest_release(): + # GitHub API URL for releases + url = "https://api.github.com/repos/Open-MSS/MSS/releases/latest" + + try: + # Make a GET request to the GitHub API + response = requests.get(url) + response.raise_for_status() # Raise an error for non-200 status codes + + # Extract the JSON response + release_data = response.json() + + # Extract the latest release tag and name + latest_release = { + 'tag_name': release_data['tag_name'], + 'release_name': release_data['name'], + 'published_at': release_data['published_at'], + 'url': release_data['html_url'] + } + return latest_release + + except requests.exceptions.RequestException as e: + print(f"Error fetching release data: {e}") + return None + + +def check_for_new_release(): + no_new_release_found = f"{datetime.date.today()}: No new release found." + latest_release = get_latest_release() + if latest_release is None: + return no_new_release_found + + result = [] + # Compare the latest release with the previous known version + if latest_release['tag_name'] != installed_version: + github_url = f'{latest_release["url"]}' + result.append(f"New release found: {latest_release['release_name']} ({latest_release['tag_name']})") + result.append(f"Published at: {latest_release['published_at']}") + result.append(f"Release URL: {github_url}") + result = ' | '.join(result) + else: + result = no_new_release_found + return result diff --git a/tests/_test_msui/test_updater.py b/tests/_test_msui/test_updater.py deleted file mode 100644 index 452ee88d7..000000000 --- a/tests/_test_msui/test_updater.py +++ /dev/null @@ -1,135 +0,0 @@ -# -*- coding: utf-8 -*- -""" - - tests._test_msui.test_updater - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - This module provides pytest functions to tests msui.updater - - This file is part of MSS. - - :copyright: Copyright 2021 May Bär - :copyright: Copyright 2021-2024 by the MSS team, see AUTHORS. - :license: APACHE-2.0, see LICENSE for details. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" -import mock -import pytest -from PyQt5 import QtWidgets - -from mslib.msui.updater import UpdaterUI, Updater -from mslib.utils.qt import Worker - - -def no_conda(args=None, **named_args): - raise FileNotFoundError - - -class SubprocessDifferentVersionMock: - def __init__(self, args=None, **named_args): - self.returncode = 0 - self.args = args - if args and "list" in args and "mss" in args: - self.stdout = "*mss 0.0.0\n" - else: - self.stdout = "*mss 999.999.999\n" - - -class SubprocessSameMock: - def __init__(self, args=None, **named_args): - self.stdout = "*mss 999.999.999\n" - self.returncode = 0 - self.args = args - - -@mock.patch("mslib.utils.qt.Worker.start", Worker.run) -class Test_MSS_ShortcutDialog: - @pytest.fixture(autouse=True) - def setup(self, qtbot): - self.updater = Updater() - self.status = "" - self.update_available = False - self.update_finished = False - - def update_signal(old, new): - self.update_available = True - - def update_finished_signal(): - self.update_finished = True - - def status_signal(s): - self.status = s - - self.updater.on_update_available.connect(update_signal) - self.updater.on_status_update.connect(status_signal) - self.updater.on_update_finished.connect(update_finished_signal) - yield - - @mock.patch("subprocess.Popen", new=SubprocessDifferentVersionMock) - @mock.patch("subprocess.run", new=SubprocessDifferentVersionMock) - def test_update_recognised(self): - self.updater.run() - - assert self.updater.new_version == "999.999.999" - assert self.update_available - self.updater.new_version = "0.0.0" - - self.updater.update_mss() - assert self.status == "Update successful. Please restart MSS." - assert self.update_finished - - @mock.patch("subprocess.Popen", new=SubprocessSameMock) - @mock.patch("subprocess.run", new=SubprocessSameMock) - def test_no_update(self): - self.updater.run() - assert self.status == "Your MSS is up to date." - assert not self.update_available - assert not self.update_finished - - @mock.patch("subprocess.Popen", new=SubprocessDifferentVersionMock) - @mock.patch("subprocess.run", new=SubprocessDifferentVersionMock) - def test_update_failed(self): - self.updater.run() - assert self.updater.new_version == "999.999.999" - assert self.update_available - self.updater.new_version = "1000.1000.1000" - self.updater.update_mss() - assert self.status == "Update failed. Please try it manually or " \ - "by creating a new environment!" - - @mock.patch("subprocess.Popen", new=no_conda) - @mock.patch("subprocess.run", new=no_conda) - def test_no_conda(self): - self.updater.run() - assert self.updater.new_version is None and self.updater.old_version is None - assert not self.update_available - assert not self.update_finished - - @mock.patch("subprocess.Popen", new=no_conda) - @mock.patch("subprocess.run", new=no_conda) - def test_exception(self): - self.updater.new_version = "999.999.999" - self.updater.old_version = "999.999.999" - self.updater.update_mss() - assert self.status == "Update failed, please do it manually." - assert not self.update_finished - - @mock.patch("subprocess.Popen", new=SubprocessSameMock) - @mock.patch("subprocess.run", new=SubprocessSameMock) - @mock.patch("PyQt5.QtWidgets.QMessageBox.information", return_value=QtWidgets.QMessageBox.Yes) - def test_ui(self, mock): - ui = UpdaterUI() - ui.updater.on_update_available.emit("", "") - assert ui.statusLabel.text() == "Update successful. Please restart MSS." - assert ui.btRestart.isEnabled() From d7e69069ef0745c6b41ee366dccb9931331a6d00 Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Fri, 30 Aug 2024 15:31:55 +0200 Subject: [PATCH 02/12] codespell --- mslib/utils/release_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mslib/utils/release_info.py b/mslib/utils/release_info.py index d7e1d57f5..a778737b0 100644 --- a/mslib/utils/release_info.py +++ b/mslib/utils/release_info.py @@ -4,7 +4,7 @@ mslib.utils.release_info ~~~~~~~~~~~~~~~~~~~~~~~~ - Shows by an github API call informations about the latests release + Shows by a github API call information about the latest release This file is part of MSS. From 9ea7aaf115ba76fd518fdf8208e36a39c5c3754a Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Fri, 30 Aug 2024 15:37:12 +0200 Subject: [PATCH 03/12] docs updated --- docs/installation.rst | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 9075d450a..beb6e1952 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -124,21 +124,7 @@ versions for dependencies. :: (mssenv) $ msui -Update ------- - -Builtin Update -.............. - -Since version 5.0 we provide a feature for updating MSS by the UI or the command line -After you started the MSS UI it informs you after a while if there is a new update available. -From the command line you can trigger this update feature by :: - - (mssenv) $ msui --update - - - -Other Methods +Update Methods ............. For updating an existing MSS installation to the current version, it is best to install From d4a8ee80a7be85c12fce9a0b00c2075e92277773 Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Fri, 30 Aug 2024 16:01:28 +0200 Subject: [PATCH 04/12] remove more updater code --- mslib/utils/qt.py | 101 ---------------------------------------------- 1 file changed, 101 deletions(-) diff --git a/mslib/utils/qt.py b/mslib/utils/qt.py index ee6af70f3..f9de96cd9 100644 --- a/mslib/utils/qt.py +++ b/mslib/utils/qt.py @@ -385,8 +385,6 @@ def __init__(self, function): self.finished = NonQtCallback() self.failed = NonQtCallback() - self.failed.connect(lambda e: self._update_gui()) - self.finished.connect(lambda x: self._update_gui()) def run(self): try: @@ -420,42 +418,6 @@ def create(function, on_success=None, on_failure=None, start=True): worker.start() return worker - def _check_version(self): - """ - Checks if conda search has a newer version of MSS - """ - # Don't notify on updates if mss is in a git repo, as you are most likely a developer - try: - git = subprocess.run(["git", "rev-parse", "--is-inside-work-tree"], - startupinfo=subprocess_startupinfo(), - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, encoding="utf8") - if "true" in git.stdout: - self.is_git_env = True - except FileNotFoundError: - pass - - # Return if conda is not installed. conda is fallback of mamba - try: - subprocess.run([self.command], startupinfo=subprocess_startupinfo(), - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - except FileNotFoundError: - return - - self.on_status_update.emit("Checking for updates...") - - # Check if "search mss" yields a higher version than the currently running one - search = self._execute_command(f"{self.command} search mss") - self.new_version = search.split("\n")[-2].split()[1] - c_list = self._execute_command(f"{self.command} list -f mss") - self.old_version = c_list.split("\n")[-2].split()[1] - if any(c.isdigit() for c in self.new_version): - if self.new_version > self.old_version: - self.on_status_update.emit("Your version of MSS is outdated!") - self.on_update_available.emit(self.old_version, self.new_version) - else: - self.on_status_update.emit("Your MSS is up to date.") - def _restart_msui(self): """ Restart msui with all the same parameters, not entirely @@ -466,69 +428,6 @@ def _restart_msui(self): command[1] += "-script.py" os.execv(sys.executable, command) - def _try_updating(self): - """ - Execute 'conda/mamba install mss=newest python -y' and return if it worked or not - """ - self.on_status_update.emit("Trying to update MSS...") - self._execute_command(f"{self.command} install mss={self.new_version} python -y") - if self._verify_newest_mss(): - return True - - return False - - def _update_mss(self): - """ - Try to install MSS' newest version - """ - if not self._try_updating(): - self.on_status_update.emit("Update failed. Please try it manually or by creating a new environment!") - else: - self.on_update_finished.emit() - self.on_status_update.emit("Update successful. Please restart MSS.") - - def _verify_newest_mss(self): - """ - Return if the newest mss exists in the environment or not - """ - verify = self._execute_command(f"{self.command} list -f mss") - if self.new_version in verify: - return True - - return False - - def _execute_command(self, command): - """ - Handles proper execution of conda subprocesses and logging - """ - process = subprocess.Popen(command.split(), - startupinfo=subprocess_startupinfo(), - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - encoding="utf8") - self.on_log_update.emit(" ".join(process.args) + "\n") - - text = "" - for line in process.stdout: - self.on_log_update.emit(line) - text += line - - # Happens e.g. on connection errors during installation attempts - if "An unexpected error has occurred. Conda has prepared the above report" in text: - raise RuntimeError("Something went wrong! Can't safely continue to update.") - else: - return text - - def update_mss(self): - """ - Installs the newest mss version - """ - def on_failure(e: Exception): - self.on_status_update.emit("Update failed, please do it manually.") - self.on_log_update.emit(str(e)) - - Worker.create(self._update_mss, on_failure=on_failure) - class NonQtCallback: """ From e9be6c9d19db9496caea70aec508cbff6fc090a0 Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Fri, 30 Aug 2024 16:06:04 +0200 Subject: [PATCH 05/12] flake8 --- mslib/utils/qt.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mslib/utils/qt.py b/mslib/utils/qt.py index f9de96cd9..2b6e9e0f9 100644 --- a/mslib/utils/qt.py +++ b/mslib/utils/qt.py @@ -30,14 +30,13 @@ import re import platform import sys -import subprocess import traceback from fslib.fs_filepicker import getSaveFileName, getOpenFileName, getExistingDirectory from PyQt5 import QtCore, QtWidgets, QtGui # noqa from mslib.utils.config import config_loader -from mslib.utils import FatalUserError, subprocess_startupinfo +from mslib.utils import FatalUserError def get_open_filename_qt(*args): @@ -385,7 +384,6 @@ def __init__(self, function): self.finished = NonQtCallback() self.failed = NonQtCallback() - def run(self): try: result = self.function() From 8bdf751ac0005782a321ab4ccc1441b530587437 Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Sun, 1 Sep 2024 07:34:04 +0200 Subject: [PATCH 06/12] Update mslib/utils/release_info.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Riße <9308656+matrss@users.noreply.github.com> --- mslib/utils/release_info.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/mslib/utils/release_info.py b/mslib/utils/release_info.py index a778737b0..797b29bcb 100644 --- a/mslib/utils/release_info.py +++ b/mslib/utils/release_info.py @@ -59,17 +59,12 @@ def get_latest_release(): def check_for_new_release(): no_new_release_found = f"{datetime.date.today()}: No new release found." latest_release = get_latest_release() - if latest_release is None: + if latest_release is None or latest_release['tag_name'] == installed_version: return no_new_release_found - result = [] - # Compare the latest release with the previous known version - if latest_release['tag_name'] != installed_version: - github_url = f'{latest_release["url"]}' - result.append(f"New release found: {latest_release['release_name']} ({latest_release['tag_name']})") - result.append(f"Published at: {latest_release['published_at']}") - result.append(f"Release URL: {github_url}") - result = ' | '.join(result) - else: - result = no_new_release_found - return result + github_url = f'{latest_release["url"]}' + return ' | '.join([ + f"New release found: {latest_release['release_name']} ({latest_release['tag_name']})", + f"Published at: {latest_release['published_at']}", + f"Release URL: {github_url}", + ]) From 0f129dd053f3d5c831d16c8948122a075a6cb131 Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Sun, 1 Sep 2024 08:40:11 +0200 Subject: [PATCH 07/12] introduce timeout_decorator different states for the release check --- localbuild/meta.yaml | 1 + mslib/mscolab/app/__init__.py | 5 +++-- mslib/msui/msui_mainwindow.py | 2 +- mslib/mswms/app/__init__.py | 5 ++++- mslib/utils/qt.py | 2 +- mslib/utils/release_info.py | 22 ++++++++++++++++------ 6 files changed, 26 insertions(+), 11 deletions(-) diff --git a/localbuild/meta.yaml b/localbuild/meta.yaml index 9e2b52fdc..413e3047d 100644 --- a/localbuild/meta.yaml +++ b/localbuild/meta.yaml @@ -86,6 +86,7 @@ requirements: - flask-login - pysaml2 - libxmlsec1 # [not win] + - timeout-decorator run_constrained: - menuinst >=2.0.2 diff --git a/mslib/mscolab/app/__init__.py b/mslib/mscolab/app/__init__.py index 38a114e98..1e9fe719e 100644 --- a/mslib/mscolab/app/__init__.py +++ b/mslib/mscolab/app/__init__.py @@ -37,8 +37,9 @@ from flask_sqlalchemy import SQLAlchemy from mslib.utils import prefix_route, release_info - -logging.debug(release_info.check_for_new_release()) +message, update = release_info.check_for_new_release() +if update: + logging.warning(message) DOCS_SERVER_PATH = os.path.dirname(os.path.abspath(mslib.__file__)) diff --git a/mslib/msui/msui_mainwindow.py b/mslib/msui/msui_mainwindow.py index 983bd6350..99a0ea409 100644 --- a/mslib/msui/msui_mainwindow.py +++ b/mslib/msui/msui_mainwindow.py @@ -408,7 +408,7 @@ def __init__(self, parent=None): super().__init__(parent) self.setupUi(self) self.lblVersion.setText(f"Version: {__version__}") - self.lblNewVersion.setText(f"{release_info.check_for_new_release()}") + self.lblNewVersion.setText(f"{release_info.check_for_new_release()[0]}") self.milestone_url = f'https://github.com/Open-MSS/MSS/issues?q=is%3Aclosed+milestone%3A{__version__[:-1]}' self.lblChanges.setText(f'New Features and Changes') blub = QtGui.QPixmap(python_powered()) diff --git a/mslib/mswms/app/__init__.py b/mslib/mswms/app/__init__.py index 1f8eadcd8..bcc1d7dd1 100644 --- a/mslib/mswms/app/__init__.py +++ b/mslib/mswms/app/__init__.py @@ -32,7 +32,10 @@ from mslib.mswms.gallery_builder import STATIC_LOCATION from mslib.utils import prefix_route, release_info -logging.debug(release_info.check_for_new_release()) + +message, update = release_info.check_for_new_release() +if update: + logging.warning(message) DOCS_SERVER_PATH = os.path.dirname(os.path.abspath(mslib.__file__)) diff --git a/mslib/utils/qt.py b/mslib/utils/qt.py index 2b6e9e0f9..7eb373eae 100644 --- a/mslib/utils/qt.py +++ b/mslib/utils/qt.py @@ -2,7 +2,7 @@ """ mslib.utils.msui_qt - ~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~ This module helps with qt diff --git a/mslib/utils/release_info.py b/mslib/utils/release_info.py index 797b29bcb..8c0ac678f 100644 --- a/mslib/utils/release_info.py +++ b/mslib/utils/release_info.py @@ -9,6 +9,7 @@ This file is part of MSS. :copyright: Copyright 2024 Reimar Bauer + :copyright: Copyright 2024 by the MSS team, see AUTHORS. :license: APACHE-2.0, see LICENSE for details. Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,18 +26,21 @@ """ import datetime +import logging import requests +import timeout_decorator from mslib.version import __version__ as installed_version +@timeout_decorator.timeout(1, use_signals=False) def get_latest_release(): - # GitHub API URL for releases + # GitHub API URL for the MSS Release url = "https://api.github.com/repos/Open-MSS/MSS/releases/latest" try: # Make a GET request to the GitHub API - response = requests.get(url) + response = requests.get(url, timeout=(1, 1)) response.raise_for_status() # Raise an error for non-200 status codes # Extract the JSON response @@ -52,19 +56,25 @@ def get_latest_release(): return latest_release except requests.exceptions.RequestException as e: - print(f"Error fetching release data: {e}") + logging.debug(f"Error fetching release data: {e}") return None def check_for_new_release(): no_new_release_found = f"{datetime.date.today()}: No new release found." - latest_release = get_latest_release() + try: + # we use the timeout_decorator on the function to stop requests trying to establish a connection + latest_release = get_latest_release() + except timeout_decorator.timeout_decorator.TimeoutError as e: + logging.debug(f"Error fetching release data: {e}") + latest_release = None + if latest_release is None or latest_release['tag_name'] == installed_version: - return no_new_release_found + return no_new_release_found, False github_url = f'{latest_release["url"]}' return ' | '.join([ f"New release found: {latest_release['release_name']} ({latest_release['tag_name']})", f"Published at: {latest_release['published_at']}", f"Release URL: {github_url}", - ]) + ]), True From d3a10b8f0f129e2e2c34e4d357f116a05ba2e716 Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Sun, 1 Sep 2024 12:05:52 +0200 Subject: [PATCH 08/12] use pebble --- localbuild/meta.yaml | 2 +- mslib/utils/release_info.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/localbuild/meta.yaml b/localbuild/meta.yaml index 413e3047d..4a26119a3 100644 --- a/localbuild/meta.yaml +++ b/localbuild/meta.yaml @@ -86,7 +86,7 @@ requirements: - flask-login - pysaml2 - libxmlsec1 # [not win] - - timeout-decorator + - pebble run_constrained: - menuinst >=2.0.2 diff --git a/mslib/utils/release_info.py b/mslib/utils/release_info.py index 8c0ac678f..594b14acd 100644 --- a/mslib/utils/release_info.py +++ b/mslib/utils/release_info.py @@ -28,12 +28,12 @@ import datetime import logging import requests -import timeout_decorator +from pebble import concurrent from mslib.version import __version__ as installed_version -@timeout_decorator.timeout(1, use_signals=False) +@concurrent.process(timeout=1) def get_latest_release(): # GitHub API URL for the MSS Release url = "https://api.github.com/repos/Open-MSS/MSS/releases/latest" @@ -64,8 +64,8 @@ def check_for_new_release(): no_new_release_found = f"{datetime.date.today()}: No new release found." try: # we use the timeout_decorator on the function to stop requests trying to establish a connection - latest_release = get_latest_release() - except timeout_decorator.timeout_decorator.TimeoutError as e: + latest_release = get_latest_release().result() + except TimeoutError as e: logging.debug(f"Error fetching release data: {e}") latest_release = None From 6f4991f1257932cdcb175070718512b271b6d0e9 Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Sun, 1 Sep 2024 12:39:58 +0200 Subject: [PATCH 09/12] improved comment --- mslib/utils/release_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mslib/utils/release_info.py b/mslib/utils/release_info.py index 594b14acd..e03ca686c 100644 --- a/mslib/utils/release_info.py +++ b/mslib/utils/release_info.py @@ -63,7 +63,7 @@ def get_latest_release(): def check_for_new_release(): no_new_release_found = f"{datetime.date.today()}: No new release found." try: - # we use the timeout_decorator on the function to stop requests trying to establish a connection + # we use the @concurrent.process(timeout=1) on the function to stop requests trying to establish a connection latest_release = get_latest_release().result() except TimeoutError as e: logging.debug(f"Error fetching release data: {e}") From 953facafa85eccdbddf70fc422f494ce684139c5 Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Sun, 1 Sep 2024 14:15:46 +0200 Subject: [PATCH 10/12] add pebble also to the RTFD env --- docs/environment.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/environment.yml b/docs/environment.yml index 2a0fbaf92..9e141ba83 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -22,6 +22,7 @@ dependencies: - PyQt5 - owslib - future + - pebble - basemap >=1.3.3 - pint - python <3.12 From 0a0db83a6ddb0c0ea3b4d74dee313372d44a0655 Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Mon, 2 Sep 2024 16:01:12 +0200 Subject: [PATCH 11/12] update --- docs/installation.rst | 2 +- mslib/utils/qt.py | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index beb6e1952..234d6b6c6 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -125,7 +125,7 @@ versions for dependencies. :: Update Methods -............. +.............. For updating an existing MSS installation to the current version, it is best to install it into a new environment. If your current version is not far behind the new version diff --git a/mslib/utils/qt.py b/mslib/utils/qt.py index 7eb373eae..fd6441fb3 100644 --- a/mslib/utils/qt.py +++ b/mslib/utils/qt.py @@ -384,6 +384,9 @@ def __init__(self, function): self.finished = NonQtCallback() self.failed = NonQtCallback() + self.failed.connect(lambda e: self._update_gui()) + self.finished.connect(lambda x: self._update_gui()) + def run(self): try: result = self.function() @@ -416,15 +419,15 @@ def create(function, on_success=None, on_failure=None, start=True): worker.start() return worker - def _restart_msui(self): + @staticmethod + def _update_gui(): """ - Restart msui with all the same parameters, not entirely - safe in case parameters change in higher versions, or while debugging + Iterate through all windows and update them. + Useful for when a thread modifies the GUI. + Happens automatically at the end of a Worker. """ - command = [sys.executable.split(os.sep)[-1]] + sys.argv - if os.name == "nt" and not command[1].endswith(".py"): - command[1] += "-script.py" - os.execv(sys.executable, command) + for window in QtWidgets.QApplication.allWindows(): + window.requestUpdate() class NonQtCallback: From d9582a4a3072a9ee38eb2ca4117ca5154aa8ab2f Mon Sep 17 00:00:00 2001 From: Reimar Bauer Date: Mon, 2 Sep 2024 18:44:58 +0200 Subject: [PATCH 12/12] remove pebble, not needed --- docs/environment.yml | 1 - localbuild/meta.yaml | 1 - mslib/utils/release_info.py | 5 +---- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/environment.yml b/docs/environment.yml index 9e141ba83..2a0fbaf92 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -22,7 +22,6 @@ dependencies: - PyQt5 - owslib - future - - pebble - basemap >=1.3.3 - pint - python <3.12 diff --git a/localbuild/meta.yaml b/localbuild/meta.yaml index 4a26119a3..9e2b52fdc 100644 --- a/localbuild/meta.yaml +++ b/localbuild/meta.yaml @@ -86,7 +86,6 @@ requirements: - flask-login - pysaml2 - libxmlsec1 # [not win] - - pebble run_constrained: - menuinst >=2.0.2 diff --git a/mslib/utils/release_info.py b/mslib/utils/release_info.py index e03ca686c..c2a5a64ea 100644 --- a/mslib/utils/release_info.py +++ b/mslib/utils/release_info.py @@ -28,12 +28,10 @@ import datetime import logging import requests -from pebble import concurrent from mslib.version import __version__ as installed_version -@concurrent.process(timeout=1) def get_latest_release(): # GitHub API URL for the MSS Release url = "https://api.github.com/repos/Open-MSS/MSS/releases/latest" @@ -63,8 +61,7 @@ def get_latest_release(): def check_for_new_release(): no_new_release_found = f"{datetime.date.today()}: No new release found." try: - # we use the @concurrent.process(timeout=1) on the function to stop requests trying to establish a connection - latest_release = get_latest_release().result() + latest_release = get_latest_release() except TimeoutError as e: logging.debug(f"Error fetching release data: {e}") latest_release = None