diff --git a/rare/shared/rare_core.py b/rare/shared/rare_core.py index 8b1b4d79..50be6226 100644 --- a/rare/shared/rare_core.py +++ b/rare/shared/rare_core.py @@ -4,7 +4,7 @@ import time from argparse import Namespace from itertools import chain from logging import getLogger -from typing import Dict, Iterator, Callable, Optional, List, Union, Iterable +from typing import Dict, Iterator, Callable, Optional, List, Union, Iterable, Tuple from PyQt5.QtCore import QObject, pyqtSignal, QSettings, pyqtSlot, QThreadPool, QRunnable, QTimer from legendary.lfs.eos import EOSOverlayApp @@ -21,8 +21,6 @@ from .workers import ( VerifyWorker, MoveWorker, FetchWorker, - GamesWorker, - NonAssetWorker, OriginWineWorker, ) from .workers.uninstall import uninstall_game @@ -52,11 +50,6 @@ class RareCore(QObject): self.__image_manager: Optional[ImageManager] = None self.__start_time = time.time() - self.__fetched_games: List = [] - self.__fetched_dlcs: Dict = {} - - self.__games_fetched: bool = False - self.__non_asset_fetched: bool = False self.args(args) self.signals(init=True) @@ -270,54 +263,21 @@ class RareCore(QObject): self.progress.emit(int(idx/length * 80) + 20, self.tr("Loaded {}").format(rgame.app_title)) @pyqtSlot(object, int) - def handle_result(self, result: object, res_type: int): - status = "" - if res_type == FetchWorker.Result.GAMES: - games, dlc_dict = result - self.__fetched_games += games - self.__fetched_dlcs.update(dlc_dict) - self.fetch_non_asset() - self.__games_fetched = True - status = self.tr("Prepared games") - if res_type == FetchWorker.Result.NON_ASSET: - games, dlc_dict = result - self.__fetched_games += games - for catalog_id, dlcs in dlc_dict.items(): - if catalog_id in self.__fetched_dlcs.keys(): - self.__fetched_dlcs[catalog_id] += dlcs - else: - self.__fetched_dlcs[catalog_id] = dlcs - self.__non_asset_fetched = True - status = self.tr("Prepared games without assets") + def __on_fetch_result(self, result: Tuple[List, Dict], res_type: int): logger.info(f"Got API results for {FetchWorker.Result(res_type).name}") - - fetched = [ - self.__games_fetched, - self.__non_asset_fetched, - ] - - self.progress.emit(sum(fetched) * 10, status) - - if all(fetched): - self.__add_games_and_dlcs(self.__fetched_games, self.__fetched_dlcs) - self.progress.emit(100, self.tr("Launching Rare")) - logger.debug(f"Fetch time {time.time() - self.__start_time} seconds") - QTimer.singleShot(100, self.__post_init) - self.completed.emit() + self.progress.emit(15, self.tr("Preparing library")) + self.__add_games_and_dlcs(*result) + self.progress.emit(100, self.tr("Launching Rare")) + logger.debug(f"Fetch time {time.time() - self.__start_time} seconds") + QTimer.singleShot(100, self.__post_init) + self.completed.emit() def fetch(self): - self.__games_fetched: bool = False - self.__non_asset_fetched: bool = False self.__start_time = time.time() - - games_worker = GamesWorker(self.__core, self.__args) - games_worker.signals.result.connect(self.handle_result) - QThreadPool.globalInstance().start(games_worker) - - def fetch_non_asset(self): - non_asset_worker = NonAssetWorker(self.__core, self.__args) - non_asset_worker.signals.result.connect(self.handle_result) - QThreadPool.globalInstance().start(non_asset_worker) + fetch_worker = FetchWorker(self.__core, self.__args) + fetch_worker.signals.progress.connect(self.progress) + fetch_worker.signals.result.connect(self.__on_fetch_result) + QThreadPool.globalInstance().start(fetch_worker) def fetch_saves(self): def __fetch() -> None: diff --git a/rare/shared/workers/__init__.py b/rare/shared/workers/__init__.py index a5b8cd46..b11df089 100644 --- a/rare/shared/workers/__init__.py +++ b/rare/shared/workers/__init__.py @@ -1,4 +1,4 @@ -from .fetch import FetchWorker, GamesWorker, NonAssetWorker +from .fetch import FetchWorker from .install_info import InstallInfoWorker from .move import MoveWorker from .uninstall import UninstallWorker diff --git a/rare/shared/workers/fetch.py b/rare/shared/workers/fetch.py index e1abe669..701e1890 100644 --- a/rare/shared/workers/fetch.py +++ b/rare/shared/workers/fetch.py @@ -16,8 +16,10 @@ class FetchWorker(Worker): class Result(IntEnum): GAMES = 1 NON_ASSET = 2 + COMBINED = 3 class Signals(QObject): + progress = pyqtSignal(int, str) result = pyqtSignal(object, int) def __init__(self, core: LegendaryCore, args: Namespace): @@ -26,33 +28,43 @@ class FetchWorker(Worker): self.core = core self.args = args - -class GamesWorker(FetchWorker): def run_real(self): + # Fetch regular EGL games with assets + self.signals.progress.emit(0, self.signals.tr("Updating game metadata")) start_time = time.time() - result = self.core.get_game_and_dlc_list(update_assets=not self.args.offline, platform="Windows", skip_ue=False) - self.signals.result.emit(result, FetchWorker.Result.GAMES) - logger.debug(f"Games: {len(result[0])}, DLCs {len(result[1])}") - logger.debug(f"Request Games: {time.time() - start_time} seconds") + games, dlc_dict = self.core.get_game_and_dlc_list( + update_assets=not self.args.offline, platform="Windows", skip_ue=False + ) + logger.debug(f"Games {len(games)}, games with DLCs {len(dlc_dict)}") + logger.debug(f"Request games: {time.time() - start_time} seconds") - -class NonAssetWorker(FetchWorker): - def run_real(self): + # Fetch non-asset games + self.signals.progress.emit(10, self.signals.tr("Updating non-asset metadata")) start_time = time.time() try: - result = self.core.get_non_asset_library_items(force_refresh=False, skip_ue=False) + na_games, na_dlc_dict = self.core.get_non_asset_library_items(force_refresh=False, skip_ue=False) except (HTTPError, ConnectionError) as e: logger.warning(f"Exception while fetching non asset games from EGS: {e}") - result = ([], {}) + na_games, na_dlc_dict = ([], {}) # FIXME: # This is here because of broken appIds from Epic: # https://discord.com/channels/826881530310819914/884510635642216499/1111321692703305729 # There is a tab character in the appId of Fallout New Vegas: Honest Hearts DLC, this breaks metadata storage # on Windows as they can't handle tabs at the end of the filename (?) - # Legendary and Heroic are also affected, but it completed breaks Rare, so dodge it for now pending a fix. + # Legendary and Heroic are also affected, but it completely breaks Rare, so dodge it for now pending a fix. except Exception as e: logger.error(f"Exception while fetching non asset games from EGS: {e}") - result = ([], {}) - self.signals.result.emit(result, FetchWorker.Result.NON_ASSET) - logger.debug(f"Non asset: {len(result[0])}, DLCs {len(result[1])}") - logger.debug(f"Request Non Asset: {time.time() - start_time} seconds") + na_games, na_dlc_dict = ([], {}) + logger.debug(f"Non-asset {len(na_games)}, games with non-asset DLCs {len(na_dlc_dict)}") + logger.debug(f"Request non-asset: {time.time() - start_time} seconds") + + # Combine the two games lists and the two dlc dictionaries between regular and non-asset results + games += na_games + for catalog_id, dlcs in na_dlc_dict.items(): + if catalog_id in dlc_dict.keys(): + dlc_dict[catalog_id] += dlcs + else: + dlc_dict[catalog_id] = dlcs + logger.debug(f"Games {len(games)}, games with DLCs {len(dlc_dict)}") + + self.signals.result.emit((games, dlc_dict), FetchWorker.Result.COMBINED)