From 52c4fbcce9f41475c3161263c27e9f1992c4928b Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Thu, 13 Jun 2024 01:05:53 +0200 Subject: [PATCH 01/10] Downloader has been generalized, now network_utils is update_utils --- artemis/resources.py | 2 +- artemis/ui/artemis.py | 17 ++-- artemis/ui/downloader.py | 41 ++++---- artemis/utils/constants.py | 4 +- artemis/utils/update_utils.py | 174 ++++++++++++++++++++++++++++++++++ 5 files changed, 206 insertions(+), 32 deletions(-) create mode 100644 artemis/utils/update_utils.py diff --git a/artemis/resources.py b/artemis/resources.py index 5d0e7a0..fcdb427 100644 --- a/artemis/resources.py +++ b/artemis/resources.py @@ -7302,7 +7302,7 @@ qt_resource_struct = b"\ \x00\x00\x03X\x00\x02\x00\x00\x00\x04\x00\x00\x00+\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01v\x14\ -\x00\x00\x01\x90\x0eD\xa3A\ +\x00\x00\x01\x90\x0eV\xebx\ \x00\x00\x05d\x00\x01\x00\x00\x00\x01\x00\x01\x8f*\ \x00\x00\x01\x90\x01\x93J\xb0\ \x00\x00\x04\xe6\x00\x01\x00\x00\x00\x01\x00\x01\x7f\x0c\ diff --git a/artemis/ui/artemis.py b/artemis/ui/artemis.py index 8d43e10..f55fe3d 100644 --- a/artemis/ui/artemis.py +++ b/artemis/ui/artemis.py @@ -7,7 +7,7 @@ from artemis.utils.constants import Constants, Messages from artemis.utils.sys_utils import open_directory, make_tar, unpack_tar from artemis.utils.sql_utils import ArtemisDatabase, ArtemisSignal from artemis.utils.path_utils import DATA_DIR -from artemis.utils.network_utils import NetworkManager +from artemis.utils.update_utils import UpdateManager from artemis.utils.generic_utils import generate_filter_query from artemis.utils.path_utils import normalize_dialog_path from artemis.utils.config_utils import CONFIGURE_QT @@ -62,13 +62,12 @@ class UIArtemis(QObject): # Creating istances for other windows self.preferences = UIPreferences(self) self.dbmanager = UIdbmanager(self) - self.downloader = UIDownloader(self) self.spaceweather = UIspaceweather(self) self.docmanager = UIdocumentsmanager(self) self.sigeditor = UIsignaleditor(self) self.cateditor = UIcategoryeditor(self) - self.network_manager = NetworkManager(self) + self.update_manager = UpdateManager(self) self.autoload_db() @@ -217,15 +216,19 @@ class UIArtemis(QObject): def check_update_db(self): """ User manual check for updates db updates """ - self.network_manager.show_popup = True - self.network_manager.check_updates() + self.update_manager.check_updates(True) def start_download_db(self): """ Show the downloader and start the download of the sigid db """ - self.downloader.show_ui.emit() - self.downloader.on_start() + self.downloader = UIDownloader(self) + self.downloader.finished.connect(self.update_manager.post_download_db) + self.downloader.on_start( + self.update_manager.remote_db_url, + self.update_manager.remote_db_size, + DATA_DIR + ) def dialog_download_db(self, message_type, title, message): diff --git a/artemis/ui/downloader.py b/artemis/ui/downloader.py index d3a38a6..99f42ad 100644 --- a/artemis/ui/downloader.py +++ b/artemis/ui/downloader.py @@ -2,14 +2,12 @@ from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtCore import QObject, Slot, Signal, QUrl, QSaveFile, QDir, QIODevice from PySide6.QtNetwork import QNetworkReply, QNetworkRequest, QNetworkAccessManager -from artemis.utils.config_utils import * -from artemis.utils.sys_utils import delete_file, delete_dir, match_hash, unpack_tar from artemis.utils.constants import Messages -from artemis.utils.path_utils import DATA_DIR class UIDownloader(QObject): # Python > QML Signals + finished = Signal() show_ui = Signal() close_ui = Signal() update_progress_bar = Signal(int, int) @@ -25,6 +23,9 @@ class UIDownloader(QObject): self._engine.load('qrc:/ui/Downloader.qml') self._window = self._engine.rootObjects()[0] + self.file_url = None + self.file_size = None + self._connect() @@ -39,20 +40,22 @@ class UIDownloader(QObject): self.update_status.connect(self._window.updateStatus) - @Slot() - def on_start(self): + def on_start(self, url, filesize, save_path): """ Start the download of the DB taking the needed url and size from the attributes of the UpdatesController class """ - url_file = QUrl(self._parent.network_manager.remote_db_url) - dest_path = QDir(DATA_DIR) - self.dest_file = dest_path.filePath(url_file.fileName()) + self.show_ui.emit() + + self.file_url = QUrl(url) + self.file_size = filesize + dest_path = QDir(save_path) + self.dest_file = dest_path.filePath(self.file_url.fileName()) self.file = QSaveFile(self.dest_file) if self.file.open(QIODevice.WriteOnly): # Start a GET HTTP request self.manager = QNetworkAccessManager(self) - self.reply = self.manager.get(QNetworkRequest(url_file)) + self.reply = self.manager.get(QNetworkRequest(self.file_url)) self.reply.downloadProgress.connect(self.on_progress) self.reply.finished.connect(self.on_finished) self.reply.readyRead.connect(self.on_ready_read) @@ -74,8 +77,6 @@ class UIDownloader(QObject): if self.file: self.file.cancelWriting() - self.close_ui.emit() - @Slot() def on_ready_read(self): @@ -95,25 +96,19 @@ class UIDownloader(QObject): if self.file: self.file.commit() + + if self.reply.error() == QNetworkReply.NoError: + self.finished.emit() - self.update_status.emit("Checking DB integrity (SHA-256)") - - if match_hash(self.dest_file, self._parent.network_manager.remote_db_hash): - self.update_status.emit("Unpacking archive...") - delete_dir(DATA_DIR / 'SigID') - unpack_tar(self.dest_file, DATA_DIR / 'SigID') - delete_file(self.dest_file) - self._parent.load_db('SigID') - self.close_ui.emit() + self.close_ui.emit() @Slot(int, int) def on_progress(self, bytesReceived: int): """ Update progress bar and label """ - total_bytes = self._parent.network_manager.remote_db_size - self.update_status.emit("{:.1f} Mb / {:.1f} Mb".format(bytesReceived/10**6, total_bytes/10**6)) - self.update_progress_bar.emit(bytesReceived, total_bytes) + self.update_status.emit("{:.1f} Mb / {:.1f} Mb".format(bytesReceived/10**6, self.file_size/10**6)) + self.update_progress_bar.emit(bytesReceived, self.file_size) @Slot(QNetworkReply.NetworkError) diff --git a/artemis/utils/constants.py b/artemis/utils/constants.py index a7f610f..c79a9de 100644 --- a/artemis/utils/constants.py +++ b/artemis/utils/constants.py @@ -39,6 +39,7 @@ class Messages: UP_TO_DATE = "You're up to date!" DB_NEW_VER = "New SigID DB version available!" ART_NEW_VER = "New Artemis version available!" + DB_CORRUPTED = "Database Corruption Detected" # Messages DB_CREATION_SUCCESS_MSG = "The new database has been created succesfully." @@ -51,7 +52,8 @@ class Messages: UP_TO_DATE_MSG = "The latest version of Artemis and SigID wiki is installed on your computer." DB_NEW_VER_MSG = "A new version of the database ({}) is available for download. Download now?" ART_NEW_VER_MSG = "A new version of Artemis ({}) is available for download. Check GitHub page now?" - DOWNLOAD_CORRUPTED_MSG = "Downloaded data corrupted or invalid. Please retry." + DB_CORRUPTED_MSG = "Downloaded data corrupted or invalid. Please retry." + DB_DOWNLOAD_SUCCESS_MSG = "The database has been successfully downloaded and is now being loaded." class Query(): diff --git a/artemis/utils/update_utils.py b/artemis/utils/update_utils.py new file mode 100644 index 0000000..5f67a0e --- /dev/null +++ b/artemis/utils/update_utils.py @@ -0,0 +1,174 @@ +import os +import requests + +from packaging.version import Version + +from artemis.utils.constants import Constants, Messages +from artemis.utils.sql_utils import ArtemisDatabase +from artemis.utils.sys_utils import is_windows, is_linux, is_macos, delete_file, delete_dir, match_hash, unpack_tar +from artemis.utils.path_utils import DATA_DIR + + +class UpdateManager: + """ Class used to manage DB and software updates + """ + + def __init__(self, parent): + self._parent = parent + self.sigid_db_path = DATA_DIR / 'SigID' / Constants.SQL_NAME + + self.db_update = None + self.art_update = None + + self.remote_db_url = None + self.remote_db_hash = None + self.remote_db_version = None + self.remote_db_size = None + self.remote_db_file_name = None + + self.remote_art_version = None + + self.check_updates() + + + def check_updates(self, show_popup=False): + """ Checks if a software or DB update is available. + Prioritize Artemis update over DB one. + + Args: + show_popup (bool, optional): + Suppress the "already up-to-date" message on startup. + Defaults to False. + """ + latest_json = self._fetch_remote_json(Constants.LATEST_VERSION_URL, show_popup) + if latest_json: + local_db = self._load_local_db() + remote_db = latest_json['sigID_DB'] + + self.remote_db_version = remote_db['version'] + self.remote_db_url = remote_db['url'] + self.remote_db_hash = remote_db['sha256_hash'] + self.remote_db_size = remote_db['total_bytes'] + self.remote_db_file_name = self.remote_db_url.split('/')[-1] + + if is_windows(): + self.remote_art_version = latest_json['windows']['version'] + elif is_linux(): + self.remote_art_version = latest_json['linux']['version'] + elif is_macos(): + self.remote_art_version = latest_json['mac']['version'] + + if Version(self.remote_art_version) > Version(Constants.APPLICATION_VERSION): + self.art_update = True + else: + self.art_update = False + + if self.art_update: + self._show_popup_art_update() + else: + if local_db: + if self.remote_db_version > local_db.version: + self._show_popup_db_update() + elif show_popup: + self._show_popup_up_to_date() + else: + self._show_popup_initial_db_download() + + + def _fetch_remote_json(self, url, show_popup=False): + """ Fetches the remote json from a url + """ + try: + response = requests.get(url) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + if show_popup: + self._parent.dialog_popup( + Messages.DIALOG_TYPE_ERROR, + Messages.NO_CONNECTION, + Messages.NO_CONNECTION_MSG.format(e) + ) + return None + + + def _load_local_db(self): + """ Loads the local database if exists + """ + if os.path.exists(self.sigid_db_path): + local_db = ArtemisDatabase('SigID') + local_db.load() + return local_db + return None + + + def post_download_db(self): + latest_db_tar_path = DATA_DIR / self.remote_db_file_name + if match_hash(latest_db_tar_path, self.remote_db_hash): + delete_dir(DATA_DIR / 'SigID') + unpack_tar(latest_db_tar_path, DATA_DIR / 'SigID') + self._parent.load_db('SigID') + self._show_popup_db_download_complete() + else: + self._show_popup_db_hash_failed() + delete_file(latest_db_tar_path) + + + def _show_popup_db_update(self): + """ Prompts the user to download the updated version of the database. + """ + self._parent.dialog_download_db( + Messages.DIALOG_TYPE_WARN, + Messages.DB_NEW_VER, + Messages.DB_NEW_VER_MSG.format(self.remote_db_version) + ) + + + def _show_popup_art_update(self): + """ Prompts the user to download the updated version of the database. + """ + self._parent.dialog_download_artemis( + Messages.DIALOG_TYPE_WARN, + Messages.ART_NEW_VER, + Messages.ART_NEW_VER_MSG.format(self.remote_art_version) + ) + + + def _show_popup_up_to_date(self): + """ Notifies the user that the database is up to date. + """ + self._parent.dialog_popup( + Messages.DIALOG_TYPE_INFO, + Messages.UP_TO_DATE, + Messages.UP_TO_DATE_MSG + ) + + + def _show_popup_initial_db_download(self): + """ Prompts the user to download the database for the first time. + """ + self._parent.dialog_download_db( + Messages.DIALOG_TYPE_QUEST, + Messages.NO_DB_DETECTED, + Messages.NO_DB_DETECTED_MSG + ) + + + def _show_popup_db_download_complete(self): + """ DB has been succesfully downloaded + """ + self._parent.dialog_popup( + Messages.DIALOG_TYPE_INFO, + Messages.GENERIC_SUCCESS, + Messages.DB_DOWNLOAD_SUCCESS_MSG + ) + + + def _show_popup_db_hash_failed(self): + """ Notify the user after detection of a corrupted database + """ + self._parent.dialog_popup( + Messages.DIALOG_TYPE_ERROR, + Messages.DB_CORRUPTED, + Messages.DB_CORRUPTED_MSG + ) From 1d795b688e5fd7dbea4045aaa19fdcc9467db638 Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Thu, 13 Jun 2024 01:54:59 +0200 Subject: [PATCH 02/10] File size request from HTTP header, handled the indeterminate size case --- artemis/resources.py | 157 +++++++++++++++++++++------------------ artemis/ui/artemis.py | 1 - artemis/ui/downloader.py | 58 ++++++++++++--- ui/Downloader.qml | 8 +- 4 files changed, 136 insertions(+), 88 deletions(-) diff --git a/artemis/resources.py b/artemis/resources.py index fcdb427..33fd87b 100644 --- a/artemis/resources.py +++ b/artemis/resources.py @@ -6635,7 +6635,7 @@ G@\x11\x10HG\x93Hp\xec\x0au\xe3\xcd\x1e\xf4\ >k\xd0\xd3b\x1eG\xb5_d\xde\xb6{\x8f\x95\xc5\ U\xaf\xbc\xfd\xe9\xb5\x9f\xe5\xe3}r\xba?\xbbI\x06\ \xfe\xfc\x0f\xf4\xcd*2\ -\x00\x00\x06\x95\ +\x00\x00\x070\ i\ mport QtQuick\x0d\x0ai\ mport QtQuick.Wi\ @@ -6674,75 +6674,84 @@ ceived\x0d\x0a \ progressBar.to =\ bytesTotal\x0d\x0a \ }\x0d\x0a\x0d\x0a functi\ -on updateStatus(\ -arg) {\x0d\x0a \ -progressLabel.te\ -xt = arg\x0d\x0a }\x0d\ -\x0a\x0d\x0a Page {\x0d\x0a \ - id: page\x0d\ -\x0a anchors\ -.fill: parent\x0d\x0a\x0d\ -\x0a ColumnL\ -ayout {\x0d\x0a \ - id: columnL\ -ayout\x0d\x0a \ - anchors.fill:\ - parent\x0d\x0a\x0d\x0a \ - Label {\x0d\x0a\ - \ -text: qsTr(\x22Down\ -loading in progr\ -ess...\x22)\x0d\x0a \ - Layout\ -.alignment: Qt.A\ -lignHCenter | Qt\ -.AlignVCenter\x0d\x0a \ - }\x0d\x0a\x0d\x0a\ - Prog\ -ressBar {\x0d\x0a \ - id: p\ -rogressBar\x0d\x0a \ - Layo\ -ut.rightMargin: \ -20\x0d\x0a \ - Layout.leftM\ -argin: 20\x0d\x0a \ - Layou\ -t.fillWidth: tru\ -e\x0d\x0a \ - value: 0\x0d\x0a \ - to:\ - 0\x0d\x0a \ -}\x0d\x0a\x0d\x0a \ - Label {\x0d\x0a \ - id: pr\ -ogressLabel\x0d\x0a \ - Lay\ -out.alignment: Q\ -t.AlignHCenter |\ - Qt.AlignVCenter\ -\x0d\x0a }\x0d\ -\x0a\x0d\x0a B\ -utton {\x0d\x0a \ +on setIndetermin\ +ateBar() {\x0d\x0a \ + progressBar.\ +indeterminate = \ +true\x0d\x0a }\x0d\x0a\x0d\x0a \ + function upda\ +teStatus(arg) {\x0d\ +\x0a progres\ +sLabel.text = ar\ +g\x0d\x0a }\x0d\x0a\x0d\x0a \ +Page {\x0d\x0a \ +id: page\x0d\x0a \ + anchors.fill: \ +parent\x0d\x0a\x0d\x0a \ + ColumnLayout {\ +\x0d\x0a id\ +: columnLayout\x0d\x0a\ + anch\ +ors.fill: parent\ +\x0d\x0a\x0d\x0a \ +Label {\x0d\x0a \ text: q\ -sTr(\x22Abort\x22)\x0d\x0a \ - ic\ -on.source: \x22qrc:\ -/images/icons/ab\ -ort.svg\x22\x0d\x0a \ - displa\ -y: AbstractButto\ -n.TextBesideIcon\ +sTr(\x22Downloading\ + in progress...\x22\ +)\x0d\x0a \ + Layout.alignm\ +ent: Qt.AlignHCe\ +nter | Qt.AlignV\ +Center\x0d\x0a \ + }\x0d\x0a\x0d\x0a \ + ProgressBar\ + {\x0d\x0a \ + id: progress\ +Bar\x0d\x0a \ + Layout.righ\ +tMargin: 20\x0d\x0a \ + Lay\ +out.leftMargin: \ +20\x0d\x0a \ + Layout.fillW\ +idth: true\x0d\x0a \ + inde\ +terminate: false\ \x0d\x0a \ - Layout.alignme\ -nt: Qt.AlignHCen\ -ter | Qt.AlignBo\ -ttom\x0d\x0a \ - onClicked:\ - { onAbort() }\x0d\x0a\ - }\x0d\x0a \ - }\x0d\x0a }\x0d\ -\x0a}\x0d\x0a\ + value: 0\x0d\x0a \ + to: \ +0\x0d\x0a }\ +\x0d\x0a\x0d\x0a \ +Label {\x0d\x0a \ + id: pro\ +gressLabel\x0d\x0a \ + Layo\ +ut.alignment: Qt\ +.AlignHCenter | \ +Qt.AlignVCenter\x0d\ +\x0a }\x0d\x0a\ +\x0d\x0a Bu\ +tton {\x0d\x0a \ + Layout.a\ +lignment: Qt.Ali\ +gnHCenter | Qt.A\ +lignBottom\x0d\x0a \ + text\ +: qsTr(\x22Abort\x22)\x0d\ +\x0a \ + icon.source: \x22q\ +rc:/images/icons\ +/abort.svg\x22\x0d\x0a \ + dis\ +play: AbstractBu\ +tton.TextBesideI\ +con\x0d\x0a \ + flat: true\x0d\ +\x0a \ + onClicked: { on\ +Abort() }\x0d\x0a \ + }\x0d\x0a \ + }\x0d\x0a }\x0d\x0a}\x0d\x0a\ \x00\x00\x05\xac\ i\ mport QtQuick\x0d\x0ai\ @@ -7293,12 +7302,12 @@ qt_resource_struct = b"\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03<\x00\x01\x00\x00\x00\x01\x00\x01>\xe2\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\x9f\xdf\ +\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xa0z\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01I\x0c\ \x00\x00\x01\x8f\xff^8_\ \x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99F\ -\x00\x00\x01\x90\x03\xb0\x82B\ +\x00\x00\x01\x90\x0e\xde\xeeO\ \x00\x00\x03X\x00\x02\x00\x00\x00\x04\x00\x00\x00+\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01v\x14\ @@ -7317,13 +7326,13 @@ qt_resource_struct = b"\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x05\x06\x00\x00\x00\x00\x00\x01\x00\x01\x85\xad\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa8\x92\ +\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa9-\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xae\xd7\ +\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xafr\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa5\x8f\ +\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa6*\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xabU\ +\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xab\xf0\ \x00\x00\x01\x8f\xff^8_\ " diff --git a/artemis/ui/artemis.py b/artemis/ui/artemis.py index f55fe3d..7506138 100644 --- a/artemis/ui/artemis.py +++ b/artemis/ui/artemis.py @@ -226,7 +226,6 @@ class UIArtemis(QObject): self.downloader.finished.connect(self.update_manager.post_download_db) self.downloader.on_start( self.update_manager.remote_db_url, - self.update_manager.remote_db_size, DATA_DIR ) diff --git a/artemis/ui/downloader.py b/artemis/ui/downloader.py index 99f42ad..c2f9e7e 100644 --- a/artemis/ui/downloader.py +++ b/artemis/ui/downloader.py @@ -1,3 +1,5 @@ +import requests + from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtCore import QObject, Slot, Signal, QUrl, QSaveFile, QDir, QIODevice from PySide6.QtNetwork import QNetworkReply, QNetworkRequest, QNetworkAccessManager @@ -7,11 +9,12 @@ from artemis.utils.constants import Messages class UIDownloader(QObject): # Python > QML Signals - finished = Signal() show_ui = Signal() close_ui = Signal() update_progress_bar = Signal(int, int) + set_indeterminate_bar = Signal() update_status = Signal(str) + finished = Signal() def __init__(self, parent): @@ -25,6 +28,10 @@ class UIDownloader(QObject): self.file_url = None self.file_size = None + self.dest_file = None + self.file = None + self.manager = None + self.reply = None self._connect() @@ -37,17 +44,22 @@ class UIDownloader(QObject): self.show_ui.connect(self._window.show) self.close_ui.connect(self._window.close) self.update_progress_bar.connect(self._window.updateProgressBar) + self.set_indeterminate_bar.connect(self._window.setIndeterminateBar) self.update_status.connect(self._window.updateStatus) - def on_start(self, url, filesize, save_path): - """ Start the download of the DB taking the needed url and size from - the attributes of the UpdatesController class + def on_start(self, url, save_path): + """ Start the download process using the specified URL + + Args: + url (str): url from where download the file + save_path (str): path where to save the downloaded file """ + self.show_ui.emit() self.file_url = QUrl(url) - self.file_size = filesize + self.file_size = self._get_filesize(url) dest_path = QDir(save_path) self.dest_file = dest_path.filePath(self.file_url.fileName()) self.file = QSaveFile(self.dest_file) @@ -69,7 +81,8 @@ class UIDownloader(QObject): @Slot() def on_abort(self): - """ Stop the download when user press abort button """ + """ Stop the download when user presses the abort button + """ if self.reply: self.reply.abort() self.update_progress_bar.emit(0, 0) @@ -80,7 +93,8 @@ class UIDownloader(QObject): @Slot() def on_ready_read(self): - """ Get available bytes and store them into the file """ + """ Write available bytes to the file + """ if self.reply: if self.reply.error() == QNetworkReply.NoError: self.file.write(self.reply.readAll()) @@ -88,8 +102,9 @@ class UIDownloader(QObject): @Slot() def on_finished(self): - """ Delete reply, close the file, check the hash for integrity, - extract the database and delete the downloaded zip + """ Finalize the download process and if no errors + occurrs emits the finished signal usefulle for + a callback """ if self.reply: self.reply.deleteLater() @@ -105,10 +120,13 @@ class UIDownloader(QObject): @Slot(int, int) def on_progress(self, bytesReceived: int): - """ Update progress bar and label + """ Update progress bar and status label """ - self.update_status.emit("{:.1f} Mb / {:.1f} Mb".format(bytesReceived/10**6, self.file_size/10**6)) - self.update_progress_bar.emit(bytesReceived, self.file_size) + if self.file_size is not None: + self.update_status.emit("{:.1f} Mb / {:.1f} Mb".format(bytesReceived/10**6, self.file_size/10**6)) + self.update_progress_bar.emit(bytesReceived, self.file_size) + else: + self.update_status.emit("{:.1f} Mb".format(bytesReceived/10**6)) @Slot(QNetworkReply.NetworkError) @@ -122,6 +140,22 @@ class UIDownloader(QObject): ) + def _get_filesize(self, url): + """ Get the file size by sending a HEAD request to the URL. + If the Content-Length in HTTP headers is missing, returns None + + Args: + url (str): URL to check the file size + """ + try: + response = requests.get(url, stream=True) + size = int(response.headers.get('content-length')) + return size + except: + self.set_indeterminate_bar.emit() + return None + + def show_popup_error(self, error_msg): self._parent.dialog_popup( Messages.DIALOG_TYPE_ERROR, diff --git a/ui/Downloader.qml b/ui/Downloader.qml index 1fa57fe..039b574 100644 --- a/ui/Downloader.qml +++ b/ui/Downloader.qml @@ -29,6 +29,10 @@ Window { progressBar.to = bytesTotal } + function setIndeterminateBar() { + progressBar.indeterminate = true + } + function updateStatus(arg) { progressLabel.text = arg } @@ -51,6 +55,7 @@ Window { Layout.rightMargin: 20 Layout.leftMargin: 20 Layout.fillWidth: true + indeterminate: false value: 0 to: 0 } @@ -61,10 +66,11 @@ Window { } Button { + Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom text: qsTr("Abort") icon.source: "qrc:/images/icons/abort.svg" display: AbstractButton.TextBesideIcon - Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom + flat: true onClicked: { onAbort() } } } From 70ed158b021569c93fa3e219994b580b5809d35e Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Thu, 13 Jun 2024 02:06:45 +0200 Subject: [PATCH 03/10] Updated resources, fixed typo --- artemis/resources.py | 2 +- artemis/ui/downloader.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/artemis/resources.py b/artemis/resources.py index 33fd87b..52a7e64 100644 --- a/artemis/resources.py +++ b/artemis/resources.py @@ -7307,7 +7307,7 @@ qt_resource_struct = b"\ \x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01I\x0c\ \x00\x00\x01\x8f\xff^8_\ \x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99F\ -\x00\x00\x01\x90\x0e\xde\xeeO\ +\x00\x00\x01\x90\x0e\xe3\x1a\x8a\ \x00\x00\x03X\x00\x02\x00\x00\x00\x04\x00\x00\x00+\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01v\x14\ diff --git a/artemis/ui/downloader.py b/artemis/ui/downloader.py index c2f9e7e..87754dd 100644 --- a/artemis/ui/downloader.py +++ b/artemis/ui/downloader.py @@ -103,7 +103,7 @@ class UIDownloader(QObject): @Slot() def on_finished(self): """ Finalize the download process and if no errors - occurrs emits the finished signal usefulle for + occurs emits the finished signal usefulle for a callback """ if self.reply: From 146a5d160560ddf76d1b3c0d1ad99d78f5013888 Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Thu, 13 Jun 2024 14:40:07 +0200 Subject: [PATCH 04/10] First implementation of the auto update for windows --- artemis/resources.py | 375 +++++++++++++++++---------------- artemis/ui/artemis.py | 16 +- artemis/ui/downloader.py | 1 + artemis/utils/constants.py | 3 +- artemis/utils/network_utils.py | 135 ------------ artemis/utils/update_utils.py | 23 +- ui/Artemis.qml | 22 +- 7 files changed, 235 insertions(+), 340 deletions(-) delete mode 100644 artemis/utils/network_utils.py diff --git a/artemis/resources.py b/artemis/resources.py index 52a7e64..d271e35 100644 --- a/artemis/resources.py +++ b/artemis/resources.py @@ -5159,171 +5159,174 @@ z7\x80\xec$\xf4c9\xf2\xd1\x8f4\xc6\xbc>\xb8\ \x116\x9d`\x1e\x97*W\xd9M\xe1\x09\x12\xa5\xfc\xda\ h;Q\xfc\xeb\x9c\x87 J\xfd\xc5\xd0c0\xc6[\ \xf7\xe4\x19\xd3~\xf5\xc8?\xf0\xff?E#\xf2\xe8\ -\x00\x00\x0a&\ +\x00\x00\x0a[\ \x00\ -\x002Ox\xda\xcd\x1ako\xdb8\xf2\xfb\x02\xfb\x1f\ -x\xfe\xb0\xb5osr\xdaC\x80=\xef\xe6\x80\xc4\xce\ -\xc3@\x92f\xebl\x8bCQ\x14\xb4D\xdb\xbc\xd0\xa2\ -\x96\xa2\xe2d[\xff\xf7\x9d!%\xeb-\xcbN\xf6z\ -n\xe1X\xe4\x0c9/\xce\x8b\xe2\xcb@*M~\xd5\ -\xbfF\xdc\xbd\xff\xfe;\x9e{v>p\xdf\x93\xab\xd2\ -\xf0P\xfaZI\x11\xd6N8\xd7T3\xc5\xa9(A\ -\x5c\xd1'\x19\xe92\xe6\x08\x80\xe5\x1c\xc6\xf1\x9f\xdd\x96\ -|\xf9\xfe;\x02\x1f\xee\x0d\xc8*&\x04\x9fW\xdc\xd3\ -\x8b\x01y\xfd\xfa\xf0\xd0\x0e,\x18\x9f/\xf4\x80\xfc\x84\ -\x03vh(ay\x9f\xf9\xda\x91>\xfe\x16L3X\ -&^\x11?\x8f\xe4\x98L\x5c\xc5\x98\xef\x98\x05I\x9f\ -\xbc!\xff \x9b\xdf)\xe4S\x0aiw\x8aA\xd3\x07\ -\x0b\xbbN6\xd7\x5c\x0b6 \xbf\x87w\xaa\xdb9Q\ -\x9a-y\xd8\xe9\xd9\xb9\x07\x1e\xf2)\xcej\x151;\ -d\xbf\x97\xd2\xa3\x82\xeb\xa7\x01\x88\xc49\x09\x02\xc1]\ -\xaa\xb9\xf4\xafq\xdc\x82\xcc\x04\x9d\x87f\xfeCF\x1c\ -\xf6\xbb\xdf'v0\x04\x16\xf4\x02dL\xa2 `\x8a\ -L\xa9J R\xfcsE\x97L\xb00\xb48\x97\xdc\ -\xd7\x09\xf1!\x9f\xfbT\x10!\xa971?\xbb0\x19\ -\x8f\x8e\xbd^\x0e(\x5c\xc8\xd5\xadb\xb3nyxt\ -\xba\xa4>\x9d3U17\xa4\xfa\xbarR\x06\xcc\x87\ -M\xcf<\xae\xa5\xea\x86Zq\x7fN\xf4S\xc0\x0e\xc8\ -\x03U\x08\xf59\xa0@\xfa\x01\x99J)\x08\x0f?\xfb\ -lU^\x7f\x12P\x97}`T/J;\xb8\x0b\xe6\ -\xde\x8f\xa6\xbf\x05\x1e\x18hX\xa4MS\xa5Gr\xe5\ -#\xf3\x95\xc4\x8d\xa6#\xae\x98\x0b\xd4=\x15f\x81\x90\ -\xd14!\xd9\x07\xe9\xe6\xa7\xd9#Z{\x0a\x11\x00q\ -y\x08{\x1eJ\x10\x16&P\xb0\xbb\xd2OF\x0c\x86\ -:\xef\x8a\x87\x1b\x9d\xcd\x22\xdfE[!\x81\x0c\x22\x01\ -\x9c\xe1d\xd7.\x1c\xe2\xef^\xd6\xf2S|0\xec\x0c\ -P\x0a\xa1\xd9\xa3>\xe7Lx\x13F\x95\xbbp\x98O\ -\xc1f=\x00O\xad\xd6\x183P\xe3FJ\xc19\x1b\ -\xfb\x1e\xc3#%`\xa1\xf7\x9c\xad\x9c\xecx\x8a\x01\xc6\ -\xa2X\xb80\xf4\xf5\xd2a\xb0\xde\x09\xd3\x04\x14\x96_\ -oJ\xdd{Bg\xe0K\x12Lc\x11\x00&r\x04\ -\xf3\x19\xe9\xe6\x10\xff}L\x0e\xc9\x0f?\xe4W\xfb\xc5\ -`\xc1\x81b\xc2qe\xe4\xe7\xc5bDSE=p\ -U\xcd\xcc\xbap\xee7j\xc8q\x99\x13}\xba\xbf\x00\ -\xd1fE0\x93\x8atQ\xa0\x1c\xf6;\xfc\x19\xfe\xfc\ -\x92\xd1\x94#\x98?\xd7\x0b\x18\xfe\xf1\xc7\x12\xd5\x88\x85\ -&\x87\xe2\xdf`|\xe4\x9f\x1c\x1ct\xb4\xbc\x92+\xa6\ -\x864d\xd9\xfd\x12D\x8f\x85\xae\xe2\x81\xa1\xbb\x88\x9f\ -\x99\xdb\xb6Lh,\x05-\xa4`;\xf8\xdc\x84\x8c\xaa\ -3tr\xdf\x15\x11\xec\xd8\xb5K\xf5\xc8\xd7\xafY\xe2\ -J\xf3%1\xe4\x05L\xc1\xfb\xf9^7\xc7Pa\xeb\ -uI\x95\x86 \xf0\xd7\xc3\x05\xf5\xe7\x16-\xa1\xb7\xac\ -\xe5\x12`\x96 +\x13\x01\xbe\x82y\x9f\xe1\x90\xc5G\ -\xc3\xd26g\xba[ij\xbd\xbcI\xe7\x16\xf8\xdb\xf1\ -1\x89\x00h\xc6}\xe6\x95-7\xf5\xd7m\xf6q&\ -\xe3\x8b\xcf\xe3QA \x0c\x1c\xaf]\xe4\x9a\xf9Q\xed\ -\xb1_\x13&BV\xa4\xa0\x16y\x06\xfe\x85\xb585\ -\xe6H\xectfr\x9e\xec\xe3\xa7z\x07V\xc2\xac\xf7\ -p\x19j\xcb$\x0a\xe9\xde#w]-\xe7s\xc1r\ -t\xa2\xc2*\x86\xf1\x83\xa1\xe3\x9c\x0b\xd6,\x18#D\ -\x13'\xda\xc1B\xc8i#\xefD7\x10u\xd9\x1c\x02\ -\xd7\x16\xedT\xea\xb6\x86\x81\xbcY4\xd2_\x06\xad#\ -\xbfb\xd1z\xea\x0b\x86Y\xa7\xb7\xa9\xd4Z.\xc7\xfe\ -L\x9e\x82\x1d,!\xf1\x81\xec\xe3\x80\xc4?\xee \xc3\ -\xc8\xe9,\x05\xbf\xa2S0<\xb4\x16\xd8,\x06O\xe1\ -BH\xb5\xc0\xe9u\xeb\xd6q\xc1\xdf\x91\xce\x8a*\x1f\ -\xc2Vg\x90\xe7\xaa\xb8\x89+\x05\x84\x80c\x92\xa4\xce\ -v\xa0\xbby|\xc7\xbc\xc2q\x9d*F\xef\x8b\xbbq\ -Xp\xe7\xad \xf8\xb0\xb9\x82\x90\xe85\xeeP+_\ -\xb4\x8f\x0b\xe63E\x85M\xe4\xb3\x229\xb0\x09\xf1F\ -\xdc9\x11y\x06<\xc6u2X\xa9\xbc\xf1\xa9\x0e\xc1\ -\xac\x8cv\x80\x7f\xb7\xacZ\xa5\xc1< \xb2Q\xef\xef\ -M\x02h\xe0\x93\x1c\x11\xb2\xb5\xdd\xf8L\x11\xdb\xb3\x9a\ -\xc1i\xe4\xb6\xbcv=\xc3\x19\xd8]y\x8e\xeb\x99=\ -\x19\x8f\xb1w\xe7>Al%\x82\xc2.\xdb\xe5\x90 \ -T\x0a\xc3\xf2\x7f\x1d\xaf\x95\xf5\xf8PQ\x16\xe5\x99\xce\ -\x9a\x82.\xa9\xf32>CS\xdf\xa3\xca;\x8d\xe0L\ -\xfaP\x8e\xd9\xe5\x9d!\xf5]&\xc8\xd7\xe4\xf9?,\ -\xcc\xa2I\xff\xc4uYP\xacb\xe3\x15\xab\xca\x96\xaa\ -\x03\xbb\x03+\xb1H\xbe\x01?P\x9f\xa2\x1e~S\xe2\ -\xec\x11\xfc\x13D\x08\xf1\xd4\xed,\xb4\x0e\xc2A\xbf?\ -\x87\xea6\x9a\x82\x0b[\xf6O \xc9~\x0f\xb3\xec\xa9\ -_\xa8\xb2\xf7\xe4=\xf6\x03{\xf3\xfc\xf6\xber\xcf\xea\ -\xcdn\xb0b\xcc\xae\xfa8 ](o\xb1ia\xbb\ -\x10q7\xa2WhG\xa4`q\x07\x22iE\xc4\x80\ -5\xe4o\xc2\x84\x90!\xbb\x95\x82\xbb\xb0\xd2-\x14\x8c\ -\x81s#O\x22-\x878\xd1\x8e\xcdT\xadV\xcdY\ -\xac\xa1\x14\xd1\xd2\xb7}\x9e\xa2j\x01x!U\xe8\xcc\ -\xb8\x00\xba,\x17y\x08\x13\xa0\xaa2{\x8c\xc1IO\ -\xe5\xcc\xc7\x8a\x10\xcb@S\xf6\xc8\x99\xfd\xcdV\x04\xca\ -z:\x8588\xe8\xf4\xcaKX\x9a\x1c\x1b\x0d\xaf\xa9\ -\x9as\x7f@^\x1f\x95\x01g\x12\x84\x1bH\xeeCB\ -\xfb\x07\x03\x987\xb5\x85\x03~\xee\x92d\xb2\x8anT\ -\xb8i\x0e\xdc\x00\xa9\xb54\xa1@>\xd8\xbeV9\xff\ -1\x1d\x00A]\xb6\x90\x02\x0e\xf8]F\x12\xb8h\xa7\ -\xb1\xaciu\xe4l\xf7bC\xa6Ix\x1a\x8e\x12\xe6\ -w\xd5\xa6\x1d\xf79\xcc\x5c&\xdb\xb6\x0d\xb1\xce-\xa4\ -\xe1\x90\xa3\x80\x0d\x80\xa5\x11JB\xfa\xc0@\xd8\xc8\x94\ -\xe38\x9dL1\x8c\x09$\xe4\xfc\x83\xccV\xce\x04\xa0\ -\xf11\x05C\xed\xc3\x08\x18\x03\x18\xe7\xc7\xce\x09d\xf2\ -\x1cV\xec:\xe0\x11{\x9dO-\x99O{3q\xb9\ -\x85\x9b\xec\xc5}\xdc\xc3i\xc9\xfd\x03\x15\xdc#@\xaa\ -3\xff\x83PK{\x0b1\xbc\x8ds\xf1\xedb\xf8\xfb\ -nrH;P\xed\xe4p2-\x9cp\x14\x01\xc5\xc1\ -\xac\x046\xe0\xb7\x05\xb7\xdb\xec\x0b\x04\x9b\xe9[\xeay\ -\x908\xc3\xf9;,\xe6\xe6\xb9\xa9tr\xc10\x02\x0e\ -\x08V\x09\x90\xe9\x978\x04\x02\xb5\x0cN\xb1%\x9a\x9f\ -A\x84J\xaf\x93m\xe5\xa2<:\xbd\x22j\x82>\x86\ -\x08T\xb5D\xea\xbc:\xe0\xf2\xc9(\xf6PyM\xe7\ -\x8a-\x7f\x08\xce\xf9\xdeh(\x13*\xe2\xe4d]F\ -Z?\x83\xa4+\x08\xf5;\xd2Th\xef\xeeB\xd0\x84\ -a\xffVC\xf1\xf1e/\xa2\xd3C\x96\x94\x98\x8d\xcc\ -\x8d\xed\x1dC\xc2^\x0b\xde\xb2'\xf8\x85\x05\x9e\xba\xc7\ -V\xb4\x9f=\xeeJ{\xd6\xf7\xd6\xd3n<\x9e\xad\x9f\ -\x07U\xad\x82\xbf\x5c\x7f\xc5j\xbeY\x0a\x00L\xee\xe8\ -~:0\x89\xec\xcbz\xcf\x5c\ -\x87\xf9\xd9<\x22\xd1\xce\xb3\xb94\xfb\xd4\xb0\xb9\x97\xd5\ -\xe4\xad\x02\xaf2I|\x97\xf9\xac\xdcc\x887\x9f\xe4\ -\x1d\xc3\x18\xd1\x82\xe5j\x08S\x15\xd6\xdc\xb0n\xe1\xff\ -9\x22\xd9$\x96-\xce\xd1%\x13\xc1\x0b\x08\x0a\xaf\xe3\ -\xe2[\xe2\x16\xd2*^+\xff/s\xa2\x8d\xd7\x95\xff\ -\x05\xa7O.\xe5\x12\x16\x9c\xb7I\x18*\x1b-\xaf\x92\ -F\x0b$\xe4\xe1\x83\xe9\xae\x98f\xcb\xab\x97\xf6\xcf#\ -\xe9FK\xc8\xf9\xcd[\x0e\xcf\xa66\xed\x059q\x87\ -\x88\xcb\xa4+\xf4\xe2\xa4O\xe0\x08\xc0Q\xb2\xf5\xdc\x8d\ -lg#\xcd\xf47\xb6\xb5\xfaS!\xa7\xfd%\x0d\x01\ -\xaf?\xbc<\xb9\xb98\xbbz{\xe1,\xbdW\xdf\xc2\ -\xd2\xac\x0f!\xe30\x8c\xd8_\xcc7\xc7=\xc2o\xc2\ -\xa5\xa9n\x9f\xe5(3\xa5p\xae\xb1\xbc\x97\xa3\xacd\ -{&\xc1\xf6\xa0\xdc\xadl\x9a\xa1\xd3,\x5c\xfc\xe4\x01\ -l\x97\x8b?2Q\xdd\xe5\xca\x95\xe0\x85.\x99\xc2~\ -c\xddd\xa1D?\xaa\xa1\xfe\x9d\x5c\xed\xdb%\x0c!\ -\xfeT\x94\xff\xdb\xda\x8f\x99\x86\xdb\x92>\xf2e\xb4\x8c\ -{no\x8e\x0e\xabL\xa5\xb1\xb1\xb7i(\xe4\xaf\x92\ -\xab\x01\xe3]\x03\x93\x1a+\xe6]\xc6\xaf\xac\xfd\xf3_\ -\x8d\xf0Z\x06I\x9f\xf2h\xff|\xa7\xae\xc7X\x0d]\ -\xd3i\xb4\xdcuzu'\x02a\xe3\xb7!\x1aOE\ -\xcd\x1b@\xdb\x0fDy0g@5\xac\xc7o?4\ -Q\x84JL\xde\x92\xa8\x87j\xdb\xa8\xad\x80O\x94\xdd\ -\x8c\xb0\x00 \x81\x80\xd7\xf2\x81\x8d\x22e\xe2\xe2\x80\x1c\ -\xd6c\xb8\x82\x07\xdbV\x9dA\x94\x0d\xb7\x01M\x5c%\ -\x858\xa5\xcay`Js\x17/\x0d6\xef\x0d6\xd2\ -:\x800\xe8j\xd0\xba`\xe4\x0b1\xf7\xca\x83\xf4Z\ -\x99\xba.\x1c\xdd\x9f\x89\xa2\x1eG*\x8e\xc8\xba~M\ -p\xaa\x997TRS\xaax\xcf\xa6a\x15\x0f\xa2\xf2\ -\x1c\xf6\x1f\x90&\x1f_T\xfd(\xc6j\x86\x8e_<\ -Ml\xcay\xc0/3\xd8\x8c\x97\xbc\x9f\xfa\xe6\xb0\x19\ -.v\xe36\x00aSw\xdd\x0c\x7f-\xa3\x90A\xd4\ -\xa4\xdb\xd8l\xe7T\xb7D\xba\xbaw\xe3x\xfe\xa5\xb8\ -\x96\x07\xba\xc5\xd4\x12_\xfa\xb1\xe26\xef\xff\xb4U\xa6\ -\x01\xdey\xc7u\x9d\x0b\xd9\x1c\x8em>\xa4\xf1\xc4\xec\ -\xec\x0e\xa8\xab\xf9\x03k\x82\xda\xa3\xc0j\x19\x1c)\x9c\ -m\x1fss\xfb22>]A2@\xben\x1e\xef\ -d\xd0x\x97\xd5\xccc\xfb\x80tG\xa7\x0d\x927\xe1\ -\xd7@\xbcD\xe0\xc3\xbd\xccMg\x93\xa2\xb3\xd7\x90\x93\ -\xf1\xc5\xcd\xc9U\xa7\xb7\xa3A\xed\xbc\xcf\xf9\xf8\xea\xee\ -\xec\xdd\xa4\xf3\xccp9\xd1\xd4\xbd\xaf\xd7\xbd\x89(\x99\ -\xa3\x9d\x88\xb6\xe6M\xdevfs9d\xe6\xae6\xb5\ -\x9c\xf7vd\xab\xc2\xb6\x9f\x92\xdd\xb4\xbb-\x1c\xd8\xa6\ -N\xf1\x92\xaa\xce\xea\xc2\x0d\xf4\xcb9\x9am\x14\xda+\ -\xbe\xb6\x14\xce6\xd0\xfbP\xb8SA\x12\xff\x81\xff\x7f\ -\x02\xa7\xa1\xa9K\ +\x003#x\xda\xcd\x1ako\xdb8\xf2\xfb\x02\xfb\x1f\ +x\xfe\xb0\xb5osJ\xdaC\x81=w{@j\xa7\ +M\x80$\xcd\xd6i\x8bCQ\x14\xb4D\xdb\xbc\xd0\xa2\ +\x96\xa2\xe2d\xdb\xfc\xf7\x9d!\xf5\xa2^\x96\x93\xf4\xf6\ +\xdc\xc2\xb1\xc8\x19r^\x9c\x17\xc5\xd7\x91T\x9a\xfc\xa6\ +\x7fK\xb8\x7f\xf5\xe3\x0f\xdcy\xf6>\xf20\x90\x9b\xda\ +\xf0D\x86ZI\x11\xb7NxgT3\xc5\xa9\xa8A\ +\x9c\xd2[\x99\xe8:\xe6\x14\x80\xe5\x12\xc6\xf1\x9f\xdd\x96\ +|\xfd\xf1\x07\x02\x1f\x1e\x8c\xc9&%\x04\x9f7<\xd0\ +\xab1y\xfa\xf4\xe0\xc0\x0e\xac\x18_\xae\xf4\x98\xfc\x82\ +\x03vh\x22a\xf9\x90\x85\xda\x93!\xfe\x16L3X\ +&]\x11?7\xe4%\x99\xf9\x8a\xb1\xd03\x0b\x92}\ +\xf2\x8c\xfc\x83\xe4\xbf\x0b\xc8\xdb\x02\xd2\xee\x94\x82\x16\x0f\ +\x16\xf6.\xdb\x5cs-\xd8\x98\xfc\x1e_\xaa\xe1\xe0P\ +i\xb6\xe6\xf1`d\xe7\xaey\xcc\xe78\xabU\xc2\xec\ +\x90\xfd^\xcb\x80\x0a\xaeo\xc7 \x12\xef0\x8a\x04\xf7\ +\xa9\xe62<\xc3q\x0b\xb2\x10t\x19\x9b\xf9\x8f%q\ +\xd8\xef\xfd}b\x07c`A\xaf@\xc6$\x89\x22\xa6\ +\xc8\x9c\xaa\x0c\xa2\xc0\x7f\xad\xe8\x9a\x09\x16\xc7\x16\xe7\x98\ +\x87:#>\xe6\xcb\x90\x0a\x22$\x0df\xe6\xe7\x10&\ +\xd3\xd1\x93`\xe4\x00\xc5+\xb9\xb9Pl1\xac\x0fO\ +_\xadiH\x97L5\xccM\xa8>k\x9c\x94\x11\x0b\ +a\xd3\xa3\x80k\xa9\x86\xb1V<\x5c\x12}\x1b\xb1=\ +rM\x15B}\x89(\x90\xbeG\xe6R\x0a\xc2\xe3/\ +!\xdb\xd4\xd7\x9fE\xd4g\x1f\x19\xd5\xab\xda\x0e\xfe\x8a\ +\xf9W\xd3\xf9\xfb(\x00\x03\x8d\xab\xb4i\xaa\xf4Tn\ +Bd\xbe\x86\x9a\x18\x9cT\x9d\x0d\x84O\xe7S\xae\x98\ +\x0f\x94\xdfVf\x81\xc8\xe9\x15\x05>\x18}\x09\xa8\x80\xd0\xecF\xbf\xe6L\x04\ +3F\x95\xbf\xf2XH\xc1\x9e\x03\x00/,\xda\x18:\ +P\xe3'J\xc1\x19<\x09\x03\x86\xc7M\xc0B\x1f8\ +\xdbx\xe5\xf1\x02\x03\x0cI\xb1xe\xe8\x1b\x15\xc3`\ +\xd93\xa6\x09(\xd3]oN\xfd+B\x17\xe0g2\ +Lc-\x00&\x1c\x82\xf9\x82\x0c\x1d\xc4\x7f\xbf$\x07\ +\xe4\xa7\x9f\xdc\xd5~5Xp\xd8\x98\xf0|\x99\x84\xae\ +X\x8ch\x9a\xa8\x07\xae\x9a\x99\xb9\xab\xf8\x84\x5c\x0d\x0e\ +\x97\x8e\xe8\x8b\xfd\x05\x88\xb6,\x82\x85Td\x88\x02\xe5\ +\xb0\xdf\xc1\x0b\xf8\xf3kIS\x9e`\xe1R\xaf`\xf8\ +\xe7\x9fkT#\x16\x9a\x1c\x8a?\xc7\xf8\xc4?{8\ +\xe8iy*7LMh\xcc\xca\xfbe\x88\x01\x8b}\ +\xc5#Cw\x15\xbf4\xb7m\x99\xd8X\x0aZH\xc5\ +v\xf0\xb9\x0b\x19Ug\xe8\xe4\xa1/\x12\xd8qh\x97\ +\x1a\x91o\xdf\xca\xc4\xd5\xe6kbp\x05L\xc13\x86\ +\xc1\xd0a\xa8\xb2\xf5]M\x95\x86 8\xfc\x93\x15\x0d\ +\x97\x16-\xa3\xb7\xae\xe5\x1a`\x99 +\x13\x01\xbe\x82\ +\x05_\xe0\x90\xa5G\xc3\xd2\xb6dz\xd8hj#\xd7\ +\xa4\x9d\x05\xfe\xf6\xf2%I\x00h\xc1C\x16\xd4-\xb7\ +\xf0\xe5}\xf6\xf1f'o\xbe\x9cL+\x02a\xe0\x94\ +\xed\x22g,LZ\x8f\xfd\x1da\x22fU\x0aZ\x91\ +\x17\xe0_X\x8fSc\x8e\xc4Ng\xc6\xf1d\x9f>\ +\xb7;\xb0\x1af\xbb\x87+Q['QH\xff\x0a\xb9\ +\x1bj\xb9\x5c\x0a\xe6\xd0\x89\x0ak\x18\xc6\x0f\x86\x8e\xd7\ +\x5c\xb0n\xc1\x18!\x9a8\xd1\x0f\x16BN\x1fyg\ +\xba\x81\x88\xcc\x96\x10\xb8\xb6h\xa7Q\xb7-\x0c\xb8f\ +\xd1I\x7f\x1d\xb4\x8d\xfc\x86E\xdb\xa9\xaf\x18f\x9b\xde\ +\xe6Rk\xb9>\x09\x17\xf2\x15\xd8\xc1\x1a\x92\x22\xc8L\ +\xf6H\xfa\xe3\x12\xb2\x0fGg\x05\xf8)\x9d\x83\xe1\xa1\ +\xb5\xc0f)x\x01\x17C\x1a\x06No\xd8\xb6\x8e\x0f\ +\xfe\x8e\x0c6T\x85\x10\xb6\x06c\x97\xab\xea&\xbe\x14\ +\x10\x02^\x92,\xad\xb6\x03\xc3\xfc\xf1\x1d\x0b*\xc7u\ +\xae\x18\xbd\xaa\xee\xc6a\xc1\x9d\xb7\x82\xe0\xc3\x96\x0aB\ +b\xd0\xb9C\xab|\xd1>\xde\xb0\x90)*l\x92_\ +\x16\xc9\x9eM\x96sq;\x22\x0a\x0cx\x8a\xeb\x95\xb0\ +\x0ay\xe3S\x1b\x82Y\x19\xed\x00\xffnY\xb5I\x83\ +. \xb2\xd1\xee\xefM\x02h\xe0\xb3\xfc\x11\xb2\xb5\xdd\ +\xf8,\x10\xfb\xb3Z\xc2\xe9\xe4\xb6\xbev;\xc3%\xd8\ +\xbe<\xbfwR\xe3\x0e\xb6\xf7\x08M\xb4l`\xdeY\ +\xa1?\xff.Z\xa7\x08\x1awh\x97\x82\x0b\x8eT\xdb\ +\x11\xc0\xc0\x87n\xf0F\xb9YQ\x9d\xa5\x1b\x97\x83\x03\ +\x14\xa6U\xd1\x17\xb3\xa6.\xcc\xca\xc5\x92{\xd14\x0c\ +\xa8\x0a^%p|C\xa8\xea\xec\xf2\xde\x84\x86>\x13\ +\xe4[\xf6\xfc\x1f\x16\x97\xd1dx\xe8\xfb,\xaa\x16\xc3\ +\xe9\x8aM\xd5O\xd3\xd9\xee\xc1\x8a#\x90\xad\xdc\xe45\ +\x8c\xa9\xeb\x0ai\x7f_\x8e1*\x17{5\xe6\x8c\x95\ +\xa2\xefE%Il\x0c\x88\xf8\x81\x1a\x1b\x8d\xe0\xbd\x12\ +G7\xe0G!\x92\x89\xdb\xe1`\xa5u\x14\x8f\xf7\xf7\ +\x97P\xa1'sp\xb5\xeb\xfdC(\x06>\xc0,\xbb\ +\xdd\xcf;\x05/\xb6\xa5\xa2\xbb(\x22\xf5_\xf76\xa8\ +\xb7W\x8d{6ov\x8e\x95ny\xd5\x9b1\x19B\ +\xc9\x8e\x8d\x18\xdbYI;,\xa3J\x8b\xa5\x00K\xbb\ +*Y{%\x05l!?\x0foB\xc6\xecB\x0a\xee\ +\xc3J\x17P\xe8F\xde\xb9<\x04\xd5Np\xa2\x1f\x9b\ +\x85\x05Y\x8b*cM\xa4H\xd6\xa1\xed]U\xd5\x0d\ +\xc0+\xa9bo\xc1\x05\xd0e\xb9p!L`m\xb2\ +\x12\xcc\x1d\xb2>\xd1Q\x88\x95,\x96\xaf\xa6\x5c\x93\x0b\ +\xfb\x9bm\x08X \x9dC\xfc\x1e\x0fF\xf5%,M\ +\x9e\x8d\xe2gT-y8&O\x9f\xd7\x01\x17\x12\x84\ +\x1bI\x1eB\x22\xfe\x07\x03\x98g\xadV\x86\x9f\xcb,\ +\x09n\xa2\x1b\x15n\x9a\x1a\xe7@j+M(\x90\x8f\ +\xb6WW\xcf\xdb\xcc\xa9\x17\xd4g+)\xc0\xdb\x5c\x96\ +$\x81\x8b\x0e:\xcb\xb1^\xa7\xdbv]r2M\xa2\ +\xd6\xe1\xd30/m6\xed\xb4?c\xe6JU\x82m\ +\xf2\x0d.\xa0|\x00\x1f\x006\x00\x96F(\x89\xe95\ +\x03a#S\x9e\xe7\x0dJE<&\xbeP\xab\x8cK\ +[y3\x80\xc6\xc7\x02\x0c\xb5\x0f#`\x0c`\x9c\x9f\ +\x06\x87P\x81pXq\xe8\x81{\x1e\x0d>\xf7d\xbe\ +\xe8)\xa5e\x22nr/\xee\xd3\xdeSO\xee\xaf\xa9\ +\xe0\x01\x01R\xbd\xe5\x1f\x84Z\xda{\x88\xe1mZC\ +l\x17\xc3\xdfw\x93C\xd19\xeb'\x87\xc3y\xe5\x84\ +\xa3\x08(\x0e\x96%\x90\x83_T\xdcn\xb7/\x10l\ +\xa1/h\x10@\xc2\x0f\xe7\xef\xa0ZS8S\xc5\xe4\ +\x8aa8\x1e\x13\xacn\xa0B\xa9q\x08\x04j\x19\xbd\ +\xc26\xaf;\x83\x08\x8d^\xa7\xdc\x9eFy\x0cFU\ +\xd4\x0c\xfd\x04\x22R\xd3\x12\x85\xf3\x1a\x80\xcb'\xd3\xd4\ +C\xb9\x9av\x8a\xc4p\x02\xce\xf9\xcah\xa8\x14*\xd2\ +L\xe9\xae\x8et\xf7\x00\x92N!\x81\xd9\x91\xa6J\xcb\ +z\x17\x82f\x0c{\xd2\x1a\x8a\xa6\xaf\xf7\x22\xba8d\ +Yi\xdc\xc9\xdc\x89\xbd7\xc9\xd8\xeb\xc1[\xf9\x04?\ +\xb2\xc0\x0b\xf7\xd8\x8b\xf6\xa3\x9b]i/\xfb\xdev\xda\ +\x8d\xc7\xb3u\xff\xb8\xa9\xc5\xf1\xdd\xf5W\xedBtK\ +\x01\x80\xc9%]\xc6=\xed\xb2|]\xf2\xff\xc8|\xb9\ +\x01\xd4\xc98z\xf9\x5c\xf9\xe4\xb5\x89\x91=dP\xbb\ +\x5cyl!\xf4p)x\xcb\xc5\xc0\x9b\xfb\xac\xaf\xd6\ +\xec\xbd\xd8#{\xb6\xa3\x1b\xae{\xecooK=\x93\ +\x15\xf7\xa3\xe1\xaeo\xf0@\x85\xc7yknKp\xb1\ +=\xbc\xfb\x85\x974\xc7\x9cu\xec\xd5G\xe9n\xa4\xea\ +\x15\x0b\xdc[\xc8'\x96\x82'{\xe4\xd3\xe7=\x93\xc8\ +>\xae\xf7t:\xe3\x0f\xe6\x11\x89\xf6\x1e\xcc\xa5\xd9\xa7\ +\x85\xcd{Y\x8dk\x15x=K\xd2\xfb\xd9\x07\xe5\x1e\ +\x13\xbc\xcd%\xef\x18\xc6\x88\x1e,7C\x98\xaa\xb0\xe5\ +\xd6x\x0b\xff\x0f\x11I\x9eX\xf68G\xc7LD\x8f\ + (\xbcFLo\xbe{H\xabzU\xfe\xbf\xcc\x89\ +r\xaf+\xff\x0bN\x9f\x1c\xcb5,\xb8\xec\x9304\ +6^\x9ed\x8d\x17H\xc8\xe3k\xd3m1\xcd\x97'\ +\x8f\xed\x9f\xa7\xd2O\xd6\x90\xf3\x9b77\x1eLm\xd1\ +\x1b\xf2\xd2\x8e\x11\x97Y\x97\xe8\xd1I\x9f\xc1\x11\x80\xa3\ +d\xeb\xb9s\xd9\xcfF\xba\xe9\xefls\xed\xcf\x85\x9c\ +\xef\xafi\x0cx\xfb\x93\xe3\xc3\xf37G\xa7o\xdfx\ +\xeb\xe0\xc9_ai\xd6\x87\x90\x938N\xd8w\xe6\x9b\ +\xe3\x1e\xf1_\xc2\xa5\xa9n\x1f\xe4(K\xa5\xb0\xd3\xe5\ +\xbe\x97\xa3ld{!\xc1\xf6\xa0\xdcml\x9a\xa1\xd3\ +\xac\x5cX\xb9\x00\xb6\xcb\xc5o\x98h\xeer9%x\ +\xa5K\xa6\xb0\xdf\xd86Y)\xd1\x9f\xb7P\xffNn\ +\xee\xdb%\x8c!\xfe4\x94\xff\xdb\xda\x8f\xa5\x86\xdb\x9a\ +\xde\xf0u\xb2N{n\xcf\x9e\x1f4\x99Jgc/\ +o(\xb8W\xe0\xcd\x80\xe9\xae\x91I\x8d\x15\x0b\x8e\xd3\ +\xd7\xf0\xfe\xf9\xafNx-\xa3\xacO\xf9\xfc\xfe\xf9N\ +[\x8f\xb1\x19\xba\xa5\xd3h\xb9\x1b\x8c\xdaN\x04\xc2\xa6\ +oqt\x9e\x8a\x967\x97\xb6\x1f\x88\xfa\xa0c@-\ +\xac\xa7omtQ\x84J\xcc\xde\xeeh\x87\xea\xdb\xa8\ +m\x80\xcf\x94\xdd\x8d\xb0\x02 \x81\x80g\xf2\x9aM\x13\ +e\xe2\xe2\x98\x1c\xb4c\xf8\x82G\xdbV]@\x94\x8d\ +\xb7\x01\xcd|%\x85xE\x95w\xcd\x94\xe6>^\x1a\ +\xe4\xefBv\xd2:\x860\xe8k\xd0\xba`\xe4+1\ +\xf7\xe1\xe3\xe2:\x9c\xfa>\x1c\xdd\x17D\xd1\x80#\x15\ +\xcf\xc9]\xfb\x9a\xe0TKo\xd6\x14\xa6\xd4\xf0~P\ +\xc7*\x01D\xe5%\xec?&]>\xbe\xaa\xfai\x8a\ +\xd5\x0d\x9d\xbeL\x9b\xd9\x94w\x8d_f\xb0\x1b/{\ +\xe7\xf6\xd9A7\x5c\xea\xc6m\x00\xc2\xa6\xee]7\xfc\ +\x99Lb\x06Q\x93nc\xb3\x9fS\xdd\x12\xe9\xda\xde\ +\xe9\xe3\xee\xcb|=\x0ft\x8f\xa95\xbe\xacd\xc5m\ +\xde[\xea\xabL\x03\xbc\xf3\x8ewm.$?\x1c\xdb\ +|H\xe7\x89\xd9\xd9\x1dP_\xf3k\xd6\x05u\x8f\x02\ +\xabgp\xa4p\xb6C\xcc\xcd\xed\x0b\xd6\xf8t\x0a\xc9\ +\x00\xf9\x96?^\xca\xa8\xf3.\xab\x9b\xc7\xfe\x01\xe9\x92\ +\xce;$o\xc2\xaf\x81x\x8c\xc0\x87{\x99\x9b\xce.\ +E\x97\xaf!g'o\xce\x0fO\x07\xa3\x1d\x0dj\xe7\ +}^\x9f\x9c^\x1e\xbd\x9b\x0d\x1e\x18.g\x9a\xfaW\ +\xed\xba7\x11\xa5t\xb43\xd1\xb6\xbc\x81\xdc\xcfl\x8e\ +'\xcc\xdc\xd5\x16\x96\xf3\xc1\x8elU\xd8\xf6S\xb2\x9b\ +v\xb7\x85\x03\xdb\xd4\xa9^R\xb5Y]\x9cC?\x9e\ +\xa3\xd9F\xa1\xbd\xe2\xebK\xe1\x22\x87\xbe\x0f\x85;\x15\ +$\xe9\x1f\xf8\xff'\xb7x\xdf\xfa\ \x00\x00\x08k\ \x00\ \x00r]x\xda\xed\x5cms\x9b\xb8\x1a\xfd\xde\x99\xfe\ @@ -7292,47 +7295,47 @@ qt_resource_struct = b"\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x01\x0e\x00\x00\x00\x00\x00\x01\x00\x01\x16\xe5\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x03\xb0\x00\x01\x00\x00\x00\x01\x00\x01Q{\ +\x00\x00\x03\xb0\x00\x01\x00\x00\x00\x01\x00\x01Q\xb0\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x04\x22\x00\x01\x00\x00\x00\x01\x00\x01[p\ +\x00\x00\x04\x22\x00\x01\x00\x00\x00\x01\x00\x01[\xa5\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x03\xe6\x00\x01\x00\x00\x00\x01\x00\x01T\x98\ +\x00\x00\x03\xe6\x00\x01\x00\x00\x00\x01\x00\x01T\xcd\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03\x12\x00\x01\x00\x00\x00\x01\x00\x019\x8e\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03<\x00\x01\x00\x00\x00\x01\x00\x01>\xe2\ +\x00\x00\x01\x90\x11\x9a\x93$\ +\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xa0\xaf\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xa0z\ -\x00\x00\x01\x8f\xff^8P\ -\x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01I\x0c\ +\x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01IA\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99F\ -\x00\x00\x01\x90\x0e\xe3\x1a\x8a\ +\x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99{\ +\x00\x00\x01\x90\x11U\xb4\x08\ \x00\x00\x03X\x00\x02\x00\x00\x00\x04\x00\x00\x00+\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01v\x14\ -\x00\x00\x01\x90\x0eV\xebx\ -\x00\x00\x05d\x00\x01\x00\x00\x00\x01\x00\x01\x8f*\ +\x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01vI\ +\x00\x00\x01\x90\x11U\xb4\x08\ +\x00\x00\x05d\x00\x01\x00\x00\x00\x01\x00\x01\x8f_\ \x00\x00\x01\x90\x01\x93J\xb0\ -\x00\x00\x04\xe6\x00\x01\x00\x00\x00\x01\x00\x01\x7f\x0c\ +\x00\x00\x04\xe6\x00\x01\x00\x00\x00\x01\x00\x01\x7fA\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x04H\x00\x01\x00\x00\x00\x01\x00\x01a\xfc\ +\x00\x00\x04H\x00\x01\x00\x00\x00\x01\x00\x01b1\ +\x00\x00\x01\x90\x11U\xb4\x08\ +\x00\x00\x04v\x00\x00\x00\x00\x00\x01\x00\x01nV\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x04v\x00\x00\x00\x00\x00\x01\x00\x01n!\ +\x00\x00\x04\x9e\x00\x01\x00\x00\x00\x01\x00\x01t\x1b\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x04\x9e\x00\x01\x00\x00\x00\x01\x00\x01s\xe6\ +\x00\x00\x05@\x00\x01\x00\x00\x00\x01\x00\x01\x8b\x0b\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05@\x00\x01\x00\x00\x00\x01\x00\x01\x8a\xd6\ +\x00\x00\x05\x06\x00\x00\x00\x00\x00\x01\x00\x01\x85\xe2\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05\x06\x00\x00\x00\x00\x00\x01\x00\x01\x85\xad\ -\x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa9-\ +\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa9b\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xafr\ +\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xaf\xa7\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa6*\ +\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa6_\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xab\xf0\ +\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xac%\ \x00\x00\x01\x8f\xff^8_\ " diff --git a/artemis/ui/artemis.py b/artemis/ui/artemis.py index 7506138..ce39396 100644 --- a/artemis/ui/artemis.py +++ b/artemis/ui/artemis.py @@ -37,7 +37,7 @@ class UIArtemis(QObject): show_dialog_popup = Signal(str, str, str) show_dialog_download_db = Signal(str, str, str) - show_dialog_download_art = Signal(str, str, str) + show_dialog_update_artemis = Signal(str, str, str, bool) update_info_bar = Signal(str, str) @@ -66,6 +66,7 @@ class UIArtemis(QObject): self.docmanager = UIdocumentsmanager(self) self.sigeditor = UIsignaleditor(self) self.cateditor = UIcategoryeditor(self) + self.downloader = UIDownloader(self) self.update_manager = UpdateManager(self) @@ -80,6 +81,7 @@ class UIArtemis(QObject): self._window.openSigEditor.connect(self.open_sig_editor) self._window.startDownloader.connect(self.start_download_db) self._window.checkDbUpdates.connect(self.check_update_db) + self._window.updateArtemis.connect(self.update_artemis) self._window.showSpaceWeather.connect(self.show_space_weather_ui) self._window.openDbDirectory.connect(self.open_db_directory) self._window.showCatManager.connect(self.open_cat_manager) @@ -102,7 +104,7 @@ class UIArtemis(QObject): self.update_info_bar.connect(self._window.bottomInfoBar) self.show_dialog_popup.connect(self._window.openGeneralDialog) self.show_dialog_download_db.connect(self._window.openDialogDownloadDb) - self.show_dialog_download_art.connect(self._window.openDialogDownloadArtemis) + self.show_dialog_update_artemis.connect(self._window.openDialogUpdateArtemis) self.lock_menu.connect(self._window.lockMenu) self.populate_sig_details.connect(self._window_signal.populateSignalParam) @@ -222,7 +224,6 @@ class UIArtemis(QObject): def start_download_db(self): """ Show the downloader and start the download of the sigid db """ - self.downloader = UIDownloader(self) self.downloader.finished.connect(self.update_manager.post_download_db) self.downloader.on_start( self.update_manager.remote_db_url, @@ -236,10 +237,15 @@ class UIArtemis(QObject): self.show_dialog_download_db.emit(message_type, title, message) - def dialog_download_artemis(self, message_type, title, message): + def dialog_update_artemis(self, message_type, title, message, auto=False): """ Dialog popup for artemis download confirmation """ - self.show_dialog_download_art.emit(message_type, title, message) + self.show_dialog_update_artemis.emit(message_type, title, message, auto) + + + @Slot() + def update_artemis(self): + print('ciao') def open_db_directory(self): diff --git a/artemis/ui/downloader.py b/artemis/ui/downloader.py index 87754dd..b934999 100644 --- a/artemis/ui/downloader.py +++ b/artemis/ui/downloader.py @@ -86,6 +86,7 @@ class UIDownloader(QObject): if self.reply: self.reply.abort() self.update_progress_bar.emit(0, 0) + self.update_status.emit('') if self.file: self.file.cancelWriting() diff --git a/artemis/utils/constants.py b/artemis/utils/constants.py index c79a9de..486021d 100644 --- a/artemis/utils/constants.py +++ b/artemis/utils/constants.py @@ -51,7 +51,8 @@ class Messages: NO_CONNECTION_MSG = "Unable to check for updates. It appears that there is a problem with your internet connection. Please check your network settings and try again later. {}" UP_TO_DATE_MSG = "The latest version of Artemis and SigID wiki is installed on your computer." DB_NEW_VER_MSG = "A new version of the database ({}) is available for download. Download now?" - ART_NEW_VER_MSG = "A new version of Artemis ({}) is available for download. Check GitHub page now?" + ART_NEW_VER_MANUAL_MSG = "A new version of Artemis ({}) is available for download. Check GitHub page now?" + ART_NEW_VER_AUTO_MSG = "A new version of Artemis ({}) is available for download. Update Artemis now?" DB_CORRUPTED_MSG = "Downloaded data corrupted or invalid. Please retry." DB_DOWNLOAD_SUCCESS_MSG = "The database has been successfully downloaded and is now being loaded." diff --git a/artemis/utils/network_utils.py b/artemis/utils/network_utils.py deleted file mode 100644 index 6198b31..0000000 --- a/artemis/utils/network_utils.py +++ /dev/null @@ -1,135 +0,0 @@ -import os -import requests - -from packaging.version import Version - -from artemis.utils.constants import Constants, Messages -from artemis.utils.sql_utils import ArtemisDatabase -from artemis.utils.sys_utils import is_windows, is_linux, is_macos -from artemis.utils.path_utils import DATA_DIR - - -class NetworkManager: - """ Class that checks for DB or software updates - """ - - def __init__(self, parent): - self._parent = parent - self.sigid_db_path = DATA_DIR / 'SigID' / Constants.SQL_NAME - - self.show_popup = False - self.db_update = None - self.art_update = None - - self.remote_db_url = None - self.remote_db_hash = None - self.remote_db_version = None - self.remote_db_size = None - - self.remote_art_version = None - - self.check_updates() - - - def check_updates(self): - """ Checks if a new DB update is available. - - Args: - popup (bool, optional): Suppress the "already up-to-date" message on startup. - Defaults to False. - """ - latest_json = self.fetch_remote_json(Constants.LATEST_VERSION_URL) - if latest_json: - local_db = self.load_local_db() - remote_db = latest_json['sigID_DB'] - - self.remote_db_version = remote_db['version'] - self.remote_db_url = remote_db['url'] - self.remote_db_hash = remote_db['sha256_hash'] - self.remote_db_size = remote_db['total_bytes'] - - if is_windows(): - self.remote_art_version = latest_json['windows']['version'] - elif is_linux(): - self.remote_art_version = latest_json['linux']['version'] - elif is_macos(): - self.remote_art_version = latest_json['mac']['version'] - - if Version(self.remote_art_version) > Version(Constants.APPLICATION_VERSION): - self.art_update = True - else: - self.art_update = False - - if self.art_update: - self.show_popup_art_update() - else: - if local_db: - if self.remote_db_version > local_db.version: - self.show_popup_db_update() - elif self.show_popup: - self.show_popup_up_to_date() - else: - self.show_popup_initial_db_download() - - - def fetch_remote_json(self, url): - """ Fetches the remote json from a url - """ - try: - response = requests.get(url) - response.raise_for_status() - return response.json() - except requests.exceptions.RequestException as e: - if self.show_popup: - self._parent.dialog_popup( - Messages.DIALOG_TYPE_ERROR, - Messages.NO_CONNECTION, - Messages.NO_CONNECTION_MSG.format(e) - ) - return None - - - def load_local_db(self): - """ Loads the local database if exists - """ - if os.path.exists(self.sigid_db_path): - local_db = ArtemisDatabase('SigID') - local_db.load() - return local_db - return None - - - def show_popup_db_update(self): - """Prompts the user to download the updated version of the database.""" - self._parent.dialog_download_db( - Messages.DIALOG_TYPE_WARN, - Messages.DB_NEW_VER, - Messages.DB_NEW_VER_MSG.format(self.remote_db_version) - ) - - - def show_popup_art_update(self): - """Prompts the user to download the updated version of the database.""" - self._parent.dialog_download_artemis( - Messages.DIALOG_TYPE_WARN, - Messages.ART_NEW_VER, - Messages.ART_NEW_VER_MSG.format(self.remote_art_version) - ) - - - def show_popup_up_to_date(self): - """Notifies the user that the database is up to date.""" - self._parent.dialog_popup( - Messages.DIALOG_TYPE_INFO, - Messages.UP_TO_DATE, - Messages.UP_TO_DATE_MSG - ) - - - def show_popup_initial_db_download(self): - """Prompts the user to download the database for the first time.""" - self._parent.dialog_download_db( - Messages.DIALOG_TYPE_QUEST, - Messages.NO_DB_DETECTED, - Messages.NO_DB_DETECTED_MSG - ) diff --git a/artemis/utils/update_utils.py b/artemis/utils/update_utils.py index 5f67a0e..2c56161 100644 --- a/artemis/utils/update_utils.py +++ b/artemis/utils/update_utils.py @@ -125,13 +125,24 @@ class UpdateManager: def _show_popup_art_update(self): - """ Prompts the user to download the updated version of the database. + """ Alerts the user of a new version of Artemis. + Windows - asks to download with automatic update + Linux, macOS - redirects to GitHub page """ - self._parent.dialog_download_artemis( - Messages.DIALOG_TYPE_WARN, - Messages.ART_NEW_VER, - Messages.ART_NEW_VER_MSG.format(self.remote_art_version) - ) + if is_windows(): + self._parent.dialog_update_artemis( + Messages.DIALOG_TYPE_QUEST, + Messages.ART_NEW_VER, + Messages.ART_NEW_VER_AUTO_MSG.format(self.remote_art_version), + True + ) + else: + self._parent.dialog_update_artemis( + Messages.DIALOG_TYPE_QUEST, + Messages.ART_NEW_VER, + Messages.ART_NEW_VER_MANUAL_MSG.format(self.remote_art_version), + False + ) def _show_popup_up_to_date(self): diff --git a/ui/Artemis.qml b/ui/Artemis.qml index 782aa4d..c2f257c 100644 --- a/ui/Artemis.qml +++ b/ui/Artemis.qml @@ -33,6 +33,7 @@ Window { signal showSpaceWeather() signal checkDbUpdates() signal startDownloader() + signal updateArtemis() signal openDbDirectory() signal newDb(string name) signal exportDb(string path) @@ -121,11 +122,12 @@ Window { dialogDownloadDb.open() } - function openDialogDownloadArtemis(messageType, title, message) { - dialogDownloadArtemis.messageType = messageType - dialogDownloadArtemis.title = title - dialogDownloadArtemis.message = message - dialogDownloadArtemis.open() + function openDialogUpdateArtemis(messageType, title, message, auto) { + dialogUpdateArtemis.messageType = messageType + dialogUpdateArtemis.title = title + dialogUpdateArtemis.message = message + dialogUpdateArtemis.autoUpdate = auto + dialogUpdateArtemis.open() } DialogMessage { @@ -140,13 +142,19 @@ Window { } DialogMessage { - id: dialogDownloadArtemis + id: dialogUpdateArtemis modal: true + property bool autoUpdate + standardButtons: Dialog.Cancel | Dialog.Yes onAccepted: { - Qt.openUrlExternally("https://github.com/AresValley/Artemis") + if (autoUpdate) { + updateArtemis(); + } else { + Qt.openUrlExternally("https://github.com/AresValley/Artemis"); + } } } From 77c43813a079afd2342ab73f095303548df243af Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Thu, 13 Jun 2024 15:46:25 +0200 Subject: [PATCH 05/10] Final ieration of the new downloader and update_manager, implemented automatic updates only for windows --- artemis/resources.py | 378 +++++++++++++++++----------------- artemis/ui/artemis.py | 35 ++-- artemis/ui/downloader.py | 14 +- artemis/utils/update_utils.py | 81 ++++++-- ui/Artemis.qml | 8 +- 5 files changed, 285 insertions(+), 231 deletions(-) diff --git a/artemis/resources.py b/artemis/resources.py index d271e35..16a0cb5 100644 --- a/artemis/resources.py +++ b/artemis/resources.py @@ -5159,174 +5159,174 @@ z7\x80\xec$\xf4c9\xf2\xd1\x8f4\xc6\xbc>\xb8\ \x116\x9d`\x1e\x97*W\xd9M\xe1\x09\x12\xa5\xfc\xda\ h;Q\xfc\xeb\x9c\x87 J\xfd\xc5\xd0c0\xc6[\ \xf7\xe4\x19\xd3~\xf5\xc8?\xf0\xff?E#\xf2\xe8\ -\x00\x00\x0a[\ +\x00\x00\x0aW\ \x00\ -\x003#x\xda\xcd\x1ako\xdb8\xf2\xfb\x02\xfb\x1f\ -x\xfe\xb0\xb5osJ\xdaC\x81=w{@j\xa7\ -M\x80$\xcd\xd6i\x8bCQ\x14\xb4D\xdb\xbc\xd0\xa2\ -\x96\xa2\xe2d\xdb\xfc\xf7\x9d!\xf5\xa2^\x96\x93\xf4\xf6\ -\xdc\xc2\xb1\xc8\x19r^\x9c\x17\xc5\xd7\x91T\x9a\xfc\xa6\ -\x7fK\xb8\x7f\xf5\xe3\x0f\xdcy\xf6>\xf20\x90\x9b\xda\ -\xf0D\x86ZI\x11\xb7NxgT3\xc5\xa9\xa8A\ -\x9c\xd2[\x99\xe8:\xe6\x14\x80\xe5\x12\xc6\xf1\x9f\xdd\x96\ -|\xfd\xf1\x07\x02\x1f\x1e\x8c\xc9&%\x04\x9f7<\xd0\ -\xab1y\xfa\xf4\xe0\xc0\x0e\xac\x18_\xae\xf4\x98\xfc\x82\ -\x03vh\x22a\xf9\x90\x85\xda\x93!\xfe\x16L3X\ -&]\x11?7\xe4%\x99\xf9\x8a\xb1\xd03\x0b\x92}\ -\xf2\x8c\xfc\x83\xe4\xbf\x0b\xc8\xdb\x02\xd2\xee\x94\x82\x16\x0f\ -\x16\xf6.\xdb\x5cs-\xd8\x98\xfc\x1e_\xaa\xe1\xe0P\ -i\xb6\xe6\xf1`d\xe7\xaey\xcc\xe78\xabU\xc2\xec\ -\x90\xfd^\xcb\x80\x0a\xaeo\xc7 \x12\xef0\x8a\x04\xf7\ -\xa9\xe62<\xc3q\x0b\xb2\x10t\x19\x9b\xf9\x8f%q\ -\xd8\xef\xfd}b\x07c`A\xaf@\xc6$\x89\x22\xa6\ -\xc8\x9c\xaa\x0c\xa2\xc0\x7f\xad\xe8\x9a\x09\x16\xc7\x16\xe7\x98\ -\x87:#>\xe6\xcb\x90\x0a\x22$\x0df\xe6\xe7\x10&\ -\xd3\xd1\x93`\xe4\x00\xc5+\xb9\xb9Pl1\xac\x0fO\ -_\xadiH\x97L5\xccM\xa8>k\x9c\x94\x11\x0b\ -a\xd3\xa3\x80k\xa9\x86\xb1V<\x5c\x12}\x1b\xb1=\ -rM\x15B}\x89(\x90\xbeG\xe6R\x0a\xc2\xe3/\ -!\xdb\xd4\xd7\x9fE\xd4g\x1f\x19\xd5\xab\xda\x0e\xfe\x8a\ -\xf9W\xd3\xf9\xfb(\x00\x03\x8d\xab\xb4i\xaa\xf4Tn\ -Bd\xbe\x86\x9a\x18\x9cT\x9d\x0d\x84O\xe7S\xae\x98\ -\x0f\x94\xdfVf\x81\xc8\xe9\x15\x05>\x18}\x09\xa8\x80\xd0\xecF\xbf\xe6L\x04\ -3F\x95\xbf\xf2XH\xc1\x9e\x03\x00/,\xda\x18:\ -P\xe3'J\xc1\x19<\x09\x03\x86\xc7M\xc0B\x1f8\ -\xdbx\xe5\xf1\x02\x03\x0cI\xb1xe\xe8\x1b\x15\xc3`\ -\xd93\xa6\x09(\xd3]oN\xfd+B\x17\xe0g2\ -Lc-\x00&\x1c\x82\xf9\x82\x0c\x1d\xc4\x7f\xbf$\x07\ -\xe4\xa7\x9f\xdc\xd5~5Xp\xd8\x98\xf0|\x99\x84\xae\ -X\x8ch\x9a\xa8\x07\xae\x9a\x99\xb9\xab\xf8\x84\x5c\x0d\x0e\ -\x97\x8e\xe8\x8b\xfd\x05\x88\xb6,\x82\x85Td\x88\x02\xe5\ -\xb0\xdf\xc1\x0b\xf8\xf3kIS\x9e`\xe1R\xaf`\xf8\ -\xe7\x9fkT#\x16\x9a\x1c\x8a?\xc7\xf8\xc4?{8\ -\xe8iy*7LMh\xcc\xca\xfbe\x88\x01\x8b}\ -\xc5#Cw\x15\xbf4\xb7m\x99\xd8X\x0aZH\xc5\ -v\xf0\xb9\x0b\x19Ug\xe8\xe4\xa1/\x12\xd8qh\x97\ -\x1a\x91o\xdf\xca\xc4\xd5\xe6kbp\x05L\xc13\x86\ -\xc1\xd0a\xa8\xb2\xf5]M\x95\x86 8\xfc\x93\x15\x0d\ -\x97\x16-\xa3\xb7\xae\xe5\x1a`\x99 +\x13\x01\xbe\x82\ -\x05_\xe0\x90\xa5G\xc3\xd2\xb6dz\xd8hj#\xd7\ -\xa4\x9d\x05\xfe\xf6\xf2%I\x00h\xc1C\x16\xd4-\xb7\ -\xf0\xe5}\xf6\xf1f'o\xbe\x9cL+\x02a\xe0\x94\ -\xed\x22g,LZ\x8f\xfd\x1da\x22fU\x0aZ\x91\ -\x17\xe0_X\x8fSc\x8e\xc4Ng\xc6\xf1d\x9f>\ -\xb7;\xb0\x1af\xbb\x87+Q['QH\xff\x0a\xb9\ -\x1bj\xb9\x5c\x0a\xe6\xd0\x89\x0ak\x18\xc6\x0f\x86\x8e\xd7\ -\x5c\xb0n\xc1\x18!\x9a8\xd1\x0f\x16BN\x1fyg\ -\xba\x81\x88\xcc\x96\x10\xb8\xb6h\xa7Q\xb7-\x0c\xb8f\ -\xd1I\x7f\x1d\xb4\x8d\xfc\x86E\xdb\xa9\xaf\x18f\x9b\xde\ -\xe6Rk\xb9>\x09\x17\xf2\x15\xd8\xc1\x1a\x92\x22\xc8L\ -\xf6H\xfa\xe3\x12\xb2\x0fGg\x05\xf8)\x9d\x83\xe1\xa1\ -\xb5\xc0f)x\x01\x17C\x1a\x06No\xd8\xb6\x8e\x0f\ -\xfe\x8e\x0c6T\x85\x10\xb6\x06c\x97\xab\xea&\xbe\x14\ -\x10\x02^\x92,\xad\xb6\x03\xc3\xfc\xf1\x1d\x0b*\xc7u\ -\xae\x18\xbd\xaa\xee\xc6a\xc1\x9d\xb7\x82\xe0\xc3\x96\x0aB\ -b\xd0\xb9C\xab|\xd1>\xde\xb0\x90)*l\x92_\ -\x16\xc9\x9eM\x96sq;\x22\x0a\x0cx\x8a\xeb\x95\xb0\ -\x0ay\xe3S\x1b\x82Y\x19\xed\x00\xffnY\xb5I\x83\ -. \xb2\xd1\xee\xefM\x02h\xe0\xb3\xfc\x11\xb2\xb5\xdd\ -\xf8,\x10\xfb\xb3Z\xc2\xe9\xe4\xb6\xbev;\xc3%\xd8\ -\xbe<\xbfwR\xe3\x0e\xb6\xf7\x08M\xb4l`\xdeY\ -\xa1?\xff.Z\xa7\x08\x1awh\x97\x82\x0b\x8eT\xdb\ -\x11\xc0\xc0\x87n\xf0F\xb9YQ\x9d\xa5\x1b\x97\x83\x03\ -\x14\xa6U\xd1\x17\xb3\xa6.\xcc\xca\xc5\x92{\xd14\x0c\ -\xa8\x0a^%p|C\xa8\xea\xec\xf2\xde\x84\x86>\x13\ -\xe4[\xf6\xfc\x1f\x16\x97\xd1dx\xe8\xfb,\xaa\x16\xc3\ -\xe9\x8aM\xd5O\xd3\xd9\xee\xc1\x8a#\x90\xad\xdc\xe45\ -\x8c\xa9\xeb\x0ai\x7f_\x8e1*\x17{5\xe6\x8c\x95\ -\xa2\xefE%Il\x0c\x88\xf8\x81\x1a\x1b\x8d\xe0\xbd\x12\ -G7\xe0G!\x92\x89\xdb\xe1`\xa5u\x14\x8f\xf7\xf7\ -\x97P\xa1'sp\xb5\xeb\xfdC(\x06>\xc0,\xbb\ -\xdd\xcf;\x05/\xb6\xa5\xa2\xbb(\x22\xf5_\xf76\xa8\ -\xb7W\x8d{6ov\x8e\x95ny\xd5\x9b1\x19B\ -\xc9\x8e\x8d\x18\xdbYI;,\xa3J\x8b\xa5\x00K\xbb\ -*Y{%\x05l!?\x0foB\xc6\xecB\x0a\xee\ -\xc3J\x17P\xe8F\xde\xb9<\x04\xd5Np\xa2\x1f\x9b\ -\x85\x05Y\x8b*cM\xa4H\xd6\xa1\xed]U\xd5\x0d\ -\xc0+\xa9bo\xc1\x05\xd0e\xb9p!L`m\xb2\ -\x12\xcc\x1d\xb2>\xd1Q\x88\x95,\x96\xaf\xa6\x5c\x93\x0b\ -\xfb\x9bm\x08X \x9dC\xfc\x1e\x0fF\xf5%,M\ -\x9e\x8d\xe2gT-y8&O\x9f\xd7\x01\x17\x12\x84\ -\x1bI\x1eB\x22\xfe\x07\x03\x98g\xadV\x86\x9f\xcb,\ -\x09n\xa2\x1b\x15n\x9a\x1a\xe7@j+M(\x90\x8f\ -\xb6WW\xcf\xdb\xcc\xa9\x17\xd4g+)\xc0\xdb\x5c\x96\ -$\x81\x8b\x0e:\xcb\xb1^\xa7\xdbv]r2M\xa2\ -\xd6\xe1\xd30/m6\xed\xb4?c\xe6JU\x82m\ -\xf2\x0d.\xa0|\x00\x1f\x006\x00\x96F(\x89\xe95\ -\x03a#S\x9e\xe7\x0dJE<&\xbeP\xab\x8cK\ -[y3\x80\xc6\xc7\x02\x0c\xb5\x0f#`\x0c`\x9c\x9f\ -\x06\x87P\x81pXq\xe8\x81{\x1e\x0d>\xf7d\xbe\ -\xe8)\xa5e\x22nr/\xee\xd3\xdeSO\xee\xaf\xa9\ -\xe0\x01\x01R\xbd\xe5\x1f\x84Z\xda{\x88\xe1mZC\ -l\x17\xc3\xdfw\x93C\xd19\xeb'\x87\xc3y\xe5\x84\ -\xa3\x08(\x0e\x96%\x90\x83_T\xdcn\xb7/\x10l\ -\xa1/h\x10@\xc2\x0f\xe7\xef\xa0ZS8S\xc5\xe4\ -\x8aa8\x1e\x13\xacn\xa0B\xa9q\x08\x04j\x19\xbd\ -\xc26\xaf;\x83\x08\x8d^\xa7\xdc\x9eFy\x0cFU\ -\xd4\x0c\xfd\x04\x22R\xd3\x12\x85\xf3\x1a\x80\xcb'\xd3\xd4\ -C\xb9\x9av\x8a\xc4p\x02\xce\xf9\xcah\xa8\x14*\xd2\ -L\xe9\xae\x8et\xf7\x00\x92N!\x81\xd9\x91\xa6J\xcb\ -z\x17\x82f\x0c{\xd2\x1a\x8a\xa6\xaf\xf7\x22\xba8d\ -Yi\xdc\xc9\xdc\x89\xbd7\xc9\xd8\xeb\xc1[\xf9\x04?\ -\xb2\xc0\x0b\xf7\xd8\x8b\xf6\xa3\x9b]i/\xfb\xdev\xda\ -\x8d\xc7\xb3u\xff\xb8\xa9\xc5\xf1\xdd\xf5W\xedBtK\ -\x01\x80\xc9%]\xc6=\xed\xb2|]\xf2\xff\xc8|\xb9\ -\x01\xd4\xc98z\xf9\x5c\xf9\xe4\xb5\x89\x91=dP\xbb\ -\x5cyl!\xf4p)x\xcb\xc5\xc0\x9b\xfb\xac\xaf\xd6\ -\xec\xbd\xd8#{\xb6\xa3\x1b\xae{\xecooK=\x93\ -\x15\xf7\xa3\xe1\xaeo\xf0@\x85\xc7yknKp\xb1\ -=\xbc\xfb\x85\x974\xc7\x9cu\xec\xd5G\xe9n\xa4\xea\ -\x15\x0b\xdc[\xc8'\x96\x82'{\xe4\xd3\xe7=\x93\xc8\ ->\xae\xf7t:\xe3\x0f\xe6\x11\x89\xf6\x1e\xcc\xa5\xd9\xa7\ -\x85\xcd{Y\x8dk\x15x=K\xd2\xfb\xd9\x07\xe5\x1e\ -\x13\xbc\xcd%\xef\x18\xc6\x88\x1e,7C\x98\xaa\xb0\xe5\ -\xd6x\x0b\xff\x0f\x11I\x9eX\xf68G\xc7LD\x8f\ - (\xbcFLo\xbe{H\xabzU\xfe\xbf\xcc\x89\ -r\xaf+\xff\x0bN\x9f\x1c\xcb5,\xb8\xec\x9304\ -6^\x9ed\x8d\x17H\xc8\xe3k\xd3m1\xcd\x97'\ -\x8f\xed\x9f\xa7\xd2O\xd6\x90\xf3\x9b77\x1eLm\xd1\ -\x1b\xf2\xd2\x8e\x11\x97Y\x97\xe8\xd1I\x9f\xc1\x11\x80\xa3\ -d\xeb\xb9s\xd9\xcfF\xba\xe9\xefls\xed\xcf\x85\x9c\ -\xef\xafi\x0cx\xfb\x93\xe3\xc3\xf37G\xa7o\xdfx\ -\xeb\xe0\xc9_ai\xd6\x87\x90\x938N\xd8w\xe6\x9b\ -\xe3\x1e\xf1_\xc2\xa5\xa9n\x1f\xe4(K\xa5\xb0\xd3\xe5\ -\xbe\x97\xa3ld{!\xc1\xf6\xa0\xdcml\x9a\xa1\xd3\ -\xac\x5cX\xb9\x00\xb6\xcb\xc5o\x98h\xeer9%x\ -\xa5K\xa6\xb0\xdf\xd86Y)\xd1\x9f\xb7P\xffNn\ -\xee\xdb%\x8c!\xfe4\x94\xff\xdb\xda\x8f\xa5\x86\xdb\x9a\ -\xde\xf0u\xb2N{n\xcf\x9e\x1f4\x99Jgc/\ -o(\xb8W\xe0\xcd\x80\xe9\xae\x91I\x8d\x15\x0b\x8e\xd3\ -\xd7\xf0\xfe\xf9\xafNx-\xa3\xacO\xf9\xfc\xfe\xf9N\ -[\x8f\xb1\x19\xba\xa5\xd3h\xb9\x1b\x8c\xdaN\x04\xc2\xa6\ -oqt\x9e\x8a\x967\x97\xb6\x1f\x88\xfa\xa0c@-\ -\xac\xa7omtQ\x84J\xcc\xde\xeeh\x87\xea\xdb\xa8\ -m\x80\xcf\x94\xdd\x8d\xb0\x02 \x81\x80g\xf2\x9aM\x13\ -e\xe2\xe2\x98\x1c\xb4c\xf8\x82G\xdbV]@\x94\x8d\ -\xb7\x01\xcd|%\x85xE\x95w\xcd\x94\xe6>^\x1a\ -\xe4\xefBv\xd2:\x860\xe8k\xd0\xba`\xe4+1\ -\xf7\xe1\xe3\xe2:\x9c\xfa>\x1c\xdd\x17D\xd1\x80#\x15\ -\xcf\xc9]\xfb\x9a\xe0TKo\xd6\x14\xa6\xd4\xf0~P\ -\xc7*\x01D\xe5%\xec?&]>\xbe\xaa\xfai\x8a\ -\xd5\x0d\x9d\xbeL\x9b\xd9\x94w\x8d_f\xb0\x1b/{\ -\xe7\xf6\xd9A7\x5c\xea\xc6m\x00\xc2\xa6\xee]7\xfc\ -\x99Lb\x06Q\x93nc\xb3\x9fS\xdd\x12\xe9\xda\xde\ -\xe9\xe3\xee\xcb|=\x0ft\x8f\xa95\xbe\xacd\xc5m\ -\xde[\xea\xabL\x03\xbc\xf3\x8ewm.$?\x1c\xdb\ -|H\xe7\x89\xd9\xd9\x1dP_\xf3k\xd6\x05u\x8f\x02\ -\xabgp\xa4p\xb6C\xcc\xcd\xed\x0b\xd6\xf8t\x0a\xc9\ -\x00\xf9\x96?^\xca\xa8\xf3.\xab\x9b\xc7\xfe\x01\xe9\x92\ -\xce;$o\xc2\xaf\x81x\x8c\xc0\x87{\x99\x9b\xce.\ -E\x97\xaf!g'o\xce\x0fO\x07\xa3\x1d\x0dj\xe7\ -}^\x9f\x9c^\x1e\xbd\x9b\x0d\x1e\x18.g\x9a\xfaW\ -\xed\xba7\x11\xa5t\xb43\xd1\xb6\xbc\x81\xdc\xcfl\x8e\ -'\xcc\xdc\xd5\x16\x96\xf3\xc1\x8elU\xd8\xf6S\xb2\x9b\ -v\xb7\x85\x03\xdb\xd4\xa9^R\xb5Y]\x9cC?\x9e\ -\xa3\xd9F\xa1\xbd\xe2\xebK\xe1\x22\x87\xbe\x0f\x85;\x15\ -$\xe9\x1f\xf8\xff'\xb7x\xdf\xfa\ +\x003\x15x\xda\xcd\x1a\xdbn\xdb8\xf6}\x80\xf9\x07\ +\xae\x1f\xa6\xf6NVI\xbb(\xb0\xebN\x17H\xed\xa4\ +\x09\x90\xa4\x99:m\xb1(\x8a\x82\x96h\x9b\x1bZ\xd4\ +PT\x9cL\x9b\x7f\xdfsH\xdd\xa8\x9b\xe5$\xb3\xb3\ +n\xe1X\xe4!y\xee7\x8a\xaf#\xa94\xf9U\xff\ +\x9ap\xff\xfa\xc7\x1f\xb8\xf3\xec}\xe2a 7\xb5\xe1\ +\x89\x0c\xb5\x92\x22n\x9d\xf0\xce\xa9f\x8aSQ\x838\ +\xa3w2\xd1\xf5\x95S\x00\x96K\x18\xc7\x7f\xf6X\xf2\ +\xed\xc7\x1f\x08|x0&\x9b\x14\x11|\xde\xf0@\xaf\ +\xc6\xe4\xf9\xf3\x83\x03;\xb0b|\xb9\xd2c\xf2\x0f\x1c\ +\xb0C\x13\x09\xdb\x87,\xd4\x9e\x0c\xf1\xb7`\x9a\xc16\ +\xe9\x8e\xf8\xb9%\xaf\xc9\xccW\x8c\x85\x9e\xd9\x90\xec\x93\ +\x17\xe4o$\xff]@\xde\x15\x90\xf6\xa4\x14\xb4x\xb0\ +\xb0\xf7\xd9\xe1\x9ak\xc1\xc6\xe4\xb7\xf8J\x0d\x07\x87J\ +\xb35\x8f\x07#;w\xc3c>\xc7Y\xad\x12f\x87\ +\xec\xf7Z\x06Tp}7\x06\x96x\x87Q$\xb8O\ +5\x97\xe19\x8e[\x90\x85\xa0\xcb\xd8\xcc\x7f*\xb1\xc3\ +~\xef\xef\x13;\x18\x03\x09z\x05<&I\x141E\ +\xe6Te\x10\xc5\xfacE\xd7L\xb08\xb6kNx\ +\xa83\xe4c\xbe\x0c\xa9 B\xd2`f~\x0ea2\ +\x1d=\x0dF\x0eP\xbc\x92\x9bK\xc5\x16\xc3\xfa\xf0\xf4\ +\xcd\x9a\x86t\xc9T\xc3\xdc\x84\xea\xf3\xc6I\x19\xb1\x10\ +\x0e=\x0a\xb8\x96j\x18k\xc5\xc3%\xd1w\x11\xdb#\ +7T!\xd4\xd7\x88\x02\xea{d.\xa5 <\xfe\x1a\ +\xb2M}\xffYD}\xf6\x89Q\xbd\xaa\x9d\xe0\xaf\x98\ +\x7f},\xd5\x87(\x00\x0d\xadL&fp:o\x1c\ +N\xe5\xd8\x80\xf1t>\xe5\x8a\xf9\x80\xf2]e\x16\xb0\ +\x83\xddR:B`\xb9;\xcdn\xd1\x04\x0a\x88\x080\ +v!\xac\x91\xd4 ,L\xa4\xe0t\xa5\xef\x0coP\ +^,8\xe3q.\xc8E\x12\xfa\xa8@$\x92Q\x22\ +\x80\x02\x9c\x1c\xda\x8dc\xfc=*\x9bC\xb1\x1e\xb4\xbd\ +\x04T@hv\xab\x8f9\x13\xc1\x8cQ\xe5\xaf<\x16\ +RP\xe4\x00\xc0\x0bU6\x1a\x0e\xd8\xf8\x89R`|\ +\xa7a\xc0\xd0\xce\x04l\xf4\x91\xb3\x8dW\x1e/V\x80\ +\x06)\x16\xaf\x0c~\xa3b\x18Tz\xc64\x01)\xba\ +\xfb\xcd\xa9\x7fM\xe8\x02\x1cL\xb6\xd2\xa8\x09\x80\x09\x07\ +a\xbe Cg\xe1\xbf^\x93\x03\xf2\xd3O\xeen\xbf\ +\x98U`eLx\xbeLB\x97-\x865M\xd8\x03\ +U\xcd\xc4\xdcW\x9cA.\x06\x87J\x87\xf5\xc5\xf9\x02\ +X[f\xc1B*2D\x86r8\xef\xe0\x15\xfc\xf9\ +\xa5$)O\xb0p\xa9W0\xfc\xf3\xcf5\xacq\x15\ +\xaa\x1c\xb2?_\xf1\x99\x7f\xf1p\xd0\xd3\xf2Ln\x98\ +\x9a\xd0\x98\x95\xcf\xcb\x16\x06,\xf6\x15\x8f\x0c\xde\xd5\xf5\ +\xa5\xb9m\xdb\xc4FSPC*\xba\x83\xcf]\x8bQ\ +t\x06O\x1e\xfa\x22\x81\x13\x87v\xab\x11\xf9\xfe\xbd\x8c\ +\x5cm\xbe\xc6\x06\x97\xc1\x14\x5cb\x18\x0c\x1d\x82*G\ +\xdf\xd7Di\x10\x02\xe3\x9f\xach\xb8\xb4\xcb2|\xeb\ +R\xae\x01\x96\x11\xb2<\x11\xe0+X\xf0\x15\x8c,5\ +\x0d\x8b\xdb\x92\xe9a\xa3\xaa\x8d\x5c\x95v6\xf8\xcb\xeb\ +\xd7$\x01\xa0\x05\x0fYP\xd7\xdc\xc2\x89\xf79\xc7\x9b\ +\x9d\xbe\xfdz:\xad0\x84\x817\xb6\x9b\x9c\xb30i\ +5\xfb{\xc2D\xcc\xaa\x18\xb4.^\x80\x7fa=\xac\ +\xc6\x98\xc4N6\xe3x\xb2\xcf_\xda\x1dXme\xbb\ +\x87+a[GQH\xff\x1a\xa9\x1bj\xb9\x5c\x0a\xe6\ +\xe0\x89\x02k\x18\xc6\x0f\x86\x8ec.X7c\x0c\x13\ +M\x9c\xe8\x07\x0b!\xa7\x0f\xbf3\xd9@(fK\x08\ +\x5c[\xa4\xd3(\xdb\x16\x02\x5c\xb5\xe8\xc4\xbf\x0e\xda\x86\ +~\xc3\xa6\xed\xd8W\x14\xb3Mns\xa9\xb5\x5c\x9f\x86\ +\x0b\xf9\x06\xf4`\x0d\xd9\x10\xa4${$\xfdq\x05i\ +\x87#\xb3\x02\xfc\x8c\xceA\xf1P[\xe0\xb0\x14\xbc\x80\ +\x8b!\xff\x02\xa77l\xdb\xc7\x07\x7fG\x06\x1b\xaaB\ +\x08[\x83\xb1KU\xf5\x10_\x0a\x08\x01\xafI\x96O\ +\xdb\x81a\xfe\xf8\x9e\x05\x15s\x9d+F\xaf\xab\xa7q\ +\xd8p\xe7\xa3 \xf8\xb0\xa5\x82\x90\x18t\x9e\xd0\xca_\ +\xd4\x8f\xb7,d\x8a\x0a\x9b\xdd\x97Y\xb2g\xb3\xe4\x9c\ +\xdd\x0e\x8b\x02\x03\x9e\xae\xf5J\xab\x0a~\xe3S\xdb\x02\ +\xb33\xea\x01\xfe\xdd\xb2k\x93\x04]@$\xa3\xdd\xdf\ +\x9b\x04\xd0\xc0O\xe5&D\xdf\x03\xd9\xdant\x16\x0b\ +\xfb\x93ZZ\xd3Im}\xefv\x82K\xb0}i\xfe\ +\xe0\xa4\xc6\x1dd\xef\x11\x9ah\xd9@\xbc\xb3C\x7f\xfa\ +\xdde\x9d,h<\xa1\x9d\x0b.8bmG`\x05\ +>t\x837\xf2\xcd\xb2\xea<=\xb8\x1c\x1c\xa0\x22\xad\ +\xb2\xbe\x985\x05aV'\x96\xdc\x8b\xa6a@U\xf0\ +&\x01\xf3\x0d\xa1\x9c\xb3\xdb{\x13\x1a\xfaL\x90\xef\xd9\ +\xf3\xbfY\x5c^&\xc3C\xdfgQ\xb5\x0a\xc6O\xb5\ +\xeci2\xea\x1e48\x9c\xd8JF^\xbc\x98J\xae\ +`\xf3\x1fK*\x86\xe3\xe2\xac\xc6d\xb1R\xed\xbd\xaa\ +d\x87\x8d\x91\x10?PU\xa3\xf4?(qt\x0b\x0e\ +\x14B\x98\xb8\x1b\x0eVZG\xf1x\x7f\x7f\x095y\ +2\x07\x1f\xbb\xde?\x84*\xe0#\xcc\xb2\xbb\xfd\xbc7\ +\xf0j[\x0e\xba\x8b R\xc7\xf5`Mzw\xddx\ +f\xf3a\x17X\xe2\x96w\xbd\x1d\x93!\x14\xe9\xd8z\ +\xb1\xbd\x94\xb4\xa72\xaa4U\x0a\xb0\xb4\x8f\x925T\ +R\xc0\x16\xf4\xf3\xb8&d\xcc.\xa5\xe0>\xect\x09\ +\x15n\xe4]\xc8C\x10\xed\x04'\xfa\x91Yh\x90\xd5\ +\xa8\xf2\xaa\x89\x14\xc9:\xb4\xdd\xaa\xaa\xb8\x01x%U\ +\xec-\xb8\x00\xbc,\x15.\x84\x89\xa8MZ\x82IC\ +\xd6\x19:\x0a\xb1\x84\xc5\xba\xd5\xd4ira\x7f\xb3\x0d\ +\x01\x0d\xa4s\x08\xdc\xe3\xc1\xa8\xbe\x85\xc5\xc9\xb3\xe1\xfb\ +\x9c\xaa%\x0f\xc7\xe4\xf9\xcb:\xe0B\x02s#\xc9C\ +\xc8\xc0\x7fg\x00\xf3\xa2U\xcb\xf0s\x95e\xbfMx\ +\xa3\xc0M7\xe3\x02Pm\xc5\x09\x19\xf2\xc9v\xe7\xea\ +\x09\x9b\xb1zA}\xb6\x92\x22`\xea\xaa\xc4\x09\xdct\ +\xd0Y\x87\xf5\xb2n\xdbn\xc9\xd14\x19Z\x87O\xc3\ +\x84\xb4Y\xb5\xd3\xc6\x8c\x99+\x95\x07\xb6\xad7\xb8\x84\ +\xba\x01|\x00\xe8\x00h\x1a\xa1$\xa67\x0c\x98\x8dD\ +y\x9e7(U\xef\x98\xf1B\x912.\x1d\xe5\xcd\x00\ +\x1a\x1f\x0b0\x94>\x8c\x802\x80r~\x1e\x1cB\xe9\ +\xc1a\xc7\xa1\xa7\xa9\x1a\x0d\xbe\xf4$\xbeh&\xa5\xf5\ +!\x1e\xf2 \xea\xd3\xa6SO\xeao\xa8\xe0\x01\x01T\ +\xbd\xe5\xef\x84Z\xdc{\xb0\xe1]Z\xeb+5{\x13\xf6\ +\xc4\x9e\xed\xe8\x96\xeb\x1e\xe7\xdb\xfbQ\xcfd\xc5\xfdp\ +\xb8\xef\x1b<\xdfi\xeb16\ +C\xb7t\x1a-u\x83Q\x9bE l\xfa\xfaF\xa7\ +U\xb4\xbc\xb2\xb4\xdd \xea\x83\x8e\x02\xb5\x90\x9e\xbe\xae\ +\xd1\x85\x11\x0a1{\xad\xa3\x1d\xaao\xa3\xb6\x01>\x13\ +v\xf7\x82\x15\x00\x09\x04<\x977l\x9a(\x13\x17\xc7\ +\xe4\xa0}\x85/x\xb4m\xd7\x05D\xd9x\x1b\xd0\xcc\ +WR\x887Ty7Li\xee\xe3\xa5A\xfe\xf6c\ +'\xaec\x08\x83\xbe\x06\xa9\x0bF\xbe\x11s\x11>.\ +\xee\xc1\xa9\xef\x83\xe9\xbe\x22\x8a\x06\x1c\xb1xI\xee\xdb\ +\xf7\x04\xa7Zz\xa5\xa6P\xa5\x86\x17\x83:v\x09 \ +*/\xe1\xfc1\xe9\xf2\xf1U\xd1O\xd3U\xdd\xd0\xe9\ +\xeb\xb3\x99Ny7\xf8e\x06\xbb\xd7eo\xd9\xbe8\ +\xe8\x86K\xdd\xb8\x0d@\xd8\xd4\xbd\xef\x86?\x97I\xcc\ + j\xd2md\xf6s\xaa[\x22]\xdb\xcb|\xdc}\ +\x8b\xaf\xa7A\xf7\x98Z\xe3[J\x96\xdd\xe6\x85\xa5\xbe\ +\xc24\xc0;\x9fx\xdf\xe6Br\xe3\xd8\xe6C:-\ +fgw@}\xcdoX\x17\xd4\x03\x0a\xac\x9e\xc1\x91\ +\x82m\x87\x98\x9b\xdbW\xaa\xf1\xe9\x0c\x92\x01\xf2=\x7f\ +\xbc\x92Q\xe7]V7\x8d\xfd\x03\xd2\x15\x9dwp\xde\ +\x84_\x03\xf1\x14\x81\x0f\xcf27\x9d]\x82._C\ +\xceN\xdf^\x1c\x9e\x0dF;*\xd4\xce\xe7\x1c\x9f\x9e\ +]\x1d\xbd\x9f\x0d\x1e\x19.g\x9a\xfa\xd7\xed\xb27\x11\ +\xa5d\xda\x19k[^=\xee\xa76'\x13f\xeej\ +\x0b\xcd\xf9hG\xb6\x0al\xbb\x95\xec&\xddm\xe1\xc0\ +6u\xaa\x97TmZ\x17\xe7\xd0O\xe7h\xb6ah\ +\xaf\xf8\xfab\xb8\xc8\xa1\x1f\x82\xe1N\x05I\xfa\x07\xfe\ +\xff\x17E\xda\xd9\xee\ \x00\x00\x08k\ \x00\ \x00r]x\xda\xed\x5cms\x9b\xb8\x1a\xfd\xde\x99\xfe\ @@ -7295,47 +7295,47 @@ qt_resource_struct = b"\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x01\x0e\x00\x00\x00\x00\x00\x01\x00\x01\x16\xe5\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x03\xb0\x00\x01\x00\x00\x00\x01\x00\x01Q\xb0\ +\x00\x00\x03\xb0\x00\x01\x00\x00\x00\x01\x00\x01Q\xac\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x04\x22\x00\x01\x00\x00\x00\x01\x00\x01[\xa5\ +\x00\x00\x04\x22\x00\x01\x00\x00\x00\x01\x00\x01[\xa1\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x03\xe6\x00\x01\x00\x00\x00\x01\x00\x01T\xcd\ +\x00\x00\x03\xe6\x00\x01\x00\x00\x00\x01\x00\x01T\xc9\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03\x12\x00\x01\x00\x00\x00\x01\x00\x019\x8e\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03<\x00\x01\x00\x00\x00\x01\x00\x01>\xe2\ -\x00\x00\x01\x90\x11\x9a\x93$\ -\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xa0\xaf\ +\x00\x00\x01\x90\x11\xc7\x00\xf9\ +\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xa0\xab\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01IA\ +\x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01I=\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99{\ -\x00\x00\x01\x90\x11U\xb4\x08\ +\x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99w\ +\x00\x00\x01\x90\x11\xad[\xc5\ \x00\x00\x03X\x00\x02\x00\x00\x00\x04\x00\x00\x00+\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01vI\ -\x00\x00\x01\x90\x11U\xb4\x08\ -\x00\x00\x05d\x00\x01\x00\x00\x00\x01\x00\x01\x8f_\ +\x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01vE\ +\x00\x00\x01\x90\x11\xad[\xc5\ +\x00\x00\x05d\x00\x01\x00\x00\x00\x01\x00\x01\x8f[\ \x00\x00\x01\x90\x01\x93J\xb0\ -\x00\x00\x04\xe6\x00\x01\x00\x00\x00\x01\x00\x01\x7fA\ +\x00\x00\x04\xe6\x00\x01\x00\x00\x00\x01\x00\x01\x7f=\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x04H\x00\x01\x00\x00\x00\x01\x00\x01b1\ -\x00\x00\x01\x90\x11U\xb4\x08\ -\x00\x00\x04v\x00\x00\x00\x00\x00\x01\x00\x01nV\ +\x00\x00\x04H\x00\x01\x00\x00\x00\x01\x00\x01b-\ +\x00\x00\x01\x90\x11\xad[\xc5\ +\x00\x00\x04v\x00\x00\x00\x00\x00\x01\x00\x01nR\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x04\x9e\x00\x01\x00\x00\x00\x01\x00\x01t\x1b\ +\x00\x00\x04\x9e\x00\x01\x00\x00\x00\x01\x00\x01t\x17\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05@\x00\x01\x00\x00\x00\x01\x00\x01\x8b\x0b\ +\x00\x00\x05@\x00\x01\x00\x00\x00\x01\x00\x01\x8b\x07\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05\x06\x00\x00\x00\x00\x00\x01\x00\x01\x85\xe2\ +\x00\x00\x05\x06\x00\x00\x00\x00\x00\x01\x00\x01\x85\xde\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa9b\ +\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa9^\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xaf\xa7\ +\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xaf\xa3\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa6_\ +\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa6[\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xac%\ +\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xac!\ \x00\x00\x01\x8f\xff^8_\ " diff --git a/artemis/ui/artemis.py b/artemis/ui/artemis.py index ce39396..16a2c53 100644 --- a/artemis/ui/artemis.py +++ b/artemis/ui/artemis.py @@ -6,10 +6,10 @@ from PySide6.QtCore import QObject, Slot, Signal from artemis.utils.constants import Constants, Messages from artemis.utils.sys_utils import open_directory, make_tar, unpack_tar from artemis.utils.sql_utils import ArtemisDatabase, ArtemisSignal -from artemis.utils.path_utils import DATA_DIR from artemis.utils.update_utils import UpdateManager from artemis.utils.generic_utils import generate_filter_query from artemis.utils.path_utils import normalize_dialog_path +from artemis.utils.path_utils import DATA_DIR from artemis.utils.config_utils import CONFIGURE_QT from artemis.ui.preferences import UIPreferences @@ -25,6 +25,7 @@ import artemis.resources class UIArtemis(QObject): # Python > QML Signals + close_ui = Signal() populate_sig_list = Signal(list) populate_sig_details = Signal(list) populate_filter_modulation = Signal(list) @@ -79,8 +80,8 @@ class UIArtemis(QObject): self._window.loadSignal.connect(self.load_sig) self._window.showPref.connect(self.show_pref_ui) self._window.openSigEditor.connect(self.open_sig_editor) - self._window.startDownloader.connect(self.start_download_db) - self._window.checkDbUpdates.connect(self.check_update_db) + self._window.checkForUpdate.connect(self.check_for_update) + self._window.updateDb.connect(self.update_db) self._window.updateArtemis.connect(self.update_artemis) self._window.showSpaceWeather.connect(self.show_space_weather_ui) self._window.openDbDirectory.connect(self.open_db_directory) @@ -99,6 +100,7 @@ class UIArtemis(QObject): self._window_signal.addCatTag.connect(self.add_cat_tag) # Python > QML connections + self.close_ui.connect(self._window.close) self.populate_sig_list.connect(self._window.populateList) self.clear_list.connect(self._window.clearList) self.update_info_bar.connect(self._window.bottomInfoBar) @@ -215,22 +217,12 @@ class UIArtemis(QObject): self.docmanager.load_documentsmanager_ui() - def check_update_db(self): - """ User manual check for updates db updates + def check_for_update(self): + """ User manual check for updates updates """ self.update_manager.check_updates(True) - def start_download_db(self): - """ Show the downloader and start the download of the sigid db - """ - self.downloader.finished.connect(self.update_manager.post_download_db) - self.downloader.on_start( - self.update_manager.remote_db_url, - DATA_DIR - ) - - def dialog_download_db(self, message_type, title, message): """ Dialog popup for DB download confirmation """ @@ -238,14 +230,23 @@ class UIArtemis(QObject): def dialog_update_artemis(self, message_type, title, message, auto=False): - """ Dialog popup for artemis download confirmation + """ Dialog popup for Artemis download confirmation """ self.show_dialog_update_artemis.emit(message_type, title, message, auto) + @Slot() + def update_db(self): + """ Start the download of the sigID DB + """ + self.update_manager.download_db() + + @Slot() def update_artemis(self): - print('ciao') + """ Start the download of Artemis + """ + self.update_manager.download_artemis() def open_db_directory(self): diff --git a/artemis/ui/downloader.py b/artemis/ui/downloader.py index b934999..209217d 100644 --- a/artemis/ui/downloader.py +++ b/artemis/ui/downloader.py @@ -55,7 +55,7 @@ class UIDownloader(QObject): url (str): url from where download the file save_path (str): path where to save the downloaded file """ - + self._clear_ui() self.show_ui.emit() self.file_url = QUrl(url) @@ -85,8 +85,6 @@ class UIDownloader(QObject): """ if self.reply: self.reply.abort() - self.update_progress_bar.emit(0, 0) - self.update_status.emit('') if self.file: self.file.cancelWriting() @@ -103,8 +101,8 @@ class UIDownloader(QObject): @Slot() def on_finished(self): - """ Finalize the download process and if no errors - occurs emits the finished signal usefulle for + """ Finalize the download process and, if no errors + occurs, emits the finished signal usefull for a callback """ if self.reply: @@ -144,6 +142,7 @@ class UIDownloader(QObject): def _get_filesize(self, url): """ Get the file size by sending a HEAD request to the URL. If the Content-Length in HTTP headers is missing, returns None + and set the progress_bar as 'indeterminate' like a 'busy indicator' Args: url (str): URL to check the file size @@ -157,6 +156,11 @@ class UIDownloader(QObject): return None + def _clear_ui(self): + self.update_progress_bar.emit(0, 0) + self.update_status.emit('') + + def show_popup_error(self, error_msg): self._parent.dialog_popup( Messages.DIALOG_TYPE_ERROR, diff --git a/artemis/utils/update_utils.py b/artemis/utils/update_utils.py index 2c56161..185a944 100644 --- a/artemis/utils/update_utils.py +++ b/artemis/utils/update_utils.py @@ -5,8 +5,8 @@ from packaging.version import Version from artemis.utils.constants import Constants, Messages from artemis.utils.sql_utils import ArtemisDatabase -from artemis.utils.sys_utils import is_windows, is_linux, is_macos, delete_file, delete_dir, match_hash, unpack_tar -from artemis.utils.path_utils import DATA_DIR +from artemis.utils.sys_utils import is_windows, is_linux, is_macos, delete_file, delete_dir, match_hash, unpack_tar, open_file +from artemis.utils.path_utils import DATA_DIR, APP_DIR class UpdateManager: @@ -26,19 +26,22 @@ class UpdateManager: self.remote_db_size = None self.remote_db_file_name = None - self.remote_art_version = None + self.remote_artemis_version = None + self.remote_artemis_url = None + self.remote_artemis_file_name = None self.check_updates() def check_updates(self, show_popup=False): """ Checks if a software or DB update is available. - Prioritize Artemis update over DB one. + Prioritize Artemis updates over the DB one. Args: show_popup (bool, optional): - Suppress the "already up-to-date" message on startup. - Defaults to False. + If False, suppress the "already up-to-date" message on startup. + Defaults to False. True is usefull when the user manual check for + updates. """ latest_json = self._fetch_remote_json(Constants.LATEST_VERSION_URL, show_popup) if latest_json: @@ -52,13 +55,18 @@ class UpdateManager: self.remote_db_file_name = self.remote_db_url.split('/')[-1] if is_windows(): - self.remote_art_version = latest_json['windows']['version'] + self.remote_artemis_version = latest_json['windows']['version'] + self.remote_artemis_url = latest_json['windows']['url'] elif is_linux(): - self.remote_art_version = latest_json['linux']['version'] + self.remote_artemis_version = latest_json['linux']['version'] + self.remote_artemis_url = latest_json['linux']['url'] elif is_macos(): - self.remote_art_version = latest_json['mac']['version'] + self.remote_artemis_version = latest_json['mac']['version'] + self.remote_artemis_url = latest_json['mac']['url'] + + self.remote_artemis_file_name = self.remote_artemis_url.split('/')[-1] - if Version(self.remote_art_version) > Version(Constants.APPLICATION_VERSION): + if Version(self.remote_artemis_version) > Version(Constants.APPLICATION_VERSION): self.art_update = True else: self.art_update = False @@ -77,6 +85,10 @@ class UpdateManager: def _fetch_remote_json(self, url, show_popup=False): """ Fetches the remote json from a url + + Args: + show_popup (bool, optional): If false, suppress any error message + Defaults to False (to avoid error if the program is used offline) """ try: response = requests.get(url) @@ -100,9 +112,25 @@ class UpdateManager: local_db.load() return local_db return None - + + + def download_db(self): + """ Open the downloader and download the sigID database in the + DATA_DIR folder. After a succesfull download the callback function + from the downloader is post_download_db + """ + self._parent.downloader.finished.connect(self.post_download_db) + self._parent.downloader.on_start( + self.remote_db_url, + DATA_DIR + ) + def post_download_db(self): + """ After a succesfull DB download, this function check the hash + for possible corrupted data, delete old sigID DB and extract + the new one + """ latest_db_tar_path = DATA_DIR / self.remote_db_file_name if match_hash(latest_db_tar_path, self.remote_db_hash): delete_dir(DATA_DIR / 'SigID') @@ -114,8 +142,29 @@ class UpdateManager: delete_file(latest_db_tar_path) + def download_artemis(self): + """ Open the downloader and download Artemis in the + APP_DIR folder. After a succesfull download the callback function + from the downloader is post_download_artemis + """ + self._parent.downloader.finished.connect(self.post_download_artemis) + self._parent.downloader.on_start( + self.remote_artemis_url, + APP_DIR + ) + + + def post_download_artemis(self): + """ After a succesfull Artemis download, this open the installer + and close the application + """ + if is_windows(): + open_file(APP_DIR / self.remote_artemis_file_name) + self._parent.close_ui.emit() + + def _show_popup_db_update(self): - """ Prompts the user to download the updated version of the database. + """ Prompts the user to download the updated version of the database """ self._parent.dialog_download_db( Messages.DIALOG_TYPE_WARN, @@ -133,20 +182,20 @@ class UpdateManager: self._parent.dialog_update_artemis( Messages.DIALOG_TYPE_QUEST, Messages.ART_NEW_VER, - Messages.ART_NEW_VER_AUTO_MSG.format(self.remote_art_version), + Messages.ART_NEW_VER_AUTO_MSG.format(self.remote_artemis_version), True ) else: self._parent.dialog_update_artemis( Messages.DIALOG_TYPE_QUEST, Messages.ART_NEW_VER, - Messages.ART_NEW_VER_MANUAL_MSG.format(self.remote_art_version), + Messages.ART_NEW_VER_MANUAL_MSG.format(self.remote_artemis_version), False ) def _show_popup_up_to_date(self): - """ Notifies the user that the database is up to date. + """ Notifies the user that the database is up to date """ self._parent.dialog_popup( Messages.DIALOG_TYPE_INFO, @@ -156,7 +205,7 @@ class UpdateManager: def _show_popup_initial_db_download(self): - """ Prompts the user to download the database for the first time. + """ Prompts the user to download the database for the first time """ self._parent.dialog_download_db( Messages.DIALOG_TYPE_QUEST, diff --git a/ui/Artemis.qml b/ui/Artemis.qml index c2f257c..4893877 100644 --- a/ui/Artemis.qml +++ b/ui/Artemis.qml @@ -31,8 +31,8 @@ Window { signal showCatManager() signal openSigEditor(string type, var sig_param, bool is_new) signal showSpaceWeather() - signal checkDbUpdates() - signal startDownloader() + signal checkForUpdate() + signal updateDb() signal updateArtemis() signal openDbDirectory() signal newDb(string name) @@ -137,7 +137,7 @@ Window { standardButtons: Dialog.Cancel | Dialog.Yes onAccepted: { - startDownloader() + updateDb() } } @@ -323,7 +323,7 @@ Window { MenuItem { text: "Check for Updates" - onClicked: {checkDbUpdates()} + onClicked: {checkForUpdate()} } MenuSeparator {} From f73034c35cb3c35b34f9692d4e032f624b995fca Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Thu, 13 Jun 2024 14:57:36 +0200 Subject: [PATCH 06/10] Preparatory update for the new update manager --- config/release-info.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/config/release-info.json b/config/release-info.json index 60b87c8..699f91a 100644 --- a/config/release-info.json +++ b/config/release-info.json @@ -6,12 +6,15 @@ "total_bytes": 244449280 }, "windows": { - "version": "4.0.3" + "version": "4.0.3", + "url": "https://github.com/AresValley/Artemis/releases/download/v4.0.3/Artemis-Windows-x86_64-4.0.3.exe" }, "linux": { - "version": "4.0.3" + "version": "4.0.3", + "url": "https://github.com/AresValley/Artemis/releases/download/v4.0.3/Artemis-Linux-x86_64-4.0.3.zip" }, "mac": { - "version": "4.0.0" + "version": "4.0.0", + "url": "" } } \ No newline at end of file From c58d85c6a2b874b97239bc842833a43ad0603724 Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Thu, 13 Jun 2024 15:52:47 +0200 Subject: [PATCH 07/10] Fixed bug of space_weather introduced with the new update_manager --- artemis/ui/spaceweather.py | 8 ++++---- artemis/utils/update_utils.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/artemis/ui/spaceweather.py b/artemis/ui/spaceweather.py index 89ed78f..7f3e521 100644 --- a/artemis/ui/spaceweather.py +++ b/artemis/ui/spaceweather.py @@ -53,10 +53,10 @@ class UIspaceweather(QObject): def download_poseidon_report(self): - network_manager = self._parent.network_manager - network_manager.show_popup = True - poseidon_data = network_manager.fetch_remote_json( - Constants.POSEIDON_REPORT_URL + update_manager = self._parent.update_manager + poseidon_data = update_manager.fetch_remote_json( + Constants.POSEIDON_REPORT_URL, + True ) if poseidon_data: self.load_poseidon_report.emit(poseidon_data) diff --git a/artemis/utils/update_utils.py b/artemis/utils/update_utils.py index 185a944..643dca4 100644 --- a/artemis/utils/update_utils.py +++ b/artemis/utils/update_utils.py @@ -43,7 +43,7 @@ class UpdateManager: Defaults to False. True is usefull when the user manual check for updates. """ - latest_json = self._fetch_remote_json(Constants.LATEST_VERSION_URL, show_popup) + latest_json = self.fetch_remote_json(Constants.LATEST_VERSION_URL, show_popup) if latest_json: local_db = self._load_local_db() remote_db = latest_json['sigID_DB'] @@ -83,7 +83,7 @@ class UpdateManager: self._show_popup_initial_db_download() - def _fetch_remote_json(self, url, show_popup=False): + def fetch_remote_json(self, url, show_popup=False): """ Fetches the remote json from a url Args: From 0f898ff6f5e2e2265b9f2970f36a4559e046d0c8 Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Thu, 13 Jun 2024 16:16:36 +0200 Subject: [PATCH 08/10] Introduced temporary folder --- artemis/utils/path_utils.py | 10 ++++++++++ artemis/utils/update_utils.py | 14 +++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/artemis/utils/path_utils.py b/artemis/utils/path_utils.py index aa7ffd9..8c800d1 100644 --- a/artemis/utils/path_utils.py +++ b/artemis/utils/path_utils.py @@ -36,6 +36,15 @@ def _data_dir(): return data_dir_path +def _tmp_dir(): + if is_windows(): + tmp_dir_path = Path.home() / 'AppData' / 'Local' / 'Temp' + else: + tmp_dir_path = Path('/tmp') + + return tmp_dir_path + + def _preference_dir(): preference_dir_path = APP_DIR / 'config' if not preference_dir_path.exists(): @@ -46,4 +55,5 @@ def _preference_dir(): BASE_DIR = Path(os.path.dirname(__file__)) / '../..' APP_DIR = _app_dir() DATA_DIR = _data_dir() +TMP_DIR = _tmp_dir() PREFERENCES_DIR = _preference_dir() diff --git a/artemis/utils/update_utils.py b/artemis/utils/update_utils.py index 643dca4..b68d397 100644 --- a/artemis/utils/update_utils.py +++ b/artemis/utils/update_utils.py @@ -6,7 +6,7 @@ from packaging.version import Version from artemis.utils.constants import Constants, Messages from artemis.utils.sql_utils import ArtemisDatabase from artemis.utils.sys_utils import is_windows, is_linux, is_macos, delete_file, delete_dir, match_hash, unpack_tar, open_file -from artemis.utils.path_utils import DATA_DIR, APP_DIR +from artemis.utils.path_utils import DATA_DIR, TMP_DIR class UpdateManager: @@ -116,13 +116,13 @@ class UpdateManager: def download_db(self): """ Open the downloader and download the sigID database in the - DATA_DIR folder. After a succesfull download the callback function + TMP_DIR folder. After a succesfull download the callback function from the downloader is post_download_db """ self._parent.downloader.finished.connect(self.post_download_db) self._parent.downloader.on_start( self.remote_db_url, - DATA_DIR + TMP_DIR ) @@ -131,7 +131,7 @@ class UpdateManager: for possible corrupted data, delete old sigID DB and extract the new one """ - latest_db_tar_path = DATA_DIR / self.remote_db_file_name + latest_db_tar_path = TMP_DIR / self.remote_db_file_name if match_hash(latest_db_tar_path, self.remote_db_hash): delete_dir(DATA_DIR / 'SigID') unpack_tar(latest_db_tar_path, DATA_DIR / 'SigID') @@ -144,13 +144,13 @@ class UpdateManager: def download_artemis(self): """ Open the downloader and download Artemis in the - APP_DIR folder. After a succesfull download the callback function + TMP_DIR folder. After a succesfull download the callback function from the downloader is post_download_artemis """ self._parent.downloader.finished.connect(self.post_download_artemis) self._parent.downloader.on_start( self.remote_artemis_url, - APP_DIR + TMP_DIR ) @@ -159,7 +159,7 @@ class UpdateManager: and close the application """ if is_windows(): - open_file(APP_DIR / self.remote_artemis_file_name) + open_file(TMP_DIR / self.remote_artemis_file_name) self._parent.close_ui.emit() From 1d0c459402eaf8b4522c721fdcc2526eb1190b5e Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Thu, 13 Jun 2024 19:19:21 +0200 Subject: [PATCH 09/10] Fixed a potential issue where the downloader window closes but the downloader instance keeps running --- artemis/resources.py | 189 ++++++++++++++++++++------------------- artemis/ui/downloader.py | 4 +- ui/Downloader.qml | 4 + 3 files changed, 101 insertions(+), 96 deletions(-) diff --git a/artemis/resources.py b/artemis/resources.py index 16a0cb5..9a29f71 100644 --- a/artemis/resources.py +++ b/artemis/resources.py @@ -6638,7 +6638,7 @@ G@\x11\x10HG\x93Hp\xec\x0au\xe3\xcd\x1e\xf4\ >k\xd0\xd3b\x1eG\xb5_d\xde\xb6{\x8f\x95\xc5\ U\xaf\xbc\xfd\xe9\xb5\x9f\xe5\xe3}r\xba?\xbbI\x06\ \xfe\xfc\x0f\xf4\xcd*2\ -\x00\x00\x070\ +\x00\x00\x07^\ i\ mport QtQuick\x0d\x0ai\ mport QtQuick.Wi\ @@ -6667,94 +6667,97 @@ Qt.Dialog\x0d\x0a\x0d\x0a \ temis - Download\ er\x22)\x0d\x0a\x0d\x0a sign\ al onAbort()\x0d\x0a\x0d\x0a\ - function upd\ -ateProgressBar(b\ -ytesReceived, by\ -tesTotal) {\x0d\x0a \ - progressBar\ -.value = bytesRe\ -ceived\x0d\x0a \ -progressBar.to =\ - bytesTotal\x0d\x0a \ - }\x0d\x0a\x0d\x0a functi\ -on setIndetermin\ -ateBar() {\x0d\x0a \ - progressBar.\ -indeterminate = \ -true\x0d\x0a }\x0d\x0a\x0d\x0a \ - function upda\ -teStatus(arg) {\x0d\ -\x0a progres\ -sLabel.text = ar\ -g\x0d\x0a }\x0d\x0a\x0d\x0a \ -Page {\x0d\x0a \ -id: page\x0d\x0a \ - anchors.fill: \ -parent\x0d\x0a\x0d\x0a \ - ColumnLayout {\ -\x0d\x0a id\ -: columnLayout\x0d\x0a\ - anch\ -ors.fill: parent\ -\x0d\x0a\x0d\x0a \ -Label {\x0d\x0a \ - text: q\ -sTr(\x22Downloading\ - in progress...\x22\ -)\x0d\x0a \ - Layout.alignm\ -ent: Qt.AlignHCe\ -nter | Qt.AlignV\ -Center\x0d\x0a \ - }\x0d\x0a\x0d\x0a \ - ProgressBar\ - {\x0d\x0a \ - id: progress\ -Bar\x0d\x0a \ - Layout.righ\ -tMargin: 20\x0d\x0a \ - Lay\ -out.leftMargin: \ -20\x0d\x0a \ - Layout.fillW\ -idth: true\x0d\x0a \ - inde\ -terminate: false\ + onClosing: {\ +\x0d\x0a onAbor\ +t()\x0d\x0a }\x0d\x0a\x0d\x0a \ + function updat\ +eProgressBar(byt\ +esReceived, byte\ +sTotal) {\x0d\x0a \ + progressBar.v\ +alue = bytesRece\ +ived\x0d\x0a pr\ +ogressBar.to = b\ +ytesTotal\x0d\x0a }\ +\x0d\x0a\x0d\x0a function\ + setIndeterminat\ +eBar() {\x0d\x0a \ + progressBar.in\ +determinate = tr\ +ue\x0d\x0a }\x0d\x0a\x0d\x0a \ + function update\ +Status(arg) {\x0d\x0a \ + progressL\ +abel.text = arg\x0d\ +\x0a }\x0d\x0a\x0d\x0a Pa\ +ge {\x0d\x0a id\ +: page\x0d\x0a \ +anchors.fill: pa\ +rent\x0d\x0a\x0d\x0a \ +ColumnLayout {\x0d\x0a\ + id: \ +columnLayout\x0d\x0a \ + anchor\ +s.fill: parent\x0d\x0a\ +\x0d\x0a La\ +bel {\x0d\x0a \ + text: qsT\ +r(\x22Downloading i\ +n progress...\x22)\x0d\ +\x0a \ + Layout.alignmen\ +t: Qt.AlignHCent\ +er | Qt.AlignVCe\ +nter\x0d\x0a \ + }\x0d\x0a\x0d\x0a \ + ProgressBar {\ \x0d\x0a \ - value: 0\x0d\x0a \ - to: \ -0\x0d\x0a }\ -\x0d\x0a\x0d\x0a \ -Label {\x0d\x0a \ - id: pro\ -gressLabel\x0d\x0a \ - Layo\ -ut.alignment: Qt\ -.AlignHCenter | \ -Qt.AlignVCenter\x0d\ + id: progressBa\ +r\x0d\x0a \ + Layout.rightM\ +argin: 20\x0d\x0a \ + Layou\ +t.leftMargin: 20\ +\x0d\x0a \ + Layout.fillWid\ +th: true\x0d\x0a \ + indete\ +rminate: false\x0d\x0a\ + \ +value: 0\x0d\x0a \ + to: 0\x0d\ \x0a }\x0d\x0a\ -\x0d\x0a Bu\ -tton {\x0d\x0a \ - Layout.a\ -lignment: Qt.Ali\ -gnHCenter | Qt.A\ -lignBottom\x0d\x0a \ - text\ -: qsTr(\x22Abort\x22)\x0d\ -\x0a \ - icon.source: \x22q\ -rc:/images/icons\ -/abort.svg\x22\x0d\x0a \ - dis\ -play: AbstractBu\ -tton.TextBesideI\ -con\x0d\x0a \ - flat: true\x0d\ -\x0a \ - onClicked: { on\ -Abort() }\x0d\x0a \ - }\x0d\x0a \ - }\x0d\x0a }\x0d\x0a}\x0d\x0a\ +\x0d\x0a La\ +bel {\x0d\x0a \ + id: progr\ +essLabel\x0d\x0a \ + Layout\ +.alignment: Qt.A\ +lignHCenter | Qt\ +.AlignVCenter\x0d\x0a \ + }\x0d\x0a\x0d\x0a\ + Butt\ +on {\x0d\x0a \ + Layout.ali\ +gnment: Qt.Align\ +HCenter | Qt.Ali\ +gnBottom\x0d\x0a \ + text: \ +qsTr(\x22Abort\x22)\x0d\x0a \ + i\ +con.source: \x22qrc\ +:/images/icons/a\ +bort.svg\x22\x0d\x0a \ + displ\ +ay: AbstractButt\ +on.TextBesideIco\ +n\x0d\x0a \ + flat: true\x0d\x0a \ + o\ +nClicked: { onAb\ +ort() }\x0d\x0a \ + }\x0d\x0a \ +}\x0d\x0a }\x0d\x0a}\x0d\x0a\ \x00\x00\x05\xac\ i\ mport QtQuick\x0d\x0ai\ @@ -7305,12 +7308,12 @@ qt_resource_struct = b"\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03<\x00\x01\x00\x00\x00\x01\x00\x01>\xe2\ \x00\x00\x01\x90\x11\xc7\x00\xf9\ -\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xa0\xab\ +\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xa0\xd9\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01I=\ \x00\x00\x01\x8f\xff^8_\ \x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99w\ -\x00\x00\x01\x90\x11\xad[\xc5\ +\x00\x00\x01\x90\x12\x9a\x0f\x0b\ \x00\x00\x03X\x00\x02\x00\x00\x00\x04\x00\x00\x00+\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01vE\ @@ -7329,13 +7332,13 @@ qt_resource_struct = b"\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x05\x06\x00\x00\x00\x00\x00\x01\x00\x01\x85\xde\ \x00\x00\x01\x8f\xff^8P\ -\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa9^\ +\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa9\x8c\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xaf\xa3\ +\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xaf\xd1\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa6[\ +\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa6\x89\ \x00\x00\x01\x8f\xff^8_\ -\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xac!\ +\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xacO\ \x00\x00\x01\x8f\xff^8_\ " diff --git a/artemis/ui/downloader.py b/artemis/ui/downloader.py index 209217d..d73b69d 100644 --- a/artemis/ui/downloader.py +++ b/artemis/ui/downloader.py @@ -74,9 +74,7 @@ class UIDownloader(QObject): self.reply.errorOccurred.connect(self.on_error) else: self.close_ui.emit() - self.show_popup_error( - self.file.errorString() - ) + self.show_popup_error(self.file.errorString()) @Slot() diff --git a/ui/Downloader.qml b/ui/Downloader.qml index 039b574..61a2e11 100644 --- a/ui/Downloader.qml +++ b/ui/Downloader.qml @@ -24,6 +24,10 @@ Window { signal onAbort() + onClosing: { + onAbort() + } + function updateProgressBar(bytesReceived, bytesTotal) { progressBar.value = bytesReceived progressBar.to = bytesTotal From c17c1fdbea5712b9979f959a66bc3fcea6168092 Mon Sep 17 00:00:00 2001 From: Marco Dalla Tiezza Date: Fri, 14 Jun 2024 01:01:53 +0200 Subject: [PATCH 10/10] Updated resources --- artemis/resources.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/artemis/resources.py b/artemis/resources.py index 9a29f71..b234ef6 100644 --- a/artemis/resources.py +++ b/artemis/resources.py @@ -7307,23 +7307,23 @@ qt_resource_struct = b"\ \x00\x00\x03\x12\x00\x01\x00\x00\x00\x01\x00\x019\x8e\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03<\x00\x01\x00\x00\x00\x01\x00\x01>\xe2\ -\x00\x00\x01\x90\x11\xc7\x00\xf9\ +\x00\x00\x01\x90\x13\xaa\xb2v\ \x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xa0\xd9\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01I=\ \x00\x00\x01\x8f\xff^8_\ \x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99w\ -\x00\x00\x01\x90\x12\x9a\x0f\x0b\ +\x00\x00\x01\x90\x13\xaa\xb2v\ \x00\x00\x03X\x00\x02\x00\x00\x00\x04\x00\x00\x00+\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01vE\ -\x00\x00\x01\x90\x11\xad[\xc5\ +\x00\x00\x01\x90\x13\xaa\xb2}\ \x00\x00\x05d\x00\x01\x00\x00\x00\x01\x00\x01\x8f[\ \x00\x00\x01\x90\x01\x93J\xb0\ \x00\x00\x04\xe6\x00\x01\x00\x00\x00\x01\x00\x01\x7f=\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x04H\x00\x01\x00\x00\x00\x01\x00\x01b-\ -\x00\x00\x01\x90\x11\xad[\xc5\ +\x00\x00\x01\x90\x13\xaa\xb2v\ \x00\x00\x04v\x00\x00\x00\x00\x00\x01\x00\x01nR\ \x00\x00\x01\x8f\xff^8P\ \x00\x00\x04\x9e\x00\x01\x00\x00\x00\x01\x00\x01t\x17\