1
0
Fork 0
mirror of synced 2024-05-24 14:29:58 +12:00

Add Ubisoft activation in legendary settings

This commit is contained in:
Dummerle 2021-12-12 01:46:38 +01:00
parent 36568c6cc5
commit e2fe157e13
No known key found for this signature in database
GPG key ID: AB68CC59CA39F2F1
5 changed files with 291 additions and 129 deletions

View file

@ -22,27 +22,28 @@ AppDir:
version: 1.7.0
exec: usr/bin/python3
exec_args: $APPDIR/usr/src/__main__.py $@
apt:d
arch: amd64
allow_unauthenticated: true
sources:
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy main restricted
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy-updates main restricted
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy universe
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy-updates universe
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy multiverse
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy-updates multiverse
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy-backports main restricted
universe multiverse
- sourceline: deb http://security.ubuntu.com/ubuntu groovy-security main restricted
- sourceline: deb http://security.ubuntu.com/ubuntu groovy-security universe
- sourceline: deb http://security.ubuntu.com/ubuntu groovy-security multiverse
include:
- python3
- python3-distutils
- python3-pyqt5
- python3-psutil
- python3-requests
apt:
arch: amd64
allow_unauthenticated: true
sources:
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy main restricted
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy-updates main restricted
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy universe
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy-updates universe
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy multiverse
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy-updates multiverse
- sourceline: deb http://de.archive.ubuntu.com/ubuntu/ groovy-backports main restricted
universe multiverse
- sourceline: deb http://security.ubuntu.com/ubuntu groovy-security main restricted
- sourceline: deb http://security.ubuntu.com/ubuntu groovy-security universe
- sourceline: deb http://security.ubuntu.com/ubuntu groovy-security multiverse
include:
- python3
- python3-distutils
- python3-pyqt5
- python3-psutil
- python3-requests
runtime:
env:

View file

@ -1,10 +1,15 @@
import re
import webbrowser
from logging import getLogger
from typing import Tuple
from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox
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
import rare.shared as shared
from legendary.models.game import Game
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
@ -12,6 +17,102 @@ 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)
@ -59,6 +160,67 @@ 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)
@staticmethod
def locale_edit_cb(text: str) -> Tuple[bool, str]:
if text:

