-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* error handling * update cli and tests to use browser auth and add option for oauth * added test that will alert us by failing if/when oauth starts working again; also no need to pass in yt_auth object to tests since it will always use browser.json unless we specify --oauth * formatted log statement * updated GUI to use browser auth by default, and optionally use oauth * re-enable passing in yt_auth in context as its needed in order to specify the path to the browser.json file in test/resources * get correct path * show generic person icon when signed in using browser auth * remove redundant log * update readmes
- Loading branch information
Showing
17 changed files
with
573 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import shutil | ||
from pathlib import Path | ||
|
||
import ytmusicapi | ||
from generated.ui_auth_dialog import Ui_AuthDialog | ||
from PySide6.QtCore import QDir | ||
from PySide6.QtCore import QObject | ||
from PySide6.QtCore import QThread | ||
from PySide6.QtCore import Signal | ||
from PySide6.QtCore import Slot | ||
from PySide6.QtWidgets import QDialog | ||
from PySide6.QtWidgets import QDialogButtonBox | ||
from PySide6.QtWidgets import QFileDialog | ||
from PySide6.QtWidgets import QLineEdit | ||
from PySide6.QtWidgets import QMessageBox | ||
from PySide6.QtWidgets import QPlainTextEdit | ||
from ytmusic_deleter import common | ||
from ytmusicapi import YTMusic | ||
|
||
|
||
class BrowserAuthDialog(QDialog, Ui_AuthDialog): | ||
def __init__(self, parent): | ||
super().__init__(parent) | ||
# self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) # also closes parent window now for some reason | ||
self.setupUi(self) | ||
|
||
# Check again in case auth file was deleted/moved | ||
self.parentWidget().is_signed_in() | ||
|
||
self.enable_ok_button() | ||
self.headersInputBox.textChanged.connect(self.enable_ok_button) | ||
self.fileNameField.textChanged.connect(self.enable_ok_button) | ||
|
||
self.browseButton.clicked.connect(self.choose_auth_file) | ||
|
||
self.auth_setup = YTAuthSetup(self.headersInputBox, self.fileNameField, self.parentWidget().credential_dir) | ||
self.auth_setup.auth_signal.connect(self.auth_finished) | ||
|
||
self.headersInputBox.setPlaceholderText( | ||
""" | ||
Paste your raw request headers here and click OK. | ||
See https://ytmusicapi.readthedocs.io/en/stable/setup/browser.html#copy-authentication-headers | ||
Alternatively, use Browse to select an existing browser.json file. | ||
""" | ||
) | ||
|
||
def accept(self): | ||
self.thread = QThread(self) | ||
self.thread.started.connect(self.auth_setup.setup_auth) | ||
self.thread.start() | ||
|
||
@Slot() | ||
def enable_ok_button(self): | ||
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( | ||
self.headersInputBox.toPlainText() != "" or self.fileNameField.text() != "" | ||
) | ||
|
||
@Slot() | ||
def choose_auth_file(self): | ||
file_name, _ = QFileDialog.getOpenFileName(self, "Select Auth File", QDir.rootPath(), "*.json") | ||
self.fileNameField.setText(file_name) | ||
|
||
@Slot(str) | ||
def auth_finished(self, auth_result): | ||
if auth_result == "Success": | ||
self.parentWidget().update_buttons() | ||
self.close() | ||
else: | ||
error_dialog = QMessageBox() | ||
error_dialog.setIcon(QMessageBox.Critical) | ||
error_dialog.setText(auth_result) | ||
error_dialog.setInformativeText( | ||
"<html>See <a href=https://ytmusicapi.readthedocs.io/en/latest/setup.html#copy-authentication-headers>" | ||
"https://ytmusicapi.readthedocs.io/en/latest/setup.html#copy-authentication-headers</a> for " | ||
"instructions on obtaining your request headers.</html>" | ||
) | ||
error_dialog.setWindowTitle("Error") | ||
error_dialog.exec() | ||
|
||
|
||
class YTAuthSetup(QObject): | ||
auth_signal = Signal(str) | ||
|
||
def __init__(self, textarea: QPlainTextEdit, filename_field: QLineEdit, cred_dir): | ||
super().__init__() | ||
self.textarea = textarea | ||
self.filename_field = filename_field | ||
self.browser_file_path = Path(cred_dir) / common.BROWSER_FILENAME | ||
|
||
@Slot() | ||
def setup_auth(self): | ||
try: | ||
# Use selected headers_auth.json file | ||
if self.filename_field.text(): | ||
YTMusic(self.filename_field.text()) | ||
shutil.copy2(self.filename_field.text(), self.browser_file_path) | ||
# Use pasted headers | ||
else: | ||
user_input = self.textarea.toPlainText() | ||
YTMusic(ytmusicapi.setup(filepath=self.browser_file_path, headers_raw=user_input)) | ||
|
||
self.auth_signal.emit("Success") | ||
except Exception as e: | ||
self.auth_signal.emit(str(e)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
################################################################################ | ||
## Form generated from reading UI file 'auth_dialog.ui' | ||
## | ||
## 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, 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, | ||
QLabel, QLineEdit, QPlainTextEdit, QPushButton, | ||
QSizePolicy, QWidget) | ||
|
||
class Ui_AuthDialog(object): | ||
def setupUi(self, AuthDialog): | ||
if not AuthDialog.objectName(): | ||
AuthDialog.setObjectName(u"AuthDialog") | ||
AuthDialog.setWindowModality(Qt.ApplicationModal) | ||
AuthDialog.resize(569, 511) | ||
self.buttonBox = QDialogButtonBox(AuthDialog) | ||
self.buttonBox.setObjectName(u"buttonBox") | ||
self.buttonBox.setEnabled(True) | ||
self.buttonBox.setGeometry(QRect(190, 470, 171, 32)) | ||
self.buttonBox.setOrientation(Qt.Horizontal) | ||
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) | ||
self.buttonBox.setCenterButtons(True) | ||
self.headersInputBox = QPlainTextEdit(AuthDialog) | ||
self.headersInputBox.setObjectName(u"headersInputBox") | ||
self.headersInputBox.setGeometry(QRect(60, 20, 451, 251)) | ||
self.orLabel = QLabel(AuthDialog) | ||
self.orLabel.setObjectName(u"orLabel") | ||
self.orLabel.setGeometry(QRect(130, 380, 331, 31)) | ||
self.browseButton = QPushButton(AuthDialog) | ||
self.browseButton.setObjectName(u"browseButton") | ||
self.browseButton.setGeometry(QRect(130, 420, 75, 23)) | ||
self.fileNameField = QLineEdit(AuthDialog) | ||
self.fileNameField.setObjectName(u"fileNameField") | ||
self.fileNameField.setEnabled(False) | ||
self.fileNameField.setGeometry(QRect(220, 420, 241, 21)) | ||
self.helpLabel = QLabel(AuthDialog) | ||
self.helpLabel.setObjectName(u"helpLabel") | ||
self.helpLabel.setGeometry(QRect(60, 270, 451, 51)) | ||
self.helpLabel.setAlignment(Qt.AlignCenter) | ||
self.helpLabel.setWordWrap(True) | ||
self.helpLabel.setOpenExternalLinks(True) | ||
|
||
self.retranslateUi(AuthDialog) | ||
self.buttonBox.accepted.connect(AuthDialog.accept) | ||
self.buttonBox.rejected.connect(AuthDialog.reject) | ||
|
||
QMetaObject.connectSlotsByName(AuthDialog) | ||
# setupUi | ||
|
||
def retranslateUi(self, AuthDialog): | ||
AuthDialog.setWindowTitle(QCoreApplication.translate("AuthDialog", u"Authentication", None)) | ||
self.orLabel.setText(QCoreApplication.translate("AuthDialog", u"Or select an existing browser.json file", None)) | ||
self.browseButton.setText(QCoreApplication.translate("AuthDialog", u"Browse", None)) | ||
self.helpLabel.setText(QCoreApplication.translate("AuthDialog", u"<html>See <a href=\"https://ytmusicapi.readthedocs.io/en/latest/setup.html#copy-authentication-headers\">https://ytmusicapi.readthedocs.io/en/latest/setup.html#copy-authentication-headers</a> for instructions on obtaining your request headers.</html>", None)) | ||
# retranslateUi | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.