Merge pull request #294 from loathingKernel/develop
Fixes for DLCs and downloads
This commit is contained in:
commit
c586305927
|
@ -89,7 +89,7 @@ class DownloadsTab(QWidget):
|
|||
@pyqtSlot()
|
||||
@pyqtSlot(int)
|
||||
def update_queues_count(self):
|
||||
count = self.updates_group.count() + self.queue_group.count() + (1 if self.is_download_active else 0)
|
||||
count = self.updates_group.count() + self.queue_group.count() + (1 if self.is_download_active else 0)
|
||||
self.update_title.emit(count)
|
||||
|
||||
@property
|
||||
|
@ -131,10 +131,11 @@ class DownloadsTab(QWidget):
|
|||
:param app_name:
|
||||
:return:
|
||||
"""
|
||||
rgame = self.rcore.get_game(app_name)
|
||||
rgame.state = RareGame.State.IDLE
|
||||
if self.updates_group.contains(app_name):
|
||||
self.updates_group.set_widget_enabled(app_name, True)
|
||||
else:
|
||||
rgame = self.rcore.get_game(app_name)
|
||||
if rgame.is_installed and rgame.has_update:
|
||||
self.__add_update(app_name)
|
||||
|
||||
|
@ -180,15 +181,17 @@ class DownloadsTab(QWidget):
|
|||
|
||||
def __start_download(self, item: InstallQueueItemModel):
|
||||
rgame = self.rcore.get_game(item.options.app_name)
|
||||
if not rgame.is_idle:
|
||||
logger.error(f"Can't start download {item.options.app_name} due to non-idle state {rgame.state}")
|
||||
if not rgame.state == RareGame.State.DOWNLOADING:
|
||||
logger.error(
|
||||
f"Can't start download {item.options.app_name}"
|
||||
f"due to incompatible state {RareGame.State(rgame.state).name}"
|
||||
)
|
||||
# lk: invalidate the queue item in case the game was uninstalled
|
||||
self.__requeue_download(InstallQueueItemModel(options=item.options))
|
||||
return
|
||||
if item.expired:
|
||||
self.__refresh_download(item)
|
||||
return
|
||||
rgame.state = RareGame.State.DOWNLOADING
|
||||
thread = DlThread(item, self.rcore.get_game(item.options.app_name), self.core, self.args.debug)
|
||||
thread.result.connect(self.__on_download_result)
|
||||
thread.progress.connect(self.__on_download_progress)
|
||||
|
@ -215,6 +218,7 @@ class DownloadsTab(QWidget):
|
|||
|
||||
def __requeue_download(self, item: InstallQueueItemModel):
|
||||
rgame = self.rcore.get_game(item.options.app_name)
|
||||
rgame.state = RareGame.State.DOWNLOADING
|
||||
self.queue_group.push_front(item, rgame.igame)
|
||||
logger.info(f"Re-queued download for {rgame.app_name} ({rgame.app_title})")
|
||||
|
||||
|
@ -278,8 +282,10 @@ class DownloadsTab(QWidget):
|
|||
|
||||
@pyqtSlot(InstallOptionsModel)
|
||||
def __get_install_options(self, options: InstallOptionsModel):
|
||||
rgame = self.rcore.get_game(options.app_name)
|
||||
rgame.state = RareGame.State.DOWNLOADING
|
||||
install_dialog = InstallDialog(
|
||||
self.rcore.get_game(options.app_name),
|
||||
rgame,
|
||||
options=options,
|
||||
parent=self,
|
||||
)
|
||||
|
@ -288,8 +294,10 @@ class DownloadsTab(QWidget):
|
|||
|
||||
@pyqtSlot(InstallQueueItemModel)
|
||||
def __on_install_dialog_closed(self, item: InstallQueueItemModel):
|
||||
rgame = self.rcore.get_game(item.options.app_name)
|
||||
if item and not item.download.game.is_dlc and not item.download.analysis.dl_size:
|
||||
self.rcore.get_game(item.download.game.app_name).set_installed(True)
|
||||
rgame.set_installed(True)
|
||||
rgame.state = RareGame.State.IDLE
|
||||
return
|
||||
if item:
|
||||
# lk: start update only if there is no other active thread and there is no queue
|
||||
|
@ -310,11 +318,14 @@ class DownloadsTab(QWidget):
|
|||
else:
|
||||
if self.updates_group.contains(item.options.app_name):
|
||||
self.updates_group.set_widget_enabled(item.options.app_name, True)
|
||||
rgame.state = RareGame.State.IDLE
|
||||
|
||||
@pyqtSlot(UninstallOptionsModel)
|
||||
def __get_uninstall_options(self, options: UninstallOptionsModel):
|
||||
rgame = self.rcore.get_game(options.app_name)
|
||||
rgame.state = RareGame.State.UNINSTALLING
|
||||
uninstall_dialog = UninstallDialog(
|
||||
self.rcore.get_game(options.app_name),
|
||||
rgame,
|
||||
options=options,
|
||||
parent=self,
|
||||
)
|
||||
|
@ -323,14 +334,17 @@ class DownloadsTab(QWidget):
|
|||
|
||||
@pyqtSlot(UninstallOptionsModel)
|
||||
def __on_uninstall_dialog_closed(self, options: UninstallOptionsModel):
|
||||
rgame = self.rcore.get_game(options.app_name)
|
||||
if options and options.accepted:
|
||||
rgame = self.rcore.get_game(options.app_name)
|
||||
rgame.set_installed(False)
|
||||
worker = UninstallWorker(self.core, rgame, options)
|
||||
worker.signals.result.connect(self.__on_uninstall_worker_result)
|
||||
QThreadPool.globalInstance().start(worker)
|
||||
else:
|
||||
rgame.state = RareGame.State.IDLE
|
||||
|
||||
@pyqtSlot(RareGame, bool, str)
|
||||
def __on_uninstall_worker_result(self, rgame: RareGame, success: bool, message: str):
|
||||
if not success:
|
||||
QMessageBox.warning(None, self.tr("Uninstall - {}").format(rgame.title), message, QMessageBox.Close)
|
||||
rgame.state = RareGame.State.IDLE
|
||||
|
|
|
@ -31,6 +31,13 @@ class GameDlcWidget(QFrame):
|
|||
|
||||
self.image.setPixmap(rdlc.pixmap)
|
||||
|
||||
self.__update()
|
||||
rdlc.signals.widget.update.connect(self.__update)
|
||||
|
||||
@pyqtSlot()
|
||||
def __update(self):
|
||||
self.ui.action_button.setEnabled(self.rdlc.is_idle)
|
||||
|
||||
|
||||
class InstalledGameDlcWidget(GameDlcWidget):
|
||||
uninstalled = pyqtSignal(RareGame)
|
||||
|
@ -42,7 +49,11 @@ class InstalledGameDlcWidget(GameDlcWidget):
|
|||
self.ui.action_button.clicked.connect(self.uninstall_dlc)
|
||||
self.ui.action_button.setText(self.tr("Uninstall DLC"))
|
||||
# lk: don't reference `self.rdlc` here because the object has been deleted
|
||||
rdlc.signals.game.uninstalled.connect(lambda: self.uninstalled.emit(rdlc))
|
||||
rdlc.signals.game.uninstalled.connect(self.__uninstalled)
|
||||
|
||||
@pyqtSlot()
|
||||
def __uninstalled(self):
|
||||
self.uninstalled.emit(self.rdlc)
|
||||
|
||||
def uninstall_dlc(self):
|
||||
self.rdlc.uninstall()
|
||||
|
@ -58,7 +69,11 @@ class AvailableGameDlcWidget(GameDlcWidget):
|
|||
self.ui.action_button.clicked.connect(self.install_dlc)
|
||||
self.ui.action_button.setText(self.tr("Install DLC"))
|
||||
# lk: don't reference `self.rdlc` here because the object has been deleted
|
||||
rdlc.signals.game.installed.connect(lambda: self.installed.emit(rdlc))
|
||||
rdlc.signals.game.installed.connect(self.__installed)
|
||||
|
||||
@pyqtSlot()
|
||||
def __installed(self):
|
||||
self.installed.emit(self.rdlc)
|
||||
|
||||
def install_dlc(self):
|
||||
if not self.rgame.is_installed:
|
||||
|
|
|
@ -5,7 +5,7 @@ from dataclasses import dataclass, field
|
|||
from datetime import datetime
|
||||
from logging import getLogger
|
||||
from threading import Lock
|
||||
from typing import List, Optional, Dict
|
||||
from typing import List, Optional, Dict, Set
|
||||
|
||||
from PyQt5.QtCore import QRunnable, pyqtSlot, QProcess, QThreadPool
|
||||
from PyQt5.QtGui import QPixmap
|
||||
|
@ -77,7 +77,7 @@ class RareGame(RareGameSlim):
|
|||
self.metadata: RareGame.Metadata = RareGame.Metadata()
|
||||
self.__load_metadata()
|
||||
|
||||
self.owned_dlcs: List[RareGame] = []
|
||||
self.owned_dlcs: Set[RareGame] = set()
|
||||
|
||||
if self.has_update:
|
||||
logger.info(f"Update available for game: {self.app_name} ({self.app_title})")
|
||||
|
@ -530,12 +530,15 @@ class RareGame(RareGameSlim):
|
|||
self.signals.game.uninstalled.emit(self.app_name)
|
||||
self.set_pixmap()
|
||||
|
||||
def repair(self, repair_and_update):
|
||||
def repair(self, repair_and_update) -> bool:
|
||||
if not self.is_idle:
|
||||
return False
|
||||
self.signals.game.install.emit(
|
||||
InstallOptionsModel(
|
||||
app_name=self.app_name, repair_mode=True, repair_and_update=repair_and_update, update=repair_and_update
|
||||
)
|
||||
)
|
||||
return True
|
||||
|
||||
def uninstall(self) -> bool:
|
||||
if not self.is_idle:
|
||||
|
|
|
@ -120,4 +120,4 @@ class UninstallOptionsModel:
|
|||
"""
|
||||
self.accepted = values[0]
|
||||
self.keep_files = values[1]
|
||||
self.keep_config = values[2]
|
||||
self.keep_config = values[2]
|
||||
|
|
|
@ -5,7 +5,7 @@ import zlib
|
|||
# from concurrent import futures
|
||||
from logging import getLogger
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from typing import TYPE_CHECKING, Optional, Set
|
||||
from typing import Tuple, Dict, Union, Type, List, Callable
|
||||
|
||||
import requests
|
||||
|
@ -34,7 +34,7 @@ from legendary.models.game import Game
|
|||
from rare.lgndr.core import LegendaryCore
|
||||
from rare.models.image import ImageSize
|
||||
from rare.models.signals import GlobalSignals
|
||||
from rare.utils.paths import image_dir, resources_path, desktop_icon_suffix, desktop_links_supported
|
||||
from rare.utils.paths import image_dir, resources_path, desktop_icon_suffix
|
||||
|
||||
# from requests_futures.sessions import FuturesSession
|
||||
|
||||
|
@ -61,7 +61,7 @@ class ImageManager(QObject):
|
|||
|
||||
def run(self):
|
||||
self.func(self.updates, self.json_data, self.game)
|
||||
logger.debug(f" Emitting singal for game {self.game.app_name} - {self.game.app_title}")
|
||||
logger.debug(f" Emitting singal for {self.game.app_name} ({self.game.app_title})")
|
||||
self.signals.completed.emit(self.game)
|
||||
|
||||
def __init__(self, signals: GlobalSignals, core: LegendaryCore):
|
||||
|
@ -69,7 +69,7 @@ class ImageManager(QObject):
|
|||
# self.__img_types: Tuple = ("DieselGameBoxTall", "Thumbnail", "DieselGameBoxLogo", "DieselGameBox", "OfferImageTall")
|
||||
self.__img_types: Tuple = ("DieselGameBoxTall", "Thumbnail", "DieselGameBoxLogo", "OfferImageTall")
|
||||
self.__dl_retries = 1
|
||||
self.__worker_app_names: List[str] = []
|
||||
self.__worker_app_names: Set[str] = set()
|
||||
super(QObject, self).__init__()
|
||||
self.signals = signals
|
||||
self.core = core
|
||||
|
@ -116,9 +116,17 @@ class ImageManager(QObject):
|
|||
else:
|
||||
json_data = json.load(open(self.__img_json(game.app_name), "r"))
|
||||
|
||||
# lk: fast path for games without images, convert Rare's logo
|
||||
if not game.metadata.get("keyImages", False):
|
||||
if not self.__img_color(game.app_name).is_file() or not self.__img_gray(game.app_name).is_file():
|
||||
# lk: Find updates or initialize if images are missing.
|
||||
# lk: `updates` will be empty for games without images
|
||||
# lk: so everything below it is skipped
|
||||
updates = []
|
||||
if not (
|
||||
self.__img_color(game.app_name).is_file()
|
||||
and self.__img_gray(game.app_name).is_file()
|
||||
and self.__img_desktop_icon(game.app_name).is_file()
|
||||
):
|
||||
# lk: fast path for games without images, convert Rare's logo
|
||||
if not game.metadata.get("keyImages", []):
|
||||
cache_data: Dict = dict(zip(self.__img_types, [None] * len(self.__img_types)))
|
||||
cache_data["DieselGameBoxTall"] = open(
|
||||
resources_path.joinpath("images", "cover.png"), "rb"
|
||||
|
@ -130,19 +138,10 @@ class ImageManager(QObject):
|
|||
json_data["scale"] = ImageSize.Image.pixel_ratio
|
||||
json_data["size"] = ImageSize.Image.size.__str__()
|
||||
json.dump(json_data, open(self.__img_json(game.app_name), "w"))
|
||||
|
||||
# lk: Find updates or initialize if images are missing.
|
||||
# lk: `updates` will be empty for games without images
|
||||
# lk: so everything below it is skipped
|
||||
if not (
|
||||
self.__img_color(game.app_name).is_file()
|
||||
and self.__img_gray(game.app_name).is_file()
|
||||
and self.__img_desktop_icon(game.app_name).is_file()
|
||||
):
|
||||
updates = [image for image in game.metadata["keyImages"] if image["type"] in self.__img_types]
|
||||
else:
|
||||
updates = [image for image in game.metadata["keyImages"] if image["type"] in self.__img_types]
|
||||
else:
|
||||
updates = []
|
||||
for image in game.metadata["keyImages"]:
|
||||
for image in game.metadata.get("keyImages", []):
|
||||
if image["type"] in self.__img_types:
|
||||
if image["type"] not in json_data.keys() or json_data[image["type"]] != image["md5"]:
|
||||
updates.append(image)
|
||||
|
@ -180,9 +179,10 @@ class ImageManager(QObject):
|
|||
# cache_data[req.image_type] = req.result().content
|
||||
# else:
|
||||
for image in updates:
|
||||
logger.info(f"Downloading {image['type']} for {game.app_title}")
|
||||
logger.info(f"Downloading {image['type']} for {game.app_name} ({game.app_title})")
|
||||
json_data[image["type"]] = image["md5"]
|
||||
payload = {"resize": 1, "w": ImageSize.Image.size.width(), "h": ImageSize.Image.size.height()}
|
||||
# cache_data[image["type"]] = requests.get(image["url"], params=payload, timeout=2).content
|
||||
cache_data[image["type"]] = requests.get(image["url"], params=payload).content
|
||||
|
||||
self.__convert(game, cache_data)
|
||||
|
@ -281,9 +281,9 @@ class ImageManager(QObject):
|
|||
painter.end()
|
||||
|
||||
cover = cover.scaled(ImageSize.Image.size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||||
if desktop_links_supported():
|
||||
icon = self.__convert_icon(cover)
|
||||
icon.save(str(self.__img_desktop_icon(game.app_name)), format=desktop_icon_suffix().upper())
|
||||
|
||||
icon = self.__convert_icon(cover)
|
||||
icon.save(str(self.__img_desktop_icon(game.app_name)), format=desktop_icon_suffix().upper())
|
||||
|
||||
# this is not required if we ever want to re-apply the alpha channel
|
||||
# cover = cover.convertToFormat(QImage.Format_Indexed8)
|
||||
|
@ -318,16 +318,17 @@ class ImageManager(QObject):
|
|||
def download_image(
|
||||
self, game: Game, load_callback: Callable[[], None], priority: int, force: bool = False
|
||||
) -> None:
|
||||
if game.app_name in self.__worker_app_names:
|
||||
return
|
||||
self.__worker_app_names.add(game.app_name)
|
||||
updates, json_data = self.__prepare_download(game, force)
|
||||
if not updates:
|
||||
self.__worker_app_names.remove(game.app_name)
|
||||
load_callback()
|
||||
return
|
||||
if updates and game.app_name not in self.__worker_app_names:
|
||||
else:
|
||||
image_worker = ImageManager.Worker(self.__download, updates, json_data, game)
|
||||
self.__worker_app_names.append(game.app_name)
|
||||
|
||||
image_worker.signals.completed.connect(load_callback)
|
||||
image_worker.signals.completed.connect(lambda g: self.__worker_app_names.remove(g.app_name))
|
||||
image_worker.signals.completed.connect(load_callback)
|
||||
self.threadpool.start(image_worker, priority)
|
||||
|
||||
def download_image_blocking(self, game: Game, force: bool = False) -> None:
|
||||
|
|
|
@ -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)
|
||||
|
@ -144,19 +137,18 @@ class RareCore(QObject):
|
|||
with open(os.path.join(path, "config.ini"), "w") as config_file:
|
||||
config_file.write("[Legendary]")
|
||||
self.__core = LegendaryCore()
|
||||
if "Legendary" not in self.__core.lgd.config.sections():
|
||||
self.__core.lgd.config.add_section("Legendary")
|
||||
self.__core.lgd.save_config()
|
||||
for section in ["Legendary", "default", "default.env"]:
|
||||
if section not in self.__core.lgd.config.sections():
|
||||
self.__core.lgd.config.add_section(section)
|
||||
# workaround if egl sync enabled, but no programdata_path
|
||||
# programdata_path might be unset if logging in through the browser
|
||||
if self.__core.egl_sync_enabled:
|
||||
if self.__core.egl.programdata_path is None:
|
||||
self.__core.lgd.config.remove_option("Legendary", "egl_sync")
|
||||
self.__core.lgd.save_config()
|
||||
else:
|
||||
if not os.path.exists(self.__core.egl.programdata_path):
|
||||
self.__core.lgd.config.remove_option("Legendary", "egl_sync")
|
||||
self.__core.lgd.save_config()
|
||||
self.__core.lgd.save_config()
|
||||
return self.__core
|
||||
|
||||
def image_manager(self, init: bool = False) -> ImageManager:
|
||||
|
@ -264,60 +256,27 @@ class RareCore(QObject):
|
|||
rdlc.signals.progress.start.connect(rgame.signals.progress.start)
|
||||
rdlc.signals.progress.update.connect(rgame.signals.progress.update)
|
||||
rdlc.signals.progress.finish.connect(rgame.signals.progress.finish)
|
||||
rgame.owned_dlcs.append(rdlc)
|
||||
rgame.owned_dlcs.add(rdlc)
|
||||
self.__add_game(rdlc)
|
||||
self.__add_game(rgame)
|
||||
self.progress.emit(int(idx/length * 80) + 20, self.tr("Loaded <b>{}</b>").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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -60,6 +60,7 @@ def create_dirs() -> None:
|
|||
for path in (data_dir(), cache_dir(), image_dir(), log_dir(), tmp_dir()):
|
||||
if not path.exists():
|
||||
path.mkdir(parents=True)
|
||||
logger.info(f"Created directory at {path}")
|
||||
|
||||
|
||||
def home_dir() -> Path:
|
||||
|
@ -83,14 +84,15 @@ __link_suffix = {
|
|||
"link": "desktop",
|
||||
"icon": "png",
|
||||
},
|
||||
# "Darwin": {
|
||||
# "link": "",
|
||||
# "icon": "icns",
|
||||
# },
|
||||
"Darwin": {
|
||||
"link": "",
|
||||
"icon": "icns",
|
||||
},
|
||||
}
|
||||
|
||||
def desktop_links_supported() -> bool:
|
||||
return platform.system() in __link_suffix.keys()
|
||||
supported_systems = [k for (k, v) in __link_suffix.items() if v["link"]]
|
||||
return platform.system() in supported_systems
|
||||
|
||||
def desktop_icon_suffix() -> str:
|
||||
return __link_suffix[platform.system()]["icon"]
|
||||
|
|
Loading…
Reference in a new issue