@ -1 +1 @@
Subproject commit ab7d209d5318f862d20081724383f523b6de4c7b
Subproject commit d371c0b3c48a422ff7e6c966af649a1502300c2d

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'rare/ui/components/tabs/settings/legendary.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
@ -14,10 +14,39 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_LegendarySettings(object):
def setupUi(self, LegendarySettings):
LegendarySettings.setObjectName("LegendarySettings")
LegendarySettings.resize(552, 268)
LegendarySettings.resize(564, 374)
LegendarySettings.setWindowTitle("LegendarySettings")
self.settings_layout = QtWidgets.QHBoxLayout(LegendarySettings)
self.settings_layout.setObjectName("settings_layout")
self.gridLayout = QtWidgets.QGridLayout(LegendarySettings)
self.gridLayout.setObjectName("gridLayout")
self.right_layout = QtWidgets.QVBoxLayout()
self.right_layout.setObjectName("right_layout")
self.locale_group = QtWidgets.QGroupBox(LegendarySettings)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.locale_group.sizePolicy().hasHeightForWidth())
self.locale_group.setSizePolicy(sizePolicy)
self.locale_group.setObjectName("locale_group")
self.locale_layout = QtWidgets.QVBoxLayout(self.locale_group)
self.locale_layout.setObjectName("locale_layout")
self.right_layout.addWidget(self.locale_group)
self.cleanup_group = QtWidgets.QGroupBox(LegendarySettings)
self.cleanup_group.setObjectName("cleanup_group")
self.cleanup_layout = QtWidgets.QVBoxLayout(self.cleanup_group)
self.cleanup_layout.setObjectName("cleanup_layout")
self.clean_keep_manifests_button = QtWidgets.QPushButton(self.cleanup_group)
self.clean_keep_manifests_button.setObjectName("clean_keep_manifests_button")
self.cleanup_layout.addWidget(self.clean_keep_manifests_button)
self.clean_button = QtWidgets.QPushButton(self.cleanup_group)
self.clean_button.setObjectName("clean_button")
self.cleanup_layout.addWidget(self.clean_button)
self.right_layout.addWidget(self.cleanup_group)
self.gridLayout.addLayout(self.right_layout, 0, 1, 1, 1)
self.ubisoft_gb = QtWidgets.QGroupBox(LegendarySettings)
self.ubisoft_gb.setObjectName("ubisoft_gb")
self.verticalLayout = QtWidgets.QVBoxLayout(self.ubisoft_gb)
self.verticalLayout.setObjectName("verticalLayout")
self.gridLayout.addWidget(self.ubisoft_gb, 1, 0, 1, 2)
self.left_layout = QtWidgets.QVBoxLayout()
self.left_layout.setObjectName("left_layout")
self.install_dir_group = QtWidgets.QGroupBox(LegendarySettings)
@ -96,41 +125,20 @@ class Ui_LegendarySettings(object):
self.disable_https_check.setObjectName("disable_https_check")
self.download_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.disable_https_check)
self.left_layout.addWidget(self.download_group)
self.gridLayout.addLayout(self.left_layout, 0, 0, 1, 1)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.left_layout.addItem(spacerItem)
self.settings_layout.addLayout(self.left_layout)
self.right_layout = QtWidgets.QVBoxLayout()
self.right_layout.setObjectName("right_layout")
self.locale_group = QtWidgets.QGroupBox(LegendarySettings)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.locale_group.sizePolicy().hasHeightForWidth())
self.locale_group.setSizePolicy(sizePolicy)
self.locale_group.setObjectName("locale_group")
self.locale_layout = QtWidgets.QVBoxLayout(self.locale_group)
self.locale_layout.setObjectName("locale_layout")
self.right_layout.addWidget(self.locale_group)
self.cleanup_group = QtWidgets.QGroupBox(LegendarySettings)
self.cleanup_group.setObjectName("cleanup_group")
self.cleanup_layout = QtWidgets.QVBoxLayout(self.cleanup_group)
self.cleanup_layout.setObjectName("cleanup_layout")
self.clean_keep_manifests_button = QtWidgets.QPushButton(self.cleanup_group)
self.clean_keep_manifests_button.setObjectName("clean_keep_manifests_button")
self.cleanup_layout.addWidget(self.clean_keep_manifests_button)
self.clean_button = QtWidgets.QPushButton(self.cleanup_group)
self.clean_button.setObjectName("clean_button")
self.cleanup_layout.addWidget(self.clean_button)
self.right_layout.addWidget(self.cleanup_group)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.right_layout.addItem(spacerItem1)
self.settings_layout.addLayout(self.right_layout)
self.gridLayout.addItem(spacerItem, 2, 0, 1, 2)
self.retranslateUi(LegendarySettings)
QtCore.QMetaObject.connectSlotsByName(LegendarySettings)
def retranslateUi(self, LegendarySettings):
_translate = QtCore.QCoreApplication.translate
self.locale_group.setTitle(_translate("LegendarySettings", "Locale"))
self.cleanup_group.setTitle(_translate("LegendarySettings", "Cleanup"))
self.clean_keep_manifests_button.setText(_translate("LegendarySettings", "Clean, but keep manifests"))
self.clean_button.setText(_translate("LegendarySettings", "Remove everything"))
self.ubisoft_gb.setTitle(_translate("LegendarySettings", "Link Ubisoft Games"))
self.install_dir_group.setTitle(_translate("LegendarySettings", "Default Installation Directory"))
self.download_group.setTitle(_translate("LegendarySettings", "Download Settings"))
self.max_workers_label.setText(_translate("LegendarySettings", "Max Workers"))
@ -141,10 +149,6 @@ class Ui_LegendarySettings(object):
self.preferred_cdn_label.setText(_translate("LegendarySettings", "Preferred CDN"))
self.preferred_cdn_line.setPlaceholderText(_translate("LegendarySettings", "Default"))
self.disable_https_label.setText(_translate("LegendarySettings", "Disable HTTPS"))
self.locale_group.setTitle(_translate("LegendarySettings", "Locale"))
self.cleanup_group.setTitle(_translate("LegendarySettings", "Cleanup"))
self.clean_keep_manifests_button.setText(_translate("LegendarySettings", "Clean, but keep manifests"))
self.clean_button.setText(_translate("LegendarySettings", "Remove everything"))
if __name__ == "__main__":

View file

@ -6,15 +6,64 @@
<rect>
<x>0</x>
<y>0</y>
<width>552</width>
<height>268</height>
<width>564</width>
<height>374</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">LegendarySettings</string>
</property>
<layout class="QHBoxLayout" name="settings_layout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<layout class="QVBoxLayout" name="right_layout">
<item>
<widget class="QGroupBox" name="locale_group">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Locale</string>
</property>
<layout class="QVBoxLayout" name="locale_layout"/>
</widget>
</item>
<item>
<widget class="QGroupBox" name="cleanup_group">
<property name="title">
<string>Cleanup</string>
</property>
<layout class="QVBoxLayout" name="cleanup_layout">
<item>
<widget class="QPushButton" name="clean_keep_manifests_button">
<property name="text">
<string>Clean, but keep manifests</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clean_button">
<property name="text">
<string>Remove everything</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="ubisoft_gb">
<property name="title">
<string>Link Ubisoft Games</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout"/>
</widget>
</item>
<item row="0" column="0">
<layout class="QVBoxLayout" name="left_layout">
<item>
<widget class="QGroupBox" name="install_dir_group">
@ -160,74 +209,20 @@
</layout>
</widget>
</item>
<item>
<spacer name="left_vspacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="right_layout">
<item>
<widget class="QGroupBox" name="locale_group">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Locale</string>
</property>
<layout class="QVBoxLayout" name="locale_layout"/>
</widget>
</item>
<item>
<widget class="QGroupBox" name="cleanup_group">
<property name="title">
<string>Cleanup</string>
</property>
<layout class="QVBoxLayout" name="cleanup_layout">
<item>
<widget class="QPushButton" name="clean_keep_manifests_button">
<property name="text">
<string>Clean, but keep manifests</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clean_button">
<property name="text">
<string>Remove everything</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="right_vspacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
<item row="2" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>