diff --git a/rare/app.py b/rare/app.py index f33a22a8..8fbb639f 100644 --- a/rare/app.py +++ b/rare/app.py @@ -6,8 +6,9 @@ import shutil import sys import time import traceback +from argparse import Namespace -from PyQt5.QtCore import QThreadPool, QSettings, QTranslator +from PyQt5.QtCore import Qt, QThreadPool, QSettings, QTranslator from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMessageBox from requests import HTTPError @@ -15,7 +16,7 @@ from requests import HTTPError import legendary # noinspection PyUnresolvedReferences import rare.resources.resources -import rare.shared as shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton from rare.utils.paths import cache_dir, resources_path, tmp_dir from rare.components.dialogs.launch_dialog import LaunchDialog from rare.components.main_window import MainWindow @@ -36,7 +37,7 @@ def excepthook(exc_type, exc_value, exc_tb): print("Error") if exc_tb == HTTPError: try: - if shared.core.login(): + if LegendaryCoreSingleton().login(): return else: raise ValueError @@ -54,15 +55,18 @@ class App(QApplication): mainwindow: MainWindow = None tray_icon: QSystemTrayIcon = None - def __init__(self): + def __init__(self, args: Namespace): super(App, self).__init__(sys.argv) - self.args = shared.args # add some options + self.args = ArgumentsSingleton(args) # add some options self.window_launched = False self.setQuitOnLastWindowClosed(False) + if hasattr(Qt, 'AA_UseHighDpiPixmaps'): + self.setAttribute(Qt.AA_UseHighDpiPixmaps) + # init Legendary try: - self.core = shared.init_legendary() + self.core = LegendaryCoreSingleton() except configparser.MissingSectionHeaderError as e: logger.warning(f"Config is corrupt: {e}") if config_path := os.environ.get("XDG_CONFIG_HOME"): @@ -71,7 +75,7 @@ class App(QApplication): path = os.path.expanduser("~/.config/legendary") with open(os.path.join(path, "config.ini"), "w") as config_file: config_file.write("[Legendary]") - self.core = shared.init_legendary() + self.core = LegendaryCoreSingleton() if "Legendary" not in self.core.lgd.config.sections(): self.core.lgd.config.add_section("Legendary") self.core.lgd.save_config() @@ -95,7 +99,7 @@ class App(QApplication): self.setOrganizationName("Rare") self.settings = QSettings() - self.signals = shared.init_signals() + self.signals = GlobalSignalsSingleton() self.signals.exit_app.connect(self.exit_app) self.signals.send_notification.connect( @@ -159,7 +163,7 @@ class App(QApplication): if self.window_launched: self.mainwindow.show() else: - self.mainwindow.show_window_centralized() + self.mainwindow.show_window_centered() def start_app(self): for igame in self.core.get_installed_list(): @@ -184,32 +188,32 @@ class App(QApplication): ) if not self.args.silent: - self.mainwindow.show_window_centralized() + self.mainwindow.show_window_centered() self.window_launched = True - if shared.args.subparser == "launch": - if shared.args.app_name in [ + if self.args.subparser == "launch": + if self.args.app_name in [ i.app_name for i in self.core.get_installed_list() ]: logger.info( - f"Launching {self.core.get_installed_game(shared.args.app_name).title}" + f"Launching {self.core.get_installed_game(self.args.app_name).title}" ) self.mainwindow.tab_widget.games_tab.game_utils.prepare_launch( - shared.args.app_name + self.args.app_name ) else: logger.error( - f"Could not find {shared.args.app_name} in Games or it is not installed" + f"Could not find {self.args.app_name} in Games or it is not installed" ) QMessageBox.warning( self.mainwindow, "Warning", self.tr( "Could not find {} in installed games. Did you modify the shortcut? " - ).format(shared.args.app_name), + ).format(self.args.app_name), ) - if shared.args.test_start: + if self.args.test_start: self.exit_app(0) def tray(self, reason): @@ -220,7 +224,7 @@ class App(QApplication): def exit_app(self, exit_code=0): # FIXME: Fix this with the downlaod tab redesign if self.mainwindow is not None: - if not shared.args.offline and self.mainwindow.tab_widget.downloadTab.is_download_active: + if not self.args.offline and self.mainwindow.tab_widget.downloadTab.is_download_active: question = QMessageBox.question( self.mainwindow, self.tr("Close"), @@ -255,7 +259,6 @@ class App(QApplication): def start(args): # set excepthook to show dialog with exception sys.excepthook = excepthook - shared.init_args(args) # configure logging if args.debug: @@ -281,7 +284,7 @@ def start(args): ) while True: - app = App() + app = App(args) exit_code = app.exec_() # if not restart # restart app diff --git a/rare/components/dialogs/install_dialog.py b/rare/components/dialogs/install_dialog.py index 16b92d35..cb3e54c5 100644 --- a/rare/components/dialogs/install_dialog.py +++ b/rare/components/dialogs/install_dialog.py @@ -11,7 +11,7 @@ from legendary.core import LegendaryCore from legendary.models.downloading import ConditionCheckResult from legendary.models.game import Game from legendary.utils.selective_dl import games -from rare import shared +from rare.shared import LegendaryCoreSingleton, ApiResultsSingleton from rare.ui.components.dialogs.install_dialog import Ui_InstallDialog from rare.utils.extra_widgets import PathEdit from rare.utils.models import InstallDownloadModel, InstallQueueItemModel @@ -29,7 +29,8 @@ class InstallDialog(QDialog, Ui_InstallDialog): self.setAttribute(Qt.WA_DeleteOnClose, True) self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint) - self.core = shared.core + self.core = LegendaryCoreSingleton() + self.api_results = ApiResultsSingleton() self.dl_item = dl_item self.dl_item.status_q = MPQueue() self.app_name = self.dl_item.options.app_name @@ -55,8 +56,8 @@ class InstallDialog(QDialog, Ui_InstallDialog): self.setWindowTitle(f'{self.windowTitle()} - {header} "{self.game.app_title}"') if not self.dl_item.options.base_path: - self.dl_item.options.base_path = shared.core.lgd.config.get("Legendary", "install_dir", - fallback=os.path.expanduser("~/legendary")) + self.dl_item.options.base_path = self.core.lgd.config.get("Legendary", "install_dir", + fallback=os.path.expanduser("~/legendary")) self.install_dir_edit = PathEdit( path=self.dl_item.options.base_path, @@ -77,9 +78,9 @@ class InstallDialog(QDialog, Ui_InstallDialog): self.warn_message.setVisible(False) platforms = ["Windows"] - if dl_item.options.app_name in shared.api_results.bit32_games: + if dl_item.options.app_name in self.api_results.bit32_games: platforms.append("Win32") - if dl_item.options.app_name in shared.api_results.mac_games: + if dl_item.options.app_name in self.api_results.mac_games: platforms.append("Mac") self.platform_combo_box.addItems(platforms) self.platform_combo_box.currentIndexChanged.connect( @@ -296,7 +297,7 @@ class InstallDialog(QDialog, Ui_InstallDialog): self.cancel_clicked() -class InstallInfoWorkerSignals(QObject): +class InstallInfoSignals(QObject): result = pyqtSignal(InstallDownloadModel) failed = pyqtSignal(str) finished = pyqtSignal() @@ -305,7 +306,7 @@ class InstallInfoWorkerSignals(QObject): class InstallInfoWorker(QRunnable): def __init__(self, core: LegendaryCore, dl_item: InstallQueueItemModel, game: Game = None): super(InstallInfoWorker, self).__init__() - self.signals = InstallInfoWorkerSignals() + self.signals = InstallInfoSignals() self.core = core self.dl_item = dl_item self.is_overlay_install = self.dl_item.options.overlay diff --git a/rare/components/dialogs/launch_dialog.py b/rare/components/dialogs/launch_dialog.py index 7b302a9d..d616cdca 100644 --- a/rare/components/dialogs/launch_dialog.py +++ b/rare/components/dialogs/launch_dialog.py @@ -7,7 +7,7 @@ from PyQt5.QtWidgets import QDialog, QApplication from legendary.core import LegendaryCore from requests.exceptions import ConnectionError, HTTPError -from rare import shared +from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton, ApiResultsSingleton from rare.components.dialogs.login import LoginDialog from rare.ui.components.dialogs.launch_dialog import Ui_LaunchDialog from rare.utils.models import ApiResults @@ -17,7 +17,7 @@ from rare.utils.utils import download_images, CloudWorker logger = getLogger("Login") -class ApiSignals(QObject): +class LaunchDialogSignals(QObject): image_progress = pyqtSignal(int) result = pyqtSignal(object, str) @@ -25,32 +25,33 @@ class ApiSignals(QObject): class ImageWorker(QRunnable): def __init__(self, core: LegendaryCore): super(ImageWorker, self).__init__() - self.core = core - self.signal = ApiSignals() + self.signals = LaunchDialogSignals() self.setAutoDelete(True) + self.core = core def run(self): - download_images(self.signal.image_progress, self.signal.result, self.core) - self.signal.image_progress.emit(100) + download_images(self.signals.image_progress, self.signals.result, self.core) + self.signals.image_progress.emit(100) class ApiRequestWorker(QRunnable): def __init__(self): super(ApiRequestWorker, self).__init__() - self.signals = ApiSignals() + self.signals = LaunchDialogSignals() self.setAutoDelete(True) + self.core = LegendaryCoreSingleton() def run(self) -> None: - if platform.system() == "Darwin" or "Mac" in shared.core.get_installed_platforms(): + if platform.system() == "Darwin" or "Mac" in self.core.get_installed_platforms(): try: - result = shared.core.get_game_and_dlc_list(True, "Mac") + result = self.core.get_game_and_dlc_list(True, "Mac") except HTTPError: result = [], {} self.signals.result.emit(result, "mac") else: self.signals.result.emit(([], {}), "mac") try: - result = shared.core.get_game_and_dlc_list(True, "Win32") + result = self.core.get_game_and_dlc_list(True, "Win32") except HTTPError: result = [], {} self.signals.result.emit(result, "32bit") @@ -68,8 +69,8 @@ class LaunchDialog(QDialog, Ui_LaunchDialog): self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint) self.setWindowModality(Qt.WindowModal) - self.core = shared.core - self.offline = shared.args.offline + self.core = LegendaryCoreSingleton() + self.args = ArgumentsSingleton() self.thread_pool = QThreadPool() self.thread_pool.setMaxThreadCount(2) self.api_results = ApiResults() @@ -77,7 +78,7 @@ class LaunchDialog(QDialog, Ui_LaunchDialog): def login(self): do_launch = True try: - if self.offline: + if self.args.offline: pass else: QApplication.processEvents() @@ -90,10 +91,10 @@ class LaunchDialog(QDialog, Ui_LaunchDialog): do_launch = LoginDialog(core=self.core, parent=self).login() except ConnectionError as e: logger.warning(e) - self.offline = True + self.args.offline = True finally: if do_launch: - if not shared.args.silent: + if not self.args.silent: self.show() self.launch() else: @@ -104,11 +105,11 @@ class LaunchDialog(QDialog, Ui_LaunchDialog): if not os.path.exists(image_dir): os.makedirs(image_dir) - if not self.offline: + if not self.args.offline: self.image_info.setText(self.tr("Downloading Images")) image_worker = ImageWorker(self.core) - image_worker.signal.image_progress.connect(self.update_image_progbar) - image_worker.signal.result.connect(self.handle_api_worker_result) + image_worker.signals.image_progress.connect(self.update_image_progbar) + image_worker.signals.result.connect(self.handle_api_worker_result) self.thread_pool.start(image_worker) # gamelist and no_asset games are from Image worker @@ -179,8 +180,7 @@ class LaunchDialog(QDialog, Ui_LaunchDialog): if self.finished == 1: logger.info("App starting") self.image_info.setText(self.tr("Starting...")) - shared.args.offline = self.offline - shared.init_api_response(self.api_results) + ApiResultsSingleton(self.api_results) self.start_app.emit() else: self.finished += 1 diff --git a/rare/components/dialogs/login/__init__.py b/rare/components/dialogs/login/__init__.py index cb3c5bf9..9a09bb6e 100644 --- a/rare/components/dialogs/login/__init__.py +++ b/rare/components/dialogs/login/__init__.py @@ -5,7 +5,7 @@ from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QSizePolicy, QLayout, QDialog, QMessageBox from legendary.core import LegendaryCore -from rare import shared +from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton from rare.components.dialogs.login.browser_login import BrowserLogin from rare.components.dialogs.login.import_login import ImportLogin from rare.ui.components.dialogs.login.login_dialog import Ui_LoginDialog @@ -32,6 +32,7 @@ class LoginDialog(QDialog, Ui_LoginDialog): self.setWindowModality(Qt.WindowModal) self.core = core + self.args = ArgumentsSingleton() self.browser_page = BrowserLogin(self.core, self.login_stack) self.login_stack.insertWidget(self.pages.browser, self.browser_page) @@ -85,7 +86,7 @@ class LoginDialog(QDialog, Ui_LoginDialog): self.import_page.do_login() def login(self): - if shared.args.test_start: + if self.args.test_start: return False self.exec_() return self.logged_in diff --git a/rare/components/main_window.py b/rare/components/main_window.py index c81f02b7..05e0cf38 100644 --- a/rare/components/main_window.py +++ b/rare/components/main_window.py @@ -5,7 +5,7 @@ from PyQt5.QtCore import Qt, QSettings, QTimer, QSize from PyQt5.QtGui import QCloseEvent, QCursor from PyQt5.QtWidgets import QMainWindow, QApplication, QStatusBar -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton from rare.components.tabs import TabWidget from rare.utils.paths import data_dir @@ -16,11 +16,11 @@ class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setAttribute(Qt.WA_DeleteOnClose) - self.settings = QSettings() - self.core = shared.core + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.args = ArgumentsSingleton() - self.signals = shared.signals - self.offline = shared.args.offline + self.settings = QSettings() self.setWindowTitle("Rare - GUI for legendary") self.tab_widget = TabWidget(self) @@ -35,7 +35,7 @@ class MainWindow(QMainWindow): self.resize(width, height) - if not shared.args.offline: + if not self.args.offline: try: from rare.utils.rpc import DiscordRPC self.rpc = DiscordRPC() @@ -46,7 +46,7 @@ class MainWindow(QMainWindow): self.timer.timeout.connect(self.timer_finished) self.timer.start(1000) - def show_window_centralized(self): + def show_window_centered(self): self.show() # get the margins of the decorated window margins = self.windowHandle().frameMargins() @@ -78,7 +78,7 @@ class MainWindow(QMainWindow): i.app_name for i in self.tab_widget.games_tab.game_list ] and self.core.is_installed(game): self.tab_widget.games_tab.game_utils.prepare_launch( - game, offline=shared.args.offline + game, offline=self.args.offline ) else: logger.info(f"Could not find {game} in Games") @@ -95,7 +95,7 @@ class MainWindow(QMainWindow): self.hide() e.ignore() return - elif self.offline: + elif self.args.offline: pass self.signals.exit_app.emit(0) e.ignore() diff --git a/rare/components/tabs/__init__.py b/rare/components/tabs/__init__.py index 29e8bcd5..bb213582 100644 --- a/rare/components/tabs/__init__.py +++ b/rare/components/tabs/__init__.py @@ -1,7 +1,7 @@ from PyQt5.QtCore import QSize from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction, QShortcut -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton from rare.components.tabs.account import MiniWidget from rare.components.tabs.downloads import DownloadsTab from rare.components.tabs.games import GamesTab @@ -15,9 +15,10 @@ from rare.utils.utils import icon class TabWidget(QTabWidget): def __init__(self, parent): super(TabWidget, self).__init__(parent=parent) - disabled_tab = 3 if not shared.args.offline else 1 - self.core = shared.core - self.signals = shared.signals + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.args = ArgumentsSingleton() + disabled_tab = 3 if not self.args.offline else 1 self.setTabBar(MainTabBar(disabled_tab)) # lk: Figure out why this adds a white line at the top # lk: despite setting qproperty-drawBase to 0 in the stylesheet @@ -26,7 +27,7 @@ class TabWidget(QTabWidget): self.games_tab = GamesTab() self.addTab(self.games_tab, self.tr("Games")) - if not shared.args.offline: + if not self.args.offline: # updates = self.games_tab.default_widget.game_list.updates self.downloadTab = DownloadsTab(self.games_tab.updates) self.addTab( @@ -42,7 +43,7 @@ class TabWidget(QTabWidget): self.addTab(self.store, self.tr("Store (Beta)")) self.settings = SettingsTab(self) - if shared.args.debug: + if self.args.debug: self.settings.addTab(DebugSettings(), "Debug") # Space Tab @@ -102,7 +103,7 @@ class TabWidget(QTabWidget): if tab_num == 0: self.games_tab.layout().setCurrentIndex(0) - if not shared.args.offline and tab_num == 2: + if not self.args.offline and tab_num == 2: self.store.load() def resizeEvent(self, event): diff --git a/rare/components/tabs/account/__init__.py b/rare/components/tabs/account/__init__.py index 8c938822..54f52ad1 100644 --- a/rare/components/tabs/account/__init__.py +++ b/rare/components/tabs/account/__init__.py @@ -2,15 +2,15 @@ import webbrowser from PyQt5.QtWidgets import QWidget, QVBoxLayout, QMessageBox, QLabel, QPushButton -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton class MiniWidget(QWidget): def __init__(self): super(MiniWidget, self).__init__() self.layout = QVBoxLayout() - self.core = shared.core - self.signals = shared.signals + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() self.layout.addWidget(QLabel("Account")) username = self.core.lgd.userdata.get("display_name") if not username: diff --git a/rare/components/tabs/downloads/__init__.py b/rare/components/tabs/downloads/__init__.py index 8722ee83..bcd157df 100644 --- a/rare/components/tabs/downloads/__init__.py +++ b/rare/components/tabs/downloads/__init__.py @@ -15,7 +15,7 @@ from PyQt5.QtWidgets import ( from legendary.core import LegendaryCore from legendary.models.downloading import UIUpdate from legendary.models.game import Game, InstalledGame -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton from rare.components.dialogs.install_dialog import InstallDialog from rare.components.tabs.downloads.dl_queue_widget import DlQueueWidget, DlWidget from rare.components.tabs.downloads.download_thread import DownloadThread @@ -34,10 +34,10 @@ class DownloadsTab(QWidget, Ui_DownloadsTab): def __init__(self, updates: list): super(DownloadsTab, self).__init__() self.setupUi(self) - self.core = shared.core + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() self.active_game: Game = None self.analysis = None - self.signals = shared.signals self.kill_button.clicked.connect(self.stop_download) @@ -68,7 +68,7 @@ class DownloadsTab(QWidget, Ui_DownloadsTab): self.signals.add_download.connect( lambda app_name: self.add_update(self.core.get_installed_game(app_name)) ) - shared.signals.game_uninstalled.connect(self.game_uninstalled) + self.signals.game_uninstalled.connect(self.game_uninstalled) self.reset_infos() diff --git a/rare/components/tabs/downloads/download_thread.py b/rare/components/tabs/downloads/download_thread.py index d2037bd3..2cf7886c 100644 --- a/rare/components/tabs/downloads/download_thread.py +++ b/rare/components/tabs/downloads/download_thread.py @@ -13,7 +13,7 @@ from PyQt5.QtWidgets import QMessageBox from legendary.core import LegendaryCore from legendary.models.downloading import UIUpdate, WriterTask -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton from rare.utils.models import InstallQueueItemModel from rare.utils.utils import create_desktop_link @@ -27,6 +27,7 @@ class DownloadThread(QThread): def __init__(self, core: LegendaryCore, queue_item: InstallQueueItemModel): super(DownloadThread, self).__init__() self.core = core + self.signals = GlobalSignalsSingleton() self.dlm = queue_item.download.dlmanager self.no_install = queue_item.options.no_install self.status_q = queue_item.status_q @@ -147,7 +148,7 @@ class DownloadThread(QThread): game = self.core.get_game(self.igame.app_name) if self.queue_item.options.overlay: - shared.signals.overlay_installation_finished.emit() + self.signals.overlay_installation_finished.emit() self.core.finish_overlay_install(self.igame) self.status.emit("finish") return diff --git a/rare/components/tabs/games/__init__.py b/rare/components/tabs/games/__init__.py index d05d67ea..a169d741 100644 --- a/rare/components/tabs/games/__init__.py +++ b/rare/components/tabs/games/__init__.py @@ -4,7 +4,7 @@ from typing import Tuple, Dict, Union, List from PyQt5.QtCore import QSettings, QObjectCleanupHandler from PyQt5.QtWidgets import QStackedWidget, QVBoxLayout, QWidget -import rare.shared as shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton, ApiResultsSingleton from legendary.models.game import InstalledGame, Game from rare.ui.components.tabs.games.games_tab import Ui_GamesTab from rare.utils.extra_widgets import FlowLayout @@ -37,15 +37,17 @@ class GamesTab(QStackedWidget, Ui_GamesTab): def __init__(self, parent=None): super(GamesTab, self).__init__(parent=parent) self.setupUi(self) - self.core = shared.core - self.signals = shared.signals + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.args = ArgumentsSingleton() + self.api_results = ApiResultsSingleton() self.settings = QSettings() - self.game_list: List[Game] = shared.api_results.game_list - self.dlcs = shared.api_results.dlcs - self.bit32 = shared.api_results.bit32_games - self.mac_games = shared.api_results.mac_games - self.no_assets = shared.api_results.no_asset_games + self.game_list: List[Game] = self.api_results.game_list + self.dlcs = self.api_results.dlcs + self.bit32 = self.api_results.bit32_games + self.mac_games = self.api_results.mac_games + self.no_assets = self.api_results.no_asset_games self.game_utils = GameUtils(parent=self) @@ -75,7 +77,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab): self.head_bar.import_game.clicked.connect(lambda: self.setCurrentIndex(2)) self.no_asset_names = [] - if not shared.args.offline: + if not self.args.offline: for game in self.no_assets: self.no_asset_names.append(game.app_name) else: diff --git a/rare/components/tabs/games/cloud_save_utils.py b/rare/components/tabs/games/cloud_save_utils.py index 2109b470..fc27820a 100644 --- a/rare/components/tabs/games/cloud_save_utils.py +++ b/rare/components/tabs/games/cloud_save_utils.py @@ -9,7 +9,7 @@ from PyQt5.QtWidgets import QDialog, QMessageBox, QSizePolicy, QLayout, QApplica from legendary.core import LegendaryCore from legendary.models.game import SaveGameStatus, InstalledGame, SaveGameFile -from rare import shared +from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton, ApiResultsSingleton from rare.ui.components.dialogs.sync_save_dialog import Ui_SyncSaveDialog from rare.utils.utils import icon @@ -30,29 +30,29 @@ class DownloadModel: path: str -class WorkerSignals(QObject): +class SaveSignals(QObject): finished = pyqtSignal(str, str) class SaveWorker(QRunnable): - signals = WorkerSignals() - def __init__(self, model: Union[UploadModel, DownloadModel]): super(SaveWorker, self).__init__() - self.model = model - + self.signals = SaveSignals() self.setAutoDelete(True) + self.core = LegendaryCoreSingleton() + self.api_results = ApiResultsSingleton() + self.model = model def run(self) -> None: try: if isinstance(self.model, DownloadModel): - shared.core.download_saves( + self.core.download_saves( self.model.app_name, self.model.latest_save.manifest_name, self.model.path, ) else: - shared.core.upload_save( + self.core.upload_save( self.model.app_name, self.model.path, self.model.date_time ) except Exception as e: @@ -62,8 +62,8 @@ class SaveWorker(QRunnable): try: if isinstance(self.model, UploadModel): logger.info("Updating cloud saves...") - result = shared.core.get_save_games(self.model.app_name) - shared.api_results.saves = result + result = self.core.get_save_games(self.model.app_name) + self.api_results.saves = result except Exception as e: self.signals.finished.emit(str(e), self.model.app_name) logger.error(str(e)) @@ -127,9 +127,11 @@ class CloudSaveUtils(QObject): def __init__(self): super(CloudSaveUtils, self).__init__() - self.core = shared.core - saves = shared.api_results.saves - if not shared.args.offline: + self.core = LegendaryCoreSingleton() + self.args = ArgumentsSingleton() + self.api_results = ApiResultsSingleton() + saves = self.api_results.saves + if not self.args.offline: self.latest_saves = self.get_latest_saves(saves) else: self.latest_saves = dict() @@ -307,7 +309,7 @@ class CloudSaveUtils(QObject): if not error_message: self.sync_finished.emit(app_name) - self.latest_saves = self.get_latest_saves(shared.api_results.saves) + self.latest_saves = self.get_latest_saves(self.api_results.saves) else: QMessageBox.warning( None, diff --git a/rare/components/tabs/games/game_info/__init__.py b/rare/components/tabs/games/game_info/__init__.py index 33c5ea19..df48e2b3 100644 --- a/rare/components/tabs/games/game_info/__init__.py +++ b/rare/components/tabs/games/game_info/__init__.py @@ -1,7 +1,7 @@ from PyQt5.QtCore import Qt from PyQt5.QtGui import QKeyEvent -import rare.shared as shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton from rare.utils.extra_widgets import SideTabWidget from .game_dlc import GameDlc from .game_info import GameInfo @@ -12,8 +12,8 @@ from ..game_utils import GameUtils class GameInfoTabs(SideTabWidget): def __init__(self, dlcs: dict, game_utils: GameUtils, parent=None): super(GameInfoTabs, self).__init__(show_back=True, parent=parent) - self.core = shared.core - self.signals = shared.signals + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() self.info = GameInfo(self, game_utils) self.addTab(self.info, self.tr("Information")) diff --git a/rare/components/tabs/games/game_info/game_dlc.py b/rare/components/tabs/games/game_info/game_dlc.py index 7d442b07..f1348890 100644 --- a/rare/components/tabs/games/game_info/game_dlc.py +++ b/rare/components/tabs/games/game_info/game_dlc.py @@ -3,7 +3,7 @@ from PyQt5.QtGui import QPixmap, QResizeEvent from PyQt5.QtWidgets import QFrame, QWidget, QMessageBox from legendary.models.game import Game -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton from rare.components.tabs.games.game_utils import GameUtils from rare.ui.components.tabs.games.game_info.game_dlc import Ui_GameDlc from rare.ui.components.tabs.games.game_info.game_dlc_widget import Ui_GameDlcWidget @@ -18,12 +18,13 @@ class GameDlc(QWidget, Ui_GameDlc): def __init__(self, dlcs: dict, game_utils: GameUtils, parent=None): super(GameDlc, self).__init__(parent=parent) self.setupUi(self) + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.game_utils = game_utils self.available_dlc_scroll.setProperty("noBorder", 1) self.installed_dlc_scroll.setProperty("noBorder", 1) - self.signals = shared.signals - self.core = shared.core self.dlcs = dlcs self.installed_dlc_widgets = list() diff --git a/rare/components/tabs/games/game_info/game_info.py b/rare/components/tabs/games/game_info/game_info.py index db0edf13..dbd32e8e 100644 --- a/rare/components/tabs/games/game_info/game_info.py +++ b/rare/components/tabs/games/game_info/game_info.py @@ -6,7 +6,7 @@ from PyQt5.QtCore import pyqtSignal, QThreadPool from PyQt5.QtWidgets import QWidget, QMessageBox from legendary.models.game import Game, InstalledGame -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton from rare.ui.components.tabs.games.game_info.game_info import Ui_GameInfo from rare.utils.legendary_utils import VerifyWorker from rare.utils.models import InstallOptionsModel @@ -26,8 +26,9 @@ class GameInfo(QWidget, Ui_GameInfo): def __init__(self, parent, game_utils): super(GameInfo, self).__init__(parent=parent) self.setupUi(self) - self.core = shared.core - self.signals = shared.signals + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.args = ArgumentsSingleton() self.game_utils = game_utils if platform.system() == "Windows": @@ -47,7 +48,7 @@ class GameInfo(QWidget, Ui_GameInfo): self.verify_pool = QThreadPool() self.verify_pool.setMaxThreadCount(2) - if shared.args.offline: + if self.args.offline: self.repair_button.setDisabled(True) else: self.repair_button.clicked.connect(self.repair) @@ -175,7 +176,7 @@ class GameInfo(QWidget, Ui_GameInfo): else: self.uninstall_button.setDisabled(False) self.verify_button.setDisabled(False) - if not shared.args.offline: + if not self.args.offline: self.repair_button.setDisabled(False) self.game_actions_stack.setCurrentIndex(0) diff --git a/rare/components/tabs/games/game_info/uninstalled_info.py b/rare/components/tabs/games/game_info/uninstalled_info.py index 1f2925d1..40ed1390 100644 --- a/rare/components/tabs/games/game_info/uninstalled_info.py +++ b/rare/components/tabs/games/game_info/uninstalled_info.py @@ -4,7 +4,7 @@ from PyQt5.QtCore import Qt, QThreadPool from PyQt5.QtGui import QKeyEvent from PyQt5.QtWidgets import QWidget, QTreeView -import rare.shared as shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton, ApiResultsSingleton from legendary.models.game import Game from rare.ui.components.tabs.games.game_info.game_info import Ui_GameInfo from rare.utils.extra_widgets import SideTabWidget @@ -17,11 +17,12 @@ from rare.utils.utils import get_pixmap class UninstalledInfoTabs(SideTabWidget): def __init__(self, parent=None): super(UninstalledInfoTabs, self).__init__(show_back=True, parent=parent) - self.core = shared.core - self.signals = shared.signals + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.args = ArgumentsSingleton() self.info = UninstalledInfo() - self.info.install_button.setDisabled(shared.args.offline) + self.info.install_button.setDisabled(self.args.offline) self.addTab(self.info, self.tr("Information")) self.view = QTreeView() @@ -55,8 +56,9 @@ class UninstalledInfo(QWidget, Ui_GameInfo): def __init__(self, parent=None): super(UninstalledInfo, self).__init__(parent=parent) self.setupUi(self) - self.core = shared.core - self.signals = shared.signals + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.api_results = ApiResultsSingleton() self.install_button.clicked.connect(self.install_game) if platform.system() != "Windows": self.steam_worker = SteamWorker(self.core) @@ -83,9 +85,9 @@ class UninstalledInfo(QWidget, Ui_GameInfo): self.game = game self.game_title.setText(f"

