playtypus/playtypus/mainwindow.py

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))