2ef70b8eb4
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.
160 lines
6.6 KiB
Python
160 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)))
|