1
0
Fork 0
mirror of synced 2024-07-03 05:31:23 +12:00
Rare/rare/components/tabs/downloads/widgets.py
loathingKernel 2ef70b8eb4 InstallQueueItemModel: Refactor to add an expiration date to the download
While not sure if it is required, add an expiration date to the prepared
download 30 minutes after it was prepared. If a download has been in the
queue for more than 30 minutes, the download will be prepared again silently
before starting.

Return only the `InstallOptionsModel` in the result of the download thread
to avoid the potential mistake of re-using it. This required for the tray
notification signal to operate on the `app_name` instead of the `app_title`.
As a result, the notification slot was moved into the TrayIcon class for
better encapsulation.
2023-02-04 17:38:07 +02:00

161 lines
6.6 KiB
Python

from logging import getLogger
from typing import Optional
from PyQt5.QtCore import pyqtSignal, Qt, QThreadPool, pyqtSlot
from PyQt5.QtWidgets import QWidget, QFrame
from legendary.models.downloading import AnalysisResult
from legendary.models.game import Game, InstalledGame
from qtawesome import icon
from rare.models.install import InstallQueueItemModel, InstallOptionsModel, InstallDownloadModel
from rare.shared import RareCore, ImageManagerSingleton
from rare.shared.workers.install_info import InstallInfoWorker
from rare.ui.components.tabs.downloads.download_widget import Ui_DownloadWidget
from rare.ui.components.tabs.downloads.info_widget import Ui_InfoWidget
from rare.utils.misc import get_size, widget_object_name, elide_text
from rare.widgets.image_widget import ImageWidget, ImageSize
logger = getLogger("DownloadWidgets")
class InfoWidget(QWidget):
def __init__(
self,
game: Optional[Game],
igame: Optional[InstalledGame],
analysis: Optional[AnalysisResult] = None,
old_igame: Optional[InstalledGame] = None,
parent=None,
):
super(InfoWidget, self).__init__(parent=parent)
self.ui = Ui_InfoWidget()
self.ui.setupUi(self)
self.image_manager = ImageManagerSingleton()
self.image = ImageWidget(self)
self.image.setFixedSize(ImageSize.Icon)
self.ui.image_layout.addWidget(self.image)
self.ui.info_widget_layout.setAlignment(Qt.AlignTop)
if game and igame:
self.update_information(game, igame, analysis, old_igame)
elif old_igame:
self.ui.title.setText(old_igame.title)
self.ui.remote_version.setText("...")
self.ui.local_version.setText("...")
self.ui.dl_size.setText("...")
self.ui.install_size.setText("...")
self.image.setPixmap(self.image_manager.get_pixmap(old_igame.app_name, color=True))
def update_information(self, game, igame, analysis, old_igame):
self.ui.title.setText(game.app_title)
self.ui.remote_version.setText(
elide_text(self.ui.remote_version, old_igame.version if old_igame else game.app_version(igame.platform))
)
self.ui.local_version.setText(elide_text(self.ui.local_version, igame.version))
self.ui.dl_size.setText(get_size(analysis.dl_size) if analysis else "")
self.ui.install_size.setText(get_size(analysis.install_size) if analysis else "")
self.image.setPixmap(self.image_manager.get_pixmap(game.app_name, color=True))
class UpdateWidget(QFrame):
enqueue = pyqtSignal(InstallOptionsModel)
def __init__(self, game: Game, igame: InstalledGame, parent=None):
super(UpdateWidget, self).__init__(parent=parent)
self.ui = Ui_DownloadWidget()
self.ui.setupUi(self)
# lk: setObjectName has to be after `setupUi` because it is also set in that function
self.setObjectName(widget_object_name(self, game.app_name))
self.game = game
self.igame = igame
self.ui.queue_buttons.setVisible(False)
self.ui.move_buttons.setVisible(False)
self.info_widget = InfoWidget(game, igame, parent=self)
self.ui.info_layout.addWidget(self.info_widget)
self.ui.update_button.clicked.connect(lambda: self.update_game(True))
self.ui.settings_button.clicked.connect(lambda: self.update_game(False))
def update_game(self, auto: bool):
self.ui.update_button.setDisabled(True)
self.ui.settings_button.setDisabled(True)
self.enqueue.emit(InstallOptionsModel(app_name=self.game.app_name, update=True, silent=auto)) # True if settings
def set_enabled(self, enabled: bool):
self.ui.update_button.setEnabled(enabled)
self.ui.settings_button.setEnabled(enabled)
def version(self) -> str:
return self.game.app_version(self.igame.platform)
class QueueWidget(QFrame):
# str: app_name
move_up = pyqtSignal(str)
# str: app_name
move_down = pyqtSignal(str)
# str: app_name
remove = pyqtSignal(str)
# InstallQueueItemModel
force = pyqtSignal(InstallQueueItemModel)
def __init__(self, item: InstallQueueItemModel, old_igame: InstalledGame, parent=None):
super(QueueWidget, self).__init__(parent=parent)
self.ui = Ui_DownloadWidget()
self.ui.setupUi(self)
# lk: setObjectName has to be after `setupUi` because it is also set in that function
self.setObjectName(widget_object_name(self, item.options.app_name))
if not item:
self.ui.queue_buttons.setEnabled(False)
worker = InstallInfoWorker(RareCore.instance().core(), item.options)
worker.signals.result.connect(self.__update_info)
worker.signals.failed.connect(
lambda m: logger.error(f"Failed to requeue download for {item.options.app_name} with error: {m}")
)
worker.signals.failed.connect(lambda m: self.remove.emit(item.options.app_name))
worker.signals.finished.connect(
lambda: logger.info(f"Download requeue worker finished for {item.options.app_name}")
)
QThreadPool.globalInstance().start(worker)
self.info_widget = InfoWidget(None, None, None, old_igame, parent=self)
else:
self.info_widget = InfoWidget(
item.download.game, item.download.igame, item.download.analysis, old_igame, parent=self
)
self.ui.info_layout.addWidget(self.info_widget)
self.ui.update_buttons.setVisible(False)
self.old_igame = old_igame
self.item = item
self.ui.move_up_button.setIcon(icon("fa.arrow-up"))
self.ui.move_up_button.clicked.connect(
lambda: self.move_up.emit(self.item.options.app_name)
)
self.ui.move_down_button.setIcon(icon("fa.arrow-down"))
self.ui.move_down_button.clicked.connect(
lambda: self.move_down.emit(self.item.options.app_name)
)
self.ui.remove_button.clicked.connect(lambda: self.remove.emit(self.item.options.app_name))
self.ui.force_button.clicked.connect(lambda: self.force.emit(self.item))
@pyqtSlot(InstallDownloadModel)
def __update_info(self, download: InstallDownloadModel):
self.item.download = download
if self.item:
self.info_widget.update_information(download.game, download.igame, download.analysis, self.old_igame)
self.ui.queue_buttons.setEnabled(bool(self.item))
def toggle_arrows(self, index: int, length: int):
self.ui.move_up_button.setEnabled(bool(index))
self.ui.move_down_button.setEnabled(bool(length - (index + 1)))