Lgndr: Create argument models for consistent function arguments and cleaner implementation.
Lgndr: Prefix files that aren't part of legendary with 'api_' Lgndr: Return statistics from 'verify_game' instead of parsing the exception VerifyWorker: Add 'error' signal for exceptions.
This commit is contained in:
parent
d7aba41aa4
commit
3aae3887f6
|
@ -8,6 +8,7 @@ from PyQt5.QtCore import Qt, QObject, QRunnable, QThreadPool, pyqtSignal, pyqtSl
|
||||||
from PyQt5.QtGui import QCloseEvent, QKeyEvent
|
from PyQt5.QtGui import QCloseEvent, QKeyEvent
|
||||||
from PyQt5.QtWidgets import QDialog, QFileDialog, QCheckBox
|
from PyQt5.QtWidgets import QDialog, QFileDialog, QCheckBox
|
||||||
|
|
||||||
|
from rare.lgndr.api_arguments import LgndrInstallGameArgs
|
||||||
from rare.lgndr.cli import LegendaryCLI
|
from rare.lgndr.cli import LegendaryCLI
|
||||||
from rare.lgndr.core import LegendaryCore
|
from rare.lgndr.core import LegendaryCore
|
||||||
from legendary.models.downloading import ConditionCheckResult
|
from legendary.models.downloading import ConditionCheckResult
|
||||||
|
@ -311,7 +312,7 @@ class InstallInfoWorker(QRunnable):
|
||||||
cli = LegendaryCLISingleton()
|
cli = LegendaryCLISingleton()
|
||||||
download = InstallDownloadModel(
|
download = InstallDownloadModel(
|
||||||
# *self.core.prepare_download(
|
# *self.core.prepare_download(
|
||||||
*cli.prepare_install(
|
*cli.prepare_install(LgndrInstallGameArgs(
|
||||||
app_name=self.dl_item.options.app_name,
|
app_name=self.dl_item.options.app_name,
|
||||||
base_path=self.dl_item.options.base_path,
|
base_path=self.dl_item.options.base_path,
|
||||||
force=self.dl_item.options.force,
|
force=self.dl_item.options.force,
|
||||||
|
@ -336,7 +337,7 @@ class InstallInfoWorker(QRunnable):
|
||||||
# disable_delta=,
|
# disable_delta=,
|
||||||
# override_delta_manifest=,
|
# override_delta_manifest=,
|
||||||
# reset_sdl=,
|
# reset_sdl=,
|
||||||
sdl_prompt=lambda app_name, title: self.dl_item.options.sdl_list,
|
sdl_prompt=lambda app_name, title: self.dl_item.options.sdl_list,)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -143,20 +143,27 @@ class GameInfo(QWidget, Ui_GameInfo):
|
||||||
return
|
return
|
||||||
self.verify_widget.setCurrentIndex(1)
|
self.verify_widget.setCurrentIndex(1)
|
||||||
verify_worker = VerifyWorker(self.game.app_name)
|
verify_worker = VerifyWorker(self.game.app_name)
|
||||||
verify_worker.signals.status.connect(self.verify_statistics)
|
verify_worker.signals.status.connect(self.verify_status)
|
||||||
verify_worker.signals.summary.connect(self.finish_verify)
|
verify_worker.signals.result.connect(self.verify_result)
|
||||||
|
verify_worker.signals.error.connect(self.verify_error)
|
||||||
self.verify_progress.setValue(0)
|
self.verify_progress.setValue(0)
|
||||||
self.verify_threads[self.game.app_name] = verify_worker
|
self.verify_threads[self.game.app_name] = verify_worker
|
||||||
self.verify_pool.start(verify_worker)
|
self.verify_pool.start(verify_worker)
|
||||||
self.move_button.setEnabled(False)
|
self.move_button.setEnabled(False)
|
||||||
|
|
||||||
def verify_statistics(self, num, total, app_name):
|
@pyqtSlot(str, str)
|
||||||
|
def verify_error(self, app_name, message):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@pyqtSlot(str, int, int, float, float)
|
||||||
|
def verify_status(self, app_name, num, total, percentage, speed):
|
||||||
# checked, max, app_name
|
# checked, max, app_name
|
||||||
if app_name == self.game.app_name:
|
if app_name == self.game.app_name:
|
||||||
self.verify_progress.setValue(num * 100 // total)
|
self.verify_progress.setValue(num * 100 // total)
|
||||||
|
|
||||||
def finish_verify(self, failed, missing, app_name):
|
@pyqtSlot(str, bool, int, int)
|
||||||
if failed == missing == 0:
|
def verify_result(self, app_name, success, failed, missing):
|
||||||
|
if success:
|
||||||
QMessageBox.information(
|
QMessageBox.information(
|
||||||
self,
|
self,
|
||||||
"Summary",
|
"Summary",
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import Tuple, Iterable, List
|
||||||
from PyQt5.QtCore import Qt, QThreadPool, QRunnable, pyqtSlot, pyqtSignal
|
from PyQt5.QtCore import Qt, QThreadPool, QRunnable, pyqtSlot, pyqtSignal
|
||||||
from PyQt5.QtWidgets import QGroupBox, QListWidgetItem, QFileDialog, QMessageBox
|
from PyQt5.QtWidgets import QGroupBox, QListWidgetItem, QFileDialog, QMessageBox
|
||||||
|
|
||||||
from rare.lgndr.exception import LgndrException
|
from rare.lgndr.api_exception import LgndrException
|
||||||
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
|
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
|
||||||
from rare.ui.components.tabs.games.import_sync.egl_sync_group import Ui_EGLSyncGroup
|
from rare.ui.components.tabs.games.import_sync.egl_sync_group import Ui_EGLSyncGroup
|
||||||
from rare.ui.components.tabs.games.import_sync.egl_sync_list_group import (
|
from rare.ui.components.tabs.games.import_sync.egl_sync_list_group import (
|
||||||
|
|
|
@ -11,7 +11,8 @@ from PyQt5.QtCore import Qt, QModelIndex, pyqtSignal, QRunnable, QObject, QThrea
|
||||||
from PyQt5.QtGui import QStandardItemModel
|
from PyQt5.QtGui import QStandardItemModel
|
||||||
from PyQt5.QtWidgets import QFileDialog, QGroupBox, QCompleter, QTreeView, QHeaderView, qApp, QMessageBox
|
from PyQt5.QtWidgets import QFileDialog, QGroupBox, QCompleter, QTreeView, QHeaderView, qApp, QMessageBox
|
||||||
|
|
||||||
from rare.lgndr.exception import LgndrException
|
from lgndr.api_arguments import LgndrImportGameArgs
|
||||||
|
from rare.lgndr.api_exception import LgndrException
|
||||||
from rare.shared import LegendaryCLISingleton, LegendaryCoreSingleton, GlobalSignalsSingleton, ApiResultsSingleton
|
from rare.shared import LegendaryCLISingleton, LegendaryCoreSingleton, GlobalSignalsSingleton, ApiResultsSingleton
|
||||||
from rare.ui.components.tabs.games.import_sync.import_group import Ui_ImportGroup
|
from rare.ui.components.tabs.games.import_sync.import_group import Ui_ImportGroup
|
||||||
from rare.utils import legendary_utils
|
from rare.utils import legendary_utils
|
||||||
|
@ -105,23 +106,12 @@ class ImportWorker(QRunnable):
|
||||||
# else:
|
# else:
|
||||||
# return err
|
# return err
|
||||||
|
|
||||||
# TODO: This should be moved into RareCore and wrap import_game
|
|
||||||
def import_game_args(self, app_path: str, app_name: str, platfrom: str = "Windows",
|
|
||||||
disable_check: bool = False, skip_dlcs: bool = False, with_dlcs: bool = False, yes: bool = False):
|
|
||||||
args = Namespace(
|
|
||||||
app_path=app_path,
|
|
||||||
app_name=app_name,
|
|
||||||
platform=platfrom,
|
|
||||||
disable_check=disable_check,
|
|
||||||
skip_dlcs=skip_dlcs,
|
|
||||||
with_dlcs=with_dlcs,
|
|
||||||
yes=yes,
|
|
||||||
)
|
|
||||||
return args
|
|
||||||
|
|
||||||
def __import_game(self, app_name: str, path: Path):
|
def __import_game(self, app_name: str, path: Path):
|
||||||
cli = LegendaryCLISingleton()
|
cli = LegendaryCLISingleton()
|
||||||
args = self.import_game_args(str(path), app_name)
|
args = LgndrImportGameArgs(
|
||||||
|
app_path=str(path),
|
||||||
|
app_name=app_name,
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
cli.import_game(args)
|
cli.import_game(args)
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
"""
|
||||||
|
Module that overloads and monkeypatches legendary's classes/methods to work with Rare
|
||||||
|
|
||||||
|
Files with the 'api_' prefix are not part of legendary's source, and contain facilities relating to Rare.
|
||||||
|
"""
|
71
rare/lgndr/api_arguments.py
Normal file
71
rare/lgndr/api_arguments.py
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from multiprocessing import Queue
|
||||||
|
from typing import Callable, List
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(kw_only=True)
|
||||||
|
class LgndrCommonArgs:
|
||||||
|
# keep this here for future reference
|
||||||
|
# when we move to 3.10 we can use 'kw_only' to do dataclass inheritance
|
||||||
|
app_name: str
|
||||||
|
platform: str = "Windows"
|
||||||
|
yes: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LgndrImportGameArgs:
|
||||||
|
app_path: str
|
||||||
|
app_name: str
|
||||||
|
platform: str = "Windows"
|
||||||
|
disable_check: bool = False
|
||||||
|
skip_dlcs: bool = False
|
||||||
|
with_dlcs: bool = False
|
||||||
|
yes: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LgndrVerifyGameArgs:
|
||||||
|
app_name: str
|
||||||
|
# Rare's extra arguments
|
||||||
|
verify_stdout: Callable[[int, int, float, float], None] = lambda a0, a1, a2, a3: print(
|
||||||
|
f"Verification progress: {a0}/{a1} ({a2:.01f}%) [{a3:.1f} MiB/s]\t\r"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LgndrInstallGameArgs:
|
||||||
|
app_name: str
|
||||||
|
base_path: str = ""
|
||||||
|
status_q: Queue = None
|
||||||
|
shared_memory: int = 0
|
||||||
|
max_workers: int = 0
|
||||||
|
force: bool = False
|
||||||
|
disable_patching: bool = False
|
||||||
|
game_folder: str = ""
|
||||||
|
override_manifest: str = ""
|
||||||
|
override_old_manifest: str = ""
|
||||||
|
override_base_url: str = ""
|
||||||
|
platform: str = "Windows"
|
||||||
|
file_prefix: List = None
|
||||||
|
file_exclude_prefix: List = None
|
||||||
|
install_tag: List = None
|
||||||
|
order_opt: bool = False
|
||||||
|
dl_timeout: int = 10
|
||||||
|
repair_mode: bool = False
|
||||||
|
repair_and_update: bool = False
|
||||||
|
disable_delta: bool = False
|
||||||
|
override_delta_manifest: str = ""
|
||||||
|
egl_guid: str = ""
|
||||||
|
preferred_cdn: str = None
|
||||||
|
no_install: bool = False
|
||||||
|
ignore_space: bool = False
|
||||||
|
disable_sdl: bool = False
|
||||||
|
reset_sdl: bool = False
|
||||||
|
skip_sdl: bool = False
|
||||||
|
disable_https: bool = False
|
||||||
|
yes: bool = True
|
||||||
|
# Rare's extra arguments
|
||||||
|
sdl_prompt: Callable[[str, str], List[str]] = lambda a0, a1: []
|
||||||
|
verify_stdout: Callable[[int, int, float, float], None] = lambda a0, a1, a2, a3: print(
|
||||||
|
f"Verification progress: {a0}/{a1} ({a2:.01f}%) [{a3:.1f} MiB/s]\t\r"
|
||||||
|
)
|
|
@ -1,9 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
from argparse import Namespace
|
from typing import Optional, Union
|
||||||
from multiprocessing import Queue
|
|
||||||
from typing import Optional, Callable, List
|
|
||||||
|
|
||||||
import legendary.cli
|
import legendary.cli
|
||||||
from PyQt5.QtWidgets import QLabel, QMessageBox
|
from PyQt5.QtWidgets import QLabel, QMessageBox
|
||||||
|
@ -14,8 +12,9 @@ from legendary.utils.lfs import validate_files
|
||||||
from legendary.utils.selective_dl import get_sdl_appname
|
from legendary.utils.selective_dl import get_sdl_appname
|
||||||
|
|
||||||
from .core import LegendaryCore
|
from .core import LegendaryCore
|
||||||
from .exception import LgndrException, LgndrLogHandler
|
|
||||||
from .manager import DLManager
|
from .manager import DLManager
|
||||||
|
from .api_arguments import LgndrInstallGameArgs, LgndrImportGameArgs, LgndrVerifyGameArgs
|
||||||
|
from .api_exception import LgndrException, LgndrLogHandler
|
||||||
|
|
||||||
|
|
||||||
def get_boolean_choice(message):
|
def get_boolean_choice(message):
|
||||||
|
@ -40,49 +39,7 @@ class LegendaryCLI(legendary.cli.LegendaryCLI):
|
||||||
self.handler = LgndrLogHandler()
|
self.handler = LgndrLogHandler()
|
||||||
self.logger.addHandler(self.handler)
|
self.logger.addHandler(self.handler)
|
||||||
|
|
||||||
# def __init__(self, core: LegendaryCore):
|
def prepare_install(self, args: LgndrInstallGameArgs) -> (DLManager, AnalysisResult, InstalledGame, Game, bool, Optional[str], ConditionCheckResult):
|
||||||
# self.core = core
|
|
||||||
# self.logger = logging.getLogger('cli')
|
|
||||||
# self.logging_queue = None
|
|
||||||
# self.handler = LgndrLogHandler()
|
|
||||||
# self.logger.addHandler(self.handler)
|
|
||||||
|
|
||||||
# app_name, repair, repair_mode, no_install, repair_and_update, file_prefix, file_exclude_prefix, platform
|
|
||||||
# sdl_prompt, status_q
|
|
||||||
def prepare_install(self, app_name: str, base_path: str = '',
|
|
||||||
status_q: Queue = None, shared_memory: int = 0, max_workers: int = 0,
|
|
||||||
force: bool = False, disable_patching: bool = False,
|
|
||||||
game_folder: str = '', override_manifest: str = '',
|
|
||||||
override_old_manifest: str = '', override_base_url: str = '',
|
|
||||||
platform: str = 'Windows', file_prefix: list = None,
|
|
||||||
file_exclude_prefix: list = None, install_tag: list = None,
|
|
||||||
order_opt: bool = False, dl_timeout: int = 10,
|
|
||||||
repair_mode: bool = False, repair_and_update: bool = False,
|
|
||||||
disable_delta: bool = False, override_delta_manifest: str = '',
|
|
||||||
egl_guid: str = '', preferred_cdn: str = None,
|
|
||||||
no_install: bool = False, ignore_space: bool = False,
|
|
||||||
disable_sdl: bool = False, reset_sdl: bool = False, skip_sdl: bool = False,
|
|
||||||
sdl_prompt: Callable[[str, str], List[str]] = list,
|
|
||||||
yes: bool = True, verify_callback: Callable[[int, int, float, float], None] = None,
|
|
||||||
disable_https: bool = False) -> (DLManager, AnalysisResult, InstalledGame, Game, bool, Optional[str], ConditionCheckResult):
|
|
||||||
args = Namespace(
|
|
||||||
app_name=app_name, base_path=base_path,
|
|
||||||
status_q=status_q, shared_memory=shared_memory, max_workers=max_workers,
|
|
||||||
force=force, disable_patching=disable_patching,
|
|
||||||
game_folder=game_folder, override_manifest=override_manifest,
|
|
||||||
override_old_manifest=override_old_manifest, override_base_url=override_base_url,
|
|
||||||
platform=platform, file_prefix=file_prefix,
|
|
||||||
file_exclude_prefix=file_exclude_prefix, install_tag=install_tag,
|
|
||||||
order_opt=order_opt, dl_timeout=dl_timeout,
|
|
||||||
repair_mode=repair_mode, repair_and_update=repair_and_update,
|
|
||||||
disable_delta=disable_delta, override_delta_manifest=override_delta_manifest,
|
|
||||||
preferred_cdn=preferred_cdn,
|
|
||||||
no_install=no_install, ignore_space=ignore_space,
|
|
||||||
disable_sdl=disable_sdl, reset_sdl=reset_sdl, skip_sdl=skip_sdl,
|
|
||||||
sdl_prompt=sdl_prompt,
|
|
||||||
yes=yes, callback=verify_callback,
|
|
||||||
disable_https=disable_https
|
|
||||||
)
|
|
||||||
old_choice = legendary.cli.get_boolean_choice
|
old_choice = legendary.cli.get_boolean_choice
|
||||||
legendary.cli.get_boolean_choice = get_boolean_choice
|
legendary.cli.get_boolean_choice = get_boolean_choice
|
||||||
try:
|
try:
|
||||||
|
@ -92,7 +49,7 @@ class LegendaryCLI(legendary.cli.LegendaryCLI):
|
||||||
finally:
|
finally:
|
||||||
legendary.cli.get_boolean_choice = old_choice
|
legendary.cli.get_boolean_choice = old_choice
|
||||||
|
|
||||||
def install_game(self, args):
|
def install_game(self, args: LgndrInstallGameArgs) -> (DLManager, AnalysisResult, InstalledGame, Game, bool, Optional[str], ConditionCheckResult):
|
||||||
args.app_name = self._resolve_aliases(args.app_name)
|
args.app_name = self._resolve_aliases(args.app_name)
|
||||||
if self.core.is_installed(args.app_name):
|
if self.core.is_installed(args.app_name):
|
||||||
igame = self.core.get_installed_game(args.app_name)
|
igame = self.core.get_installed_game(args.app_name)
|
||||||
|
@ -267,10 +224,7 @@ class LegendaryCLI(legendary.cli.LegendaryCLI):
|
||||||
def uninstall_game(self, args):
|
def uninstall_game(self, args):
|
||||||
super(LegendaryCLI, self).uninstall_game(args)
|
super(LegendaryCLI, self).uninstall_game(args)
|
||||||
|
|
||||||
def verify_game(self, args, print_command=True, repair_mode=False, repair_online=False):
|
def verify_game(self, args: Union[LgndrVerifyGameArgs, LgndrInstallGameArgs], print_command=True, repair_mode=False, repair_online=False):
|
||||||
if not hasattr(args, 'callback') or args.callback is None:
|
|
||||||
args.callback = print
|
|
||||||
|
|
||||||
args.app_name = self._resolve_aliases(args.app_name)
|
args.app_name = self._resolve_aliases(args.app_name)
|
||||||
if not self.core.is_installed(args.app_name):
|
if not self.core.is_installed(args.app_name):
|
||||||
logger.error(f'Game "{args.app_name}" is not installed')
|
logger.error(f'Game "{args.app_name}" is not installed')
|
||||||
|
@ -339,8 +293,8 @@ class LegendaryCLI(legendary.cli.LegendaryCLI):
|
||||||
speed = (processed - last_processed) / 1024 / 1024 / delta
|
speed = (processed - last_processed) / 1024 / 1024 / delta
|
||||||
last_processed = processed
|
last_processed = processed
|
||||||
|
|
||||||
if args.callback:
|
if args.verify_stdout:
|
||||||
args.callback(num, total, percentage, speed)
|
args.verify_stdout(num, total, percentage, speed)
|
||||||
|
|
||||||
if result == VerifyResult.HASH_MATCH:
|
if result == VerifyResult.HASH_MATCH:
|
||||||
repair_file.append(f'{result_hash}:{path}')
|
repair_file.append(f'{result_hash}:{path}')
|
||||||
|
@ -356,8 +310,8 @@ class LegendaryCLI(legendary.cli.LegendaryCLI):
|
||||||
logger.info(f'Other failure (see log), treating file as missing: "{path}"')
|
logger.info(f'Other failure (see log), treating file as missing: "{path}"')
|
||||||
missing.append(path)
|
missing.append(path)
|
||||||
|
|
||||||
if args.callback:
|
if args.verify_stdout:
|
||||||
args.callback(num, total, percentage, speed)
|
args.verify_stdout(num, total, percentage, speed)
|
||||||
|
|
||||||
# always write repair file, even if all match
|
# always write repair file, even if all match
|
||||||
if repair_file:
|
if repair_file:
|
||||||
|
@ -368,12 +322,14 @@ class LegendaryCLI(legendary.cli.LegendaryCLI):
|
||||||
|
|
||||||
if not missing and not failed:
|
if not missing and not failed:
|
||||||
logger.info('Verification finished successfully.')
|
logger.info('Verification finished successfully.')
|
||||||
|
return True, 0, 0
|
||||||
else:
|
else:
|
||||||
logger.error(f'Verification failed, {len(failed)} file(s) corrupted, {len(missing)} file(s) are missing.')
|
logger.warning(f'Verification failed, {len(failed)} file(s) corrupted, {len(missing)} file(s) are missing.')
|
||||||
if print_command:
|
if print_command:
|
||||||
logger.info(f'Run "legendary repair {args.app_name}" to repair your game installation.')
|
logger.info(f'Run "legendary repair {args.app_name}" to repair your game installation.')
|
||||||
|
return False, len(failed), len(missing)
|
||||||
|
|
||||||
def import_game(self, args):
|
def import_game(self, args: LgndrImportGameArgs):
|
||||||
old_choice = legendary.cli.get_boolean_choice
|
old_choice = legendary.cli.get_boolean_choice
|
||||||
legendary.cli.get_boolean_choice = get_boolean_choice
|
legendary.cli.get_boolean_choice = get_boolean_choice
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -5,7 +5,7 @@ from legendary.models.downloading import AnalysisResult
|
||||||
from legendary.models.game import Game
|
from legendary.models.game import Game
|
||||||
from legendary.models.manifest import ManifestMeta
|
from legendary.models.manifest import ManifestMeta
|
||||||
|
|
||||||
from .exception import LgndrException, LgndrLogHandler
|
from .api_exception import LgndrException, LgndrLogHandler
|
||||||
from .manager import DLManager
|
from .manager import DLManager
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
from argparse import Namespace
|
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, QCoreApplication, QObject, QRunnable, QStandardPaths
|
from PyQt5.QtCore import pyqtSignal, QCoreApplication, QObject, QRunnable, QStandardPaths
|
||||||
from legendary.core import LegendaryCore
|
from legendary.core import LegendaryCore
|
||||||
from legendary.models.game import VerifyResult
|
|
||||||
from legendary.utils.lfs import validate_files
|
|
||||||
from parse import parse
|
|
||||||
|
|
||||||
|
from rare.lgndr.api_arguments import LgndrVerifyGameArgs
|
||||||
|
from rare.lgndr.api_exception import LgndrException
|
||||||
from rare.shared import LegendaryCLISingleton, LegendaryCoreSingleton
|
from rare.shared import LegendaryCLISingleton, LegendaryCoreSingleton
|
||||||
from rare.utils import config_helper
|
from rare.utils import config_helper
|
||||||
from rare.lgndr.exception import LgndrException
|
|
||||||
|
|
||||||
logger = getLogger("Legendary Utils")
|
logger = getLogger("Legendary Utils")
|
||||||
|
|
||||||
|
@ -88,8 +85,9 @@ def update_manifest(app_name: str, core: LegendaryCore):
|
||||||
|
|
||||||
class VerifyWorker(QRunnable):
|
class VerifyWorker(QRunnable):
|
||||||
class Signals(QObject):
|
class Signals(QObject):
|
||||||
status = pyqtSignal(int, int, str)
|
status = pyqtSignal(str, int, int, float, float)
|
||||||
summary = pyqtSignal(int, int, str)
|
result = pyqtSignal(str, bool, int, int)
|
||||||
|
error = pyqtSignal(str, str)
|
||||||
|
|
||||||
num: int = 0
|
num: int = 0
|
||||||
total: int = 1 # set default to 1 to avoid DivisionByZero before it is initialized
|
total: int = 1 # set default to 1 to avoid DivisionByZero before it is initialized
|
||||||
|
@ -103,25 +101,22 @@ class VerifyWorker(QRunnable):
|
||||||
self.app_name = app_name
|
self.app_name = app_name
|
||||||
|
|
||||||
def status_callback(self, num: int, total: int, percentage: float, speed: float):
|
def status_callback(self, num: int, total: int, percentage: float, speed: float):
|
||||||
self.signals.status.emit(num, total, self.app_name)
|
self.signals.status.emit(self.app_name, num, total, percentage, speed)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
args = Namespace(app_name=self.app_name,
|
args = LgndrVerifyGameArgs(app_name=self.app_name,
|
||||||
callback=self.status_callback)
|
verify_stdout=self.status_callback)
|
||||||
try:
|
try:
|
||||||
# TODO: offer this as an alternative when manifest doesn't exist
|
# TODO: offer this as an alternative when manifest doesn't exist
|
||||||
# TODO: requires the client to be online. To do it this way, we need to
|
# TODO: requires the client to be online. To do it this way, we need to
|
||||||
# TODO: somehow detect the error and offer a dialog in which case `verify_games` is
|
# TODO: somehow detect the error and offer a dialog in which case `verify_games` is
|
||||||
# TODO: re-run with `repair_mode` and `repair_online`
|
# TODO: re-run with `repair_mode` and `repair_online`
|
||||||
self.cli.verify_game(args, print_command=False, repair_mode=True, repair_online=True)
|
success, failed, missing = self.cli.verify_game(
|
||||||
# self.cli.verify_game(args, print_command=False)
|
args, print_command=False, repair_mode=True, repair_online=True)
|
||||||
self.signals.summary.emit(0, 0, self.app_name)
|
# success, failed, missing = self.cli.verify_game(args, print_command=False)
|
||||||
|
self.signals.result.emit(self.app_name, success, failed, missing)
|
||||||
except LgndrException as ret:
|
except LgndrException as ret:
|
||||||
r = parse('Verification failed, {:d} file(s) corrupted, {:d} file(s) are missing.', ret.message)
|
self.signals.error.emit(self.app_name, ret.message)
|
||||||
if r is None:
|
|
||||||
raise ret
|
|
||||||
else:
|
|
||||||
self.signals.summary.emit(r[0], r[1], self.app_name)
|
|
||||||
|
|
||||||
|
|
||||||
# FIXME: lk: ah ef me sideways, we can't even import this thing properly
|
# FIXME: lk: ah ef me sideways, we can't even import this thing properly
|
||||||
|
|
Loading…
Reference in a new issue