148 lines
5.9 KiB
Python
148 lines
5.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
from funksnake import Funkwhale
|
|
from PyQt5 import QtCore, QtWidgets
|
|
|
|
from playtypus.ui_mainwindow import UiMainWindow
|
|
from playtypus.settingsdialog import SettingsDialog
|
|
from playtypus.threads import AlbumWorker, ArtistWorker, PlaylistWorker, RadioWorker
|
|
|
|
|
|
class MainWindow(QtWidgets.QMainWindow, UiMainWindow):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.setup_ui()
|
|
self.settingsAction.triggered.connect(self.on_settings_action_triggered)
|
|
self.settings = QtCore.QSettings('info.snyman.playtypus', 'Playtypus')
|
|
self.settings_dialog = SettingsDialog(self)
|
|
self.funkwhale = None
|
|
self.threads = {}
|
|
# Check for Funkwhale settings, and load all the things
|
|
if self.settings.contains('funkwhale/server_url'):
|
|
self.setup_funkwhale(self.settings.value('funkwhale/server_url'),
|
|
self.settings.value('funkwhale/username', None),
|
|
self.settings.value('funkwhale/password', None))
|
|
|
|
@property
|
|
def is_funkwhale_active(self):
|
|
return self.funkwhale and self.funkwhale.token
|
|
|
|
def run_thread(self, worker, thread_name):
|
|
"""
|
|
Create a thread and its worker. This gets rid of a lot of unnecessary boilerplate code.
|
|
|
|
:param ThreadWorker worker: A worker object that actually performs the work
|
|
:param str thread_name: The name of the thread, used to keep track of the thread.
|
|
:param bool can_start: Start the thread. Defaults to True.
|
|
"""
|
|
if not thread_name:
|
|
raise ValueError('A thread name is required')
|
|
if thread_name in self.threads:
|
|
raise KeyError('A thread with name "{}" already exists'.format(thread_name))
|
|
# Create the thread and add the thread and the worker to the thread tracker
|
|
thread = QtCore.QThread()
|
|
self.threads[thread_name] = {
|
|
'thread': thread,
|
|
'worker': worker
|
|
}
|
|
# Move the worker into the thread's context
|
|
worker.moveToThread(thread)
|
|
# Connect slots and signals
|
|
thread.started.connect(worker.start)
|
|
worker.quit.connect(thread.quit)
|
|
worker.quit.connect(worker.deleteLater)
|
|
thread.finished.connect(thread.deleteLater)
|
|
thread.finished.connect(self.make_remove_thread(thread_name))
|
|
thread.start()
|
|
|
|
def get_thread_worker(self, thread_name):
|
|
"""
|
|
Get the worker by the thread name
|
|
|
|
:param str thread_name: The name of the thread
|
|
:returns: The worker for this thread name, or None
|
|
"""
|
|
thread = self.threads.get(thread_name)
|
|
if not thread:
|
|
return
|
|
return thread.get('worker')
|
|
|
|
def is_thread_finished(self, thread_name):
|
|
"""
|
|
Check if a thread is finished running.
|
|
|
|
:param str thread_name: The name of the thread
|
|
:returns: True if the thread is finished, False if it is still running
|
|
"""
|
|
return thread_name not in self.threads or self.threads[thread_name]['thread'].isFinished()
|
|
|
|
def make_remove_thread(self, thread_name):
|
|
"""
|
|
Create a function to remove the thread once the thread is finished.
|
|
|
|
:param str thread_name: The name of the thread which should be removed from the thread registry.
|
|
:returns: A function which will remove the thread from the thread registry.
|
|
"""
|
|
def remove_thread():
|
|
"""
|
|
Stop and remove a registered thread
|
|
|
|
:param str thread_name: The name of the thread to stop and remove
|
|
"""
|
|
if thread_name in self.threads:
|
|
del self.threads[thread_name]
|
|
|
|
return remove_thread
|
|
|
|
def setup_funkwhale(self, server_url=None, username=None, password=None):
|
|
if not self.funkwhale and not server_url:
|
|
raise ValueError('A server url needs to be defined')
|
|
if not self.funkwhale and server_url:
|
|
self.funkwhale = Funkwhale(server_url)
|
|
if username and password:
|
|
self.funkwhale.login(username, password)
|
|
if self.is_funkwhale_active:
|
|
self.load_albums()
|
|
self.load_artists()
|
|
self.load_playlists()
|
|
|
|
def load_albums(self):
|
|
if not self.is_funkwhale_active:
|
|
return
|
|
worker = AlbumWorker()
|
|
worker.window = self
|
|
self.run_thread(worker, 'get-albums')
|
|
|
|
def load_artists(self):
|
|
if not self.is_funkwhale_active:
|
|
return
|
|
worker = ArtistWorker()
|
|
worker.window = self
|
|
self.run_thread(worker, 'get-artists')
|
|
|
|
def load_playlists(self):
|
|
if not self.is_funkwhale_active:
|
|
return
|
|
worker = PlaylistWorker()
|
|
worker.window = self
|
|
self.run_thread(worker, 'get-playlists')
|
|
|
|
def load_radios(self):
|
|
if not self.is_funkwhale_active:
|
|
return
|
|
worker = RadioWorker()
|
|
worker.window = self
|
|
self.run_thread(worker, 'get-radios')
|
|
|
|
def on_settings_action_triggered(self):
|
|
self.settings_dialog.server_url = self.settings.value('funkwhale/server_url', '')
|
|
self.settings_dialog.username = self.settings.value('funkwhale/username', '')
|
|
self.settings_dialog.password = self.settings.value('funkwhale/password', '')
|
|
if self.settings_dialog.exec() == QtWidgets.QDialog.Accepted \
|
|
and self.settings.value('funkwhale/server_url', '') != self.settings_dialog.server_url:
|
|
self.settings.setValue('funkwhale/server_url', self.settings_dialog.server_url)
|
|
self.settings.setValue('funkwhale/username', self.settings_dialog.username)
|
|
self.settings.setValue('funkwhale/password', self.settings_dialog.password)
|
|
self.setup_funkwhale(self.settings.value('funkwhale/server_url'),
|
|
self.settings.value('funkwhale/username', None),
|
|
self.settings.value('funkwhale/password', None))
|