{self.game.app_title}

") available_platforms = ["Windows"] - if self.game.app_name in shared.api_results.bit32_games: + if self.game.app_name in self.api_results.bit32_games: available_platforms.append("32 Bit") - if self.game.app_name in shared.api_results.mac_games: + if self.game.app_name in self.api_results.mac_games: available_platforms.append("macOS") self.platform.setText(", ".join(available_platforms)) diff --git a/rare/components/tabs/games/game_utils.py b/rare/components/tabs/games/game_utils.py index 2e8ac2a4..c2022090 100644 --- a/rare/components/tabs/games/game_utils.py +++ b/rare/components/tabs/games/game_utils.py @@ -10,7 +10,7 @@ from PyQt5.QtCore import QObject, QSettings, QProcess, QProcessEnvironment, pyqt from PyQt5.QtWidgets import QMessageBox, QPushButton from legendary.models.game import LaunchParameters -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton from rare.components.dialogs.uninstall_dialog import UninstallDialog from rare.components.extra.console import ConsoleWindow from rare.components.tabs.games import CloudSaveUtils @@ -50,8 +50,10 @@ class GameUtils(QObject): def __init__(self, parent=None): super(GameUtils, self).__init__(parent=parent) + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.args = ArgumentsSingleton() - self.core = shared.core self.console = ConsoleWindow() self.cloud_save_utils = CloudSaveUtils() self.cloud_save_utils.sync_finished.connect(self.sync_finished) @@ -80,7 +82,7 @@ class GameUtils(QObject): if infos == 0: return False legendary_utils.uninstall(game.app_name, self.core, infos) - shared.signals.game_uninstalled.emit(app_name) + self.signals.game_uninstalled.emit(app_name) return True def prepare_launch( @@ -116,7 +118,7 @@ class GameUtils(QObject): wine_pfx: str = None, ask_always_sync: bool = False, ): - if shared.args.offline: + if self.args.offline: offline = True game = self.core.get_game(app_name) igame = self.core.get_installed_game(app_name) @@ -253,7 +255,7 @@ class GameUtils(QObject): self.running_games[game.app_name] = running_game else: - origin_uri = self.core.get_origin_uri(game.app_name, shared.args.offline) + origin_uri = self.core.get_origin_uri(game.app_name, self.args.offline) logger.info("Launch Origin Game: ") if platform.system() == "Windows": webbrowser.open(origin_uri) diff --git a/rare/components/tabs/games/game_widgets/base_installed_widget.py b/rare/components/tabs/games/game_widgets/base_installed_widget.py index aa10e929..ae54f0a9 100644 --- a/rare/components/tabs/games/game_widgets/base_installed_widget.py +++ b/rare/components/tabs/games/game_widgets/base_installed_widget.py @@ -6,7 +6,7 @@ from PyQt5.QtCore import pyqtSignal, QProcess, QSettings, Qt, QByteArray from PyQt5.QtGui import QPixmap from PyQt5.QtWidgets import QGroupBox, QMessageBox, QAction, QLabel -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton from rare.components.tabs.games.game_utils import GameUtils from rare.utils import utils from rare.utils.utils import create_desktop_link @@ -22,7 +22,9 @@ class BaseInstalledWidget(QGroupBox): def __init__(self, app_name, pixmap: QPixmap, game_utils: GameUtils): super(BaseInstalledWidget, self).__init__() - self.core = shared.core + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.args = ArgumentsSingleton() self.game_utils = game_utils self.syncing_cloud_saves = False @@ -53,7 +55,7 @@ class BaseInstalledWidget(QGroupBox): pixmap.scaled(200, int(200 * 4 / 3), transformMode=Qt.SmoothTransformation) ) self.game_running = False - self.offline = shared.args.offline + self.offline = self.args.offline self.update_available = False if self.igame and self.core.lgd.assets: try: @@ -120,7 +122,7 @@ class BaseInstalledWidget(QGroupBox): uninstall = QAction(self.tr("Uninstall"), self) uninstall.triggered.connect( - lambda: shared.signals.update_gamelist.emit([self.game.app_name]) + lambda: self.signals.update_gamelist.emit([self.game.app_name]) if self.game_utils.uninstall_game(self.game.app_name) else None ) diff --git a/rare/components/tabs/games/game_widgets/installed_icon_widget.py b/rare/components/tabs/games/game_widgets/installed_icon_widget.py index 7f7b1120..40d6abd3 100644 --- a/rare/components/tabs/games/game_widgets/installed_icon_widget.py +++ b/rare/components/tabs/games/game_widgets/installed_icon_widget.py @@ -4,7 +4,7 @@ from PyQt5.QtCore import QEvent, pyqtSignal, QSize, Qt from PyQt5.QtGui import QMouseEvent from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QPushButton, QLabel -from rare import shared +from rare.shared import LegendaryCoreSingleton from rare.components.tabs.games.game_widgets.base_installed_widget import ( BaseInstalledWidget, ) @@ -22,7 +22,7 @@ class InstalledIconWidget(BaseInstalledWidget): self.setContextMenuPolicy(Qt.ActionsContextMenu) self.layout = QVBoxLayout() - self.core = shared.core + self.core = LegendaryCoreSingleton() if self.update_available: logger.info(f"Update available for game: {self.game.app_name}") diff --git a/rare/components/tabs/games/game_widgets/installing_game_widget.py b/rare/components/tabs/games/game_widgets/installing_game_widget.py index d8b637a1..cb636771 100644 --- a/rare/components/tabs/games/game_widgets/installing_game_widget.py +++ b/rare/components/tabs/games/game_widgets/installing_game_widget.py @@ -3,7 +3,7 @@ from PyQt5.QtGui import QPaintEvent, QPainter, QPixmap, QPen, QFont, QColor from PyQt5.QtWidgets import QVBoxLayout, QLabel, QHBoxLayout, QWidget from legendary.models.game import Game -from rare import shared +from rare.shared import LegendaryCoreSingleton from rare.utils.utils import ( get_pixmap, optimal_text_background, @@ -21,6 +21,8 @@ class InstallingGameWidget(QWidget): self.setProperty("noBorder", 1) self.setLayout(QVBoxLayout()) + self.core = LegendaryCoreSingleton() + self.pixmap = QPixmap() w = 200 # self.pixmap = self.pixmap.scaled(w, int(w * 4 / 3), transformMode=Qt.SmoothTransformation) @@ -42,7 +44,7 @@ class InstallingGameWidget(QWidget): if not app_name: self.game = None return - self.game = shared.core.get_game(app_name) + self.game = self.core.get_game(app_name) self.title_label.setText(f"

