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"