1
0
Fork 0
mirror of synced 2024-06-23 08:40:45 +12:00

Merge pull request #225 from loathingKernel/fixups

Fixups
This commit is contained in:
Dummerle 2022-07-03 00:05:21 +02:00 committed by GitHub
commit 90aa28323c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 159 additions and 117 deletions

View file

@ -1,9 +1,9 @@
import os
import platform
from logging import getLogger
from typing import Tuple, Iterable
from typing import Tuple, Iterable, List
from PyQt5.QtCore import Qt, QThreadPool, QRunnable, pyqtSlot
from PyQt5.QtCore import Qt, QThreadPool, QRunnable, pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import QGroupBox, QListWidgetItem, QFileDialog, QMessageBox
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
@ -200,12 +200,16 @@ class EGLSyncListItem(QListWidgetItem):
class EGLSyncListGroup(QGroupBox, Ui_EGLSyncListGroup):
action_errors = pyqtSignal(list)
def __init__(self, export: bool, parent=None):
super(EGLSyncListGroup, self).__init__(parent=parent)
self.setupUi(self)
self.core = LegendaryCoreSingleton()
self.signals = GlobalSignalsSingleton()
self.list.setProperty("noBorder", 1)
# TODO: Convert the CSS and the code to adhere to NoFrame
# self.list.setFrameShape(self.list.NoFrame)
self.export = export
@ -232,6 +236,8 @@ class EGLSyncListGroup(QGroupBox, Ui_EGLSyncListGroup):
self.action_button.clicked.connect(self.action)
self.action_errors.connect(self.show_errors)
def has_selected(self):
for item in self.items:
if item.is_checked():
@ -258,8 +264,8 @@ class EGLSyncListGroup(QGroupBox, Ui_EGLSyncListGroup):
self.buttons_widget.setVisible(enabled and bool(self.list.count()))
def action(self):
imported = list()
errors = list()
imported: List = []
errors: List = []
for item in self.items:
if item.is_checked():
if e := item.action():
@ -271,13 +277,17 @@ class EGLSyncListGroup(QGroupBox, Ui_EGLSyncListGroup):
self.signals.update_gamelist.emit(imported)
self.populate(True)
if errors:
QMessageBox.warning(
self.parent(),
self.tr("The following errors occurred while {}.").format(
self.tr("exporting") if self.export else self.tr("importing")
),
"\n".join(errors),
)
self.action_errors.emit(errors)
@pyqtSlot(list)
def show_errors(self, errors: List):
QMessageBox.warning(
self.parent(),
self.tr("The following errors occurred while {}.").format(
self.tr("exporting") if self.export else self.tr("importing")
),
"\n".join(errors),
)
@property
def items(self) -> Iterable[EGLSyncListItem]:

View file

