2021-03-27 04:09:42 +13:00
|
|
|
import datetime
|
2021-02-18 05:46:03 +13:00
|
|
|
from logging import getLogger
|
|
|
|
|
2021-05-23 07:56:13 +12:00
|
|
|
from PyQt5.QtCore import QThread, pyqtSignal, QSettings
|
|
|
|
from PyQt5.QtWidgets import QWidget, QMessageBox, QVBoxLayout, QLabel, QGridLayout, QProgressBar, QPushButton, \
|
|
|
|
QHBoxLayout, QGroupBox
|
2021-03-16 00:03:03 +13:00
|
|
|
|
2021-09-07 07:10:18 +12:00
|
|
|
from legendary.core import LegendaryCore
|
|
|
|
from legendary.models.downloading import UIUpdate
|
|
|
|
from legendary.models.game import Game, InstalledGame
|
2021-05-21 11:47:03 +12:00
|
|
|
from rare.components.dialogs.install_dialog import InstallDialog
|
2021-04-23 00:34:06 +12:00
|
|
|
from rare.components.tabs.downloads.dl_queue_widget import DlQueueWidget
|
|
|
|
from rare.components.tabs.downloads.download_thread import DownloadThread
|
2021-09-30 10:22:47 +13:00
|
|
|
from rare.utils.models import InstallOptionsModel, InstallQueueItemModel, Signals
|
2021-04-12 07:02:56 +12:00
|
|
|
from rare.utils.utils import get_size
|
2021-02-18 05:46:03 +13:00
|
|
|
|
|
|
|
logger = getLogger("Download")
|
|
|
|
|
|
|
|
|
2021-02-10 23:48:25 +13:00
|
|
|
class DownloadTab(QWidget):
|
2021-02-18 05:46:03 +13:00
|
|
|
thread: QThread
|
2021-04-08 00:46:51 +12:00
|
|
|
dl_queue = []
|
2021-08-28 10:16:17 +12:00
|
|
|
dl_status = pyqtSignal(int)
|
2021-02-18 05:46:03 +13:00
|
|
|
|
2021-09-30 10:22:47 +13:00
|
|
|
def __init__(self, core: LegendaryCore, updates: list, signals: Signals):
|
|
|
|
super(DownloadTab, self).__init__()
|
2021-02-18 05:46:03 +13:00
|
|
|
self.core = core
|
|
|
|
self.layout = QVBoxLayout()
|
2021-02-20 00:57:55 +13:00
|
|
|
self.active_game: Game = None
|
2021-05-22 02:48:15 +12:00
|
|
|
self.analysis = None
|
2021-09-30 10:22:47 +13:00
|
|
|
self.signals = signals
|
|
|
|
self.signals.dl_tab.connect(lambda x: self.signal_received(*x))
|
2021-02-18 05:46:03 +13:00
|
|
|
self.info_layout = QGridLayout()
|
|
|
|
|
2021-04-18 04:58:18 +12:00
|
|
|
self.installing_game = QLabel(self.tr("No active Download"))
|
2021-02-18 05:46:03 +13:00
|
|
|
self.info_layout.addWidget(self.installing_game, 0, 0)
|
2021-04-18 04:58:18 +12:00
|
|
|
self.dl_speed = QLabel()
|
2021-02-18 05:46:03 +13:00
|
|
|
self.info_layout.addWidget(self.dl_speed, 0, 1)
|
2021-04-18 04:58:18 +12:00
|
|
|
self.cache_used = QLabel()
|
2021-02-27 07:28:54 +13:00
|
|
|
self.info_layout.addWidget(self.cache_used, 1, 0)
|
2021-04-18 04:58:18 +12:00
|
|
|
self.downloaded = QLabel()
|
2021-02-27 07:28:54 +13:00
|
|
|
self.info_layout.addWidget(self.downloaded, 1, 1)
|
2021-04-18 04:58:18 +12:00
|
|
|
self.time_left = QLabel()
|
2021-03-27 04:09:42 +13:00
|
|
|
self.info_layout.addWidget(self.time_left, 2, 0)
|
2021-04-18 04:58:18 +12:00
|
|
|
|
2021-02-18 05:46:03 +13:00
|
|
|
self.layout.addLayout(self.info_layout)
|
2021-03-15 10:11:03 +13:00
|
|
|
|
2021-03-17 03:12:37 +13:00
|
|
|
self.mini_layout = QHBoxLayout()
|
2021-02-18 05:46:03 +13:00
|
|
|
self.prog_bar = QProgressBar()
|
2021-03-17 03:12:37 +13:00
|
|
|
self.mini_layout.addWidget(self.prog_bar)
|
2021-04-18 04:58:18 +12:00
|
|
|
self.prog_bar.setMaximum(100)
|
2021-03-17 03:12:37 +13:00
|
|
|
|
|
|
|
self.kill_button = QPushButton(self.tr("Stop Download"))
|
2021-04-18 04:58:18 +12:00
|
|
|
self.mini_layout.addWidget(self.kill_button)
|
2021-03-17 03:12:37 +13:00
|
|
|
self.kill_button.setDisabled(True)
|
|
|
|
self.kill_button.clicked.connect(self.stop_download)
|
|
|
|
|
|
|
|
self.layout.addLayout(self.mini_layout)
|
2021-02-18 05:46:03 +13:00
|
|
|
|
2021-04-08 02:50:36 +12:00
|
|
|
self.queue_widget = DlQueueWidget()
|
|
|
|
self.layout.addWidget(self.queue_widget)
|
|
|
|
self.queue_widget.update_list.connect(self.update_dl_queue)
|
2021-04-08 00:46:51 +12:00
|
|
|
|
2021-04-08 04:18:50 +12:00
|
|
|
self.updates = QGroupBox(self.tr("Updates"))
|
2021-04-18 04:58:18 +12:00
|
|
|
self.layout.addWidget(self.updates)
|
2021-04-08 04:18:50 +12:00
|
|
|
self.update_layout = QVBoxLayout()
|
2021-04-18 04:58:18 +12:00
|
|
|
self.updates.setLayout(self.update_layout)
|
|
|
|
|
|
|
|
self.updates.setObjectName("group")
|
|
|
|
|
2021-03-17 09:25:07 +13:00
|
|
|
self.update_widgets = {}
|
2021-03-01 00:06:33 +13:00
|
|
|
|
2021-04-08 04:18:50 +12:00
|
|
|
self.update_text = QLabel(self.tr("No updates available"))
|
|
|
|
self.update_layout.addWidget(self.update_text)
|
2021-04-18 04:58:18 +12:00
|
|
|
self.update_text.setVisible(len(updates) == 0)
|
2021-04-08 04:18:50 +12:00
|
|
|
|
|
|
|
for igame in updates:
|
2021-05-18 20:32:46 +12:00
|
|
|
self.add_update(igame)
|
2021-04-08 04:18:50 +12:00
|
|
|
|
2021-02-18 05:46:03 +13:00
|
|
|
self.layout.addStretch(1)
|
|
|
|
|
|
|
|
self.setLayout(self.layout)
|
|
|
|
|
2021-09-30 10:22:47 +13:00
|
|
|
def signal_received(self, action, data):
|
|
|
|
if action == self.signals.actions.install_game:
|
|
|
|
self.get_install_options(data)
|
|
|
|
|
2021-05-18 20:32:46 +12:00
|
|
|
def add_update(self, igame: InstalledGame):
|
|
|
|
widget = UpdateWidget(self.core, igame, self)
|
|
|
|
self.update_layout.addWidget(widget)
|
|
|
|
self.update_widgets[igame.app_name] = widget
|
2021-09-30 10:22:47 +13:00
|
|
|
widget.update_signal.connect(self.get_install_options)
|
2021-05-18 20:32:46 +12:00
|
|
|
if QSettings().value("auto_update", False, bool):
|
2021-09-30 10:22:47 +13:00
|
|
|
self.get_install_options(InstallOptionsModel(app_name=igame.app_name, update=True, silent=True))
|
2021-05-18 20:32:46 +12:00
|
|
|
widget.update_button.setDisabled(True)
|
|
|
|
|
2021-04-08 02:50:36 +12:00
|
|
|
def update_dl_queue(self, dl_queue):
|
|
|
|
self.dl_queue = dl_queue
|
|
|
|
|
2021-03-17 03:12:37 +13:00
|
|
|
def stop_download(self):
|
2021-04-12 03:03:55 +12:00
|
|
|
self.thread.kill()
|
2021-03-17 03:12:37 +13:00
|
|
|
|
2021-05-24 00:15:36 +12:00
|
|
|
def install_game(self, queue_item: InstallQueueItemModel):
|
2021-04-08 01:34:52 +12:00
|
|
|
if self.active_game is None:
|
2021-05-23 07:56:13 +12:00
|
|
|
self.start_installation(queue_item)
|
2021-04-08 01:34:52 +12:00
|
|
|
else:
|
2021-05-23 07:56:13 +12:00
|
|
|
self.dl_queue.append(queue_item)
|
2021-04-08 02:50:36 +12:00
|
|
|
self.queue_widget.update_queue(self.dl_queue)
|
2021-02-18 05:46:03 +13:00
|
|
|
|
2021-05-23 07:56:13 +12:00
|
|
|
def start_installation(self, queue_item: InstallQueueItemModel):
|
2021-04-13 00:24:10 +12:00
|
|
|
if self.dl_queue:
|
|
|
|
self.dl_queue.pop(0)
|
|
|
|
self.queue_widget.update_queue(self.dl_queue)
|
2021-05-23 07:56:13 +12:00
|
|
|
self.active_game = queue_item.download.game
|
|
|
|
self.thread = DownloadThread(self.core, queue_item)
|
2021-02-18 05:46:03 +13:00
|
|
|
self.thread.status.connect(self.status)
|
2021-03-15 10:11:03 +13:00
|
|
|
self.thread.statistics.connect(self.statistics)
|
2021-02-18 05:46:03 +13:00
|
|
|
self.thread.start()
|
2021-03-17 03:12:37 +13:00
|
|
|
self.kill_button.setDisabled(False)
|
2021-05-23 07:56:13 +12:00
|
|
|
self.analysis = queue_item.download.analysis
|
2021-04-08 00:46:51 +12:00
|
|
|
self.installing_game.setText(self.tr("Installing Game: ") + self.active_game.app_title)
|
2021-03-17 09:25:07 +13:00
|
|
|
|
2021-09-30 10:22:47 +13:00
|
|
|
self.signals.games_tab.emit((self.signals.actions.start_installation, self.active_game))
|
|
|
|
|
2021-02-18 05:46:03 +13:00
|
|
|
def status(self, text):
|
|
|
|
if text == "dl_finished":
|
|
|
|
pass
|
|
|
|
elif text == "finish":
|
2021-04-06 21:00:37 +12:00
|
|
|
self.installing_game.setText(self.tr("Download finished. Reload library"))
|
2021-02-27 07:28:54 +13:00
|
|
|
# QMessageBox.information(self, "Info", "Download finished")
|
2021-03-25 23:49:05 +13:00
|
|
|
logger.info("Download finished: " + self.active_game.app_title)
|
2021-04-08 00:46:51 +12:00
|
|
|
|
2021-09-30 10:22:47 +13:00
|
|
|
game = self.active_game
|
2021-05-18 06:22:29 +12:00
|
|
|
self.active_game = None
|
|
|
|
|
2021-04-08 02:50:36 +12:00
|
|
|
if self.dl_queue:
|
2021-09-30 10:22:47 +13:00
|
|
|
if self.dl_queue[0].download.game.app_name == game.app_name:
|
2021-04-08 02:50:36 +12:00
|
|
|
self.dl_queue.pop(0)
|
|
|
|
self.queue_widget.update_queue(self.dl_queue)
|
2021-04-08 00:46:51 +12:00
|
|
|
|
2021-09-30 10:22:47 +13:00
|
|
|
if game.app_name in self.update_widgets.keys():
|
|
|
|
self.update_widgets[game.app_name].setVisible(False)
|
|
|
|
self.update_widgets.pop(game.app_name)
|
2021-04-09 21:36:27 +12:00
|
|
|
if len(self.update_widgets) == 0:
|
|
|
|
self.update_text.setVisible(True)
|
2021-03-17 09:25:07 +13:00
|
|
|
|
2021-09-30 10:22:47 +13:00
|
|
|
self.signals.app.emit((self.signals.actions.installation_finished, (True, game.app_title)))
|
|
|
|
self.signals.games_tab.emit((self.signals.actions.installation_finished, game.app_name))
|
|
|
|
self.signals.tab_widget.emit(
|
|
|
|
(self.signals.actions.set_dl_tab_text, len(self.dl_queue) + len(self.update_widgets.keys())))
|
2021-04-08 05:53:07 +12:00
|
|
|
self.reset_infos()
|
2021-04-08 00:46:51 +12:00
|
|
|
|
|
|
|
if len(self.dl_queue) != 0:
|
2021-05-23 07:56:13 +12:00
|
|
|
self.start_installation(self.dl_queue[0])
|
2021-04-08 00:46:51 +12:00
|
|
|
else:
|
2021-04-08 02:50:36 +12:00
|
|
|
self.queue_widget.update_queue(self.dl_queue)
|
2021-04-08 00:46:51 +12:00
|
|
|
|
2021-04-12 03:03:55 +12:00
|
|
|
elif text[:5] == "error":
|
2021-04-23 00:34:06 +12:00
|
|
|
QMessageBox.warning(self, "warn", "Download error: " + text[6:])
|
2021-02-18 05:46:03 +13:00
|
|
|
|
2021-03-17 03:12:37 +13:00
|
|
|
elif text == "stop":
|
2021-04-08 05:53:07 +12:00
|
|
|
self.reset_infos()
|
2021-09-30 10:22:47 +13:00
|
|
|
self.signals.app.emit((self.signals.actions.installation_finished, (False, self.active_game.app_title)))
|
2021-04-12 03:03:55 +12:00
|
|
|
self.active_game = None
|
2021-04-13 00:24:10 +12:00
|
|
|
if self.dl_queue:
|
2021-05-23 07:56:13 +12:00
|
|
|
self.start_installation(self.dl_queue[0])
|
2021-04-08 05:53:07 +12:00
|
|
|
|
|
|
|
def reset_infos(self):
|
|
|
|
self.kill_button.setDisabled(True)
|
|
|
|
self.installing_game.setText(self.tr("Installing Game: No active download"))
|
|
|
|
self.prog_bar.setValue(0)
|
|
|
|
self.dl_speed.setText("")
|
|
|
|
self.time_left.setText("")
|
|
|
|
self.cache_used.setText("")
|
|
|
|
self.downloaded.setText("")
|
2021-04-12 07:02:56 +12:00
|
|
|
self.analysis = None
|
2021-03-17 03:12:37 +13:00
|
|
|
|
2021-03-15 10:11:03 +13:00
|
|
|
def statistics(self, ui_update: UIUpdate):
|
|
|
|
self.prog_bar.setValue(ui_update.progress)
|
2021-05-21 09:00:38 +12:00
|
|
|
self.dl_speed.setText(self.tr("Download speed") + f": {get_size(ui_update.download_speed)}/s")
|
2021-05-21 23:40:10 +12:00
|
|
|
self.cache_used.setText(
|
|
|
|
self.tr("Cache used") + f": {get_size(ui_update.cache_usage) if ui_update.cache_usage > 1023 else '0KB'}")
|
2021-04-23 00:34:06 +12:00
|
|
|
self.downloaded.setText(
|
|
|
|
self.tr("Downloaded") + f": {get_size(ui_update.total_downloaded)} / {get_size(self.analysis.dl_size)}")
|
2021-03-27 04:09:42 +13:00
|
|
|
self.time_left.setText(self.tr("Time left: ") + self.get_time(ui_update.estimated_time_left))
|
2021-09-30 10:22:47 +13:00
|
|
|
self.signals.games_tab.emit(
|
|
|
|
(self.signals.actions.dl_status, int(100 * ui_update.total_downloaded / self.analysis.dl_size)))
|
2021-03-27 04:09:42 +13:00
|
|
|
|
|
|
|
def get_time(self, seconds: int) -> str:
|
|
|
|
return str(datetime.timedelta(seconds=seconds))
|
2021-03-15 10:11:03 +13:00
|
|
|
|
2021-05-26 08:37:50 +12:00
|
|
|
def on_install_dialog_closed(self, download_item: InstallQueueItemModel):
|
2021-05-24 00:15:36 +12:00
|
|
|
if download_item:
|
|
|
|
self.install_game(download_item)
|
2021-09-30 10:22:47 +13:00
|
|
|
self.signals.tab_widget.emit((self.signals.actions.set_index, 1))
|
2021-05-20 20:19:10 +12:00
|
|
|
else:
|
2021-09-30 10:22:47 +13:00
|
|
|
if w := self.update_widgets.get(download_item.options.app_name):
|
|
|
|
w.update_button.setDisabled(False)
|
|
|
|
w.update_with_settings.setDisabled(False)
|
|
|
|
|
|
|
|
def get_install_options(self, options: InstallOptionsModel):
|
|
|
|
|
|
|
|
install_dialog = InstallDialog(self.core,
|
|
|
|
InstallQueueItemModel(options=options),
|
|
|
|
update=options.update, silent=options.silent, parent=self)
|
|
|
|
install_dialog.result_ready.connect(self.on_install_dialog_closed)
|
|
|
|
install_dialog.execute()
|
|
|
|
|
|
|
|
def start_download(self, download_item: InstallQueueItemModel):
|
|
|
|
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys()) + 1
|
|
|
|
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
|
|
|
|
self.setCurrentIndex(1)
|
|
|
|
self.downloadTab.install_game(download_item)
|
|
|
|
self.games_tab.start_download(download_item.options.app_name)
|
2021-03-09 05:20:28 +13:00
|
|
|
|
2021-03-01 00:06:33 +13:00
|
|
|
|
|
|
|
class UpdateWidget(QWidget):
|
2021-09-30 10:22:47 +13:00
|
|
|
update_signal = pyqtSignal(InstallOptionsModel)
|
2021-03-01 00:06:33 +13:00
|
|
|
|
2021-04-18 04:58:18 +12:00
|
|
|
def __init__(self, core: LegendaryCore, game: InstalledGame, parent):
|
|
|
|
super(UpdateWidget, self).__init__(parent=parent)
|
2021-03-01 00:06:33 +13:00
|
|
|
self.core = core
|
2021-03-25 23:49:05 +13:00
|
|
|
self.game = game
|
2021-03-01 00:06:33 +13:00
|
|
|
|
|
|
|
self.layout = QVBoxLayout()
|
|
|
|
self.title = QLabel(self.game.title)
|
|
|
|
self.layout.addWidget(self.title)
|
|
|
|
|
2021-03-01 08:01:15 +13:00
|
|
|
self.update_button = QPushButton(self.tr("Update Game"))
|
2021-05-20 20:19:10 +12:00
|
|
|
self.update_button.clicked.connect(lambda: self.update_game(True))
|
|
|
|
self.update_with_settings = QPushButton("Update with settings")
|
|
|
|
self.update_with_settings.clicked.connect(lambda: self.update_game(False))
|
2021-03-01 00:06:33 +13:00
|
|
|
self.layout.addWidget(self.update_button)
|
2021-05-20 20:19:10 +12:00
|
|
|
self.layout.addWidget(self.update_with_settings)
|
2021-05-21 23:40:10 +12:00
|
|
|
self.layout.addWidget(QLabel(
|
|
|
|
self.tr("Version: ") + self.game.version + " -> " + self.core.get_asset(self.game.app_name,
|
|
|
|
True).build_version))
|
2021-03-01 00:06:33 +13:00
|
|
|
|
|
|
|
self.setLayout(self.layout)
|
2021-04-10 08:40:27 +12:00
|
|
|
|
2021-05-20 20:19:10 +12:00
|
|
|
def update_game(self, auto: bool):
|
2021-04-10 08:40:27 +12:00
|
|
|
self.update_button.setDisabled(True)
|
2021-05-20 20:19:10 +12:00
|
|
|
self.update_with_settings.setDisabled(True)
|
2021-09-30 10:22:47 +13:00
|
|
|
self.update_signal.emit(InstallOptionsModel(app_name=self.game.app_name, silent=auto)) # True if settings
|