1
0
Fork 0
mirror of synced 2024-06-26 18:20:50 +12:00

Move Ubisoft logic to external class

This commit is contained in:
Dummerle 2021-12-13 20:53:21 +01:00
parent e2fe157e13
commit cc95d231b6
No known key found for this signature in database
GPG key ID: AB68CC59CA39F2F1
2 changed files with 177 additions and 163 deletions

View file

@ -1,15 +1,11 @@
import re
import webbrowser
from logging import getLogger
from typing import Tuple
from PyQt5.QtCore import QThreadPool, QRunnable, QObject, pyqtSignal, QSize
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox, QLabel, QPushButton, QHBoxLayout
from qtawesome import icon
from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox
import rare.shared as shared
from legendary.models.game import Game
from rare.components.tabs.settings.ubisoft_activation import UbiActivationHelper
from rare.ui.components.tabs.settings.legendary import Ui_LegendarySettings
from rare.utils.extra_widgets import PathEdit, IndicatorLineEdit
from rare.utils.utils import get_size
@ -17,102 +13,6 @@ from rare.utils.utils import get_size
logger = getLogger("LegendarySettings")
class Signals(QObject):
worker_finished = pyqtSignal(set, set, str)
connected = pyqtSignal(str)
class UbiGetInfoWorker(QRunnable):
def __init__(self):
super(UbiGetInfoWorker, self).__init__()
self.signals = Signals()
self.setAutoDelete(True)
def run(self) -> None:
try:
external_auths = shared.core.egs.get_external_auths()
for ext_auth in external_auths:
if ext_auth['type'] != 'ubisoft':
continue
ubi_account_id = ext_auth['externalAuthId']
break
else:
self.signals.worker_finished.emit(set(), set(), "")
return
uplay_keys = shared.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 = {i['entitlementName'] for i in entitlements}
self.signals.worker_finished.emit(redeemed, entitlements, ubi_account_id)
except Exception as e:
logger.error(str(e))
self.signals.worker_finished.emit(set(), set(), "error")
class UbiConnectWorker(QRunnable):
def __init__(self, ubi_account_id, partner_link_id):
super(UbiConnectWorker, self).__init__()
self.signals = Signals()
self.setAutoDelete(True)
self.ubi_account_id = ubi_account_id
self.partner_link_id = partner_link_id
def run(self) -> None:
try:
shared.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)
except Exception as e:
self.signals.connected.emit(str(e))
return
else:
self.signals.connected.emit("")
class UbiLinkWidget(QWidget):
def __init__(self, game: Game, ubi_account_id):
super(UbiLinkWidget, self).__init__()
self.setLayout(QHBoxLayout())
self.game = game
self.ubi_account_id = ubi_account_id
self.ok_indicator = QLabel()
self.ok_indicator.setVisible(False)
self.ok_indicator.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
self.layout().addWidget(self.ok_indicator)
self.title_label = QLabel(game.app_title)
self.layout().addWidget(self.title_label)
if not shared.args.debug:
self.link_button = QPushButton(self.tr("Redeem to Ubisoft"))
self.layout().addWidget(self.link_button)
self.link_button.clicked.connect(self.activate)
else:
btn = QPushButton(self.tr("Test: error"))
self.layout().addWidget(btn)
btn.clicked.connect(lambda: self.worker_finished("Any Error"))
ok_button = QPushButton(self.tr("Test: Ok"))
self.layout().addWidget(ok_button)
ok_button.clicked.connect(lambda: self.worker_finished(""))
def activate(self):
if shared.args.debug:
self.worker_finished("Connection Error")
return
worker = UbiConnectWorker(self.ubi_account_id, self.game.partner_link_id)
worker.signals.worker_finished.connect(self.worker_finished)
QThreadPool.globalInstance().start(worker)
def worker_finished(self, error):
self.ok_indicator.setVisible(True)
if not error:
self.ok_indicator.setPixmap(icon("ei.ok-circle", color="green").pixmap(QSize(20, 20)))
else:
self.ok_indicator.setPixmap(icon("fa.info-circle", color="red").pixmap(QSize(20, 20)))
self.ok_indicator.setToolTip(error)
class LegendarySettings(QWidget, Ui_LegendarySettings):
def __init__(self, parent=None):
super(LegendarySettings, self).__init__(parent=parent)
@ -160,66 +60,7 @@ class LegendarySettings(QWidget, Ui_LegendarySettings):
)
self.locale_layout.addWidget(self.locale_edit)
self.thread_pool = QThreadPool.globalInstance()
worker = UbiGetInfoWorker()
worker.signals.worker_finished.connect(self.show_ubi_games)
self.thread_pool.start(worker)
def show_ubi_games(self, redeemed: set, entitlements: set, ubi_account_id: str):
if not redeemed and ubi_account_id != "error":
logger.error('No linked ubisoft account found! Link your accounts via your browser and try again.')
self.ubisoft_gb.layout().addWidget(
QLabel(self.tr("Your account is not linked with Ubisoft. Please link your account first")))
open_browser_button = QPushButton(self.tr("Open link page"))
open_browser_button.clicked.connect(lambda: webbrowser.open("https://www.epicgames.com/id/link/ubisoft"))
self.ubisoft_gb.layout().addWidget(open_browser_button)
return
elif ubi_account_id == "error":
self.ubisoft_gb.layout().addWidget(QLabel(self.tr("An error occurred")))
return
games = self.core.get_game_list(False)
uplay_games = []
activated = 0
for game in games:
for dlc_data in game.metadata.get('dlcItemList', []):
if dlc_data['entitlementName'] not in entitlements:
continue
try:
app_name = dlc_data['releaseInfo'][0]['appId']
except (IndexError, KeyError):
app_name = 'unknown'
dlc_game = Game(app_name=app_name, app_title=dlc_data['title'], metadata=dlc_data)
if dlc_game.partner_link_type != 'ubisoft':
continue
if dlc_game.partner_link_id in redeemed:
continue
uplay_games.append(dlc_game)
if game.partner_link_type != "ubisoft":
continue
if game.partner_link_id in redeemed:
activated += 1
continue
uplay_games.append(game)
if not uplay_games:
if activated >= 1:
self.ubisoft_gb.layout().addWidget(QLabel(self.tr("All your Ubisoft games have already been activated")))
else:
self.ubisoft_gb.layout().addWidget(QLabel(self.tr("You don't own any Ubisoft games")))
if shared.args.debug:
widget = UbiLinkWidget(Game(app_name="Test", app_title="Test Game"), ubi_account_id)
self.ubisoft_gb.layout().addWidget(widget)
return
logger.info(f'Found {len(uplay_games)} game(s) to redeem')
for game in uplay_games:
widget = UbiLinkWidget(game, ubi_account_id)
self.ubisoft_gb.layout().addWidget(widget)
self.ubi_helper = UbiActivationHelper(self.ubisoft_gb)
@staticmethod
def locale_edit_cb(text: str) -> Tuple[bool, str]:
@ -273,7 +114,7 @@ class LegendarySettings(QWidget, Ui_LegendarySettings):
self.core.lgd.config.set("Legendary", "disable_https", str(bool(checked)).lower())
self.core.lgd.save_config()
def cleanup(self, keep_manifests):
def cleanup(self, keep_manifests: bool):
before = self.core.lgd.get_dir_size()
logger.debug('Removing app metadata...')
app_names = set(g.app_name for g in self.core.get_assets(update_assets=False))