@ -1,13 +1,14 @@
import json
import os
from dataclasses import dataclass
from enum import IntEnum
from logging import getLogger
from pathlib import Path
from typing import List, Tuple, Optional
from PyQt5.QtCore import Qt, QModelIndex, pyqtSignal, QRunnable, QObject, QThreadPool
from PyQt5.QtCore import Qt, QModelIndex, pyqtSignal, QRunnable, QObject, QThreadPool, pyqtSlot
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QFileDialog, QGroupBox, QCompleter, QTreeView, QHeaderView, QApplication, QMessageBox
from PyQt5.QtWidgets import QFileDialog, QGroupBox, QCompleter, QTreeView, QHeaderView, qApp, QMessageBox
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ApiResultsSingleton
from rare.ui.components.tabs.games.import_sync.import_group import Ui_ImportGroup
@ -34,22 +35,22 @@ def find_app_name(path: str, core) -> Optional[str]:
return None
@dataclass
class ResultGame:
app_name: str
error: Optional[str] = None
class ImportResult(IntEnum):
ERROR = 0
FAILED = 1
SUCCESS = 2
@dataclass
class Result:
successful_games: List[ResultGame] = None
failed_games: List[ResultGame] = None
error_messages: List[str] = None
class ImportedGame:
result: ImportResult
app_name: Optional[str] = None
message: Optional[str] = None
class ImportWorker(QRunnable):
class Signals(QObject):
finished = pyqtSignal(Result)
finished = pyqtSignal(list)
progress = pyqtSignal(int)
def __init__(self, path: str, import_folder: bool = False, app_name: str = None):
@ -59,39 +60,37 @@ class ImportWorker(QRunnable):
self.path = Path(path)
self.import_folder = import_folder
self.app_name = app_name
self.tr = lambda message: QApplication.translate("ImportThread", message)
self.tr = lambda message: qApp.translate("ImportThread", message)
def run(self) -> None:
result = Result([], [], [])
result_list: List = []
if self.import_folder:
number_of_folders = len(list(self.path.iterdir()))
for i, child in enumerate(self.path.iterdir()):
folders = [i for i in self.path.iterdir() if i.is_dir()]
number_of_folders = len(folders)
for i, child in enumerate(folders):
if not child.is_dir():
continue
if (app_name := find_app_name(str(child), self.core)) is not None:
logger.debug(f"Found app_name {app_name} for {child}")
err = self.__import_game(app_name, child)
if err:
result.failed_games.append(ResultGame(app_name, err))
else:
result.successful_games.append(ResultGame(app_name))
else:
result.error_messages.append(self.tr("Could not find AppName for {}").format(child))
result = self.__try_import(child, None)
result_list.append(result)
self.signals.progress.emit(int(100 * i // number_of_folders))
else:
if not self.app_name:
# try to find app name
if a_n := find_app_name(str(self.path), self.core):
self.app_name = a_n
else:
result.error_messages.append(self.tr("Could not find AppName for {}").format(str(self.path)))
return
err = self.__import_game(self.app_name, self.path)
result = self.__try_import(self.path, self.app_name)
result_list.append(result)
self.signals.finished.emit(result_list)
def __try_import(self, path: Path, app_name: str = None) -> ImportedGame:
result = ImportedGame(ImportResult.ERROR, None, None)
if app_name or (app_name := find_app_name(str(path), self.core)):
result.app_name = app_name
err = self.__import_game(app_name, path)
if err:
result.failed_games.append(ResultGame(self.app_name, err))
result.result = ImportResult.FAILED
result.message = err
else:
result.successful_games.append(ResultGame(self.app_name))
self.signals.finished.emit(result)
result.result = ImportResult.SUCCESS
else:
result.message = self.tr("Could not find AppName for {}").format(str(path))
return result
def __import_game(self, app_name: str, path: Path) -> str:
if not (err := legendary_utils.import_game(self.core, app_name=app_name, path=str(path))):
@ -205,12 +204,12 @@ class ImportGroup(QGroupBox):
return False, path, ""
def path_changed(self, path):
self.ui.info_label.setText(str())
self.ui.info_label.setText("")
self.ui.import_folder_check.setChecked(False)
if self.path_edit.is_valid:
self.app_name_edit.setText(find_app_name(path, self.core))
else:
self.app_name_edit.setText(str())
self.app_name_edit.setText("")
def app_name_edit_cb(self, text) -> Tuple[bool, str, str]:
if not text:
@ -221,7 +220,7 @@ class ImportGroup(QGroupBox):
return False, text, IndicatorLineEdit.reasons.game_not_installed
def app_name_changed(self, text):
self.ui.info_label.setText(str())
self.ui.info_label.setText("")
if self.app_name_edit.is_valid:
self.ui.import_button.setEnabled(True)
else:
@ -235,33 +234,63 @@ class ImportGroup(QGroupBox):
worker.signals.progress.connect(self.import_progress)
self.threadpool.start(worker)
def import_finished(self, result: Result):
logger.info(f"Import finished: {result.__dict__}")
if result.successful_games:
self.signals.update_gamelist.emit([i.app_name for i in result.successful_games])
if len(result.successful_games) == 1:
@pyqtSlot(list)
def import_finished(self, result: List):
logger.info(f"Import finished: {result}")
self.signals.update_gamelist.emit([r.app_name for r in result if r.result == ImportResult.SUCCESS])
for failed in (f for f in result if f.result == ImportResult.FAILED):
igame = self.core.get_installed_game(failed.app_name)
if igame and igame.version != self.core.get_asset(igame.app_name, igame.platform, False).build_version:
# update available
self.signals.add_download.emit(igame.app_name)
self.signals.update_download_tab_text.emit()
if len(result) == 1:
res = result[0]
if res.result == ImportResult.SUCCESS:
self.ui.info_label.setText(
self.tr(f"{self.core.get_game(result.successful_games[0].app_name).app_title} imported successfully: ")
self.tr("{} was imported successfully").format(self.core.get_game(res.app_name).app_title)
)
elif res.result == ImportResult.FAILED:
self.ui.info_label.setText(
self.tr("Failed: {}").format(res.message)
)
else:
self.ui.info_label.setText(
self.tr("Imported {} games successfully".format(len(result.successful_games)))
self.tr("Error: {}").format(res.message)
)
for res_game in result.failed_games:
igame = self.core.get_installed_game(res_game.app_name)
if igame.version != self.core.get_asset(igame.app_name, igame.platform, False).build_version:
# update available
self.signals.add_download.emit(igame.app_name)
self.signals.update_download_tab_text.emit()
if result.failed_games:
self.ui.info_label.setText(
self.tr(f"Failed to import: "
f"{', '.join([self.core.get_game(i.app_name).app_title for i in result.failed_games])}")
else:
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]
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,
)
if result.error_messages:
QMessageBox.warning(self, self.tr("Error"), self.tr("\n".join(result.error_messages)))
messagebox.setWindowModality(Qt.NonModal)
details: List = []
for res in success:
details.append(
self.tr("{} was imported successfully").format(self.core.get_game(res.app_name).app_title)
)
for res in failure:
details.append(
self.tr("Failed: {}").format(res.message)
)
for res in errored:
details.append(
self.tr("Error: {}").format(res.message)
)
messagebox.setDetailedText("\n".join(details))
messagebox.show()
def import_progress(self, progress: int):
pass

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/import_sync/import_group.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
@ -14,31 +14,34 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_ImportGroup(object):
def setupUi(self, ImportGroup):
ImportGroup.setObjectName("ImportGroup")
ImportGroup.resize(501, 154)
ImportGroup.resize(501, 136)
ImportGroup.setWindowTitle("ImportGroup")
ImportGroup.setWindowFilePath("")
self.import_layout = QtWidgets.QFormLayout(ImportGroup)
self.import_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.import_layout.setObjectName("import_layout")
self.formLayout = QtWidgets.QFormLayout(ImportGroup)
self.formLayout.setObjectName("formLayout")
self.path_edit_label = QtWidgets.QLabel(ImportGroup)
self.path_edit_label.setObjectName("path_edit_label")
self.import_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.path_edit_label)
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.path_edit_label)
self.path_edit_layout = QtWidgets.QHBoxLayout()
self.path_edit_layout.setObjectName("path_edit_layout")
self.import_layout.setLayout(0, QtWidgets.QFormLayout.FieldRole, self.path_edit_layout)
self.formLayout.setLayout(0, QtWidgets.QFormLayout.FieldRole, self.path_edit_layout)
self.app_name_label = QtWidgets.QLabel(ImportGroup)
self.app_name_label.setObjectName("app_name_label")
self.import_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.app_name_label)
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.app_name_label)
self.app_name_layout = QtWidgets.QHBoxLayout()
self.app_name_layout.setObjectName("app_name_layout")
self.import_layout.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.app_name_layout)
self.formLayout.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.app_name_layout)
self.import_folder_label = QtWidgets.QLabel(ImportGroup)
self.import_folder_label.setObjectName("import_folder_label")
self.import_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.import_folder_label)
self.info_label = QtWidgets.QLabel(ImportGroup)
self.info_label.setText("")
self.info_label.setObjectName("info_label")
self.import_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.info_label)
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.import_folder_label)
self.import_folder_check = QtWidgets.QCheckBox(ImportGroup)
font = QtGui.QFont()
font.setItalic(True)
self.import_folder_check.setFont(font)
self.import_folder_check.setObjectName("import_folder_check")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.import_folder_check)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.import_button = QtWidgets.QPushButton(ImportGroup)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
@ -46,13 +49,12 @@ class Ui_ImportGroup(object):
sizePolicy.setHeightForWidth(self.import_button.sizePolicy().hasHeightForWidth())
self.import_button.setSizePolicy(sizePolicy)
self.import_button.setObjectName("import_button")
self.import_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.import_button)
self.import_folder_check = QtWidgets.QCheckBox(ImportGroup)
font = QtGui.QFont()
font.setItalic(True)
self.import_folder_check.setFont(font)
self.import_folder_check.setObjectName("import_folder_check")
self.import_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.import_folder_check)
self.horizontalLayout.addWidget(self.import_button)
self.info_label = QtWidgets.QLabel(ImportGroup)
self.info_label.setText("")
self.info_label.setObjectName("info_label")
self.horizontalLayout.addWidget(self.info_label)
self.formLayout.setLayout(3, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout)
self.retranslateUi(ImportGroup)
QtCore.QMetaObject.connectSlotsByName(ImportGroup)
@ -63,8 +65,8 @@ class Ui_ImportGroup(object):
self.path_edit_label.setText(_translate("ImportGroup", "Installation path"))
self.app_name_label.setText(_translate("ImportGroup", "Override app name"))
self.import_folder_label.setText(_translate("ImportGroup", "Import all folders"))
self.import_button.setText(_translate("ImportGroup", "Import Game"))
self.import_folder_check.setText(_translate("ImportGroup", "Scan the installation path for game folders and import them"))
self.import_button.setText(_translate("ImportGroup", "Import Game"))
if __name__ == "__main__":

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>501</width>
<height>154</height>
<height>136</height>
</rect>
</property>
<property name="windowTitle">
@ -19,10 +19,7 @@
<property name="title">
<string>Import EGL game from a directory</string>
</property>
<layout class="QFormLayout" name="import_layout">
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="path_edit_label">
<property name="text">
@ -50,26 +47,6 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="info_label">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QPushButton" name="import_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Import Game</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="import_folder_check">
<property name="font">
@ -82,6 +59,30 @@
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="import_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Import Game</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="info_label">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>