{self.game.app_title}

") self.image_widget.set_game(self.game.app_name) @@ -59,9 +61,10 @@ class PaintWidget(QWidget): def __init__(self): super(PaintWidget, self).__init__() + self.core = LegendaryCoreSingleton() def set_game(self, app_name: str): - game = shared.core.get_game(app_name, False) + game = self.core.get_game(app_name, False) self.color_image = get_pixmap(game.app_name) w = 200 self.color_image = self.color_image.scaled( diff --git a/rare/components/tabs/games/head_bar.py b/rare/components/tabs/games/head_bar.py index 31fb3a81..f0243633 100644 --- a/rare/components/tabs/games/head_bar.py +++ b/rare/components/tabs/games/head_bar.py @@ -8,7 +8,7 @@ from PyQt5.QtWidgets import ( QComboBox, ) -from rare import shared +from rare.shared import ApiResultsSingleton from rare.utils.extra_widgets import SelectViewWidget from rare.utils.utils import icon @@ -18,6 +18,7 @@ class GameListHeadBar(QWidget): def __init__(self, parent=None): super(GameListHeadBar, self).__init__(parent=parent) + self.api_results = ApiResultsSingleton() self.setLayout(QHBoxLayout()) # self.installed_only = QCheckBox(self.tr("Installed only")) self.settings = QSettings() @@ -38,15 +39,15 @@ class GameListHeadBar(QWidget): "installed", "offline", ] - if shared.api_results.bit32_games: + if self.api_results.bit32_games: self.filter.addItem(self.tr("32 Bit Games")) self.available_filters.append("32bit") - if shared.api_results.mac_games: + if self.api_results.mac_games: self.filter.addItem(self.tr("Mac games")) self.available_filters.append("mac") - if shared.api_results.no_asset_games: + if self.api_results.no_asset_games: self.filter.addItem(self.tr("Exclude Origin")) self.available_filters.append("installable") diff --git a/rare/components/tabs/games/import_sync/egl_sync_group.py b/rare/components/tabs/games/import_sync/egl_sync_group.py index 9d316a53..0d32d13a 100644 --- a/rare/components/tabs/games/import_sync/egl_sync_group.py +++ b/rare/components/tabs/games/import_sync/egl_sync_group.py @@ -6,7 +6,7 @@ from typing import Tuple, Iterable from PyQt5.QtCore import Qt, QThreadPool, QRunnable, pyqtSlot from PyQt5.QtWidgets import QGroupBox, QListWidgetItem, QFileDialog, QMessageBox -import rare.shared as shared +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_list_group import ( Ui_EGLSyncListGroup, @@ -22,6 +22,7 @@ class EGLSyncGroup(QGroupBox, Ui_EGLSyncGroup): def __init__(self, parent=None): super(EGLSyncGroup, self).__init__(parent=parent) self.setupUi(self) + self.core = LegendaryCoreSingleton() self.egl_path_info.setProperty("infoLabel", 1) self.thread_pool = QThreadPool.globalInstance() @@ -32,7 +33,7 @@ class EGLSyncGroup(QGroupBox, Ui_EGLSyncGroup): self.egl_path_info.setVisible(False) else: self.egl_path_edit = PathEdit( - path=shared.core.egl.programdata_path, + path=self.core.egl.programdata_path, ph_text=self.tr( "Path to the Wine prefix where EGL is installed, or the Manifests folder" ), @@ -44,10 +45,10 @@ class EGLSyncGroup(QGroupBox, Ui_EGLSyncGroup): self.egl_path_edit.textChanged.connect(self.egl_path_changed) self.egl_path_edit_layout.addWidget(self.egl_path_edit) - if not shared.core.egl.programdata_path: + if not self.core.egl.programdata_path: self.egl_path_info.setText(self.tr("Updating...")) wine_resolver = WineResolver( - PathSpec.egl_programdata, "default", shared.core + PathSpec.egl_programdata, "default", self.core ) wine_resolver.signals.result_ready.connect(self.wine_resolver_cb) self.thread_pool.start(wine_resolver) @@ -55,7 +56,7 @@ class EGLSyncGroup(QGroupBox, Ui_EGLSyncGroup): self.egl_path_info_label.setVisible(False) self.egl_path_info.setVisible(False) - self.egl_sync_check.setChecked(shared.core.egl_sync_enabled) + self.egl_sync_check.setChecked(self.core.egl_sync_enabled) self.egl_sync_check.stateChanged.connect(self.egl_sync_changed) self.import_list = EGLSyncListGroup(export=False, parent=self) @@ -109,22 +110,21 @@ class EGLSyncGroup(QGroupBox, Ui_EGLSyncGroup): return True, path, "" return False, path, PathEdit.reasons.dir_not_exist - @staticmethod - def egl_path_edit_save_cb(path): + def egl_path_edit_save_cb(self, path): if not path or not os.path.exists(path): # This is the same as "--unlink" - shared.core.egl.programdata_path = None - shared.core.lgd.config.remove_option("Legendary", "egl_programdata") - shared.core.lgd.config.remove_option("Legendary", "egl_sync") + self.core.egl.programdata_path = None + self.core.lgd.config.remove_option("Legendary", "egl_programdata") + self.core.lgd.config.remove_option("Legendary", "egl_sync") # remove EGL GUIDs from all games, DO NOT remove .egstore folders because that would fuck things up. - for igame in shared.core.get_installed_list(): + for igame in self.core.get_installed_list(): igame.egl_guid = "" - shared.core.install_game(igame) + self.core.install_game(igame) else: - shared.core.egl.programdata_path = path - shared.core.lgd.config.set("Legendary", "egl_programdata", path) + self.core.egl.programdata_path = path + self.core.lgd.config.set("Legendary", "egl_programdata", path) - shared.core.lgd.save_config() + self.core.lgd.save_config() def egl_path_changed(self, path): if self.egl_path_edit.is_valid: @@ -138,9 +138,9 @@ class EGLSyncGroup(QGroupBox, Ui_EGLSyncGroup): if state == Qt.Unchecked: self.import_list.setEnabled(bool(self.import_list.items)) self.export_list.setEnabled(bool(self.export_list.items)) - shared.core.lgd.config.remove_option("Legendary", "egl_sync") + self.core.lgd.config.remove_option("Legendary", "egl_sync") else: - shared.core.lgd.config.set("Legendary", "egl_sync", str(True)) + self.core.lgd.config.set("Legendary", "egl_sync", str(True)) # lk: do import/export here since automatic sync was selected self.import_list.mark(Qt.Checked) self.export_list.mark(Qt.Checked) @@ -149,15 +149,15 @@ class EGLSyncGroup(QGroupBox, Ui_EGLSyncGroup): self.import_list.setEnabled(False) self.export_list.setEnabled(False) # self.update_lists() - shared.core.lgd.save_config() + self.core.lgd.save_config() def update_lists(self): # self.egl_watcher.blockSignals(True) - if have_path := bool(shared.core.egl.programdata_path) and os.path.exists( - shared.core.egl.programdata_path + if have_path := bool(self.core.egl.programdata_path) and os.path.exists( + self.core.egl.programdata_path ): # NOTE: need to clear known manifests to force refresh - shared.core.egl.manifests.clear() + self.core.egl.manifests.clear() self.egl_sync_check_label.setEnabled(have_path) self.egl_sync_check.setEnabled(have_path) self.import_list.populate(have_path) @@ -172,21 +172,22 @@ class EGLSyncListItem(QListWidgetItem): super(EGLSyncListItem, self).__init__(parent=parent) self.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) self.setCheckState(Qt.Unchecked) + self.core = LegendaryCoreSingleton() self.game = game self.export = export if export: self.setText(game.title) else: # import - self.setText(shared.core.get_game(game.app_name).app_title) + self.setText(self.core.get_game(game.app_name).app_title) def is_checked(self) -> bool: return self.checkState() == Qt.Checked def action(self) -> None: if self.export: - error = shared.core.egl_export(self.game.app_name) + error = self.core.egl_export(self.game.app_name) else: - error = shared.core.egl_import(self.game.app_name) + error = self.core.egl_import(self.game.app_name) return error @property @@ -202,6 +203,8 @@ class EGLSyncListGroup(QGroupBox, Ui_EGLSyncListGroup): 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) self.export = export @@ -210,12 +213,12 @@ class EGLSyncListGroup(QGroupBox, Ui_EGLSyncListGroup): self.setTitle(self.tr("Exportable games")) self.label.setText(self.tr("No games to export to EGL")) self.action_button.setText(self.tr("Export")) - self.list_func = shared.core.egl_get_exportable + self.list_func = self.core.egl_get_exportable else: self.setTitle(self.tr("Importable games")) self.label.setText(self.tr("No games to import from EGL")) self.action_button.setText(self.tr("Import")) - self.list_func = shared.core.egl_get_importable + self.list_func = self.core.egl_get_importable self.list.itemDoubleClicked.connect( lambda item: item.setCheckState(Qt.Unchecked) @@ -265,7 +268,7 @@ class EGLSyncListGroup(QGroupBox, Ui_EGLSyncListGroup): imported.append(item.app_name) self.list.takeItem(self.list.row(item)) if not self.export and imported: - shared.signals.update_gamelist.emit(imported) + self.signals.update_gamelist.emit(imported) self.populate(True) if errors: QMessageBox.warning( @@ -351,7 +354,7 @@ class EGLSyncItemWidget(QGroupBox): if export: self.app_title_label = QLabel(game.title) else: - title = shared.core.get_game(game.app_name).app_title + title = self.core.get_game(game.app_name).app_title self.app_title_label = QLabel(title) self.layout.addWidget(self.app_title_label) self.button = QPushButton(self.tr("Export") if export else self.tr("Import")) @@ -365,13 +368,13 @@ class EGLSyncItemWidget(QGroupBox): self.setLayout(self.layout) def export_game(self): - shared.core.egl_export(self.game.app_name) + self.core.egl_export(self.game.app_name) # FIXME: on update_egl_widget this is going to crash because # FIXME: the item is not removed from the list in the python's side self.deleteLater() def import_game(self): - shared.core.egl_import(self.game.app_name) + self.core.egl_import(self.game.app_name) # FIXME: on update_egl_widget this is going to crash because # FIXME: the item is not removed from the list in the python's side self.deleteLater() diff --git a/rare/components/tabs/games/import_sync/import_group.py b/rare/components/tabs/games/import_sync/import_group.py index 7dc4becc..811a60ab 100644 --- a/rare/components/tabs/games/import_sync/import_group.py +++ b/rare/components/tabs/games/import_sync/import_group.py @@ -7,7 +7,7 @@ from PyQt5.QtCore import Qt, QModelIndex, pyqtSignal from PyQt5.QtGui import QStandardItemModel from PyQt5.QtWidgets import QFileDialog, QGroupBox, QCompleter, QTreeView, QHeaderView -import rare.shared as shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ApiResultsSingleton from rare.ui.components.tabs.games.import_sync.import_group import Ui_ImportGroup from rare.utils import legendary_utils from rare.utils.extra_widgets import IndicatorLineEdit, PathEdit @@ -64,13 +64,16 @@ class ImportGroup(QGroupBox, Ui_ImportGroup): def __init__(self, parent=None): super(ImportGroup, self).__init__(parent=parent) self.setupUi(self) - self.core = shared.core - self.app_name_list = [game.app_name for game in shared.api_results.game_list] + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.api_results = ApiResultsSingleton() + + self.app_name_list = [game.app_name for game in self.api_results.game_list] self.install_dir_list = [ game.metadata.get("customAttributes", {}) .get("FolderName", {}) .get("value", game.app_name) - for game in shared.api_results.game_list + for game in self.api_results.game_list if not game.is_dlc ] @@ -87,7 +90,7 @@ class ImportGroup(QGroupBox, Ui_ImportGroup): ph_text=self.tr("Use in case the app name was not found automatically"), completer=AppNameCompleter( app_names=[ - (i.app_name, i.app_title) for i in shared.api_results.game_list + (i.app_name, i.app_title) for i in self.api_results.game_list ] ), edit_func=self.app_name_edit_cb, @@ -162,15 +165,15 @@ class ImportGroup(QGroupBox, Ui_ImportGroup): self.tr("Successfully imported {}").format(igame.title) ) self.app_name.setText(str()) - shared.signals.update_gamelist.emit([app_name]) + self.signals.update_gamelist.emit([app_name]) if ( igame.version != self.core.get_asset(app_name, igame.platform, False).build_version ): # update available - shared.signals.add_download.emit(igame.app_name) - shared.signals.update_download_tab_text.emit() + self.signals.add_download.emit(igame.app_name) + self.signals.update_download_tab_text.emit() else: logger.warning(f'Failed to import "{app_name}"') diff --git a/rare/components/tabs/settings/dxvk.py b/rare/components/tabs/settings/dxvk.py index 29cf7ae5..00b33dc3 100644 --- a/rare/components/tabs/settings/dxvk.py +++ b/rare/components/tabs/settings/dxvk.py @@ -2,7 +2,7 @@ from logging import getLogger from PyQt5.QtWidgets import QGroupBox -from rare import shared +from rare.shared import LegendaryCoreSingleton from rare.ui.components.tabs.settings.dxvk import Ui_DxvkSettings logger = getLogger("DXVK Settings") @@ -14,7 +14,7 @@ class DxvkSettings(QGroupBox, Ui_DxvkSettings): self.setupUi(self) self.name = name if name is not None else "default" - self.core = shared.core + self.core = LegendaryCoreSingleton() self.dxvk_options_map = { "devinfo": self.devinfo, diff --git a/rare/components/tabs/settings/eos.py b/rare/components/tabs/settings/eos.py index cb1bb9af..1655772b 100644 --- a/rare/components/tabs/settings/eos.py +++ b/rare/components/tabs/settings/eos.py @@ -7,7 +7,7 @@ from PyQt5.QtCore import QRunnable, QObject, pyqtSignal, QThreadPool from PyQt5.QtWidgets import QGroupBox, QMessageBox from legendary.utils import eos -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton from rare.ui.components.tabs.settings.eos_widget import Ui_EosWidget from rare.utils.models import InstallOptionsModel @@ -19,9 +19,9 @@ def get_wine_prefixes() -> List[str]: prefixes = [p] else: prefixes = [] - for i in shared.core.get_installed_list(): + for i in LegendaryCoreSingleton().get_installed_list(): # get prefix from environment - env = shared.core.get_app_environment(i.app_name) + env = LegendaryCoreSingleton().get_app_environment(i.app_name) if pfx := env.get("WINEPREFIX"): if pfx not in prefixes and os.path.exists(os.path.join(pfx, "user.reg")): prefixes.append(pfx) @@ -31,26 +31,28 @@ def get_wine_prefixes() -> List[str]: return prefixes -class WorkerSignals(QObject): +class CheckForUpdateSignals(QObject): update_available = pyqtSignal(bool) class CheckForUpdateWorker(QRunnable): def __init__(self): super(CheckForUpdateWorker, self).__init__() + self.signals = CheckForUpdateSignals() self.setAutoDelete(True) - self.signals = WorkerSignals() + self.core = LegendaryCoreSingleton() def run(self) -> None: - shared.core.check_for_overlay_updates() - self.signals.update_available.emit(shared.core.overlay_update_available) + self.core.check_for_overlay_updates() + self.signals.update_available.emit(self.core.overlay_update_available) class EosWidget(QGroupBox, Ui_EosWidget): def __init__(self): super(EosWidget, self).__init__() self.setupUi(self) - self.core = shared.core + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() if platform.system() != "Windows": self.setTitle(f"{self.title()} - {self.tr(' - This won´t work with Wine. It might work in the Future')}") @@ -64,8 +66,8 @@ class EosWidget(QGroupBox, Ui_EosWidget): self.update_info_lbl.setVisible(False) self.overlay = self.core.lgd.get_overlay_install_info() - shared.signals.overlay_installation_finished.connect(self.overlay_installation_finished) - shared.signals.wine_prefix_updated.connect(self.update_prefixes) + self.signals.overlay_installation_finished.connect(self.overlay_installation_finished) + self.signals.wine_prefix_updated.connect(self.update_prefixes) self.update_check_button.clicked.connect(self.check_for_update) self.install_button.clicked.connect(self.install_overlay) @@ -217,7 +219,7 @@ class EosWidget(QGroupBox, Ui_EosWidget): options = InstallOptionsModel(app_name="", base_path=base_path, platform="Windows", overlay=True) - shared.signals.install_game.emit(options) + self.signals.install_game.emit(options) def uninstall_overlay(self): if not self.core.is_overlay_installed(): diff --git a/rare/components/tabs/settings/legendary.py b/rare/components/tabs/settings/legendary.py index 8c5cc4de..48a23de6 100644 --- a/rare/components/tabs/settings/legendary.py +++ b/rare/components/tabs/settings/legendary.py @@ -5,7 +5,7 @@ from typing import Tuple from PyQt5.QtCore import Qt, QRunnable, QObject, pyqtSignal, QThreadPool from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox -import rare.shared as shared +from rare.shared import LegendaryCoreSingleton from rare.components.tabs.settings.eos import EosWidget from rare.components.tabs.settings.ubisoft_activation import UbiActivationHelper from rare.ui.components.tabs.settings.legendary import Ui_LegendarySettings @@ -15,21 +15,22 @@ from rare.utils.utils import get_size logger = getLogger("LegendarySettings") -class WorkerSignals(QObject): +class RefreshGameMetaSignals(QObject): finished = pyqtSignal() def __init__(self): - super(WorkerSignals, self).__init__() + super(RefreshGameMetaSignals, self).__init__() class RefreshGameMetaWorker(QRunnable): def __init__(self): super(RefreshGameMetaWorker, self).__init__() + self.signals = RefreshGameMetaSignals() self.setAutoDelete(True) - self.signals = WorkerSignals() + self.core = LegendaryCoreSingleton() def run(self) -> None: - shared.core.get_game_and_dlc_list(True, force_refresh=True) + self.core.get_game_and_dlc_list(True, force_refresh=True) self.signals.finished.emit() @@ -38,7 +39,7 @@ class LegendarySettings(QWidget, Ui_LegendarySettings): super(LegendarySettings, self).__init__(parent=parent) self.setupUi(self) - self.core = shared.core + self.core = LegendaryCoreSingleton() # Default installation directory self.install_dir = PathEdit( diff --git a/rare/components/tabs/settings/linux.py b/rare/components/tabs/settings/linux.py index 3cba9f28..33fc672f 100644 --- a/rare/components/tabs/settings/linux.py +++ b/rare/components/tabs/settings/linux.py @@ -3,7 +3,7 @@ from logging import getLogger from PyQt5.QtWidgets import QFileDialog, QWidget -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton from rare.components.tabs.settings.dxvk import DxvkSettings from rare.ui.components.tabs.settings.linux import Ui_LinuxSettings from rare.utils.extra_widgets import PathEdit @@ -16,6 +16,9 @@ class LinuxSettings(QWidget, Ui_LinuxSettings): super(LinuxSettings, self).__init__() self.setupUi(self) + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() + self.name = name if name is not None else "default" # Wine prefix @@ -52,29 +55,27 @@ class LinuxSettings(QWidget, Ui_LinuxSettings): def save_prefix(self, text: str): self.save_setting(text, f"{self.name}.env", "WINEPREFIX") self.save_setting(text, self.name, "wine_prefix") - shared.signals.wine_prefix_updated.emit() + self.signals.wine_prefix_updated.emit() - @staticmethod - def load_setting(section: str, setting: str, fallback: str = str()): - return shared.core.lgd.config.get(section, setting, fallback=fallback) + def load_setting(self, section: str, setting: str, fallback: str = str()): + return self.core.lgd.config.get(section, setting, fallback=fallback) - @staticmethod - def save_setting(text: str, section: str, setting: str): + def save_setting(self, text: str, section: str, setting: str): if text: - if section not in shared.core.lgd.config.sections(): - shared.core.lgd.config.add_section(section) + if section not in self.core.lgd.config.sections(): + self.core.lgd.config.add_section(section) logger.debug(f"Added {f'[{section}]'} configuration section") - shared.core.lgd.config.set(section, setting, text) + self.core.lgd.config.set(section, setting, text) logger.debug(f"Set {setting} in {f'[{section}]'} to {text}") else: - if shared.core.lgd.config.has_section( + if self.core.lgd.config.has_section( section - ) and shared.core.lgd.config.has_option(section, setting): - shared.core.lgd.config.remove_option(section, setting) + ) and self.core.lgd.config.has_option(section, setting): + self.core.lgd.config.remove_option(section, setting) logger.debug(f"Unset {setting} from {f'[{section}]'}") - if not shared.core.lgd.config[section]: - shared.core.lgd.config.remove_section(section) + if not self.core.lgd.config[section]: + self.core.lgd.config.remove_section(section) logger.debug(f"Removed {f'[{section}]'} configuration section") - shared.core.lgd.save_config() + self.core.lgd.save_config() diff --git a/rare/components/tabs/settings/rare.py b/rare/components/tabs/settings/rare.py index 0120f63f..97a6548d 100644 --- a/rare/components/tabs/settings/rare.py +++ b/rare/components/tabs/settings/rare.py @@ -7,8 +7,7 @@ from logging import getLogger from PyQt5.QtCore import QSettings, Qt from PyQt5.QtWidgets import QWidget, QMessageBox -from rare import shared - +from rare.shared import LegendaryCoreSingleton from rare.components.tabs.settings.rpc import RPCSettings from rare.ui.components.tabs.settings.rare import Ui_RareSettings from rare.utils import utils @@ -35,7 +34,7 @@ class RareSettings(QWidget, Ui_RareSettings): def __init__(self): super(RareSettings, self).__init__() self.setupUi(self) - self.core = shared.core + self.core = LegendaryCoreSingleton() # (widget_name, option_name, default) self.checkboxes = [ (self.sys_tray, "sys_tray", True), diff --git a/rare/components/tabs/settings/ubisoft_activation.py b/rare/components/tabs/settings/ubisoft_activation.py index eb123e71..d6bdd0b7 100644 --- a/rare/components/tabs/settings/ubisoft_activation.py +++ b/rare/components/tabs/settings/ubisoft_activation.py @@ -6,26 +6,26 @@ from PyQt5.QtCore import QObject, pyqtSignal, QRunnable, QThreadPool, QSize from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QSizePolicy, QPushButton from legendary.models.game import Game -from rare import shared +from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton from rare.utils.utils import icon logger = getLogger("Ubisoft") -class Signals(QObject): +class UbiGetInfoSignals(QObject): worker_finished = pyqtSignal(set, set, str) - linked = pyqtSignal(str) class UbiGetInfoWorker(QRunnable): def __init__(self): super(UbiGetInfoWorker, self).__init__() - self.signals = Signals() + self.signals = UbiGetInfoSignals() self.setAutoDelete(True) + self.core = LegendaryCoreSingleton() def run(self) -> None: try: - external_auths = shared.core.egs.get_external_auths() + external_auths = self.core.egs.get_external_auths() for ext_auth in external_auths: if ext_auth["type"] != "ubisoft": continue @@ -35,11 +35,11 @@ class UbiGetInfoWorker(QRunnable): self.signals.worker_finished.emit(set(), set(), "") return - uplay_keys = shared.core.egs.store_get_uplay_codes() + uplay_keys = self.core.egs.store_get_uplay_codes() key_list = uplay_keys["data"]["PartnerIntegration"]["accountUplayCodes"] redeemed = {k["gameId"] for k in key_list if k["redeemedOnUplay"]} - entitlements = shared.core.egs.get_user_entitlements() + entitlements = self.core.egs.get_user_entitlements() entitlements = {i["entitlementName"] for i in entitlements} self.signals.worker_finished.emit(redeemed, entitlements, ubi_account_id) except Exception as e: @@ -47,11 +47,16 @@ class UbiGetInfoWorker(QRunnable): self.signals.worker_finished.emit(set(), set(), "error") +class UbiConnectSignals(QObject): + linked = pyqtSignal(str) + + class UbiConnectWorker(QRunnable): def __init__(self, ubi_account_id, partner_link_id): super(UbiConnectWorker, self).__init__() - self.signals = Signals() + self.signals = UbiConnectSignals() self.setAutoDelete(True) + self.core = LegendaryCoreSingleton() self.ubi_account_id = ubi_account_id self.partner_link_id = partner_link_id @@ -61,10 +66,10 @@ class UbiConnectWorker(QRunnable): self.signals.linked.emit("") return try: - shared.core.egs.store_claim_uplay_code( + self.core.egs.store_claim_uplay_code( self.ubi_account_id, self.partner_link_id ) - shared.core.egs.store_redeem_uplay_codes(self.ubi_account_id) + self.core.egs.store_redeem_uplay_codes(self.ubi_account_id) except Exception as e: self.signals.linked.emit(str(e)) return @@ -75,6 +80,7 @@ class UbiConnectWorker(QRunnable): class UbiLinkWidget(QWidget): def __init__(self, game: Game, ubi_account_id): super(UbiLinkWidget, self).__init__() + self.args = ArgumentsSingleton() self.setLayout(QHBoxLayout()) self.game = game self.ubi_account_id = ubi_account_id @@ -88,7 +94,7 @@ class UbiLinkWidget(QWidget): self.layout().addWidget(self.ok_indicator) self.link_button = QPushButton( - self.tr("Redeem to Ubisoft") + ": Test" if shared.args.debug else "" + self.tr("Redeem to Ubisoft") + ": Test" if self.args.debug else "" ) self.layout().addWidget(self.link_button) self.link_button.clicked.connect(self.activate) @@ -100,7 +106,7 @@ class UbiLinkWidget(QWidget): icon("mdi.transit-connection-horizontal", color="grey").pixmap(20, 20) ) - if shared.args.debug: + if self.args.debug: worker = UbiConnectWorker(None, None) else: worker = UbiConnectWorker(self.ubi_account_id, self.game.partner_link_id) @@ -126,8 +132,9 @@ class UbiLinkWidget(QWidget): class UbiActivationHelper(QObject): def __init__(self, widget: QWidget): super(UbiActivationHelper, self).__init__() + self.core = LegendaryCoreSingleton() + self.args = ArgumentsSingleton() self.widget = widget - self.core = shared.core self.thread_pool = QThreadPool.globalInstance() worker = UbiGetInfoWorker() @@ -196,7 +203,7 @@ class UbiActivationHelper(QObject): self.widget.layout().addWidget( QLabel(self.tr("You don't own any Ubisoft games")) ) - if shared.args.debug: + if self.args.debug: widget = UbiLinkWidget( Game(app_name="Test", app_title="This is a test game"), ubi_account_id, diff --git a/rare/components/tabs/shop/__init__.py b/rare/components/tabs/shop/__init__.py index 409eb490..53be94ba 100644 --- a/rare/components/tabs/shop/__init__.py +++ b/rare/components/tabs/shop/__init__.py @@ -1,7 +1,7 @@ from PyQt5.QtWidgets import QStackedWidget, QTabWidget from legendary.core import LegendaryCore -from rare import shared +from rare.shared import LegendaryCoreSingleton, ApiResultsSingleton from rare.utils.paths import cache_dir from .game_info import ShopGameInfo from .search_results import SearchResults @@ -16,13 +16,14 @@ class Shop(QStackedWidget): def __init__(self, core: LegendaryCore): super(Shop, self).__init__() self.core = core + self.api_results = ApiResultsSingleton() self.api_core = ShopApiCore( self.core.egs.session.headers["Authorization"], self.core.language_code, self.core.country_code, ) - self.shop = ShopWidget(cache_dir, core, self.api_core) + self.shop = ShopWidget(cache_dir, self.core, self.api_core) self.wishlist_widget = Wishlist(self.api_core) self.store_tabs = QTabWidget() @@ -35,7 +36,7 @@ class Shop(QStackedWidget): self.addWidget(self.search_results) self.search_results.show_info.connect(self.show_game_info) self.info = ShopGameInfo( - [i.asset_infos["Windows"].namespace for i in shared.api_results.game_list], + [i.asset_infos["Windows"].namespace for i in self.api_results.game_list], self.api_core, ) self.addWidget(self.info) diff --git a/rare/components/tabs/shop/game_info.py b/rare/components/tabs/shop/game_info.py index d678d8ee..8b08f9a6 100644 --- a/rare/components/tabs/shop/game_info.py +++ b/rare/components/tabs/shop/game_info.py @@ -13,7 +13,7 @@ from PyQt5.QtWidgets import ( QGridLayout, ) -from rare import shared +from rare.shared import LegendaryCoreSingleton from rare.components.tabs.shop.shop_models import ShopGame from rare.ui.components.tabs.store.shop_game_info import Ui_shop_info from rare.utils.extra_widgets import WaitingSpinner, ImageLabel @@ -30,6 +30,7 @@ class ShopGameInfo(QWidget, Ui_shop_info): def __init__(self, installed_titles: list, api_core): super(ShopGameInfo, self).__init__() self.setupUi(self) + self.core = LegendaryCoreSingleton() self.api_core = api_core self.installed = installed_titles self.open_store_button.clicked.connect(self.button_clicked) @@ -258,7 +259,7 @@ class ShopGameInfo(QWidget, Ui_shop_info): self.wishlist.append(game["offer"]["title"]) def button_clicked(self): - QDesktopServices.openUrl(QUrl(f"https://www.epicgames.com/store/{shared.core.language_code}/p/{self.slug}")) + QDesktopServices.openUrl(QUrl(f"https://www.epicgames.com/store/{self.core.language_code}/p/{self.slug}")) class SocialButton(QPushButton): diff --git a/rare/components/tray_icon.py b/rare/components/tray_icon.py index 119f4288..f0e92722 100644 --- a/rare/components/tray_icon.py +++ b/rare/components/tray_icon.py @@ -3,13 +3,15 @@ from typing import List from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QSystemTrayIcon, QMenu, QAction -from rare import shared +from rare.shared import LegendaryCoreSingleton from rare.utils.meta import GameMeta class TrayIcon(QSystemTrayIcon): def __init__(self, parent): super(TrayIcon, self).__init__(parent) + self.core = LegendaryCoreSingleton() + self.setIcon(QIcon(":/images/Rare.png")) self.setVisible(True) self.setToolTip("Rare") @@ -24,7 +26,7 @@ class TrayIcon(QSystemTrayIcon): self.text_action.setEnabled(False) self.menu.addAction(self.text_action) - if len(installed := shared.core.get_installed_list()) < 5: + if len(installed := self.core.get_installed_list()) < 5: last_played = [GameMeta(i.app_name) for i in sorted(installed, key=lambda x: x.title)] elif games := sorted( parent.mainwindow.tab_widget.games_tab.game_utils.game_meta.get_games(), @@ -36,7 +38,7 @@ class TrayIcon(QSystemTrayIcon): self.game_actions = [] for game in last_played: - a = QAction(shared.core.get_game(game.app_name).app_title) + a = QAction(self.core.get_game(game.app_name).app_title) a.setProperty("app_name", game.app_name) self.game_actions.append(a) a.triggered.connect( diff --git a/rare/shared.py b/rare/shared.py index 450c4068..5de855fd 100644 --- a/rare/shared.py +++ b/rare/shared.py @@ -1,31 +1,38 @@ from argparse import Namespace from legendary.core import LegendaryCore -from rare.utils.models import ApiResults, Signals +from rare.utils.models import ApiResults, GlobalSignals -core: LegendaryCore = None -signals: Signals = None -args: Namespace = None -api_results: ApiResults = None +_legendary_core_singleton: LegendaryCore = None +_global_signals_singleton: GlobalSignals = None +_arguments_singleton: Namespace = None +_api_results_singleton: ApiResults = None -def init_legendary(): - global core - core = LegendaryCore() - return core +def LegendaryCoreSingleton() -> LegendaryCore: + global _legendary_core_singleton + if _legendary_core_singleton is None: + _legendary_core_singleton = LegendaryCore() + return _legendary_core_singleton -def init_signals(): - global signals - signals = Signals() - return signals +def GlobalSignalsSingleton() -> GlobalSignals: + global _global_signals_singleton + if _global_signals_singleton is None: + _global_signals_singleton = GlobalSignals() + return _global_signals_singleton -def init_args(a: Namespace): - global args - args = a +def ArgumentsSingleton(args: Namespace = None) -> Namespace: + global _arguments_singleton + if _arguments_singleton is None: + _arguments_singleton = args + return _arguments_singleton -def init_api_response(res: ApiResults): - global api_results - api_results = res +def ApiResultsSingleton(res: ApiResults = None) -> ApiResults: + global _api_results_singleton + if _api_results_singleton is None: + _api_results_singleton = res + return _api_results_singleton + diff --git a/rare/utils/legendary_utils.py b/rare/utils/legendary_utils.py index c0464efb..17ef38cd 100644 --- a/rare/utils/legendary_utils.py +++ b/rare/utils/legendary_utils.py @@ -8,7 +8,7 @@ from PyQt5.QtCore import pyqtSignal, QCoreApplication, QObject, QRunnable from legendary.core import LegendaryCore from legendary.models.game import VerifyResult from legendary.utils.lfs import validate_files -from rare import shared +from rare.shared import LegendaryCoreSingleton from rare.utils import config_helper logger = getLogger("Legendary Utils") @@ -102,19 +102,20 @@ class VerifyWorker(QRunnable): def __init__(self, app_name): super(VerifyWorker, self).__init__() - self.app_name = app_name self.signals = VerifySignals() self.setAutoDelete(True) + self.core = LegendaryCoreSingleton() + self.app_name = app_name def run(self): - if not shared.core.is_installed(self.app_name): + if not self.core.is_installed(self.app_name): logger.error(f'Game "{self.app_name}" is not installed') return logger.info(f'Loading installed manifest for "{self.app_name}"') - igame = shared.core.get_installed_game(self.app_name) - manifest_data, _ = shared.core.get_installed_manifest(self.app_name) - manifest = shared.core.load_manifest(manifest_data) + igame = self.core.get_installed_game(self.app_name) + manifest_data, _ = self.core.get_installed_manifest(self.app_name) + manifest = self.core.load_manifest(manifest_data) files = sorted(manifest.file_manifest_list.elements, key=lambda a: a.filename.lower()) @@ -148,7 +149,7 @@ class VerifyWorker(QRunnable): # always write repair file, even if all match if repair_file: - repair_filename = os.path.join(shared.core.lgd.get_tmp_path(), f'{self.app_name}.repair') + repair_filename = os.path.join(self.core.lgd.get_tmp_path(), f'{self.app_name}.repair') with open(repair_filename, 'w') as f: f.write('\n'.join(repair_file)) logger.debug(f'Written repair file to "{repair_filename}"') diff --git a/rare/utils/models.py b/rare/utils/models.py index 5c9dd61f..f175aec1 100644 --- a/rare/utils/models.py +++ b/rare/utils/models.py @@ -121,7 +121,7 @@ class ApiResults: ) -class Signals(QObject): +class GlobalSignals(QObject): exit_app = pyqtSignal(int) # exit code send_notification = pyqtSignal(str) # app_title diff --git a/rare/utils/rpc.py b/rare/utils/rpc.py index d17014ef..3aef3cf5 100644 --- a/rare/utils/rpc.py +++ b/rare/utils/rpc.py @@ -6,7 +6,7 @@ import pypresence.exceptions from PyQt5.QtCore import QObject, QSettings from pypresence import Presence -from rare import shared +from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton client_id = "830732538225360908" logger = getLogger("RPC") @@ -17,8 +17,8 @@ class DiscordRPC(QObject): super(DiscordRPC, self).__init__() self.RPC = None self.state = 1 # 0: game, 1: always active, 2: off - self.core = shared.core - self.signals = shared.signals + self.core = LegendaryCoreSingleton() + self.signals = GlobalSignalsSingleton() self.settings = QSettings() if self.settings.value("rpc_enable", 0, int) == 1: # show always diff --git a/rare/utils/steam_grades.py b/rare/utils/steam_grades.py index 1d8fef5b..0d63d4c8 100644 --- a/rare/utils/steam_grades.py +++ b/rare/utils/steam_grades.py @@ -7,7 +7,7 @@ import requests from PyQt5.QtCore import pyqtSignal, QRunnable, QObject, QCoreApplication from legendary.core import LegendaryCore -from rare import shared +from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton from rare.utils.paths import data_dir, cache_dir replace_chars = ",;.:-_ " @@ -48,15 +48,17 @@ class SteamWorker(QRunnable): def get_rating(app_name: str): + core = LegendaryCoreSingleton() + args = ArgumentsSingleton() if os.path.exists(p := os.path.join(data_dir, "steam_ids.json")): grades = json.load(open(p)) else: grades = {} if not grades.get(app_name): - if shared.args.offline: + if args.offline: return "pending" - game = shared.core.get_game(app_name) + game = core.get_game(app_name) steam_id = get_steam_id(game.app_title) grade = get_grade(steam_id) diff --git a/rare/utils/utils.py b/rare/utils/utils.py index ea5913ee..0df9d06a 100644 --- a/rare/utils/utils.py +++ b/rare/utils/utils.py @@ -33,7 +33,7 @@ if platform.system() == "Windows": # noinspection PyUnresolvedReferences from win32com.client import Dispatch # pylint: disable=E0401 -from rare import shared +from rare.shared import LegendaryCoreSingleton, ApiResultsSingleton from rare.utils.paths import image_dir, resources_path # Mac not supported @@ -63,7 +63,7 @@ def download_images(progress: pyqtSignal, results: pyqtSignal, core: LegendaryCo for i, game in enumerate(game_list): if game.app_title == "Unreal Engine": game.app_title += f" {game.app_name.split('_')[-1]}" - shared.core.lgd.set_game_meta(game.app_name, game) + core.lgd.set_game_meta(game.app_name, game) try: download_image(game) except json.decoder.JSONDecodeError: @@ -453,8 +453,8 @@ class WineResolverSignals(QObject): class WineResolver(QRunnable): def __init__(self, path: str, app_name: str, core: LegendaryCore): super(WineResolver, self).__init__() - self.setAutoDelete(True) self.signals = WineResolverSignals() + self.setAutoDelete(True) self.wine_env = os.environ.copy() self.wine_env.update(core.get_app_environment(app_name)) self.wine_env["WINEDLLOVERRIDES"] = "winemenubuilder=d;mscoree=d;mshtml=d;" @@ -514,19 +514,20 @@ class WineResolver(QRunnable): return -class CloudResultSignal(QObject): +class CloudSignals(QObject): result_ready = pyqtSignal(list) # List[SaveGameFile] class CloudWorker(QRunnable): def __init__(self): super(CloudWorker, self).__init__() - self.signals = CloudResultSignal() + self.signals = CloudSignals() self.setAutoDelete(True) + self.core = LegendaryCoreSingleton() def run(self) -> None: try: - result = shared.core.get_save_games() + result = self.core.get_save_games() except HTTPError: result = None self.signals.result_ready.emit(result) @@ -542,7 +543,8 @@ def get_raw_save_path(game: Game): def get_default_platform(app_name): - if platform.system() != "Darwin" or app_name not in shared.api_results.mac_games: + api_results = ApiResultsSingleton() + if platform.system() != "Darwin" or app_name not in api_results.mac_games: return "Windows" else: return "Mac"