2021-10-12 10:19:32 +13:00
|
|
|
import json
|
|
|
|
import os
|
2022-07-02 03:43:25 +12:00
|
|
|
from dataclasses import dataclass
|
2022-07-03 04:22:12 +12:00
|
|
|
from enum import IntEnum
|
2021-10-12 10:19:32 +13:00
|
|
|
from logging import getLogger
|
2022-05-05 08:11:41 +12:00
|
|
|
from pathlib import Path
|
2023-12-11 10:43:46 +13:00
|
|
|
from typing import List, Tuple, Optional, Set
|
2021-10-12 10:19:32 +13:00
|
|
|
|
2022-07-03 04:22:12 +12:00
|
|
|
from PyQt5.QtCore import Qt, QModelIndex, pyqtSignal, QRunnable, QObject, QThreadPool, pyqtSlot
|
2023-12-11 10:43:46 +13:00
|
|
|
from PyQt5.QtGui import QStandardItemModel, QShowEvent
|
2023-03-13 11:58:16 +13:00
|
|
|
from PyQt5.QtWidgets import (
|
|
|
|
QFileDialog,
|
|
|
|
QGroupBox,
|
|
|
|
QCompleter,
|
|
|
|
QTreeView,
|
|
|
|
QHeaderView,
|
|
|
|
QMessageBox,
|
|
|
|
QStackedWidget,
|
|
|
|
QProgressBar,
|
|
|
|
QSizePolicy,
|
2023-12-11 10:43:46 +13:00
|
|
|
QFormLayout,
|
2023-03-13 11:58:16 +13:00
|
|
|
)
|
2021-10-12 10:19:32 +13:00
|
|
|
|
2022-08-30 11:33:08 +12:00
|
|
|
from rare.lgndr.cli import LegendaryCLI
|
2023-01-25 02:35:51 +13:00
|
|
|
from rare.lgndr.core import LegendaryCore
|
2022-10-27 14:00:48 +13:00
|
|
|
from rare.lgndr.glue.arguments import LgndrImportGameArgs
|
2023-12-11 09:44:19 +13:00
|
|
|
from rare.lgndr.glue.monkeys import LgndrIndirectStatus, get_boolean_choice_factory
|
2023-01-27 15:11:10 +13:00
|
|
|
from rare.shared import RareCore
|
2022-11-04 09:39:48 +13:00
|
|
|
from rare.ui.components.tabs.games.integrations.import_group import Ui_ImportGroup
|
2022-07-24 10:06:35 +12:00
|
|
|
from rare.widgets.elide_label import ElideLabel
|
2023-02-19 04:29:41 +13:00
|
|
|
from rare.widgets.indicator_edit import IndicatorLineEdit, IndicatorReasonsCommon, PathEdit
|
2021-10-12 10:19:32 +13:00
|
|
|
|
|
|
|
logger = getLogger("Import")
|
|
|
|
|
|
|
|
|
2022-07-02 03:43:25 +12:00
|
|
|
def find_app_name(path: str, core) -> Optional[str]:
|
|
|
|
if os.path.exists(os.path.join(path, ".egstore")):
|
|
|
|
for i in os.listdir(os.path.join(path, ".egstore")):
|
|
|
|
if i.endswith(".mancpn"):
|
2022-07-06 23:39:24 +12:00
|
|
|
with open(os.path.join(path, ".egstore", i)) as file:
|
|
|
|
app_name = json.load(file).get("AppName")
|
|
|
|
return app_name
|
2022-08-01 23:31:07 +12:00
|
|
|
elif app_name := LegendaryCLI(core).resolve_aliases(os.path.basename(os.path.normpath(path))):
|
2022-07-02 03:43:25 +12:00
|
|
|
# return None if game does not exist (Workaround for overlay)
|
|
|
|
if not core.get_game(app_name):
|
|
|
|
return None
|
|
|
|
return app_name
|
|
|
|
else:
|
|
|
|
logger.warning(f"Could not find AppName for {path}")
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2022-07-03 04:22:12 +12:00
|
|
|
class ImportResult(IntEnum):
|
|
|
|
ERROR = 0
|
|
|
|
FAILED = 1
|
|
|
|
SUCCESS = 2
|
2022-07-02 03:43:25 +12:00
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
2022-07-03 04:22:12 +12:00
|
|
|
class ImportedGame:
|
|
|
|
result: ImportResult
|
2022-07-24 10:06:35 +12:00
|
|
|
path: Optional[str] = None
|
2022-07-03 04:22:12 +12:00
|
|
|
app_name: Optional[str] = None
|
2022-07-24 10:06:35 +12:00
|
|
|
app_title: Optional[str] = None
|
2022-07-03 04:22:12 +12:00
|
|
|
message: Optional[str] = None
|
2022-07-02 03:43:25 +12:00
|
|
|
|
|
|
|
|
|
|
|
class ImportWorker(QRunnable):
|
|
|
|
class Signals(QObject):
|
2023-01-26 00:08:18 +13:00
|
|
|
progress = pyqtSignal(ImportedGame, int)
|
|
|
|
result = pyqtSignal(list)
|
2022-07-02 03:43:25 +12:00
|
|
|
|
2023-05-08 01:31:05 +12:00
|
|
|
def __init__(
|
|
|
|
self,
|
2023-12-17 12:20:07 +13:00
|
|
|
core: LegendaryCore,
|
|
|
|
path: str,
|
2023-05-08 01:31:05 +12:00
|
|
|
app_name: str = None,
|
2023-12-17 12:20:07 +13:00
|
|
|
platform: Optional[str] = None,
|
2023-05-08 01:31:05 +12:00
|
|
|
import_folder: bool = False,
|
|
|
|
import_dlcs: bool = False,
|
|
|
|
import_force: bool = False
|
|
|
|
):
|
2022-07-02 03:43:25 +12:00
|
|
|
super(ImportWorker, self).__init__()
|
2023-12-11 09:12:17 +13:00
|
|
|
self.setAutoDelete(True)
|
2023-01-27 15:11:10 +13:00
|
|
|
self.signals = ImportWorker.Signals()
|
2023-01-25 02:35:51 +13:00
|
|
|
self.core = core
|
2022-07-14 21:01:57 +12:00
|
|
|
|
2022-07-02 03:43:25 +12:00
|
|
|
self.path = Path(path)
|
|
|
|
self.app_name = app_name
|
2022-07-14 21:01:57 +12:00
|
|
|
self.import_folder = import_folder
|
2023-12-17 12:20:07 +13:00
|
|
|
self.platform = platform if platform is not None else self.core.default_platform
|
2022-07-14 21:01:57 +12:00
|
|
|
self.import_dlcs = import_dlcs
|
2023-05-08 01:31:05 +12:00
|
|
|
self.import_force = import_force
|
2022-07-02 03:43:25 +12:00
|
|
|
|
|
|
|
def run(self) -> None:
|
2022-07-03 04:22:12 +12:00
|
|
|
result_list: List = []
|
2022-07-02 03:43:25 +12:00
|
|
|
if self.import_folder:
|
2022-07-03 04:22:12 +12:00
|
|
|
folders = [i for i in self.path.iterdir() if i.is_dir()]
|
|
|
|
number_of_folders = len(folders)
|
|
|
|
for i, child in enumerate(folders):
|
2022-07-02 03:43:25 +12:00
|
|
|
if not child.is_dir():
|
|
|
|
continue
|
2022-07-03 04:22:12 +12:00
|
|
|
result = self.__try_import(child, None)
|
|
|
|
result_list.append(result)
|
2023-01-26 00:08:18 +13:00
|
|
|
self.signals.progress.emit(result, int(100 * i // number_of_folders))
|
2022-07-02 03:43:25 +12:00
|
|
|
else:
|
2022-07-03 04:22:12 +12:00
|
|
|
result = self.__try_import(self.path, self.app_name)
|
|
|
|
result_list.append(result)
|
2023-01-26 00:08:18 +13:00
|
|
|
self.signals.progress.emit(result, 100)
|
|
|
|
self.signals.result.emit(result_list)
|
2022-07-03 04:22:12 +12:00
|
|
|
|
|
|
|
def __try_import(self, path: Path, app_name: str = None) -> ImportedGame:
|
2022-07-24 10:06:35 +12:00
|
|
|
result = ImportedGame(ImportResult.ERROR)
|
|
|
|
result.path = str(path)
|
2022-07-03 04:22:12 +12:00
|
|
|
if app_name or (app_name := find_app_name(str(path), self.core)):
|
2023-12-17 12:20:07 +13:00
|
|
|
game = self.core.get_game(app_name)
|
2022-07-03 04:22:12 +12:00
|
|
|
result.app_name = app_name
|
2023-12-17 12:20:07 +13:00
|
|
|
result.app_title = game.app_title
|
|
|
|
platform = self.platform
|
|
|
|
if platform not in self.core.get_game(app_name, update_meta=False).asset_infos:
|
|
|
|
platform = "Windows"
|
|
|
|
success, message = self.__import_game(path, app_name, platform)
|
2022-07-21 08:33:44 +12:00
|
|
|
if not success:
|
2022-07-03 04:22:12 +12:00
|
|
|
result.result = ImportResult.FAILED
|
2022-07-24 10:06:35 +12:00
|
|
|
result.message = message
|
2022-07-02 03:43:25 +12:00
|
|
|
else:
|
2022-07-03 04:22:12 +12:00
|
|
|
result.result = ImportResult.SUCCESS
|
|
|
|
return result
|
2022-07-02 03:43:25 +12:00
|
|
|
|
2023-12-17 12:20:07 +13:00
|
|
|
def __import_game(self, path: Path, app_name: str, platform: str):
|
2022-08-01 23:31:07 +12:00
|
|
|
cli = LegendaryCLI(self.core)
|
2022-07-24 10:06:35 +12:00
|
|
|
status = LgndrIndirectStatus()
|
2022-07-11 04:32:42 +12:00
|
|
|
args = LgndrImportGameArgs(
|
|
|
|
app_path=str(path),
|
|
|
|
app_name=app_name,
|
2023-12-16 04:56:33 +13:00
|
|
|
platform=platform,
|
2023-05-08 01:31:05 +12:00
|
|
|
disable_check=self.import_force,
|
|
|
|
skip_dlcs=not self.import_dlcs,
|
|
|
|
with_dlcs=self.import_dlcs,
|
2022-07-24 10:06:35 +12:00
|
|
|
indirect_status=status,
|
2023-12-11 09:44:19 +13:00
|
|
|
get_boolean_choice=get_boolean_choice_factory(self.import_dlcs)
|
2022-07-11 04:32:42 +12:00
|
|
|
)
|
2022-07-24 10:06:35 +12:00
|
|
|
cli.import_game(args)
|
|
|
|
return status.success, status.message
|
2022-07-02 03:43:25 +12:00
|
|
|
|
|
|
|
|
2021-11-06 00:16:58 +13:00
|
|
|
class AppNameCompleter(QCompleter):
|
|
|
|
activated = pyqtSignal(str)
|
|
|
|
|
2023-12-11 10:43:46 +13:00
|
|
|
def __init__(self, app_names: Set[Tuple[str, str]], parent=None):
|
2021-11-06 00:16:58 +13:00
|
|
|
super(AppNameCompleter, self).__init__(parent)
|
2021-11-06 04:48:56 +13:00
|
|
|
# pylint: disable=E1136
|
2022-05-05 08:11:41 +12:00
|
|
|
super(AppNameCompleter, self).activated[QModelIndex].connect(self.__activated_idx)
|
2021-11-06 00:16:58 +13:00
|
|
|
|
|
|
|
model = QStandardItemModel(len(app_names), 2)
|
|
|
|
for idx, game in enumerate(app_names):
|
|
|
|
app_name, app_title = game
|
|
|
|
model.setData(model.index(idx, 0), app_title)
|
|
|
|
model.setData(model.index(idx, 1), app_name)
|
|
|
|
self.setModel(model)
|
|
|
|
|
2021-11-06 04:48:56 +13:00
|
|
|
treeview = QTreeView()
|
|
|
|
self.setPopup(treeview)
|
|
|
|
treeview.setRootIsDecorated(False)
|
|
|
|
treeview.header().hide()
|
|
|
|
treeview.header().setSectionResizeMode(0, QHeaderView.Stretch)
|
|
|
|
treeview.header().setSectionResizeMode(1, QHeaderView.Stretch)
|
2021-11-06 00:16:58 +13:00
|
|
|
|
2021-11-06 04:48:56 +13:00
|
|
|
# listview = QListView()
|
|
|
|
# self.setPopup(listview)
|
|
|
|
# # listview.setModelColumn(1)
|
2021-11-06 00:16:58 +13:00
|
|
|
|
|
|
|
self.setFilterMode(Qt.MatchContains)
|
|
|
|
self.setCaseSensitivity(Qt.CaseInsensitive)
|
|
|
|
# self.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
|
|
|
|
|
2021-11-06 11:49:37 +13:00
|
|
|
def __activated_idx(self, idx):
|
2021-11-06 00:16:58 +13:00
|
|
|
# lk: don't even look at this in a funny way, it will die of shame
|
|
|
|
# lk: Note to self, the completer and popup models are different.
|
|
|
|
# lk: Getting the index from the popup and trying to use it in the completer will return invalid results
|
2021-11-06 11:49:37 +13:00
|
|
|
if isinstance(idx, QModelIndex):
|
2022-05-05 08:11:41 +12:00
|
|
|
self.activated.emit(self.popup().model().data(self.popup().model().index(idx.row(), 1)))
|
2021-11-06 11:49:37 +13:00
|
|
|
# TODO: implement conversion from app_name to app_title (signal loop here)
|
2021-11-06 00:16:58 +13:00
|
|
|
# if isinstance(idx_str, str):
|
|
|
|
# self.activated.emit(idx_str)
|
|
|
|
|
|
|
|
|
2022-05-05 08:11:41 +12:00
|
|
|
class ImportGroup(QGroupBox):
|
2021-10-12 10:19:32 +13:00
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(ImportGroup, self).__init__(parent=parent)
|
2022-05-05 08:11:41 +12:00
|
|
|
self.ui = Ui_ImportGroup()
|
|
|
|
self.ui.setupUi(self)
|
2023-01-25 02:35:51 +13:00
|
|
|
self.rcore = RareCore.instance()
|
2023-01-27 15:11:10 +13:00
|
|
|
self.core = RareCore.instance().core()
|
2022-02-26 06:43:27 +13:00
|
|
|
|
2023-12-11 09:12:17 +13:00
|
|
|
self.worker: Optional[ImportWorker] = None
|
|
|
|
self.threadpool = QThreadPool.globalInstance()
|
|
|
|
|
2023-12-11 10:43:46 +13:00
|
|
|
self.__app_names: Set[str] = set()
|
|
|
|
self.__install_dirs: Set[str] = set()
|
2021-10-12 10:19:32 +13:00
|
|
|
|
|
|
|
self.path_edit = PathEdit(
|
2023-12-16 11:40:15 +13:00
|
|
|
self.core.get_default_install_dir(self.core.default_platform),
|
2021-10-12 10:19:32 +13:00
|
|
|
QFileDialog.DirectoryOnly,
|
2022-10-26 15:12:36 +13:00
|
|
|
edit_func=self.path_edit_callback,
|
2021-12-24 22:09:50 +13:00
|
|
|
parent=self,
|
2021-10-12 10:19:32 +13:00
|
|
|
)
|
|
|
|
self.path_edit.textChanged.connect(self.path_changed)
|
2023-12-11 10:43:46 +13:00
|
|
|
self.ui.import_layout.setWidget(
|
2023-12-12 11:46:22 +13:00
|
|
|
self.ui.import_layout.getWidgetPosition(self.ui.path_edit_label)[0],
|
|
|
|
QFormLayout.FieldRole, self.path_edit
|
2023-12-11 10:43:46 +13:00
|
|
|
)
|
2021-10-12 10:19:32 +13:00
|
|
|
|
2022-05-05 08:11:41 +12:00
|
|
|
self.app_name_edit = IndicatorLineEdit(
|
2022-03-15 11:29:54 +13:00
|
|
|
placeholder=self.tr("Use in case the app name was not found automatically"),
|
2022-10-26 15:12:36 +13:00
|
|
|
edit_func=self.app_name_edit_callback,
|
2023-12-17 12:20:07 +13:00
|
|
|
save_func=self.app_name_save_callback,
|
2021-12-24 22:09:50 +13:00
|
|
|
parent=self,
|
2021-10-12 10:19:32 +13:00
|
|
|
)
|
2022-05-05 08:11:41 +12:00
|
|
|
self.app_name_edit.textChanged.connect(self.app_name_changed)
|
2023-12-11 10:43:46 +13:00
|
|
|
self.ui.import_layout.setWidget(
|
2023-12-12 11:46:22 +13:00
|
|
|
self.ui.import_layout.getWidgetPosition(self.ui.app_name_label)[0],
|
|
|
|
QFormLayout.FieldRole, self.app_name_edit
|
2023-12-11 10:43:46 +13:00
|
|
|
)
|
2022-05-05 08:11:41 +12:00
|
|
|
|
2022-07-14 21:01:57 +12:00
|
|
|
self.ui.import_folder_check.stateChanged.connect(self.import_folder_changed)
|
|
|
|
self.ui.import_dlcs_check.setEnabled(False)
|
2022-10-26 15:12:36 +13:00
|
|
|
self.ui.import_dlcs_check.stateChanged.connect(self.import_dlcs_changed)
|
2022-07-14 21:01:57 +12:00
|
|
|
|
2023-12-11 10:43:46 +13:00
|
|
|
self.ui.import_button_label.setText("")
|
2022-05-05 08:11:41 +12:00
|
|
|
self.ui.import_button.setEnabled(False)
|
|
|
|
self.ui.import_button.clicked.connect(
|
2023-03-13 23:29:33 +13:00
|
|
|
lambda: self.__import(self.path_edit.text())
|
2022-05-05 08:11:41 +12:00
|
|
|
)
|
2022-07-24 10:06:35 +12:00
|
|
|
|
2023-01-27 05:04:07 +13:00
|
|
|
self.button_info_stack = QStackedWidget(self)
|
2023-03-13 11:58:16 +13:00
|
|
|
self.button_info_stack.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
|
|
self.button_info_stack.setFixedHeight(self.ui.import_button.sizeHint().height())
|
|
|
|
self.info_label = ElideLabel(text="", parent=self.button_info_stack)
|
|
|
|
self.info_label.setFixedHeight(False)
|
|
|
|
self.info_label.setAlignment(Qt.AlignVCenter)
|
|
|
|
self.info_progress = QProgressBar(self.button_info_stack)
|
2023-01-27 05:04:07 +13:00
|
|
|
self.button_info_stack.addWidget(self.info_label)
|
|
|
|
self.button_info_stack.addWidget(self.info_progress)
|
2023-12-11 10:43:46 +13:00
|
|
|
self.ui.button_info_layout.insertWidget(0, self.button_info_stack)
|
|
|
|
|
|
|
|
def showEvent(self, a0: QShowEvent) -> None:
|
|
|
|
if a0.spontaneous():
|
|
|
|
return super().showEvent(a0)
|
|
|
|
self.__app_names = {rgame.app_name for rgame in self.rcore.games}
|
|
|
|
self.__install_dirs = {rgame.folder_name for rgame in self.rcore.games if not rgame.is_dlc}
|
|
|
|
self.app_name_edit.setCompleter(
|
|
|
|
AppNameCompleter(app_names={(rgame.app_name, rgame.app_title) for rgame in self.rcore.games})
|
|
|
|
)
|
|
|
|
super().showEvent(a0)
|
2022-07-24 10:06:35 +12:00
|
|
|
|
2023-04-17 08:01:09 +12:00
|
|
|
def set_game(self, app_name: str):
|
|
|
|
if app_name:
|
2023-12-17 01:02:53 +13:00
|
|
|
rgame = self.rcore.get_game(app_name)
|
|
|
|
self.path_edit.setText(
|
|
|
|
os.path.join(self.core.get_default_install_dir(rgame.default_platform), rgame.folder_name)
|
|
|
|
)
|
2023-04-17 08:01:09 +12:00
|
|
|
self.app_name_edit.setText(app_name)
|
|
|
|
|
2023-02-19 01:33:42 +13:00
|
|
|
def path_edit_callback(self, path) -> Tuple[bool, str, int]:
|
2023-12-25 07:44:46 +13:00
|
|
|
if not os.path.exists(path):
|
2023-02-19 01:33:42 +13:00
|
|
|
return False, path, IndicatorReasonsCommon.DIR_NOT_EXISTS
|
2023-12-25 07:44:46 +13:00
|
|
|
if os.path.exists(os.path.join(path, ".egstore")):
|
|
|
|
return True, path, IndicatorReasonsCommon.VALID
|
|
|
|
elif os.path.basename(path) in self.__install_dirs:
|
|
|
|
return True, path, IndicatorReasonsCommon.VALID
|
2023-02-19 01:33:42 +13:00
|
|
|
return False, path, IndicatorReasonsCommon.UNDEFINED
|
2021-10-12 10:19:32 +13:00
|
|
|
|
2022-10-26 15:12:36 +13:00
|
|
|
@pyqtSlot(str)
|
|
|
|
def path_changed(self, path: str):
|
2022-07-24 10:06:35 +12:00
|
|
|
self.info_label.setText("")
|
2022-07-14 21:01:57 +12:00
|
|
|
self.ui.import_folder_check.setCheckState(Qt.Unchecked)
|
2023-05-08 01:31:05 +12:00
|
|
|
self.ui.import_force_check.setCheckState(Qt.Unchecked)
|
2021-10-12 10:19:32 +13:00
|
|
|
if self.path_edit.is_valid:
|
2022-07-02 03:43:25 +12:00
|
|
|
self.app_name_edit.setText(find_app_name(path, self.core))
|
2021-10-12 10:19:32 +13:00
|
|
|
else:
|
2022-07-03 04:22:12 +12:00
|
|
|
self.app_name_edit.setText("")
|
2021-10-12 10:19:32 +13:00
|
|
|
|
2023-02-19 01:33:42 +13:00
|
|
|
def app_name_edit_callback(self, text) -> Tuple[bool, str, int]:
|
2021-10-12 10:19:32 +13:00
|
|
|
if not text:
|
2023-02-19 01:33:42 +13:00
|
|
|
return False, text, IndicatorReasonsCommon.UNDEFINED
|
2023-12-11 10:43:46 +13:00
|
|
|
if text in self.__app_names:
|
2023-02-19 01:33:42 +13:00
|
|
|
return True, text, IndicatorReasonsCommon.VALID
|
2021-10-12 10:19:32 +13:00
|
|
|
else:
|
2023-02-19 01:33:42 +13:00
|
|
|
return False, text, IndicatorReasonsCommon.NOT_INSTALLED
|
2021-10-12 10:19:32 +13:00
|
|
|
|
2023-12-17 12:20:07 +13:00
|
|
|
def app_name_save_callback(self, text) -> None:
|
|
|
|
rgame = self.rcore.get_game(text)
|
|
|
|
self.ui.platform_combo.clear()
|
|
|
|
self.ui.platform_combo.addItems(rgame.platforms)
|
|
|
|
self.ui.platform_combo.setCurrentText(rgame.default_platform)
|
|
|
|
|
2022-10-26 15:12:36 +13:00
|
|
|
@pyqtSlot(str)
|
2022-07-14 21:01:57 +12:00
|
|
|
def app_name_changed(self, app_name: str):
|
2022-07-24 10:06:35 +12:00
|
|
|
self.info_label.setText("")
|
2022-07-14 21:01:57 +12:00
|
|
|
self.ui.import_dlcs_check.setCheckState(Qt.Unchecked)
|
2023-05-08 01:31:05 +12:00
|
|
|
self.ui.import_force_check.setCheckState(Qt.Unchecked)
|
2023-12-11 10:43:46 +13:00
|
|
|
self.ui.import_dlcs_check.setEnabled(
|
|
|
|
self.app_name_edit.is_valid and bool(self.core.get_dlc_for_game(app_name))
|
|
|
|
)
|
|
|
|
self.ui.import_button.setEnabled(
|
|
|
|
not bool(self.worker) and (self.app_name_edit.is_valid and self.path_edit.is_valid)
|
|
|
|
)
|
2022-05-05 08:11:41 +12:00
|
|
|
|
2022-10-26 15:12:36 +13:00
|
|
|
@pyqtSlot(int)
|
|
|
|
def import_folder_changed(self, state: Qt.CheckState):
|
2022-07-14 21:01:57 +12:00
|
|
|
self.app_name_edit.setEnabled(not state)
|
2023-12-17 12:20:07 +13:00
|
|
|
self.ui.platform_combo.setEnabled(not state)
|
|
|
|
self.ui.platform_combo.setToolTip(
|
|
|
|
self.tr(
|
|
|
|
"When importing multiple games, the current OS will be used at the"
|
|
|
|
" platform for the games that support it, otherwise the Windows version"
|
|
|
|
" will be imported."
|
|
|
|
) if state else ""
|
|
|
|
)
|
2022-07-14 21:01:57 +12:00
|
|
|
self.ui.import_dlcs_check.setCheckState(Qt.Unchecked)
|
2023-05-08 01:31:05 +12:00
|
|
|
self.ui.import_force_check.setCheckState(Qt.Unchecked)
|
2022-07-14 21:01:57 +12:00
|
|
|
self.ui.import_dlcs_check.setEnabled(
|
|
|
|
state
|
|
|
|
or (self.app_name_edit.is_valid and bool(self.core.get_dlc_for_game(self.app_name_edit.text())))
|
|
|
|
)
|
2023-12-11 09:12:17 +13:00
|
|
|
self.ui.import_button.setEnabled(
|
|
|
|
not bool(self.worker) and (state or (not state and self.app_name_edit.is_valid))
|
|
|
|
)
|
2022-07-14 21:01:57 +12:00
|
|
|
|
2022-10-26 15:12:36 +13:00
|
|
|
@pyqtSlot(int)
|
|
|
|
def import_dlcs_changed(self, state: Qt.CheckState):
|
2023-12-11 09:12:17 +13:00
|
|
|
self.ui.import_button.setEnabled(
|
|
|
|
not bool(self.worker) and (self.ui.import_folder_check.isChecked() or self.app_name_edit.is_valid)
|
|
|
|
)
|
2022-10-26 15:12:36 +13:00
|
|
|
|
2023-01-27 04:37:57 +13:00
|
|
|
@pyqtSlot(str)
|
2023-03-13 23:29:33 +13:00
|
|
|
def __import(self, path: Optional[str] = None):
|
2023-12-11 10:43:46 +13:00
|
|
|
self.ui.import_button.setDisabled(True)
|
|
|
|
self.info_label.setText(self.tr("Status: Importing games"))
|
|
|
|
self.info_progress.setValue(0)
|
|
|
|
self.button_info_stack.setCurrentWidget(self.info_progress)
|
|
|
|
|
2021-10-12 10:19:32 +13:00
|
|
|
if not path:
|
|
|
|
path = self.path_edit.text()
|
2023-12-11 09:12:17 +13:00
|
|
|
self.worker = ImportWorker(
|
2023-01-25 02:35:51 +13:00
|
|
|
self.core,
|
2022-07-14 21:01:57 +12:00
|
|
|
path,
|
2023-12-17 12:20:07 +13:00
|
|
|
app_name=self.app_name_edit.text(),
|
|
|
|
platform=self.ui.platform_combo.currentText() if not self.ui.import_folder_check.isChecked() else None,
|
|
|
|
import_folder=self.ui.import_folder_check.isChecked(),
|
|
|
|
import_dlcs=self.ui.import_dlcs_check.isChecked(),
|
|
|
|
import_force=self.ui.import_force_check.isChecked()
|
2022-07-14 21:01:57 +12:00
|
|
|
)
|
2023-12-11 09:12:17 +13:00
|
|
|
self.worker.signals.progress.connect(self.__on_import_progress)
|
2023-12-11 10:43:46 +13:00
|
|
|
self.worker.signals.result.connect(self.__on_import_result)
|
2023-12-11 09:12:17 +13:00
|
|
|
self.threadpool.start(self.worker)
|
2022-07-02 03:43:25 +12:00
|
|
|
|
2023-01-26 00:08:18 +13:00
|
|
|
@pyqtSlot(ImportedGame, int)
|
|
|
|
def __on_import_progress(self, imported: ImportedGame, progress: int):
|
2023-01-27 05:04:07 +13:00
|
|
|
self.info_progress.setValue(progress)
|
2023-05-03 11:12:03 +12:00
|
|
|
if imported.result == ImportResult.SUCCESS:
|
2023-01-27 15:11:10 +13:00
|
|
|
self.rcore.get_game(imported.app_name).set_installed(True)
|
2023-01-27 02:51:45 +13:00
|
|
|
status = "error" if not imported.result else (
|
|
|
|
"failed" if imported.result == ImportResult.FAILED else "successful"
|
|
|
|
)
|
2023-01-26 00:08:18 +13:00
|
|
|
logger.info(f"Import {status}: {imported.app_title}: {imported.path} ({imported.message})")
|
|
|
|
|
2022-07-03 04:22:12 +12:00
|
|
|
@pyqtSlot(list)
|
2023-01-26 00:08:18 +13:00
|
|
|
def __on_import_result(self, result: List[ImportedGame]):
|
2023-12-11 09:12:17 +13:00
|
|
|
self.worker = None
|
2023-01-27 05:04:07 +13:00
|
|
|
self.button_info_stack.setCurrentWidget(self.info_label)
|
2022-07-03 04:22:12 +12:00
|
|
|
if len(result) == 1:
|
|
|
|
res = result[0]
|
|
|
|
if res.result == ImportResult.SUCCESS:
|
2022-07-24 10:06:35 +12:00
|
|
|
self.info_label.setText(
|
|
|
|
self.tr("Success: <b>{}</b> imported").format(res.app_title)
|
2022-07-03 04:22:12 +12:00
|
|
|
)
|
|
|
|
elif res.result == ImportResult.FAILED:
|
2022-07-24 10:06:35 +12:00
|
|
|
self.info_label.setText(
|
|
|
|
self.tr("Failed: <b>{}</b> - {}").format(res.app_title, res.message)
|
2022-07-02 03:43:25 +12:00
|
|
|
)
|
2021-10-12 10:19:32 +13:00
|
|
|
else:
|
2022-07-24 10:06:35 +12:00
|
|
|
self.info_label.setText(
|
|
|
|
self.tr("Error: Could not find AppName for <b>{}</b>").format(res.path)
|
2022-07-02 03:43:25 +12:00
|
|
|
)
|
2022-07-03 04:22:12 +12:00
|
|
|
else:
|
2023-12-11 10:43:46 +13:00
|
|
|
self.info_label.setText(self.tr("Status: Finished importing games"))
|
2022-07-03 04:22:12 +12:00
|
|
|
success = [r for r in result if r.result == ImportResult.SUCCESS]
|
|
|
|
failure = [r for r in result if r.result == ImportResult.FAILED]
|
|
|
|
errored = [r for r in result if r.result == ImportResult.ERROR]
|
2022-08-30 11:33:08 +12:00
|
|
|
# pylint: disable=E1101
|
2022-07-03 04:22:12 +12:00
|
|
|
messagebox = QMessageBox(
|
|
|
|
QMessageBox.Information,
|
|
|
|
self.tr("Import summary"),
|
|
|
|
self.tr(
|
|
|
|
"Tried to import {} folders.\n\n"
|
|
|
|
"Successfully imported {} games, failed to import {} games and {} errors occurred"
|
|
|
|
).format(len(success) + len(failure) + len(errored), len(success), len(failure), len(errored)),
|
|
|
|
buttons=QMessageBox.StandardButton.Close,
|
|
|
|
parent=self,
|
2022-07-02 03:43:25 +12:00
|
|
|
)
|
2022-07-03 04:22:12 +12:00
|
|
|
messagebox.setWindowModality(Qt.NonModal)
|
|
|
|
details: List = []
|
|
|
|
for res in success:
|
|
|
|
details.append(
|
2022-07-24 10:06:35 +12:00
|
|
|
self.tr("Success: {} imported").format(res.app_title)
|
2022-07-03 04:22:12 +12:00
|
|
|
)
|
|
|
|
for res in failure:
|
|
|
|
details.append(
|
2022-07-24 10:06:35 +12:00
|
|
|
self.tr("Failed: {} - {}").format(res.app_title, res.message)
|
2022-07-03 04:22:12 +12:00
|
|
|
)
|
|
|
|
for res in errored:
|
|
|
|
details.append(
|
2022-07-24 10:06:35 +12:00
|
|
|
self.tr("Error: Could not find AppName for {}").format(res.path)
|
2022-07-03 04:22:12 +12:00
|
|
|
)
|
|
|
|
messagebox.setDetailedText("\n".join(details))
|
|
|
|
messagebox.show()
|