Merge pull request #34 from exislow/reload-lists

✨ GUI user lists can be reloaded. Logout is possible.
This commit is contained in:
exislow
2024-02-05 06:33:22 +01:00
committed by GitHub
7 changed files with 206 additions and 131 deletions
+8
View File
@@ -2,6 +2,7 @@ import os
import shutil import shutil
from collections.abc import Callable from collections.abc import Callable
from json import JSONDecodeError from json import JSONDecodeError
from pathlib import Path
from typing import Any from typing import Any
import tidalapi 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...") fn_print("Something went wrong. Did you login using your browser correctly? May try again...")
return result return result
def logout(self):
Path(self.file_path).unlink(missing_ok=True)
self.token_from_storage = False
del self.session
return True
+1 -1
View File
@@ -158,7 +158,7 @@ class DialogPreferences(QtWidgets.QDialog):
line_edit.setText(getattr(self.data, pn)) line_edit.setText(getattr(self.data, pn))
# Base Path File Dialog # 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): def populate_combo(self):
+31 -6
View File
@@ -40,8 +40,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
threadpool: QtCore.QThreadPool threadpool: QtCore.QThreadPool
tray: QtWidgets.QSystemTrayIcon tray: QtWidgets.QSystemTrayIcon
spinner: QtWaitingSpinner spinner: QtWaitingSpinner
spinner_start: QtCore.Signal = QtCore.Signal(QtWidgets.QWidget) s_spinner_start: QtCore.Signal = QtCore.Signal(QtWidgets.QWidget)
spinner_stop: QtCore.Signal = QtCore.Signal() s_spinner_stop: QtCore.Signal = QtCore.Signal()
pb_item: QtWidgets.QProgressBar pb_item: QtWidgets.QProgressBar
s_item_advance: QtCore.Signal = QtCore.Signal(float) s_item_advance: QtCore.Signal = QtCore.Signal(float)
s_item_name: QtCore.Signal = QtCore.Signal(str) 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_statusbar_message: QtCore.Signal = QtCore.Signal(object)
s_tr_results_add_top_level_item: 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_settings_save: QtCore.Signal = QtCore.Signal()
s_pb_reload_status: QtCore.Signal = QtCore.Signal(bool)
def __init__(self, tidal: Tidal | None = None): def __init__(self, tidal: Tidal | None = None):
super().__init__() super().__init__()
@@ -176,7 +177,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def tidal_user_lists(self): def tidal_user_lists(self):
# Start loading spinner # 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) 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 TidalLists.MIXES.value, QtCore.Qt.MatchExactly, 0
)[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: for item in user_lists:
if isinstance(item, UserPlaylist): if isinstance(item, UserPlaylist):
twi_child = QtWidgets.QTreeWidgetItem(twi_playlists) 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) twi_child.setData(3, QtCore.Qt.ItemDataRole.UserRole, item)
# Stop load spinner # 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): def _init_tree_lists(self, tree: QtWidgets.QTreeWidget):
# Adjust Tree. # 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_audio.currentIndexChanged.connect(self.on_quality_set_audio)
self.cb_quality_video.currentIndexChanged.connect(self.on_quality_set_video) self.cb_quality_video.currentIndexChanged.connect(self.on_quality_set_video)
self.tr_lists_user.itemClicked.connect(self.on_list_items_show) self.tr_lists_user.itemClicked.connect(self.on_list_items_show)
self.spinner_start[QtWidgets.QWidget].connect(self.on_spinner_start) self.s_spinner_start[QtWidgets.QWidget].connect(self.on_spinner_start)
self.spinner_stop.connect(self.on_spinner_stop) self.s_spinner_stop.connect(self.on_spinner_stop)
self.s_item_advance.connect(self.on_progress_item) self.s_item_advance.connect(self.on_progress_item)
self.s_item_name.connect(self.on_progress_item_name) self.s_item_name.connect(self.on_progress_item_name)
self.s_list_name.connect(self.on_progress_list_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_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_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.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 # Menubar
self.a_exit.triggered.connect(sys.exit) self.a_exit.triggered.connect(sys.exit)
self.a_version.triggered.connect(self.on_version) self.a_version.triggered.connect(self.on_version)
self.a_preferences.triggered.connect(self.on_preferences) self.a_preferences.triggered.connect(self.on_preferences)
self.a_logout.triggered.connect(self.on_logout)
# Results # Results
self.tr_results.itemExpanded.connect(self.on_tr_results_expanded) 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): def on_progress_list(self, value: float):
self.pb_list.setValue(int(math.ceil(value))) 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) 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. # TODO: Comment with Google Docstrings.
def gui_activate(tidal: Tidal | None = None): def gui_activate(tidal: Tidal | None = None):
+4 -4
View File
@@ -378,10 +378,10 @@ class Ui_DialogSettings:
self.horizontalLayout_3.addWidget(self.le_download_base_path) self.horizontalLayout_3.addWidget(self.le_download_base_path)
self.b_download_base_path = QPushButton(self.gb_path) self.pb_download_base_path = QPushButton(self.gb_path)
self.b_download_base_path.setObjectName("b_download_base_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) 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_format_playlist.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None))
self.l_icon_format_mix.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.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 # retranslateUi
+1 -1
View File
@@ -538,7 +538,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="b_download_base_path"> <widget class="QPushButton" name="pb_download_base_path">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
+26 -7
View File
@@ -51,6 +51,8 @@ class Ui_MainWindow:
self.a_version.setObjectName("a_version") self.a_version.setObjectName("a_version")
self.a_exit = QAction(MainWindow) self.a_exit = QAction(MainWindow)
self.a_exit.setObjectName("a_exit") 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 = QWidget(MainWindow)
self.w_central.setObjectName("w_central") self.w_central.setObjectName("w_central")
self.w_central.setEnabled(True) self.w_central.setEnabled(True)
@@ -79,10 +81,12 @@ class Ui_MainWindow:
self.lh_main = QHBoxLayout() self.lh_main = QHBoxLayout()
self.lh_main.setObjectName("lh_main") self.lh_main.setObjectName("lh_main")
self.lh_main.setSizeConstraint(QLayout.SetNoConstraint) self.lh_main.setSizeConstraint(QLayout.SetNoConstraint)
self.verticalLayout = QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.tr_lists_user = QTreeWidget(self.w_central) self.tr_lists_user = QTreeWidget(self.w_central)
__qtreewidgetitem = QTreeWidgetItem() __qtreewidgetitem = QTreeWidgetItem()
__qtreewidgetitem.setText(1, "Info") __qtreewidgetitem.setText(1, "Info")
__qtreewidgetitem.setText(0, "Playlist") __qtreewidgetitem.setText(0, "Name")
self.tr_lists_user.setHeaderItem(__qtreewidgetitem) self.tr_lists_user.setHeaderItem(__qtreewidgetitem)
__qtreewidgetitem1 = QTreeWidgetItem(self.tr_lists_user) __qtreewidgetitem1 = QTreeWidgetItem(self.tr_lists_user)
__qtreewidgetitem1.setFlags(Qt.ItemIsEnabled) __qtreewidgetitem1.setFlags(Qt.ItemIsEnabled)
@@ -115,7 +119,19 @@ class Ui_MainWindow:
self.tr_lists_user.header().setHighlightSections(True) self.tr_lists_user.header().setHighlightSections(True)
self.tr_lists_user.header().setProperty("showSortIndicator", 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() self.lv_search_result = QVBoxLayout()
# ifndef Q_OS_MAC # ifndef Q_OS_MAC
@@ -332,11 +348,11 @@ class Ui_MainWindow:
self.te_debug = QPlainTextEdit(self.w_central) self.te_debug = QPlainTextEdit(self.w_central)
self.te_debug.setObjectName("te_debug") self.te_debug.setObjectName("te_debug")
self.te_debug.setEnabled(True) self.te_debug.setEnabled(True)
sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
sizePolicy1.setHorizontalStretch(0) sizePolicy2.setHorizontalStretch(0)
sizePolicy1.setVerticalStretch(0) sizePolicy2.setVerticalStretch(0)
sizePolicy1.setHeightForWidth(self.te_debug.sizePolicy().hasHeightForWidth()) sizePolicy2.setHeightForWidth(self.te_debug.sizePolicy().hasHeightForWidth())
self.te_debug.setSizePolicy(sizePolicy1) self.te_debug.setSizePolicy(sizePolicy2)
self.te_debug.setMaximumSize(QSize(16777215, 16777215)) self.te_debug.setMaximumSize(QSize(16777215, 16777215))
self.te_debug.setAcceptDrops(False) self.te_debug.setAcceptDrops(False)
# if QT_CONFIG(tooltip) # if QT_CONFIG(tooltip)
@@ -426,6 +442,7 @@ class Ui_MainWindow:
self.menubar.addAction(self.m_file.menuAction()) self.menubar.addAction(self.m_file.menuAction())
self.m_file.addAction(self.a_preferences) self.m_file.addAction(self.a_preferences)
self.m_file.addAction(self.a_version) self.m_file.addAction(self.a_version)
self.m_file.addAction(self.a_logout)
self.m_file.addAction(self.a_exit) self.m_file.addAction(self.a_exit)
self.retranslateUi(MainWindow) self.retranslateUi(MainWindow)
@@ -438,6 +455,7 @@ class Ui_MainWindow:
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", "MainWindow", None)) MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", "MainWindow", None))
self.a_version.setText(QCoreApplication.translate("MainWindow", "Version", None)) self.a_version.setText(QCoreApplication.translate("MainWindow", "Version", None))
self.a_exit.setText(QCoreApplication.translate("MainWindow", "Exit", 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 = self.tr_lists_user.headerItem()
___qtreewidgetitem.setText(2, QCoreApplication.translate("MainWindow", "obj", None)) ___qtreewidgetitem.setText(2, QCoreApplication.translate("MainWindow", "obj", None))
@@ -451,6 +469,7 @@ class Ui_MainWindow:
___qtreewidgetitem3.setText(0, QCoreApplication.translate("MainWindow", "Favorites", None)) ___qtreewidgetitem3.setText(0, QCoreApplication.translate("MainWindow", "Favorites", None))
self.tr_lists_user.setSortingEnabled(__sortingEnabled) self.tr_lists_user.setSortingEnabled(__sortingEnabled)
self.pb_reload_user_lists.setText(QCoreApplication.translate("MainWindow", "Reload", None))
___qtreewidgetitem4 = self.tr_results.headerItem() ___qtreewidgetitem4 = self.tr_results.headerItem()
___qtreewidgetitem4.setText(5, QCoreApplication.translate("MainWindow", "obj", None)) ___qtreewidgetitem4.setText(5, QCoreApplication.translate("MainWindow", "obj", None))
___qtreewidgetitem4.setText(4, QCoreApplication.translate("MainWindow", "Duration", None)) ___qtreewidgetitem4.setText(4, QCoreApplication.translate("MainWindow", "Duration", None))
+135 -112
View File
@@ -45,122 +45,139 @@
<enum>QLayout::SetNoConstraint</enum> <enum>QLayout::SetNoConstraint</enum>
</property> </property>
<item> <item>
<widget class="QTreeWidget" name="tr_lists_user"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="toolTip">
<string notr="true"/>
</property>
<property name="statusTip">
<string notr="true"/>
</property>
<property name="whatsThis">
<string notr="true"/>
</property>
<property name="accessibleName">
<string notr="true"/>
</property>
<property name="accessibleDescription">
<string notr="true"/>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="indentation">
<number>10</number>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="headerHighlightSections">
<bool>true</bool>
</attribute>
<attribute name="headerShowSortIndicator" stdset="0">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string notr="true">Playlist</string>
</property>
<property name="toolTip">
<string notr="true"/>
</property>
<property name="statusTip">
<string notr="true"/>
</property>
<property name="whatsThis">
<string notr="true"/>
</property>
</column>
<column>
<property name="text">
<string notr="true">Info</string>
</property>
<property name="toolTip">
<string notr="true"/>
</property>
<property name="statusTip">
<string notr="true"/>
</property>
<property name="whatsThis">
<string notr="true"/>
</property>
</column>
<column>
<property name="text">
<string>obj</string>
</property>
</column>
<item> <item>
<property name="text"> <widget class="QTreeWidget" name="tr_lists_user">
<string>Playlists</string> <property name="toolTip">
</property> <string notr="true"/>
<property name="text"> </property>
<string/> <property name="statusTip">
</property> <string notr="true"/>
<property name="text"> </property>
<string/> <property name="whatsThis">
</property> <string notr="true"/>
<property name="flags"> </property>
<set>ItemIsEnabled</set> <property name="accessibleName">
</property> <string notr="true"/>
</property>
<property name="accessibleDescription">
<string notr="true"/>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="indentation">
<number>10</number>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="headerHighlightSections">
<bool>true</bool>
</attribute>
<attribute name="headerShowSortIndicator" stdset="0">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string notr="true">Name</string>
</property>
<property name="toolTip">
<string notr="true"/>
</property>
<property name="statusTip">
<string notr="true"/>
</property>
<property name="whatsThis">
<string notr="true"/>
</property>
</column>
<column>
<property name="text">
<string notr="true">Info</string>
</property>
<property name="toolTip">
<string notr="true"/>
</property>
<property name="statusTip">
<string notr="true"/>
</property>
<property name="whatsThis">
<string notr="true"/>
</property>
</column>
<column>
<property name="text">
<string>obj</string>
</property>
</column>
<item>
<property name="text">
<string>Playlists</string>
</property>
<property name="text">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="flags">
<set>ItemIsEnabled</set>
</property>
</item>
<item>
<property name="text">
<string>Mixes</string>
</property>
<property name="text">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="flags">
<set>ItemIsEnabled</set>
</property>
</item>
<item>
<property name="text">
<string>Favorites</string>
</property>
<property name="text">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="flags">
<set>ItemIsEnabled</set>
</property>
</item>
</widget>
</item> </item>
<item> <item>
<property name="text"> <widget class="QPushButton" name="pb_reload_user_lists">
<string>Mixes</string> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<property name="text"> <horstretch>0</horstretch>
<string/> <verstretch>0</verstretch>
</property> </sizepolicy>
<property name="text"> </property>
<string/> <property name="text">
</property> <string>Reload</string>
<property name="flags"> </property>
<set>ItemIsEnabled</set> </widget>
</property>
</item> </item>
<item> </layout>
<property name="text">
<string>Favorites</string>
</property>
<property name="text">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="flags">
<set>ItemIsEnabled</set>
</property>
</item>
</widget>
</item> </item>
<item> <item>
<layout class="QVBoxLayout" name="lv_search_result" stretch="0,0,0,0"> <layout class="QVBoxLayout" name="lv_search_result" stretch="0,0,0,0">
@@ -542,6 +559,7 @@
</property> </property>
<addaction name="a_preferences"/> <addaction name="a_preferences"/>
<addaction name="a_version"/> <addaction name="a_version"/>
<addaction name="a_logout"/>
<addaction name="a_exit"/> <addaction name="a_exit"/>
</widget> </widget>
<addaction name="m_file"/> <addaction name="m_file"/>
@@ -596,6 +614,11 @@
<string>Exit</string> <string>Exit</string>
</property> </property>
</action> </action>
<action name="a_logout">
<property name="text">
<string>Logout</string>
</property>
</action>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>