View file

@ -0,0 +1,173 @@
import webbrowser
from logging import getLogger
from PyQt5.QtCore import QObject, pyqtSignal, QRunnable, QThreadPool, QSize
from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QSizePolicy, QPushButton
from qtawesome import icon
from legendary.models.game import Game
from rare import shared
logger = getLogger("Ubisoft")
class Signals(QObject):
worker_finished = pyqtSignal(set, set, str)
connected = pyqtSignal(str)
class UbiGetInfoWorker(QRunnable):
def __init__(self):
super(UbiGetInfoWorker, self).__init__()
self.signals = Signals()
self.setAutoDelete(True)
def run(self) -> None:
try:
external_auths = shared.core.egs.get_external_auths()
for ext_auth in external_auths:
if ext_auth['type'] != 'ubisoft':
continue
ubi_account_id = ext_auth['externalAuthId']
break
else:
self.signals.worker_finished.emit(set(), set(), "")
return
uplay_keys = shared.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 = {i['entitlementName'] for i in entitlements}
self.signals.worker_finished.emit(redeemed, entitlements, ubi_account_id)
except Exception as e:
logger.error(str(e))
self.signals.worker_finished.emit(set(), set(), "error")
class UbiConnectWorker(QRunnable):
def __init__(self, ubi_account_id, partner_link_id):
super(UbiConnectWorker, self).__init__()
self.signals = Signals()
self.setAutoDelete(True)
self.ubi_account_id = ubi_account_id
self.partner_link_id = partner_link_id
def run(self) -> None:
try:
shared.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)
except Exception as e:
self.signals.connected.emit(str(e))
return
else:
self.signals.connected.emit("")
class UbiLinkWidget(QWidget):
def __init__(self, game: Game, ubi_account_id):
super(UbiLinkWidget, self).__init__()
self.setLayout(QHBoxLayout())
self.game = game
self.ubi_account_id = ubi_account_id
self.ok_indicator = QLabel()
self.ok_indicator.setVisible(False)
self.ok_indicator.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
self.layout().addWidget(self.ok_indicator)
self.title_label = QLabel(game.app_title)
self.layout().addWidget(self.title_label)
if not shared.args.debug:
self.link_button = QPushButton(self.tr("Redeem to Ubisoft"))
self.layout().addWidget(self.link_button)
self.link_button.clicked.connect(self.activate)
else:
btn = QPushButton("Redeem to ubisoft: Test")
self.layout().addWidget(btn)
btn.clicked.connect(lambda: self.worker_finished("Any Error"))
def activate(self):
if shared.args.debug:
self.worker_finished("Connection Error")
return
worker = UbiConnectWorker(self.ubi_account_id, self.game.partner_link_id)
worker.signals.worker_finished.connect(self.worker_finished)
QThreadPool.globalInstance().start(worker)
def worker_finished(self, error):
self.ok_indicator.setVisible(True)
if not error:
self.ok_indicator.setPixmap(icon("ei.ok-circle", color="green").pixmap(QSize(20, 20)))
else:
self.ok_indicator.setPixmap(icon("fa.info-circle", color="red").pixmap(QSize(20, 20)))
self.ok_indicator.setToolTip(error)
class UbiActivationHelper(QObject):
def __init__(self, widget: QWidget):
super(UbiActivationHelper, self).__init__()
self.widget = widget
self.core = shared.core
self.thread_pool = QThreadPool.globalInstance()
worker = UbiGetInfoWorker()
worker.signals.worker_finished.connect(self.show_ubi_games)
self.thread_pool.start(worker)
def show_ubi_games(self, redeemed: set, entitlements: set, ubi_account_id: str):
if not redeemed and ubi_account_id != "error":
logger.error('No linked ubisoft account found! Link your accounts via your browser and try again.')
self.widget.layout().addWidget(
QLabel(self.tr("Your account is not linked with Ubisoft. Please link your account first")))
open_browser_button = QPushButton(self.tr("Open link page"))
open_browser_button.clicked.connect(lambda: webbrowser.open("https://www.epicgames.com/id/link/ubisoft"))
self.widget.layout().addWidget(open_browser_button)
return
elif ubi_account_id == "error":
self.widget.layout().addWidget(QLabel(self.tr("An error occurred")))
return
games = self.core.get_game_list(False)
uplay_games = []
activated = 0
for game in games:
for dlc_data in game.metadata.get('dlcItemList', []):
if dlc_data['entitlementName'] not in entitlements:
continue
try:
app_name = dlc_data['releaseInfo'][0]['appId']
except (IndexError, KeyError):
app_name = 'unknown'
dlc_game = Game(app_name=app_name, app_title=dlc_data['title'], metadata=dlc_data)
if dlc_game.partner_link_type != 'ubisoft':
continue
if dlc_game.partner_link_id in redeemed:
continue
uplay_games.append(dlc_game)
if game.partner_link_type != "ubisoft":
continue
if game.partner_link_id in redeemed:
activated += 1
continue
uplay_games.append(game)
if not uplay_games:
if activated >= 1:
self.widget.layout().addWidget(
QLabel(self.tr("All your Ubisoft games have already been activated")))
else:
self.widget.layout().addWidget(QLabel(self.tr("You don't own any Ubisoft games")))
if shared.args.debug:
widget = UbiLinkWidget(Game(app_name="Test", app_title="This is a test game"), ubi_account_id)
self.widget.layout().addWidget(widget)
return
logger.info(f'Found {len(uplay_games)} game(s) to redeem')
for game in uplay_games:
widget = UbiLinkWidget(game, ubi_account_id)
self.widget.layout().addWidget(widget)