diff --git a/tidal_dl_ng/config.py b/tidal_dl_ng/config.py index 92eea3b..7e93e7f 100644 --- a/tidal_dl_ng/config.py +++ b/tidal_dl_ng/config.py @@ -2,6 +2,7 @@ import os import shutil from collections.abc import Callable from json import JSONDecodeError +from pathlib import Path from typing import Any import tidalapi @@ -158,3 +159,10 @@ class Tidal(BaseConfig, metaclass=SingletonMeta): fn_print("Something went wrong. Did you login using your browser correctly? May try again...") return result + + def logout(self): + Path(self.file_path).unlink(missing_ok=True) + self.token_from_storage = False + del self.session + + return True diff --git a/tidal_dl_ng/dialog.py b/tidal_dl_ng/dialog.py index 8757675..b1901fd 100644 --- a/tidal_dl_ng/dialog.py +++ b/tidal_dl_ng/dialog.py @@ -158,7 +158,7 @@ class DialogPreferences(QtWidgets.QDialog): line_edit.setText(getattr(self.data, pn)) # Base Path File Dialog - self.ui.b_download_base_path.clicked.connect(lambda x: self.dialog_dir_open(self.ui.le_download_base_path)) + self.ui.pb_download_base_path.clicked.connect(lambda x: self.dialog_dir_open(self.ui.le_download_base_path)) def populate_combo(self): diff --git a/tidal_dl_ng/gui.py b/tidal_dl_ng/gui.py index 81f70a4..f7248fd 100644 --- a/tidal_dl_ng/gui.py +++ b/tidal_dl_ng/gui.py @@ -40,8 +40,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): threadpool: QtCore.QThreadPool tray: QtWidgets.QSystemTrayIcon spinner: QtWaitingSpinner - spinner_start: QtCore.Signal = QtCore.Signal(QtWidgets.QWidget) - spinner_stop: QtCore.Signal = QtCore.Signal() + s_spinner_start: QtCore.Signal = QtCore.Signal(QtWidgets.QWidget) + s_spinner_stop: QtCore.Signal = QtCore.Signal() pb_item: QtWidgets.QProgressBar s_item_advance: QtCore.Signal = QtCore.Signal(float) s_item_name: QtCore.Signal = QtCore.Signal(str) @@ -53,6 +53,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): s_statusbar_message: QtCore.Signal = QtCore.Signal(object) s_tr_results_add_top_level_item: QtCore.Signal = QtCore.Signal(object) s_settings_save: QtCore.Signal = QtCore.Signal() + s_pb_reload_status: QtCore.Signal = QtCore.Signal(bool) def __init__(self, tidal: Tidal | None = None): super().__init__() @@ -176,7 +177,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def tidal_user_lists(self): # Start loading spinner - self.spinner_start.emit(self.tr_lists_user) + self.s_spinner_start.emit(self.tr_lists_user) + self.s_pb_reload_status.emit(False) user_all: [Playlist | UserPlaylist | Mix] = user_media_lists(self.tidal.session) @@ -195,6 +197,11 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): TidalLists.MIXES.value, QtCore.Qt.MatchExactly, 0 )[0] + # Remove all children if present + for twi in [twi_playlists, twi_mixes, twi_favorites]: + for i in reversed(range(twi.childCount())): + twi.removeChild(twi.child(i)) + for item in user_lists: if isinstance(item, UserPlaylist): twi_child = QtWidgets.QTreeWidgetItem(twi_playlists) @@ -214,7 +221,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): twi_child.setData(3, QtCore.Qt.ItemDataRole.UserRole, item) # Stop load spinner - self.spinner_stop.emit() + self.s_spinner_stop.emit() + self.s_pb_reload_status.emit(True) def _init_tree_lists(self, tree: QtWidgets.QTreeWidget): # Adjust Tree. @@ -405,8 +413,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.cb_quality_audio.currentIndexChanged.connect(self.on_quality_set_audio) self.cb_quality_video.currentIndexChanged.connect(self.on_quality_set_video) self.tr_lists_user.itemClicked.connect(self.on_list_items_show) - self.spinner_start[QtWidgets.QWidget].connect(self.on_spinner_start) - self.spinner_stop.connect(self.on_spinner_stop) + self.s_spinner_start[QtWidgets.QWidget].connect(self.on_spinner_start) + self.s_spinner_stop.connect(self.on_spinner_stop) self.s_item_advance.connect(self.on_progress_item) self.s_item_name.connect(self.on_progress_item_name) self.s_list_name.connect(self.on_progress_list_name) @@ -416,15 +424,24 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.s_statusbar_message.connect(self.on_statusbar_message) self.s_tr_results_add_top_level_item.connect(self.on_tr_results_add_top_level_item) self.s_settings_save.connect(self.on_settings_save) + self.pb_reload_user_lists.clicked.connect(lambda x: self.thread_it(self.tidal_user_lists)) + self.s_pb_reload_status.connect(self.button_reload_status) # Menubar self.a_exit.triggered.connect(sys.exit) self.a_version.triggered.connect(self.on_version) self.a_preferences.triggered.connect(self.on_preferences) + self.a_logout.triggered.connect(self.on_logout) # Results self.tr_results.itemExpanded.connect(self.on_tr_results_expanded) + def on_logout(self): + result: bool = self.tidal.logout() + + if result: + sys.exit(0) + def on_progress_list(self, value: float): self.pb_list.setValue(int(math.ceil(value))) @@ -536,6 +553,14 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.list_items_show_result(media_list=media_list, parent=child) + def button_reload_status(self, status: bool): + button_text: str = "Reloading..." + if status: + button_text = "Reload" + + self.pb_reload_user_lists.setEnabled(status) + self.pb_reload_user_lists.setText(button_text) + # TODO: Comment with Google Docstrings. def gui_activate(tidal: Tidal | None = None): diff --git a/tidal_dl_ng/ui/dialog_settings.py b/tidal_dl_ng/ui/dialog_settings.py index 019fdc6..eb358e1 100644 --- a/tidal_dl_ng/ui/dialog_settings.py +++ b/tidal_dl_ng/ui/dialog_settings.py @@ -378,10 +378,10 @@ class Ui_DialogSettings: self.horizontalLayout_3.addWidget(self.le_download_base_path) - self.b_download_base_path = QPushButton(self.gb_path) - self.b_download_base_path.setObjectName("b_download_base_path") + self.pb_download_base_path = QPushButton(self.gb_path) + self.pb_download_base_path.setObjectName("pb_download_base_path") - self.horizontalLayout_3.addWidget(self.b_download_base_path) + self.horizontalLayout_3.addWidget(self.pb_download_base_path) self.verticalLayout.addLayout(self.horizontalLayout_3) @@ -488,6 +488,6 @@ class Ui_DialogSettings: self.l_format_playlist.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.l_icon_format_mix.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.l_format_mix.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) - self.b_download_base_path.setText(QCoreApplication.translate("DialogSettings", "...", None)) + self.pb_download_base_path.setText(QCoreApplication.translate("DialogSettings", "...", None)) # retranslateUi diff --git a/tidal_dl_ng/ui/dialog_settings.ui b/tidal_dl_ng/ui/dialog_settings.ui index 7826271..acdb1cf 100644 --- a/tidal_dl_ng/ui/dialog_settings.ui +++ b/tidal_dl_ng/ui/dialog_settings.ui @@ -538,7 +538,7 @@ - + ... diff --git a/tidal_dl_ng/ui/main.py b/tidal_dl_ng/ui/main.py index 65735e6..8ee8f4c 100644 --- a/tidal_dl_ng/ui/main.py +++ b/tidal_dl_ng/ui/main.py @@ -51,6 +51,8 @@ class Ui_MainWindow: self.a_version.setObjectName("a_version") self.a_exit = QAction(MainWindow) self.a_exit.setObjectName("a_exit") + self.a_logout = QAction(MainWindow) + self.a_logout.setObjectName("a_logout") self.w_central = QWidget(MainWindow) self.w_central.setObjectName("w_central") self.w_central.setEnabled(True) @@ -79,10 +81,12 @@ class Ui_MainWindow: self.lh_main = QHBoxLayout() self.lh_main.setObjectName("lh_main") self.lh_main.setSizeConstraint(QLayout.SetNoConstraint) + self.verticalLayout = QVBoxLayout() + self.verticalLayout.setObjectName("verticalLayout") self.tr_lists_user = QTreeWidget(self.w_central) __qtreewidgetitem = QTreeWidgetItem() __qtreewidgetitem.setText(1, "Info") - __qtreewidgetitem.setText(0, "Playlist") + __qtreewidgetitem.setText(0, "Name") self.tr_lists_user.setHeaderItem(__qtreewidgetitem) __qtreewidgetitem1 = QTreeWidgetItem(self.tr_lists_user) __qtreewidgetitem1.setFlags(Qt.ItemIsEnabled) @@ -115,7 +119,19 @@ class Ui_MainWindow: self.tr_lists_user.header().setHighlightSections(True) self.tr_lists_user.header().setProperty("showSortIndicator", True) - self.lh_main.addWidget(self.tr_lists_user) + self.verticalLayout.addWidget(self.tr_lists_user) + + self.pb_reload_user_lists = QPushButton(self.w_central) + self.pb_reload_user_lists.setObjectName("pb_reload_user_lists") + sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) + sizePolicy1.setHorizontalStretch(0) + sizePolicy1.setVerticalStretch(0) + sizePolicy1.setHeightForWidth(self.pb_reload_user_lists.sizePolicy().hasHeightForWidth()) + self.pb_reload_user_lists.setSizePolicy(sizePolicy1) + + self.verticalLayout.addWidget(self.pb_reload_user_lists) + + self.lh_main.addLayout(self.verticalLayout) self.lv_search_result = QVBoxLayout() # ifndef Q_OS_MAC @@ -332,11 +348,11 @@ class Ui_MainWindow: self.te_debug = QPlainTextEdit(self.w_central) self.te_debug.setObjectName("te_debug") self.te_debug.setEnabled(True) - sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) - sizePolicy1.setHorizontalStretch(0) - sizePolicy1.setVerticalStretch(0) - sizePolicy1.setHeightForWidth(self.te_debug.sizePolicy().hasHeightForWidth()) - self.te_debug.setSizePolicy(sizePolicy1) + sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) + sizePolicy2.setHorizontalStretch(0) + sizePolicy2.setVerticalStretch(0) + sizePolicy2.setHeightForWidth(self.te_debug.sizePolicy().hasHeightForWidth()) + self.te_debug.setSizePolicy(sizePolicy2) self.te_debug.setMaximumSize(QSize(16777215, 16777215)) self.te_debug.setAcceptDrops(False) # if QT_CONFIG(tooltip) @@ -426,6 +442,7 @@ class Ui_MainWindow: self.menubar.addAction(self.m_file.menuAction()) self.m_file.addAction(self.a_preferences) self.m_file.addAction(self.a_version) + self.m_file.addAction(self.a_logout) self.m_file.addAction(self.a_exit) self.retranslateUi(MainWindow) @@ -438,6 +455,7 @@ class Ui_MainWindow: MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", "MainWindow", None)) self.a_version.setText(QCoreApplication.translate("MainWindow", "Version", None)) self.a_exit.setText(QCoreApplication.translate("MainWindow", "Exit", None)) + self.a_logout.setText(QCoreApplication.translate("MainWindow", "Logout", None)) ___qtreewidgetitem = self.tr_lists_user.headerItem() ___qtreewidgetitem.setText(2, QCoreApplication.translate("MainWindow", "obj", None)) @@ -451,6 +469,7 @@ class Ui_MainWindow: ___qtreewidgetitem3.setText(0, QCoreApplication.translate("MainWindow", "Favorites", None)) self.tr_lists_user.setSortingEnabled(__sortingEnabled) + self.pb_reload_user_lists.setText(QCoreApplication.translate("MainWindow", "Reload", None)) ___qtreewidgetitem4 = self.tr_results.headerItem() ___qtreewidgetitem4.setText(5, QCoreApplication.translate("MainWindow", "obj", None)) ___qtreewidgetitem4.setText(4, QCoreApplication.translate("MainWindow", "Duration", None)) diff --git a/tidal_dl_ng/ui/main.ui b/tidal_dl_ng/ui/main.ui index 7a5f86f..ea018c6 100644 --- a/tidal_dl_ng/ui/main.ui +++ b/tidal_dl_ng/ui/main.ui @@ -45,122 +45,139 @@ QLayout::SetNoConstraint - - - - - - - - - - - - - - - - - - QAbstractItemView::NoEditTriggers - - - false - - - 10 - - - true - - - true - - - true - - - true - - - true - - - - Playlist - - - - - - - - - - - - - - Info - - - - - - - - - - - - - - obj - - + - - Playlists - - - - - - - - - ItemIsEnabled - + + + + + + + + + + + + + + + + + + QAbstractItemView::NoEditTriggers + + + false + + + 10 + + + true + + + true + + + true + + + true + + + true + + + + Name + + + + + + + + + + + + + + Info + + + + + + + + + + + + + + obj + + + + + Playlists + + + + + + + + + ItemIsEnabled + + + + + Mixes + + + + + + + + + ItemIsEnabled + + + + + Favorites + + + + + + + + + ItemIsEnabled + + + - - Mixes - - - - - - - - - ItemIsEnabled - + + + + 0 + 0 + + + + Reload + + - - - Favorites - - - - - - - - - ItemIsEnabled - - - + @@ -542,6 +559,7 @@ + @@ -596,6 +614,11 @@ Exit + + + Logout + +