[view.qt] refactoring: using a different approach to cancel file downloads to keep compatibility with older Python versions

This commit is contained in:
Vinicius Moreira
2023-12-12 18:14:12 -03:00
parent d0a7da8ffd
commit 3b7b22c9c7
3 changed files with 27 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
import operator
import os
from functools import reduce
from logging import Logger
from threading import Lock
from typing import List, Optional, Dict
@@ -71,12 +72,13 @@ class PackagesTable(QTableWidget):
COL_NUMBER = 9
DEFAULT_ICON_SIZE = QSize(16, 16)
def __init__(self, parent: QWidget, icon_cache: MemoryCache, download_icons: bool):
def __init__(self, parent: QWidget, icon_cache: MemoryCache, download_icons: bool, logger: Logger):
super(PackagesTable, self).__init__()
self.setObjectName('table_packages')
self.setParent(parent)
self.window = parent
self.download_icons = download_icons
self.logger = logger
self.setColumnCount(self.COL_NUMBER)
self.setFocusPolicy(Qt.NoFocus)
self.setShowGrid(False)
@@ -614,9 +616,10 @@ class PackagesTable(QTableWidget):
return reduce(operator.add, [self.columnWidth(i) for i in range(self.columnCount())])
def _setup_file_downloader(self, max_workers: int = 50, max_downloads: int = -1) -> None:
self.file_downloader = URLFileDownloader(parent=self,
self.file_downloader = URLFileDownloader(logger=self.logger,
max_workers=max_workers,
max_downloads=max_downloads)
max_downloads=max_downloads,
parent=self)
self.file_downloader.signal_downloaded.connect(self._update_pkg_icon)
self.file_downloader.start()

View File

@@ -1117,9 +1117,10 @@ class URLFileDownloader(QThread):
signal_downloaded = pyqtSignal(str, bytes, object)
def __init__(self, max_workers: int = 50, request_timeout: int = 30, inactivity_timeout: int = 3,
def __init__(self, logger: Logger, max_workers: int = 50, request_timeout: int = 30, inactivity_timeout: int = 3,
max_downloads: int = -1, parent: Optional[QWidget] = None):
super().__init__(parent)
self._logger = logger
self._queue = Queue()
self._max_workers = max_workers
self._request_timeout = request_timeout
@@ -1129,6 +1130,7 @@ class URLFileDownloader(QThread):
def _get(self, url_: str, id_: Optional[object]):
if self._stop:
self._logger.info(f"File '{url_}' download cancelled")
return
try:
@@ -1136,21 +1138,31 @@ class URLFileDownloader(QThread):
content = res.content if res.status_code == 200 else None
self.signal_downloaded.emit(url_, content, id_)
except Exception as e:
sys.stderr.write(f"[ERROR] could not download file from '{url_}': "
f"{e.__class__.__name__}({str(e.args)})\n")
self._logger.error(f"[ERROR] could not download file from '{url_}': "
f"{e.__class__.__name__}({str(e.args)})\n")
def run(self) -> None:
download_count = 0
futures = []
with ThreadPoolExecutor(max_workers=self._max_workers) as executor:
while not self._stop and (self._max_downloads <= 0 or download_count < self._max_downloads):
try:
url_, id_ = self._queue.get(timeout=self._inactivity_timeout)
executor.submit(self._get, url_, id_)
futures.append(executor.submit(self._get, url_, id_))
download_count += 1
except Exception:
self._stop = True
executor.shutdown(wait=False, cancel_futures=True)
cancelled_count = 0
for f in futures:
if not f.done():
f.cancel()
cancelled_count += 1
if cancelled_count > 0:
self._logger.info(f"{cancelled_count} file downloads cancelled")
self._logger.info(f"Finished to download files (count={download_count})")
def stop(self) -> None:
self._stop = True

View File

@@ -290,8 +290,10 @@ class ManageWindow(QWidget):
self.table_container.setLayout(QVBoxLayout())
self.table_container.layout().setContentsMargins(0, 0, 0, 0)
self.table_apps = PackagesTable(self, self.icon_cache,
download_icons=bool(self.config['download']['icons']))
self.table_apps = PackagesTable(parent=self,
icon_cache=self.icon_cache,
download_icons=bool(self.config['download']['icons']),
logger=logger)
self.table_apps.change_headers_policy()
self.table_container.layout().addWidget(self.table_apps)