1
0
Fork 0
mirror of synced 2024-05-26 23:40:05 +12:00
Rare/rare/components/tabs/games/integrations/ubisoft_group.py

221 lines
8 KiB
Python

import time
import webbrowser
from logging import getLogger
from PyQt5.QtCore import QObject, pyqtSignal, QRunnable, QThreadPool, QSize
from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QSizePolicy, QPushButton, QGroupBox, QVBoxLayout
from legendary.models.game import Game
from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton
from rare.utils.misc import icon
logger = getLogger("Ubisoft")
class UbiGetInfoSignals(QObject):
worker_finished = pyqtSignal(set, set, str)
class UbiGetInfoWorker(QRunnable):
def __init__(self):
super(UbiGetInfoWorker, self).__init__()
self.signals = UbiGetInfoSignals()
self.setAutoDelete(True)
self.core = LegendaryCoreSingleton()
def run(self) -> None:
try:
external_auths = self.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 = 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 = 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:
logger.error(str(e))
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 = UbiConnectSignals()
self.setAutoDelete(True)
self.core = LegendaryCoreSingleton()
self.ubi_account_id = ubi_account_id
self.partner_link_id = partner_link_id
def run(self) -> None:
if not self.ubi_account_id: # debug
time.sleep(2)
self.signals.linked.emit("")
return
try:
self.core.egs.store_claim_uplay_code(
self.ubi_account_id, self.partner_link_id
)
self.core.egs.store_redeem_uplay_codes(self.ubi_account_id)
except Exception as e:
self.signals.linked.emit(str(e))
return
else:
self.signals.linked.emit("")
class UbiLinkWidget(QWidget):
def __init__(self, game: Game, ubi_account_id):
super(UbiLinkWidget, self).__init__()
self.args = ArgumentsSingleton()
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
self.game = game
self.ubi_account_id = ubi_account_id
self.title_label = QLabel(game.app_title)
layout.addWidget(self.title_label, stretch=1)
self.ok_indicator = QLabel()
self.ok_indicator.setPixmap(icon("fa.info-circle", color="grey").pixmap(20, 20))
self.ok_indicator.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
layout.addWidget(self.ok_indicator)
self.link_button = QPushButton(
self.tr("Redeem to Ubisoft") + ": Test" if self.args.debug else ""
)
layout.addWidget(self.link_button)
self.link_button.clicked.connect(self.activate)
self.setLayout(layout)
def activate(self):
self.link_button.setDisabled(True)
# self.ok_indicator.setPixmap(icon("mdi.loading", color="grey").pixmap(20, 20))
self.ok_indicator.setPixmap(
icon("mdi.transit-connection-horizontal", color="grey").pixmap(20, 20)
)
if self.args.debug:
worker = UbiConnectWorker(None, None)
else:
worker = UbiConnectWorker(self.ubi_account_id, self.game.partner_link_id)
worker.signals.linked.connect(self.worker_finished)
QThreadPool.globalInstance().start(worker)
def worker_finished(self, error):
if not error:
self.ok_indicator.setPixmap(
icon("ei.ok-circle", color="green").pixmap(QSize(20, 20))
)
self.link_button.setDisabled(True)
self.link_button.setText(self.tr("Already activated"))
else:
self.ok_indicator.setPixmap(
icon("fa.info-circle", color="red").pixmap(QSize(20, 20))
)
self.ok_indicator.setToolTip(error)
self.link_button.setText(self.tr("Try again"))
self.link_button.setDisabled(False)
class UbisoftGroup(QGroupBox):
def __init__(self, parent=None):
super(UbisoftGroup, self).__init__(parent=parent)
self.setTitle(self.tr("Link Ubisoft Games"))
self.setLayout(QVBoxLayout())
self.core = LegendaryCoreSingleton()
self.args = ArgumentsSingleton()
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.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.layout().addWidget(open_browser_button)
return
elif ubi_account_id == "error":
self.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.layout().addWidget(
QLabel(
self.tr("All your Ubisoft games have already been activated")
)
)
else:
self.layout().addWidget(
QLabel(self.tr("You don't own any Ubisoft games"))
)
if self.args.debug:
widget = UbiLinkWidget(
Game(app_name="Test", app_title="This is a test game"),
ubi_account_id,
)
self.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.layout().addWidget(widget)