From 408dd5e4ce492ea4b33fe43f9b8082885f10a435 Mon Sep 17 00:00:00 2001 From: alessandro90 Date: Sat, 29 Jun 2019 00:24:45 +0200 Subject: [PATCH] Update the download speed every 2s. Speed is the average in the 2s. Also update downloaded MB only if at least 1 MB has been downloaded since last update. --- constants.py | 2 ++ download_db_window.ui | 18 +++++++++++++++--- download_window.py | 39 +++++++++++++++++++++++++-------------- threads.py | 24 ++++++++++++++++++------ 4 files changed, 60 insertions(+), 23 deletions(-) diff --git a/constants.py b/constants.py index 59b0656..a6847e1 100644 --- a/constants.py +++ b/constants.py @@ -186,6 +186,8 @@ class Constants: UNKNOWN = "N/A" EXTRACTING_MSG = "Extracting..." EXTRACTING_CODE = -1 + ZERO_INITIAL_SPEED = -1 + ZERO_FINAL_SPEED = -2 NOT_AVAILABLE = "spectrumnotavailable.png" NOT_SELECTED = "nosignalselected.png" FIELD_SEPARATOR = ";" diff --git a/download_db_window.ui b/download_db_window.ui index b982512..6e63c27 100644 --- a/download_db_window.ui +++ b/download_db_window.ui @@ -21,9 +21,6 @@ - - QLayout::SetDefaultConstraint - @@ -56,6 +53,21 @@ Please wait... + + + + + 12 + + + + Speed + + + Qt::AlignCenter + + + diff --git a/download_window.py b/download_window.py index 763cdc8..ba21b9a 100644 --- a/download_window.py +++ b/download_window.py @@ -44,6 +44,7 @@ class DownloadWindow(QWidget, Ui_Download_window): self._download_thread = DownloadThread() self._download_thread.finished.connect(self._wait_close) self._download_thread.progress.connect(self._display_progress) + self._download_thread.speed_progress.connect(self._display_speed) self.closed.connect(self._download_thread.set_exit) self.cancel_btn.clicked.connect(self._terminate_process) @@ -51,28 +52,38 @@ class DownloadWindow(QWidget, Ui_Download_window): """Start the download thread.""" self._download_thread.start() - def _downlaod_format_str(self, n, speed): - """Return a well-formatted string with downloaded MB and speed.""" - ret = f"Downloaded: {n} MB\nSpeed: " - if speed == 0.0: + def _downlaod_format_str(self, n): + """Return a well-formatted string with the downloaded MB.""" + return f"Downloaded: {n} MB" + + @pyqtSlot(float) + def _display_speed(self, speed): + """Display the download speed.""" + ret = "Speed: " + if speed == Constants.ZERO_INITIAL_SPEED: + ret += "Calculating..." + elif speed == 0.0: ret += "VERY SLOW" + elif speed == Constants.ZERO_FINAL_SPEED: + ret = "" else: ret += f"{speed} MB/s" - return ret + self.speed_lbl.setText(ret) + + @pyqtSlot(int) + def _display_progress(self, progress): + """Display the downloaded MB.""" + if progress != Constants.EXTRACTING_CODE: + self.status_lbl.setText(self._downlaod_format_str(progress)) + elif progress == Constants.EXTRACTING_CODE: + self.status_lbl.setText(Constants.EXTRACTING_MSG) def show(self): """Extends QWidget.show. Set downloaded MB and speed to zero.""" - self.status_lbl.setText(self._downlaod_format_str(0, 0)) + self._display_progress(0) + self._display_speed(Constants.ZERO_INITIAL_SPEED) super().show() - @pyqtSlot(int, float) - def _display_progress(self, progress, speed): - """Display the downloaded MB and speed.""" - if progress != Constants.EXTRACTING_CODE: - self.status_lbl.setText(self._downlaod_format_str(progress, speed)) - elif progress == Constants.EXTRACTING_CODE: - self.status_lbl.setText(Constants.EXTRACTING_MSG + '\n') - def _stop_thread(self): """Ask the download thread to stop.""" if self._download_thread.isRunning(): diff --git a/threads.py b/threads.py index ed965f6..830de03 100644 --- a/threads.py +++ b/threads.py @@ -45,9 +45,11 @@ class BaseDownloadThread(QThread): class DownloadThread(BaseDownloadThread): """Subclass BaseDownloadThread. Download the database, images and audio samples.""" - progress = pyqtSignal(int, float) + progress = pyqtSignal(int) + speed_progress = pyqtSignal(float) _CHUNK = 128 * 1024 _MEGA = 1024**2 + _DELTAT = 2 def __init__(self): """Just call super().__init__.""" @@ -80,6 +82,7 @@ class DownloadThread(BaseDownloadThread): self.status = ThreadStatus.UNDEFINED self._db = None raw_data = bytes(0) + sub_data = bytes(0) try: self._db = urllib3.PoolManager().request( 'GET', @@ -88,6 +91,7 @@ class DownloadThread(BaseDownloadThread): timeout=4.0 ) start = perf_counter() + prev_downloaded = 0 while True: try: data = self._db.read(self._CHUNK) @@ -98,10 +102,17 @@ class DownloadThread(BaseDownloadThread): if not data: break raw_data += data - self.progress.emit( - self._pretty_len(raw_data), - self._get_download_speed(raw_data, delta) - ) + sub_data += data + # Emit a progress signal only if at least 1 MB has been downloaded. + if len(raw_data) - prev_downloaded >= self._MEGA: + prev_downloaded = len(raw_data) + self.progress.emit(self._pretty_len(raw_data)) + if delta >= self._DELTAT: + self.speed_progress.emit( + self._get_download_speed(sub_data, delta) + ) + sub_data = bytes(0) + start = perf_counter() if self._exit_call: self._exit_call = False self._db.release_conn() @@ -128,7 +139,8 @@ class DownloadThread(BaseDownloadThread): if os.path.exists(Constants.DATA_FOLDER): rmtree(Constants.DATA_FOLDER) try: - self.progress.emit(Constants.EXTRACTING_CODE, 0.0) + self.progress.emit(Constants.EXTRACTING_CODE) + self.speed_progress.emit(Constants.ZERO_FINAL_SPEED) with ZipFile(BytesIO(raw_data)) as zipped: zipped.extractall() except Exception: