Move api requests to login dialog
This commit is contained in:
parent
0324202d9f
commit
df7964a79f
|
@ -124,9 +124,10 @@ class App(QApplication):
|
|||
if not args.silent or args.subparser == "launch":
|
||||
self.launch_dialog.login()
|
||||
|
||||
def start_app(self, offline=False):
|
||||
def start_app(self, offline=False, api_results=None):
|
||||
self.args.offline = offline
|
||||
self.mainwindow = MainWindow(self.core, self.args, self.signals)
|
||||
self.mainwindow = MainWindow(self.core, self.args, self.signals, api_results)
|
||||
self.launch_dialog.close()
|
||||
self.tray_icon = TrayIcon(self)
|
||||
self.tray_icon.exit_action.triggered.connect(self.exit_app)
|
||||
self.tray_icon.start_rare.triggered.connect(self.mainwindow.show)
|
||||
|
|
|
@ -1,34 +1,57 @@
|
|||
import os
|
||||
from logging import getLogger
|
||||
|
||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, QRunnable, QObject, QThreadPool
|
||||
from PyQt5.QtWidgets import QDialog
|
||||
from requests.exceptions import ConnectionError
|
||||
|
||||
from legendary.core import LegendaryCore
|
||||
from legendary.models.game import GameAsset
|
||||
from rare import image_dir
|
||||
from rare.components.dialogs.login import LoginDialog
|
||||
from rare.ui.components.dialogs.launch_dialog import Ui_LaunchDialog
|
||||
from rare.utils.models import ApiResults
|
||||
from rare.utils.utils import download_images
|
||||
|
||||
logger = getLogger("Login")
|
||||
|
||||
|
||||
class ImageThread(QThread):
|
||||
download_progess = pyqtSignal(int)
|
||||
class ApiSignals(QObject):
|
||||
image_progress = pyqtSignal(int)
|
||||
result = pyqtSignal(object, str)
|
||||
|
||||
def __init__(self, core: LegendaryCore, parent=None):
|
||||
super(ImageThread, self).__init__(parent)
|
||||
|
||||
class ImageWorker(QRunnable):
|
||||
download_progress = pyqtSignal(int)
|
||||
|
||||
def __init__(self, core: LegendaryCore):
|
||||
super(ImageWorker, self).__init__()
|
||||
self.core = core
|
||||
self.signal = ApiSignals()
|
||||
self.setAutoDelete(True)
|
||||
|
||||
def run(self):
|
||||
download_images(self.download_progess, self.core)
|
||||
self.download_progess.emit(100)
|
||||
download_images(self.signal.image_progress, self.core)
|
||||
self.signal.image_progress.emit(100)
|
||||
|
||||
|
||||
class ApiRequestWorker(QRunnable):
|
||||
def __init__(self, text: str, function: callable, args: tuple):
|
||||
super(ApiRequestWorker, self).__init__()
|
||||
self.function, self.args = function, args
|
||||
self.signals = ApiSignals()
|
||||
self.text = text
|
||||
self.setAutoDelete(True)
|
||||
|
||||
def run(self) -> None:
|
||||
result = self.function(*self.args)
|
||||
self.signals.result.emit(result, self.text)
|
||||
|
||||
|
||||
class LaunchDialog(QDialog, Ui_LaunchDialog):
|
||||
quit_app = pyqtSignal(int)
|
||||
start_app = pyqtSignal(bool)
|
||||
start_app = pyqtSignal(bool, ApiResults)
|
||||
finished = False
|
||||
|
||||
def __init__(self, core: LegendaryCore, offline=False, parent=None):
|
||||
super(LaunchDialog, self).__init__(parent=parent)
|
||||
|
@ -36,7 +59,8 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
|
|||
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
||||
self.core = core
|
||||
self.offline = offline
|
||||
self.image_thread = None
|
||||
self.thread_pool = QThreadPool()
|
||||
self.api_results = ApiResults()
|
||||
|
||||
def login(self):
|
||||
do_launch = True
|
||||
|
@ -68,20 +92,54 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
|
|||
|
||||
if not self.offline:
|
||||
self.image_info.setText(self.tr("Downloading Images"))
|
||||
self.image_thread = ImageThread(self.core, self)
|
||||
self.image_thread.download_progess.connect(self.update_image_progbar)
|
||||
self.image_thread.finished.connect(self.finish)
|
||||
self.image_thread.finished.connect(lambda: self.image_info.setText(self.tr("Ready")))
|
||||
self.image_thread.finished.connect(self.image_thread.quit)
|
||||
self.image_thread.finished.connect(self.image_thread.deleteLater)
|
||||
self.image_thread.start()
|
||||
image_worker = ImageWorker(self.core)
|
||||
image_worker.signal.image_progress.connect(self.update_image_progbar)
|
||||
self.thread_pool.start(image_worker)
|
||||
|
||||
api_requests = [
|
||||
["gamelist", self.core.get_game_and_dlc_list, (True,)],
|
||||
["32bit", self.core.get_game_and_dlc_list, (True, "Win32")],
|
||||
["mac", self.core.get_game_and_dlc_list, (True, "Mac")],
|
||||
["assets", self.core.egs.get_game_assets, ()],
|
||||
["no_assets", self.core.get_non_asset_library_items, ()]
|
||||
]
|
||||
for r in api_requests:
|
||||
worker = ApiRequestWorker(*r)
|
||||
worker.signals.result.connect(self.handle_api_worker_result)
|
||||
self.thread_pool.start(worker)
|
||||
|
||||
else:
|
||||
self.finished = True
|
||||
self.api_results.game_list, self.api_results.dlcs = self.core.get_game_and_dlc_list(False)
|
||||
self.finish()
|
||||
|
||||
def handle_api_worker_result(self, result, text):
|
||||
logger.debug("Api Request got from " + text)
|
||||
if text == "gamelist":
|
||||
self.api_results.game_list, self.api_results.dlcs = result
|
||||
elif text == "32bit":
|
||||
self.api_results.bit32_games = [i.app_name for i in result[0]]
|
||||
elif text == "mac":
|
||||
self.api_results.mac_games = [i.app_name for i in result[0]]
|
||||
elif text == "assets":
|
||||
assets = [GameAsset.from_egs_json(a) for a in result]
|
||||
self.core.lgd.assets = assets
|
||||
self.api_results.assets = assets
|
||||
elif text == "no_assets":
|
||||
self.api_results.no_asset_games = result[0]
|
||||
|
||||
if self.api_results:
|
||||
self.finish()
|
||||
|
||||
def update_image_progbar(self, i: int):
|
||||
self.image_prog_bar.setValue(i)
|
||||
if i == 100:
|
||||
self.finish()
|
||||
|
||||
def finish(self):
|
||||
self.image_info.setText(self.tr("Starting..."))
|
||||
self.image_prog_bar.setValue(100)
|
||||
self.start_app.emit(self.offline)
|
||||
if self.finished:
|
||||
logger.info("App starting")
|
||||
self.image_info.setText(self.tr("Starting..."))
|
||||
self.start_app.emit(self.offline, self.api_results)
|
||||
else:
|
||||
self.finished = True
|
||||
|
|
|
@ -16,7 +16,7 @@ logger = getLogger("Window")
|
|||
|
||||
class MainWindow(QMainWindow):
|
||||
|
||||
def __init__(self, core: LegendaryCore, args, signals: Signals):
|
||||
def __init__(self, core: LegendaryCore, args, signals: Signals, api_results):
|
||||
super(MainWindow, self).__init__()
|
||||
self.setAttribute(Qt.WA_DeleteOnClose)
|
||||
self.settings = QSettings()
|
||||
|
@ -34,7 +34,7 @@ class MainWindow(QMainWindow):
|
|||
self.setGeometry((desktop.width() - width) / 2, (desktop.height() - height) / 2, width, height)
|
||||
|
||||
self.setWindowTitle("Rare - GUI for legendary")
|
||||
self.tab_widget = TabWidget(core, self.signals, self, args)
|
||||
self.tab_widget = TabWidget(core, self.signals, self, args, api_results)
|
||||
self.setCentralWidget(self.tab_widget)
|
||||
if not args.offline:
|
||||
self.rpc = DiscordRPC(core)
|
||||
|
|
|
@ -4,7 +4,6 @@ from PyQt5.QtCore import pyqtSignal, QSettings
|
|||
from PyQt5.QtWidgets import QStackedWidget, QVBoxLayout, QWidget
|
||||
|
||||
from legendary.core import LegendaryCore
|
||||
from legendary.models.game import GameAsset
|
||||
from rare.components.dialogs.uninstall_dialog import UninstallDialog
|
||||
from rare.components.tabs.games.game_info import InfoTabs
|
||||
from rare.components.tabs.games.game_info.uninstalled_info import UninstalledTabInfo
|
||||
|
@ -20,7 +19,7 @@ from rare.components.tabs.games.import_widget import ImportWidget
|
|||
from rare.ui.components.tabs.games.games_tab import Ui_GamesTab
|
||||
from rare.utils import legendary_utils
|
||||
from rare.utils.extra_widgets import FlowLayout
|
||||
from rare.utils.models import Signals
|
||||
from rare.utils.models import Signals, ApiResults
|
||||
from rare.utils.utils import get_pixmap, download_image, get_uninstalled_pixmap
|
||||
|
||||
logger = getLogger("GamesTab")
|
||||
|
@ -33,7 +32,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
game_exited = pyqtSignal(str)
|
||||
game_started = pyqtSignal(str)
|
||||
|
||||
def __init__(self, core: LegendaryCore, offline, signals: Signals):
|
||||
def __init__(self, core: LegendaryCore, offline, signals: Signals, api_results: ApiResults):
|
||||
super(GamesTab, self).__init__()
|
||||
self.setupUi(self)
|
||||
self.core = core
|
||||
|
@ -51,7 +50,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.import_widget = ImportWidget(core, self)
|
||||
self.addWidget(self.import_widget)
|
||||
|
||||
self.uninstalled_info_widget = UninstalledTabInfo(core, self.signals, self)
|
||||
self.uninstalled_info_widget = UninstalledTabInfo(core, self.signals, self.offline, self)
|
||||
self.layout().addWidget(self.uninstalled_info_widget)
|
||||
|
||||
# navigation
|
||||
|
@ -59,6 +58,18 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.import_widget.back_button.clicked.connect(lambda: self.setCurrentIndex(0))
|
||||
self.uninstalled_info_widget.tabBarClicked.connect(lambda x: self.setCurrentIndex(0) if x == 0 else None)
|
||||
|
||||
self.game_list = api_results.game_list
|
||||
self.dlcs = api_results.dlcs
|
||||
self.bit32 = api_results.bit32_games
|
||||
self.mac_games = api_results.mac_games
|
||||
self.no_assets = api_results.no_asset_games
|
||||
self.no_asset_names = []
|
||||
if not self.offline:
|
||||
for game in self.no_assets:
|
||||
self.no_asset_names.append(game.app_name)
|
||||
else:
|
||||
self.no_assets = []
|
||||
|
||||
self.setup_game_list()
|
||||
|
||||
if not self.settings.value("icon_view", True, bool):
|
||||
|
@ -108,26 +119,8 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.list_view = QWidget()
|
||||
self.list_view.setLayout(QVBoxLayout())
|
||||
|
||||
# TODO move to seperate thread
|
||||
if not self.offline:
|
||||
self.game_list, self.dlcs = self.core.get_game_and_dlc_list(True)
|
||||
self.bit32 = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Win32")[0]]
|
||||
self.mac_games = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Mac")[0]]
|
||||
self.core.lgd.assets = [GameAsset.from_egs_json(a) for a in self.core.egs.get_game_assets()]
|
||||
no_assets = self.core.get_non_asset_library_items()[0]
|
||||
self.no_assets = []
|
||||
for game in no_assets:
|
||||
self.no_assets.append(game)
|
||||
self.no_asset_names = []
|
||||
for game in self.no_assets:
|
||||
self.no_asset_names.append(game.app_name)
|
||||
else:
|
||||
self.bit32 = []
|
||||
self.mac_games = []
|
||||
self.dlcs = []
|
||||
|
||||
self.installed = sorted(self.core.get_installed_list(), key=lambda x: x.title)
|
||||
|
||||
installed_names = [i.app_name for i in self.installed]
|
||||
self.update_count_games_label()
|
||||
|
||||
# add installing game widget for icon view: List view not supported
|
||||
|
@ -146,15 +139,10 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.icon_view.layout().addWidget(icon_widget)
|
||||
self.list_view.layout().addWidget(list_widget)
|
||||
|
||||
if not self.offline:
|
||||
self.uninstalled_games = []
|
||||
installed = [i.app_name for i in self.core.get_installed_list()]
|
||||
# get Uninstalled games
|
||||
for game in self.game_list:
|
||||
if game.app_name not in installed:
|
||||
self.uninstalled_games.append(game)
|
||||
|
||||
for game in sorted(self.uninstalled_games, key=lambda x: x.app_title):
|
||||
self.uninstalled_games = []
|
||||
for game in sorted(self.game_list, key=lambda x: x.app_title):
|
||||
if game.app_name not in [i.app_name for i in self.installed]:
|
||||
self.uninstalled_games.append(game)
|
||||
icon_widget, list_widget = self.add_uninstalled_widget(game)
|
||||
self.icon_view.layout().addWidget(icon_widget)
|
||||
self.list_view.layout().addWidget(list_widget)
|
||||
|
@ -386,7 +374,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
# add uninstalled games
|
||||
for game in sorted(games, key=lambda x: x.app_title):
|
||||
if game.app_name not in installed_names:
|
||||
self.uninstalled_names.append(game)
|
||||
self.uninstalled_names.append(game.app_name)
|
||||
for game in self.uninstalled_names:
|
||||
i_widget, list_widget = self.widgets[game.app_name]
|
||||
icon_layout.addWidget(i_widget)
|
||||
|
@ -394,8 +382,8 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
|
||||
QWidget().setLayout(self.icon_view.layout())
|
||||
QWidget().setLayout(self.list_view.layout())
|
||||
#self.icon_view.layout().deleteLater()
|
||||
#self.list_view.layout().deleteLater()
|
||||
# self.icon_view.layout().deleteLater()
|
||||
# self.list_view.layout().deleteLater()
|
||||
|
||||
self.icon_view.setLayout(icon_layout)
|
||||
self.list_view.setLayout(list_layout)
|
||||
|
@ -404,7 +392,8 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.list_view.setParent(None)
|
||||
|
||||
# insert widget in layout
|
||||
self.scroll_widget.layout().insertWidget(1, self.icon_view if self.head_bar.view.isChecked() else self.list_view)
|
||||
self.scroll_widget.layout().insertWidget(1,
|
||||
self.icon_view if self.head_bar.view.isChecked() else self.list_view)
|
||||
|
||||
def toggle_view(self):
|
||||
self.settings.setValue("icon_view", not self.head_bar.view.isChecked())
|
||||
|
|
|
@ -16,7 +16,7 @@ from rare.utils.utils import get_pixmap
|
|||
|
||||
|
||||
class UninstalledTabInfo(QTabWidget):
|
||||
def __init__(self, core, signals: Signals, parent):
|
||||
def __init__(self, core, signals: Signals, offline, parent):
|
||||
super(UninstalledTabInfo, self).__init__(parent=parent)
|
||||
self.app_name = ""
|
||||
self.core = core
|
||||
|
@ -26,6 +26,7 @@ class UninstalledTabInfo(QTabWidget):
|
|||
|
||||
self.addTab(QWidget(), icon("mdi.keyboard-backspace"), self.tr("Back"))
|
||||
self.info = UninstalledInfo(core, self.signals, self)
|
||||
self.info.install_button.setDisabled(offline)
|
||||
self.addTab(self.info, self.tr("Game Info"))
|
||||
|
||||
self.view = QTreeView()
|
||||
|
|
|
@ -17,18 +17,18 @@ from rare.utils.models import InstallOptionsModel, Signals
|
|||
class TabWidget(QTabWidget):
|
||||
delete_presence = pyqtSignal()
|
||||
|
||||
def __init__(self, core: LegendaryCore, signals: Signals, parent, args):
|
||||
def __init__(self, core: LegendaryCore, signals: Signals, parent, args, api_results):
|
||||
super(TabWidget, self).__init__(parent=parent)
|
||||
offline = args.offline
|
||||
disabled_tab = 4 if not offline else 1
|
||||
self.offline = args.offline
|
||||
disabled_tab = 4 if not self.offline else 1
|
||||
self.core = core
|
||||
self.signals = signals
|
||||
self.setTabBar(TabBar(disabled_tab))
|
||||
# Generate Tabs
|
||||
self.games_tab = GamesTab(core, args.offline, self.signals)
|
||||
self.games_tab = GamesTab(core, args.offline, self.signals, api_results)
|
||||
self.addTab(self.games_tab, self.tr("Games"))
|
||||
self.signals.tab_widget.connect(lambda x: self.handle_signal(*x))
|
||||
if not offline:
|
||||
if not self.offline:
|
||||
# updates = self.games_tab.default_widget.game_list.updates
|
||||
self.downloadTab = DownloadTab(core, [], self.signals)
|
||||
self.addTab(self.downloadTab, "Downloads" + (" (" + str(len([])) + ")" if len([]) != 0 else ""))
|
||||
|
@ -64,7 +64,7 @@ class TabWidget(QTabWidget):
|
|||
# imported
|
||||
self.games_tab.import_widget.update_list.connect(self.game_imported)
|
||||
|
||||
if not offline:
|
||||
if not self.offline:
|
||||
# install dlc
|
||||
self.games_tab.game_info.dlc.install_dlc.connect(
|
||||
lambda app_name, update: self.install_game(
|
||||
|
@ -95,7 +95,8 @@ class TabWidget(QTabWidget):
|
|||
def mouse_clicked(self, tab_num):
|
||||
if tab_num == 0:
|
||||
self.games_tab.layout().setCurrentIndex(0)
|
||||
if tab_num == 3:
|
||||
|
||||
if not self.offline and tab_num == 3:
|
||||
self.store.load()
|
||||
|
||||
def game_imported(self, app_name: str):
|
||||
|
@ -114,7 +115,6 @@ class TabWidget(QTabWidget):
|
|||
if game and game.supports_cloud_saves:
|
||||
self.cloud_saves.sync_game(app_name, True)
|
||||
|
||||
|
||||
def resizeEvent(self, event):
|
||||
self.tabBar().setMinimumWidth(self.width())
|
||||
super(TabWidget, self).resizeEvent(event)
|
||||
|
|
|
@ -64,3 +64,21 @@ class Signals(QObject):
|
|||
dl_tab = pyqtSignal(tuple)
|
||||
main_window = pyqtSignal(tuple)
|
||||
app = pyqtSignal(tuple)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ApiResults:
|
||||
game_list: list = None
|
||||
dlcs: list = None
|
||||
bit32_games: list = None
|
||||
mac_games: list = None
|
||||
assets: list = None
|
||||
no_asset_games: list = None
|
||||
|
||||
def __bool__(self):
|
||||
return self.game_list is not None \
|
||||
and self.dlcs is not None \
|
||||
and self.bit32_games is not None \
|
||||
and self.mac_games is not None \
|
||||
and self.assets is not None \
|
||||
and self.no_asset_games is not None
|
||||
|
|
Loading…
Reference in a new issue