QueueWidget: Prepare requeued downloads after adding it.
By preparing the download inside the widget, the delay after stopping the running download and visual feedback of adding the widget is reduced. The widget will now appear containing the basic information and will be populated with the information about the download when it is ready. The widget is disabled in the meantime. Move `InstallInfoWorker` to `rare.shared.workers` module and revert it to emitting a `InstallDownloadItem` model only instead of a `InstallQueueItemModel.`
This commit is contained in:
parent
0830c17ee5
commit
523391d166
5 changed files with 159 additions and 124 deletions
|
@ -1,24 +1,17 @@
|
||||||
import os
|
import os
|
||||||
import platform as pf
|
import platform as pf
|
||||||
import sys
|
|
||||||
from typing import Tuple, List, Union, Optional
|
from typing import Tuple, List, Union, Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, QRunnable, pyqtSignal, pyqtSlot
|
|
||||||
from PyQt5.QtCore import Qt, QThreadPool, QSettings
|
from PyQt5.QtCore import Qt, QThreadPool, QSettings
|
||||||
|
from PyQt5.QtCore import pyqtSignal, pyqtSlot
|
||||||
from PyQt5.QtGui import QCloseEvent, QKeyEvent
|
from PyQt5.QtGui import QCloseEvent, QKeyEvent
|
||||||
from PyQt5.QtWidgets import QDialog, QFileDialog, QCheckBox, QLayout, QWidget, QVBoxLayout, QApplication
|
from PyQt5.QtWidgets import QDialog, QFileDialog, QCheckBox, QLayout, QWidget, QVBoxLayout, QApplication
|
||||||
from legendary.lfs.eos import EOSOverlayApp
|
|
||||||
from legendary.models.downloading import ConditionCheckResult
|
|
||||||
from legendary.utils.selective_dl import get_sdl_appname
|
from legendary.utils.selective_dl import get_sdl_appname
|
||||||
|
|
||||||
from rare.lgndr.cli import LegendaryCLI
|
|
||||||
from rare.lgndr.core import LegendaryCore
|
|
||||||
from rare.lgndr.glue.arguments import LgndrInstallGameArgs
|
|
||||||
from rare.lgndr.glue.exception import LgndrException
|
|
||||||
from rare.lgndr.glue.monkeys import LgndrIndirectStatus
|
|
||||||
from rare.models.game import RareGame
|
from rare.models.game import RareGame
|
||||||
from rare.models.install import InstallDownloadModel, InstallQueueItemModel, InstallOptionsModel
|
from rare.models.install import InstallDownloadModel, InstallQueueItemModel, InstallOptionsModel
|
||||||
from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton
|
from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton
|
||||||
|
from rare.shared.workers.install_info import InstallInfoWorker
|
||||||
from rare.ui.components.dialogs.install_dialog import Ui_InstallDialog
|
from rare.ui.components.dialogs.install_dialog import Ui_InstallDialog
|
||||||
from rare.ui.components.dialogs.install_dialog_advanced import Ui_InstallDialogAdvanced
|
from rare.ui.components.dialogs.install_dialog_advanced import Ui_InstallDialogAdvanced
|
||||||
from rare.utils import config_helper
|
from rare.utils import config_helper
|
||||||
|
@ -291,11 +284,11 @@ class InstallDialog(QDialog):
|
||||||
self.reject_close = False
|
self.reject_close = False
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
@pyqtSlot(InstallQueueItemModel)
|
@pyqtSlot(InstallDownloadModel)
|
||||||
def on_worker_result(self, dl_item: InstallQueueItemModel):
|
def on_worker_result(self, download: InstallDownloadModel):
|
||||||
self.__download = dl_item.download
|
self.__download = download
|
||||||
download_size = dl_item.download.analysis.dl_size
|
download_size = download.analysis.dl_size
|
||||||
install_size = dl_item.download.analysis.install_size
|
install_size = download.analysis.install_size
|
||||||
# install_size = self.dl_item.download.analysis.disk_space_delta
|
# install_size = self.dl_item.download.analysis.disk_space_delta
|
||||||
if download_size:
|
if download_size:
|
||||||
self.ui.download_size_text.setText(get_size(download_size))
|
self.ui.download_size_text.setText(get_size(download_size))
|
||||||
|
@ -309,12 +302,12 @@ class InstallDialog(QDialog):
|
||||||
self.ui.verify_button.setEnabled(self.options_changed)
|
self.ui.verify_button.setEnabled(self.options_changed)
|
||||||
self.ui.cancel_button.setEnabled(True)
|
self.ui.cancel_button.setEnabled(True)
|
||||||
if pf.system() == "Windows" or ArgumentsSingleton().debug:
|
if pf.system() == "Windows" or ArgumentsSingleton().debug:
|
||||||
if dl_item.download.igame.prereq_info and not dl_item.download.igame.prereq_info.get("installed", False):
|
if download.igame.prereq_info and not download.igame.prereq_info.get("installed", False):
|
||||||
self.advanced.ui.install_prereqs_check.setEnabled(True)
|
self.advanced.ui.install_prereqs_check.setEnabled(True)
|
||||||
self.advanced.ui.install_prereqs_label.setEnabled(True)
|
self.advanced.ui.install_prereqs_label.setEnabled(True)
|
||||||
self.advanced.ui.install_prereqs_check.setChecked(True)
|
self.advanced.ui.install_prereqs_check.setChecked(True)
|
||||||
prereq_name = dl_item.download.igame.prereq_info.get("name", "")
|
prereq_name = download.igame.prereq_info.get("name", "")
|
||||||
prereq_path = os.path.split(dl_item.download.igame.prereq_info.get("path", ""))[-1]
|
prereq_path = os.path.split(download.igame.prereq_info.get("path", ""))[-1]
|
||||||
prereq_desc = prereq_name if prereq_name else prereq_path
|
prereq_desc = prereq_name if prereq_name else prereq_path
|
||||||
self.advanced.ui.install_prereqs_check.setText(
|
self.advanced.ui.install_prereqs_check.setText(
|
||||||
self.tr("Also install: {}").format(prereq_desc)
|
self.tr("Also install: {}").format(prereq_desc)
|
||||||
|
@ -358,62 +351,6 @@ class InstallDialog(QDialog):
|
||||||
self.cancel_clicked()
|
self.cancel_clicked()
|
||||||
|
|
||||||
|
|
||||||
class InstallInfoWorker(QRunnable):
|
|
||||||
class Signals(QObject):
|
|
||||||
result = pyqtSignal(InstallQueueItemModel)
|
|
||||||
failed = pyqtSignal(str)
|
|
||||||
finished = pyqtSignal()
|
|
||||||
|
|
||||||
def __init__(self, core: LegendaryCore, options: InstallOptionsModel):
|
|
||||||
sys.excepthook = sys.__excepthook__
|
|
||||||
super(InstallInfoWorker, self).__init__()
|
|
||||||
self.setAutoDelete(True)
|
|
||||||
self.signals = InstallInfoWorker.Signals()
|
|
||||||
self.core = core
|
|
||||||
self.options = options
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def run(self):
|
|
||||||
try:
|
|
||||||
if not self.options.overlay:
|
|
||||||
cli = LegendaryCLI(self.core)
|
|
||||||
status = LgndrIndirectStatus()
|
|
||||||
result = cli.install_game(
|
|
||||||
LgndrInstallGameArgs(**self.options.as_install_kwargs(), indirect_status=status)
|
|
||||||
)
|
|
||||||
if result:
|
|
||||||
download = InstallDownloadModel(*result)
|
|
||||||
else:
|
|
||||||
raise LgndrException(status.message)
|
|
||||||
else:
|
|
||||||
if not os.path.exists(path := self.options.base_path):
|
|
||||||
os.makedirs(path)
|
|
||||||
|
|
||||||
dlm, analysis, igame = self.core.prepare_overlay_install(
|
|
||||||
path=self.options.base_path
|
|
||||||
)
|
|
||||||
|
|
||||||
download = InstallDownloadModel(
|
|
||||||
dlm=dlm,
|
|
||||||
analysis=analysis,
|
|
||||||
igame=igame,
|
|
||||||
game=EOSOverlayApp,
|
|
||||||
repair=False,
|
|
||||||
repair_file="",
|
|
||||||
res=ConditionCheckResult(), # empty
|
|
||||||
)
|
|
||||||
|
|
||||||
if not download.res or not download.res.failures:
|
|
||||||
self.signals.result.emit(InstallQueueItemModel(options=self.options, download=download))
|
|
||||||
else:
|
|
||||||
self.signals.failed.emit("\n".join(str(i) for i in download.res.failures))
|
|
||||||
except LgndrException as ret:
|
|
||||||
self.signals.failed.emit(ret.message)
|
|
||||||
except Exception as e:
|
|
||||||
self.signals.failed.emit(str(e))
|
|
||||||
self.signals.finished.emit()
|
|
||||||
|
|
||||||
|
|
||||||
class TagCheckBox(QCheckBox):
|
class TagCheckBox(QCheckBox):
|
||||||
def __init__(self, text, tags: List[str], parent=None):
|
def __init__(self, text, tags: List[str], parent=None):
|
||||||
super(TagCheckBox, self).__init__(parent)
|
super(TagCheckBox, self).__init__(parent)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from PyQt5.QtWidgets import (
|
||||||
QMessageBox,
|
QMessageBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
from rare.components.dialogs.install_dialog import InstallDialog, InstallInfoWorker
|
from rare.components.dialogs.install_dialog import InstallDialog
|
||||||
from rare.components.dialogs.uninstall_dialog import UninstallDialog
|
from rare.components.dialogs.uninstall_dialog import UninstallDialog
|
||||||
from rare.lgndr.models.downloading import UIUpdate
|
from rare.lgndr.models.downloading import UIUpdate
|
||||||
from rare.models.game import RareGame
|
from rare.models.game import RareGame
|
||||||
|
@ -68,11 +68,7 @@ class DownloadsTab(QWidget):
|
||||||
self.__reset_download()
|
self.__reset_download()
|
||||||
|
|
||||||
self.__forced_item: Optional[InstallQueueItemModel] = None
|
self.__forced_item: Optional[InstallQueueItemModel] = None
|
||||||
self.__omit_queue = False
|
self.__omit_requeue = False
|
||||||
|
|
||||||
def __check_updates(self):
|
|
||||||
for rgame in self.rcore.updates:
|
|
||||||
self.__add_update(rgame)
|
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
|
@ -80,6 +76,14 @@ class DownloadsTab(QWidget):
|
||||||
count = self.updates_group.count() + self.queue_group.count()
|
count = self.updates_group.count() + self.queue_group.count()
|
||||||
self.update_title.emit(count)
|
self.update_title.emit(count)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_download_active(self):
|
||||||
|
return self.thread is not None
|
||||||
|
|
||||||
|
def __check_updates(self):
|
||||||
|
for rgame in self.rcore.updates:
|
||||||
|
self.__add_update(rgame)
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
@pyqtSlot(RareGame)
|
@pyqtSlot(RareGame)
|
||||||
def __add_update(self, update: Union[str,RareGame]):
|
def __add_update(self, update: Union[str,RareGame]):
|
||||||
|
@ -140,7 +144,7 @@ class DownloadsTab(QWidget):
|
||||||
# `self.on_exit` control whether we try to add the download
|
# `self.on_exit` control whether we try to add the download
|
||||||
# back in the queue. If we are on exit we wait for the thread
|
# back in the queue. If we are on exit we wait for the thread
|
||||||
# to finish, we do not care about handling the result really
|
# to finish, we do not care about handling the result really
|
||||||
self.__omit_queue = omit_queue
|
self.__omit_requeue = omit_queue
|
||||||
if omit_queue:
|
if omit_queue:
|
||||||
self.thread.wait()
|
self.thread.wait()
|
||||||
|
|
||||||
|
@ -154,10 +158,6 @@ class DownloadsTab(QWidget):
|
||||||
self.ui.kill_button.setDisabled(False)
|
self.ui.kill_button.setDisabled(False)
|
||||||
self.ui.dl_name.setText(item.download.game.app_title)
|
self.ui.dl_name.setText(item.download.game.app_title)
|
||||||
|
|
||||||
@property
|
|
||||||
def is_download_active(self):
|
|
||||||
return self.thread is not None
|
|
||||||
|
|
||||||
@pyqtSlot(UIUpdate, c_ulonglong)
|
@pyqtSlot(UIUpdate, c_ulonglong)
|
||||||
def __on_download_progress(self, ui_update: UIUpdate, dl_size: c_ulonglong):
|
def __on_download_progress(self, ui_update: UIUpdate, dl_size: c_ulonglong):
|
||||||
self.ui.progress_bar.setValue(int(ui_update.progress))
|
self.ui.progress_bar.setValue(int(ui_update.progress))
|
||||||
|
@ -170,19 +170,10 @@ class DownloadsTab(QWidget):
|
||||||
)
|
)
|
||||||
self.ui.time_left.setText(get_time(ui_update.estimated_time_left))
|
self.ui.time_left.setText(get_time(ui_update.estimated_time_left))
|
||||||
|
|
||||||
@pyqtSlot(InstallQueueItemModel)
|
def __requeue_download(self, item: InstallQueueItemModel):
|
||||||
def __on_info_worker_result(self, item: InstallQueueItemModel):
|
|
||||||
rgame = self.rcore.get_game(item.options.app_name)
|
rgame = self.rcore.get_game(item.options.app_name)
|
||||||
self.queue_group.push_front(item, rgame.igame)
|
self.queue_group.push_front(item, rgame.igame)
|
||||||
logger.info(f"Re-queued download for {item.download.game.app_name} ({item.download.game.app_title})")
|
logger.info(f"Re-queued download for {rgame.app_name} ({rgame.app_title})")
|
||||||
|
|
||||||
@pyqtSlot(str)
|
|
||||||
def __on_info_worker_failed(self, message: str):
|
|
||||||
logger.error(f"Failed to re-queue stopped download with error: {message}")
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def __on_info_worker_finished(self):
|
|
||||||
logger.info("Download re-queue worker finished")
|
|
||||||
|
|
||||||
@pyqtSlot(DlResultModel)
|
@pyqtSlot(DlResultModel)
|
||||||
def __on_download_result(self, result: DlResultModel):
|
def __on_download_result(self, result: DlResultModel):
|
||||||
|
@ -211,12 +202,8 @@ class DownloadsTab(QWidget):
|
||||||
|
|
||||||
elif result.code == DlResultCode.STOPPED:
|
elif result.code == DlResultCode.STOPPED:
|
||||||
logger.info(f"Download stopped: {result.item.download.game.app_title}")
|
logger.info(f"Download stopped: {result.item.download.game.app_title}")
|
||||||
if not self.__omit_queue:
|
if not self.__omit_requeue:
|
||||||
worker = InstallInfoWorker(self.core, result.item.options)
|
self.__requeue_download(InstallQueueItemModel(options=result.item.options))
|
||||||
worker.signals.result.connect(self.__on_info_worker_result)
|
|
||||||
worker.signals.failed.connect(self.__on_info_worker_failed)
|
|
||||||
worker.signals.finished.connect(self.__on_info_worker_finished)
|
|
||||||
self.threadpool.start(worker)
|
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import Optional, List, Deque
|
from typing import Optional, Deque, Union
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
|
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
|
@ -125,7 +125,7 @@ class QueueGroup(QGroupBox):
|
||||||
|
|
||||||
def __create_widget(self, item: InstallQueueItemModel, old_igame: InstalledGame) -> QueueWidget:
|
def __create_widget(self, item: InstallQueueItemModel, old_igame: InstalledGame) -> QueueWidget:
|
||||||
widget: QueueWidget = QueueWidget(item, old_igame, parent=self.__container)
|
widget: QueueWidget = QueueWidget(item, old_igame, parent=self.__container)
|
||||||
widget.toggle_arrows(self.__queue.index(item.download.game.app_name), len(self.__queue))
|
widget.toggle_arrows(self.__queue.index(item.options.app_name), len(self.__queue))
|
||||||
widget.destroyed.connect(self.__update_group)
|
widget.destroyed.connect(self.__update_group)
|
||||||
widget.remove.connect(self.remove)
|
widget.remove.connect(self.remove)
|
||||||
widget.force.connect(self.__on_force)
|
widget.force.connect(self.__on_force)
|
||||||
|
@ -136,7 +136,7 @@ class QueueGroup(QGroupBox):
|
||||||
def push_front(self, item: InstallQueueItemModel, old_igame: InstalledGame):
|
def push_front(self, item: InstallQueueItemModel, old_igame: InstalledGame):
|
||||||
self.__text.setVisible(False)
|
self.__text.setVisible(False)
|
||||||
self.__container.setVisible(True)
|
self.__container.setVisible(True)
|
||||||
self.__queue.appendleft(item.download.game.app_name)
|
self.__queue.appendleft(item.options.app_name)
|
||||||
widget = self.__create_widget(item, old_igame)
|
widget = self.__create_widget(item, old_igame)
|
||||||
self.__container.layout().insertWidget(0, widget)
|
self.__container.layout().insertWidget(0, widget)
|
||||||
if self.count() > 1:
|
if self.count() > 1:
|
||||||
|
|
|
@ -1,24 +1,28 @@
|
||||||
|
from logging import getLogger
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, Qt
|
from PyQt5.QtCore import pyqtSignal, Qt, QThreadPool, pyqtSlot
|
||||||
from PyQt5.QtWidgets import QWidget, QFrame
|
from PyQt5.QtWidgets import QWidget, QFrame
|
||||||
from legendary.models.downloading import AnalysisResult
|
from legendary.models.downloading import AnalysisResult
|
||||||
from legendary.models.game import Game, InstalledGame
|
from legendary.models.game import Game, InstalledGame
|
||||||
from qtawesome import icon
|
from qtawesome import icon
|
||||||
|
|
||||||
from rare.models.install import InstallQueueItemModel, InstallOptionsModel
|
from rare.models.install import InstallQueueItemModel, InstallOptionsModel, InstallDownloadModel
|
||||||
from rare.shared import ImageManagerSingleton
|
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.download_widget import Ui_DownloadWidget
|
||||||
from rare.ui.components.tabs.downloads.info_widget import Ui_InfoWidget
|
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.utils.misc import get_size, widget_object_name, elide_text
|
||||||
from rare.widgets.image_widget import ImageWidget, ImageSize
|
from rare.widgets.image_widget import ImageWidget, ImageSize
|
||||||
|
|
||||||
|
logger = getLogger("DownloadWidgets")
|
||||||
|
|
||||||
|
|
||||||
class InfoWidget(QWidget):
|
class InfoWidget(QWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
game: Game,
|
game: Optional[Game],
|
||||||
igame: InstalledGame,
|
igame: Optional[InstalledGame],
|
||||||
analysis: Optional[AnalysisResult] = None,
|
analysis: Optional[AnalysisResult] = None,
|
||||||
old_igame: Optional[InstalledGame] = None,
|
old_igame: Optional[InstalledGame] = None,
|
||||||
parent=None,
|
parent=None,
|
||||||
|
@ -29,6 +33,23 @@ class InfoWidget(QWidget):
|
||||||
|
|
||||||
self.image_manager = ImageManagerSingleton()
|
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.title.setText(game.app_title)
|
||||||
self.ui.remote_version.setText(
|
self.ui.remote_version.setText(
|
||||||
elide_text(self.ui.remote_version, old_igame.version if old_igame else game.app_version(igame.platform))
|
elide_text(self.ui.remote_version, old_igame.version if old_igame else game.app_version(igame.platform))
|
||||||
|
@ -36,13 +57,7 @@ class InfoWidget(QWidget):
|
||||||
self.ui.local_version.setText(elide_text(self.ui.local_version, igame.version))
|
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.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.ui.install_size.setText(get_size(analysis.install_size) if analysis else "")
|
||||||
|
|
||||||
self.image = ImageWidget(self)
|
|
||||||
self.image.setFixedSize(ImageSize.Icon)
|
|
||||||
self.image.setPixmap(self.image_manager.get_pixmap(game.app_name, color=True))
|
self.image.setPixmap(self.image_manager.get_pixmap(game.app_name, color=True))
|
||||||
self.ui.image_layout.addWidget(self.image)
|
|
||||||
|
|
||||||
self.ui.info_widget_layout.setAlignment(Qt.AlignTop)
|
|
||||||
|
|
||||||
|
|
||||||
class UpdateWidget(QFrame):
|
class UpdateWidget(QFrame):
|
||||||
|
@ -98,28 +113,55 @@ class QueueWidget(QFrame):
|
||||||
# lk: setObjectName has to be after `setupUi` because it is also set in that function
|
# 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))
|
self.setObjectName(widget_object_name(self, item.options.app_name))
|
||||||
|
|
||||||
self.item = item
|
self.threadpool = QThreadPool.globalInstance()
|
||||||
|
|
||||||
self.ui.update_buttons.setVisible(False)
|
|
||||||
|
|
||||||
self.ui.move_up_button.setIcon(icon("fa.arrow-up"))
|
|
||||||
self.ui.move_up_button.clicked.connect(
|
|
||||||
lambda: self.move_up.emit(self.item.download.game.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.download.game.app_name)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
if not item:
|
||||||
|
self.ui.queue_buttons.setEnabled(False)
|
||||||
|
worker = InstallInfoWorker(RareCore.instance().core(), item.options)
|
||||||
|
worker.signals.result.connect(self.add_info_widget)
|
||||||
|
worker.signals.failed.connect(self.__on_info_worker_failed)
|
||||||
|
worker.signals.finished.connect(self.__on_info_worker_finished)
|
||||||
|
self.threadpool.start(worker)
|
||||||
|
self.info_widget = InfoWidget(None, None, None, old_igame, parent=self)
|
||||||
|
else:
|
||||||
self.info_widget = InfoWidget(
|
self.info_widget = InfoWidget(
|
||||||
item.download.game, item.download.igame, item.download.analysis, old_igame, parent=self
|
item.download.game, item.download.igame, item.download.analysis, old_igame, parent=self
|
||||||
)
|
)
|
||||||
self.ui.info_layout.addWidget(self.info_widget)
|
self.ui.info_layout.addWidget(self.info_widget)
|
||||||
|
self.ui.update_buttons.setVisible(False)
|
||||||
|
|
||||||
self.ui.remove_button.clicked.connect(lambda: self.remove.emit(self.item.download.game.app_name))
|
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))
|
self.ui.force_button.clicked.connect(lambda: self.force.emit(self.item))
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def __on_info_worker_failed(self, message: str):
|
||||||
|
logger.error(f"Failed to requeue download for {self.item.options.app_name} with error: {message}")
|
||||||
|
self.remove.emit(self.item.options.app_name)
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def __on_info_worker_finished(self):
|
||||||
|
logger.info(f"Download requeue worker finished for {self.item.options.app_name}")
|
||||||
|
|
||||||
|
@pyqtSlot(InstallDownloadModel)
|
||||||
|
def add_info_widget(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):
|
def toggle_arrows(self, index: int, length: int):
|
||||||
self.ui.move_up_button.setEnabled(bool(index))
|
self.ui.move_up_button.setEnabled(bool(index))
|
||||||
self.ui.move_down_button.setEnabled(bool(length - (index + 1)))
|
self.ui.move_down_button.setEnabled(bool(length - (index + 1)))
|
||||||
|
|
69
rare/shared/workers/install_info.py
Normal file
69
rare/shared/workers/install_info.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QObject, QRunnable, pyqtSignal, pyqtSlot
|
||||||
|
from legendary.lfs.eos import EOSOverlayApp
|
||||||
|
from legendary.models.downloading import ConditionCheckResult
|
||||||
|
|
||||||
|
from rare.lgndr.cli import LegendaryCLI
|
||||||
|
from rare.lgndr.core import LegendaryCore
|
||||||
|
from rare.lgndr.glue.arguments import LgndrInstallGameArgs
|
||||||
|
from rare.lgndr.glue.exception import LgndrException
|
||||||
|
from rare.lgndr.glue.monkeys import LgndrIndirectStatus
|
||||||
|
from rare.models.install import InstallDownloadModel, InstallOptionsModel
|
||||||
|
|
||||||
|
|
||||||
|
class InstallInfoWorker(QRunnable):
|
||||||
|
class Signals(QObject):
|
||||||
|
result = pyqtSignal(InstallDownloadModel)
|
||||||
|
failed = pyqtSignal(str)
|
||||||
|
finished = pyqtSignal()
|
||||||
|
|
||||||
|
def __init__(self, core: LegendaryCore, options: InstallOptionsModel):
|
||||||
|
sys.excepthook = sys.__excepthook__
|
||||||
|
super(InstallInfoWorker, self).__init__()
|
||||||
|
self.setAutoDelete(True)
|
||||||
|
self.signals = InstallInfoWorker.Signals()
|
||||||
|
self.core = core
|
||||||
|
self.options = options
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
if not self.options.overlay:
|
||||||
|
cli = LegendaryCLI(self.core)
|
||||||
|
status = LgndrIndirectStatus()
|
||||||
|
result = cli.install_game(
|
||||||
|
LgndrInstallGameArgs(**self.options.as_install_kwargs(), indirect_status=status)
|
||||||
|
)
|
||||||
|
if result:
|
||||||
|
download = InstallDownloadModel(*result)
|
||||||
|
else:
|
||||||
|
raise LgndrException(status.message)
|
||||||
|
else:
|
||||||
|
if not os.path.exists(path := self.options.base_path):
|
||||||
|
os.makedirs(path)
|
||||||
|
|
||||||
|
dlm, analysis, igame = self.core.prepare_overlay_install(
|
||||||
|
path=self.options.base_path
|
||||||
|
)
|
||||||
|
|
||||||
|
download = InstallDownloadModel(
|
||||||
|
dlm=dlm,
|
||||||
|
analysis=analysis,
|
||||||
|
igame=igame,
|
||||||
|
game=EOSOverlayApp,
|
||||||
|
repair=False,
|
||||||
|
repair_file="",
|
||||||
|
res=ConditionCheckResult(), # empty
|
||||||
|
)
|
||||||
|
|
||||||
|
if not download.res or not download.res.failures:
|
||||||
|
self.signals.result.emit(download)
|
||||||
|
else:
|
||||||
|
self.signals.failed.emit("\n".join(str(i) for i in download.res.failures))
|
||||||
|
except LgndrException as ret:
|
||||||
|
self.signals.failed.emit(ret.message)
|
||||||
|
except Exception as e:
|
||||||
|
self.signals.failed.emit(str(e))
|
||||||
|
self.signals.finished.emit()
|
Loading…
Reference in a new issue