diff --git a/tidal_dl_ng/config.py b/tidal_dl_ng/config.py index 1d17953..c6fdaee 100644 --- a/tidal_dl_ng/config.py +++ b/tidal_dl_ng/config.py @@ -168,9 +168,9 @@ class Tidal(BaseConfig, metaclass=SingletonMeta): fn_print("You either do not have a token or your token is invalid.") fn_print("No worries, we will handle this...") # Login method: Device linking - # self.session.login_oauth_simple(fn_print) - # Login method: PKCE authorization (enables HiRes streaming) - self.session.login_pkce(fn_print) + self.session.login_oauth_simple(fn_print) + # Login method: PKCE authorization (was necessary for HI_RES_LOSSLESS streaming earlier) + # self.session.login_pkce(fn_print) is_login = self.login_finalize() diff --git a/tidal_dl_ng/dialog.py b/tidal_dl_ng/dialog.py index c035867..f82386b 100644 --- a/tidal_dl_ng/dialog.py +++ b/tidal_dl_ng/dialog.py @@ -1,6 +1,7 @@ import os.path import shutil import webbrowser +import datetime from enum import Enum, StrEnum from pathlib import Path @@ -83,24 +84,25 @@ class DialogLogin(QtWidgets.QDialog): ui: Ui_DialogLogin url_redirect: str - return_code: int - def __init__(self, url_login: str, hint: str, parent=None): + def __init__(self, url_login: str, hint: str, expires_in: int, parent=None): super().__init__(parent) + datetime_current: datetime.datetime = datetime.datetime.now() + datetime_expires: datetime.datetime = datetime_current + datetime.timedelta(0, expires_in) + # Create an instance of the GUI self.ui = Ui_DialogLogin() # Run the .setupUi() method to show the GUI self.ui.setupUi(self) # Set data. - self.ui.tb_url_login.setText(f'{url_login}') + self.ui.tb_url_login.setText(f'https://{url_login}') self.ui.l_hint.setText(hint) + self.ui.l_expires_date_time.setText(datetime_expires.strftime("%Y-%m-%d %H:%M")) # Show self.return_code = self.exec() - self.url_redirect = self.ui.te_url_redirect.toPlainText() - class DialogPreferences(QtWidgets.QDialog): """Preferences dialog.""" diff --git a/tidal_dl_ng/gui.py b/tidal_dl_ng/gui.py index 7aa2150..4cc3150 100644 --- a/tidal_dl_ng/gui.py +++ b/tidal_dl_ng/gui.py @@ -128,14 +128,16 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): result = self.tidal.login_token() if not result: - hint: str = "Watiting for user input." + hint: str = "After you have finished the TIDAL login via web browser click the 'OK' button." + while not result: - url_login = self.tidal.session.pkce_login_url() - d_login: DialogLogin = DialogLogin(url_login=url_login, hint=hint, parent=self) - url_redirect: str = d_login.url_redirect + login, future = self.tidal.session.login_oauth() + + d_login: DialogLogin = DialogLogin(url_login=login.verification_uri_complete, hint=hint, expires_in=login.expires_in, parent=self) if d_login.return_code == 1: try: + future.result() token: dict[str, str | int] = self.tidal.session.pkce_get_auth_token(url_redirect) self.tidal.session.process_auth_token(token) self.tidal.login_finalize() diff --git a/tidal_dl_ng/ui/dialog_login.py b/tidal_dl_ng/ui/dialog_login.py index bbc916f..d30ca6c 100644 --- a/tidal_dl_ng/ui/dialog_login.py +++ b/tidal_dl_ng/ui/dialog_login.py @@ -1,42 +1,51 @@ +# -*- coding: utf-8 -*- + ################################################################################ ## Form generated from reading UI file 'dialog_login.ui' ## -## Created by: Qt User Interface Compiler version 6.6.1 +## Created by: Qt User Interface Compiler version 6.8.0 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ -from PySide6.QtCore import QCoreApplication, QMetaObject, QRect, Qt -from PySide6.QtGui import QFont -from PySide6.QtWidgets import QDialogButtonBox, QLabel, QSizePolicy, QTextBrowser, QTextEdit, QVBoxLayout, QWidget +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QAbstractButton, QApplication, QDialog, QDialogButtonBox, + QHBoxLayout, QLabel, QSizePolicy, QTextBrowser, + QVBoxLayout, QWidget) - -class Ui_DialogLogin: +class Ui_DialogLogin(object): def setupUi(self, DialogLogin): if not DialogLogin.objectName(): - DialogLogin.setObjectName("DialogLogin") + DialogLogin.setObjectName(u"DialogLogin") DialogLogin.resize(451, 400) - sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(DialogLogin.sizePolicy().hasHeightForWidth()) DialogLogin.setSizePolicy(sizePolicy) self.bb_dialog = QDialogButtonBox(DialogLogin) - self.bb_dialog.setObjectName("bb_dialog") + self.bb_dialog.setObjectName(u"bb_dialog") self.bb_dialog.setGeometry(QRect(20, 350, 411, 32)) sizePolicy.setHeightForWidth(self.bb_dialog.sizePolicy().hasHeightForWidth()) self.bb_dialog.setSizePolicy(sizePolicy) - self.bb_dialog.setStyleSheet("") - self.bb_dialog.setOrientation(Qt.Horizontal) - self.bb_dialog.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) + self.bb_dialog.setLayoutDirection(Qt.LayoutDirection.LeftToRight) + self.bb_dialog.setStyleSheet(u"") + self.bb_dialog.setOrientation(Qt.Orientation.Horizontal) + self.bb_dialog.setStandardButtons(QDialogButtonBox.StandardButton.Cancel|QDialogButtonBox.StandardButton.Ok) self.verticalLayoutWidget = QWidget(DialogLogin) - self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") + self.verticalLayoutWidget.setObjectName(u"verticalLayoutWidget") self.verticalLayoutWidget.setGeometry(QRect(20, 20, 411, 325)) self.lv_main = QVBoxLayout(self.verticalLayoutWidget) - self.lv_main.setObjectName("lv_main") + self.lv_main.setObjectName(u"lv_main") self.lv_main.setContentsMargins(0, 0, 0, 0) self.l_header = QLabel(self.verticalLayoutWidget) - self.l_header.setObjectName("l_header") + self.l_header.setObjectName(u"l_header") sizePolicy.setHeightForWidth(self.l_header.sizePolicy().hasHeightForWidth()) self.l_header.setSizePolicy(sizePolicy) font = QFont() @@ -47,7 +56,7 @@ class Ui_DialogLogin: self.lv_main.addWidget(self.l_header) self.l_description = QLabel(self.verticalLayoutWidget) - self.l_description.setObjectName("l_description") + self.l_description.setObjectName(u"l_description") sizePolicy.setHeightForWidth(self.l_description.sizePolicy().hasHeightForWidth()) self.l_description.setSizePolicy(sizePolicy) font1 = QFont() @@ -58,47 +67,54 @@ class Ui_DialogLogin: self.lv_main.addWidget(self.l_description) self.tb_url_login = QTextBrowser(self.verticalLayoutWidget) - self.tb_url_login.setObjectName("tb_url_login") + self.tb_url_login.setObjectName(u"tb_url_login") self.tb_url_login.setOpenExternalLinks(True) self.lv_main.addWidget(self.tb_url_login) - self.te_url_redirect = QTextEdit(self.verticalLayoutWidget) - self.te_url_redirect.setObjectName("te_url_redirect") + self.horizontalLayout = QHBoxLayout() + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.l_expires_description = QLabel(self.verticalLayoutWidget) + self.l_expires_description.setObjectName(u"l_expires_description") - self.lv_main.addWidget(self.te_url_redirect) + self.horizontalLayout.addWidget(self.l_expires_description) + + self.l_expires_date_time = QLabel(self.verticalLayoutWidget) + self.l_expires_date_time.setObjectName(u"l_expires_date_time") + font2 = QFont() + font2.setBold(True) + self.l_expires_date_time.setFont(font2) + self.l_expires_date_time.setAlignment(Qt.AlignmentFlag.AlignRight|Qt.AlignmentFlag.AlignTrailing|Qt.AlignmentFlag.AlignVCenter) + + self.horizontalLayout.addWidget(self.l_expires_date_time) + + + self.lv_main.addLayout(self.horizontalLayout) self.l_hint = QLabel(self.verticalLayoutWidget) - self.l_hint.setObjectName("l_hint") + self.l_hint.setObjectName(u"l_hint") sizePolicy.setHeightForWidth(self.l_hint.sizePolicy().hasHeightForWidth()) self.l_hint.setSizePolicy(sizePolicy) self.l_hint.setFont(font1) + self.l_hint.setWordWrap(True) self.lv_main.addWidget(self.l_hint) + self.retranslateUi(DialogLogin) self.bb_dialog.accepted.connect(DialogLogin.accept) self.bb_dialog.rejected.connect(DialogLogin.reject) QMetaObject.connectSlotsByName(DialogLogin) - # setupUi def retranslateUi(self, DialogLogin): - DialogLogin.setWindowTitle(QCoreApplication.translate("DialogLogin", "Dialog", None)) - self.l_header.setText(QCoreApplication.translate("DialogLogin", "TIDAL PKCE Login", None)) - self.l_description.setText( - QCoreApplication.translate( - "DialogLogin", - 'Click the link below and login with your TIDAL credentials. You will be redirected to an "Ooops" page' - ' after a successful login. Copy the URL of this "Ooops" page and post it in the box below.', - None, - ) - ) - self.tb_url_login.setPlaceholderText(QCoreApplication.translate("DialogLogin", "Copy this login URL...", None)) - self.te_url_redirect.setPlaceholderText( - QCoreApplication.translate("DialogLogin", "Copy and paste the redirect URL after login here...", None) - ) - self.l_hint.setText(QCoreApplication.translate("DialogLogin", "Waiting...", None)) - + DialogLogin.setWindowTitle(QCoreApplication.translate("DialogLogin", u"Dialog", None)) + self.l_header.setText(QCoreApplication.translate("DialogLogin", u"TIDAL Login (as Device)", None)) + self.l_description.setText(QCoreApplication.translate("DialogLogin", u"Click the link below and login with your TIDAL credentials. TIDAL will ask you, if you like to add this app as a new device. You need to confirm this.", None)) + self.tb_url_login.setPlaceholderText(QCoreApplication.translate("DialogLogin", u"Copy this login URL...", None)) + self.l_expires_description.setText(QCoreApplication.translate("DialogLogin", u"This link expires at:", None)) + self.l_expires_date_time.setText(QCoreApplication.translate("DialogLogin", u"COMPUTING", None)) + self.l_hint.setText(QCoreApplication.translate("DialogLogin", u"Waiting...", None)) # retranslateUi + diff --git a/tidal_dl_ng/ui/dialog_login.ui b/tidal_dl_ng/ui/dialog_login.ui index c9c9774..2ff401f 100644 --- a/tidal_dl_ng/ui/dialog_login.ui +++ b/tidal_dl_ng/ui/dialog_login.ui @@ -34,14 +34,17 @@ 0 + + Qt::LayoutDirection::LeftToRight + - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok @@ -69,7 +72,7 @@ - TIDAL PKCE Login + TIDAL Login (as Device) @@ -87,7 +90,7 @@ - Click the link below and login with your TIDAL credentials. You will be redirected to an "Ooops" page after a successful login. Copy the URL of this "Ooops" page and post it in the box below. + Click the link below and login with your TIDAL credentials. TIDAL will ask you, if you like to add this app as a new device. You need to confirm this. true @@ -105,11 +108,30 @@ - - - Copy and paste the redirect URL after login here... - - + + + + + This link expires at: + + + + + + + + true + + + + COMPUTING + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + + @@ -127,6 +149,9 @@ Waiting... + + true +