1
0
Fork 0
mirror of synced 2024-07-02 21:20:54 +12:00
Rare/rare/components/tabs/games/integrations/ubisoft_group.py

273 lines
11 KiB
Python
Raw Normal View History

2021-12-14 09:57:21 +13:00
import time
2021-12-14 08:53:21 +13:00
import webbrowser
from logging import getLogger
from typing import Optional
2021-12-14 08:53:21 +13:00
from PyQt5.QtCore import QObject, pyqtSignal, QThreadPool, QSize, pyqtSlot, Qt
from PyQt5.QtGui import QShowEvent
from PyQt5.QtWidgets import (
QFrame,
QLabel,
QHBoxLayout,
QSizePolicy,
QPushButton,
QGroupBox,
QVBoxLayout,
)
2021-12-14 08:53:21 +13:00
from legendary.models.game import Game
from rare.lgndr.core import LegendaryCore
from rare.shared import RareCore
from rare.shared.workers.worker import Worker
from rare.utils.metrics import timelogger
from rare.utils.misc import qta_icon
from rare.widgets.elide_label import ElideLabel
from rare.widgets.loading_widget import LoadingWidget
2021-12-14 08:53:21 +13:00
logger = getLogger("Ubisoft")
class UbiGetInfoWorker(Worker):
class Signals(QObject):
worker_finished = pyqtSignal(set, set, str)
2021-12-14 08:53:21 +13:00
def __init__(self, core: LegendaryCore):
2021-12-14 08:53:21 +13:00
super(UbiGetInfoWorker, self).__init__()
self.signals = UbiGetInfoWorker.Signals()
2021-12-14 08:53:21 +13:00
self.setAutoDelete(True)
self.core = core
2021-12-14 08:53:21 +13:00
def run_real(self) -> None:
2021-12-14 08:53:21 +13:00
try:
with timelogger(logger, "Request external auths"):
external_auths = self.core.egs.get_external_auths()
2021-12-14 08:53:21 +13:00
for ext_auth in external_auths:
2021-12-24 22:09:50 +13:00
if ext_auth["type"] != "ubisoft":
2021-12-14 08:53:21 +13:00
continue
2021-12-24 22:09:50 +13:00
ubi_account_id = ext_auth["externalAuthId"]
2021-12-14 08:53:21 +13:00
break
else:
self.signals.worker_finished.emit(set(), set(), "")
return
with timelogger(logger, "Request uplay codes"):
uplay_keys = self.core.egs.store_get_uplay_codes()
2021-12-24 22:09:50 +13:00
key_list = uplay_keys["data"]["PartnerIntegration"]["accountUplayCodes"]
redeemed = {k["gameId"] for k in key_list if k["redeemedOnUplay"]}
2021-12-14 08:53:21 +13:00
if (entitlements := self.core.lgd.entitlements) is None:
with timelogger(logger, "Request entitlements"):
entitlements = self.core.egs.get_user_entitlements()
self.core.lgd.entitlements = entitlements
2021-12-24 22:09:50 +13:00
entitlements = {i["entitlementName"] for i in entitlements}
2021-12-14 08:53:21 +13:00
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(Worker):
class Signals(QObject):
linked = pyqtSignal(str)
def __init__(self, core: LegendaryCore, ubi_account_id, partner_link_id):
2021-12-14 08:53:21 +13:00
super(UbiConnectWorker, self).__init__()
self.signals = UbiConnectWorker.Signals()
self.core = core
2021-12-14 08:53:21 +13:00
self.ubi_account_id = ubi_account_id
self.partner_link_id = partner_link_id
def run_real(self) -> None:
2021-12-14 09:57:21 +13:00
if not self.ubi_account_id: # debug
time.sleep(2)
self.signals.linked.emit("")
return
2021-12-14 08:53:21 +13:00
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)
2021-12-14 08:53:21 +13:00
except Exception as e:
2021-12-14 09:57:21 +13:00
self.signals.linked.emit(str(e))
2021-12-14 08:53:21 +13:00
return
else:
2021-12-14 09:57:21 +13:00
self.signals.linked.emit("")
2021-12-14 08:53:21 +13:00
class UbiLinkWidget(QFrame):
def __init__(self, game: Game, ubi_account_id, activated: bool = False, parent=None):
super(UbiLinkWidget, self).__init__(parent=parent)
self.setFrameShape(QFrame.StyledPanel)
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.args = RareCore.instance().args()
2021-12-14 08:53:21 +13:00
self.game = game
self.ubi_account_id = ubi_account_id
self.ok_indicator = QLabel(parent=self)
self.ok_indicator.setPixmap(qta_icon("fa.circle-o", color="grey").pixmap(20, 20))
2021-12-14 08:53:21 +13:00
self.ok_indicator.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
self.title_label = ElideLabel(game.app_title, parent=self)
self.link_button = QPushButton(self.tr("Redeem in Ubisoft"), parent=self)
self.link_button.setMinimumWidth(150)
2021-12-14 09:57:21 +13:00
self.link_button.clicked.connect(self.activate)
if activated:
self.link_button.setText(self.tr("Already activated"))
self.link_button.setDisabled(True)
self.ok_indicator.setPixmap(qta_icon("fa.check-circle-o", color="green").pixmap(QSize(20, 20)))
layout = QHBoxLayout(self)
layout.setContentsMargins(-1, 0, 0, 0)
layout.addWidget(self.ok_indicator)
layout.addWidget(self.title_label, stretch=1)
layout.addWidget(self.link_button)
2021-12-14 08:53:21 +13:00
def activate(self):
2021-12-14 09:57:21 +13:00
self.link_button.setDisabled(True)
# self.ok_indicator.setPixmap(icon("mdi.loading", color="grey").pixmap(20, 20))
self.ok_indicator.setPixmap(qta_icon("mdi.transit-connection-horizontal", color="grey").pixmap(20, 20))
2021-12-14 09:57:21 +13:00
if self.args.debug:
worker = UbiConnectWorker(RareCore.instance().core(), None, None)
2021-12-14 09:57:21 +13:00
else:
worker = UbiConnectWorker(
RareCore.instance().core(), self.ubi_account_id, self.game.partner_link_id
)
2021-12-14 09:57:21 +13:00
worker.signals.linked.connect(self.worker_finished)
2021-12-14 08:53:21 +13:00
QThreadPool.globalInstance().start(worker)
def worker_finished(self, error):
if not error:
self.ok_indicator.setPixmap(qta_icon("fa.check-circle-o", color="green").pixmap(QSize(20, 20)))
2021-12-14 09:57:21 +13:00
self.link_button.setDisabled(True)
self.link_button.setText(self.tr("Already activated"))
2021-12-14 08:53:21 +13:00
else:
self.ok_indicator.setPixmap(qta_icon("fa.times-circle-o", color="red").pixmap(QSize(20, 20)))
2021-12-14 08:53:21 +13:00
self.ok_indicator.setToolTip(error)
2021-12-14 09:57:21 +13:00
self.link_button.setText(self.tr("Try again"))
self.link_button.setDisabled(False)
2021-12-14 08:53:21 +13:00
class UbisoftGroup(QGroupBox):
def __init__(self, parent=None):
super(UbisoftGroup, self).__init__(parent=parent)
self.setTitle(self.tr("Link Ubisoft Games"))
self.rcore = RareCore.instance()
self.core = RareCore.instance().core()
self.args = RareCore.instance().args()
2021-12-14 08:53:21 +13:00
self.thread_pool = QThreadPool.globalInstance()
self.worker: Optional[UbiGetInfoWorker] = None
self.info_label = QLabel(parent=self)
self.info_label.setText(self.tr("Getting information about your redeemable Ubisoft games."))
self.browser_button = QPushButton(self.tr("Link Ubisoft acccount"), parent=self)
self.browser_button.setMinimumWidth(140)
self.browser_button.clicked.connect(
lambda: webbrowser.open("https://www.epicgames.com/id/link/ubisoft")
)
self.browser_button.setEnabled(False)
self.loading_widget = LoadingWidget(self)
self.loading_widget.stop()
header_layout = QHBoxLayout()
header_layout.addWidget(self.info_label, stretch=1)
header_layout.addWidget(self.browser_button)
layout = QVBoxLayout(self)
layout.addLayout(header_layout)
layout.addWidget(self.loading_widget)
def showEvent(self, a0: QShowEvent) -> None:
if a0.spontaneous():
return super().showEvent(a0)
2021-12-14 08:53:21 +13:00
if self.worker is not None:
return
for widget in self.findChildren(UbiLinkWidget, options=Qt.FindDirectChildrenOnly):
widget.deleteLater()
self.loading_widget.start()
self.worker = UbiGetInfoWorker(self.core)
self.worker.signals.worker_finished.connect(self.show_ubi_games)
self.thread_pool.start(self.worker)
super().showEvent(a0)
@pyqtSlot(set, set, str)
2021-12-14 08:53:21 +13:00
def show_ubi_games(self, redeemed: set, entitlements: set, ubi_account_id: str):
self.worker = None
2021-12-14 08:53:21 +13:00
if not redeemed and ubi_account_id != "error":
2021-12-24 22:09:50 +13:00
logger.error(
"No linked ubisoft account found! Link your accounts via your browser and try again."
)
self.info_label.setText(
self.tr("Your account is not linked with Ubisoft. Please link your account and try again.")
2021-12-24 22:09:50 +13:00
)
self.browser_button.setEnabled(True)
2021-12-14 08:53:21 +13:00
elif ubi_account_id == "error":
self.info_label.setText(
self.tr("An error has occurred while requesting your account's Ubisoft information.")
)
self.browser_button.setEnabled(True)
else:
self.browser_button.setEnabled(False)
2021-12-14 08:53:21 +13:00
uplay_games = []
activated = 0
for rgame in self.rcore.ubisoft_games:
game = rgame.game
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"
2021-12-14 08:53:21 +13:00
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)
2021-12-14 08:53:21 +13:00
if game.partner_link_type != "ubisoft":
2021-12-14 08:53:21 +13:00
continue
if game.partner_link_id in redeemed:
activated += 1
uplay_games.append(game)
if not uplay_games:
self.info_label.setText(self.tr("You don't own any Ubisoft games."))
elif activated == len(uplay_games):
self.info_label.setText(self.tr("All your Ubisoft games have already been activated."))
2021-12-14 08:53:21 +13:00
else:
self.info_label.setText(
self.tr("You have <b>{}</b> games available to redeem.").format(
len(uplay_games) - activated
)
)
logger.info(f"Found {len(uplay_games) - activated} game(s) to redeem.")
self.loading_widget.stop()
for game in uplay_games:
widget = UbiLinkWidget(
game, ubi_account_id, activated=game.partner_link_id in redeemed, parent=self
2021-12-24 22:09:50 +13:00
)
self.layout().addWidget(widget)
if self.args.debug:
2021-12-24 22:09:50 +13:00
widget = UbiLinkWidget(
Game(app_name="RareTestGame", app_title="Super Fake Super Rare Super Test (Super?) Game"),
2021-12-24 22:09:50 +13:00
ubi_account_id,
activated=False,
parent=self,
2021-12-24 22:09:50 +13:00
)
self.layout().addWidget(widget)
self.browser_button.setEnabled(True)