207 lines
7.3 KiB
Python
207 lines
7.3 KiB
Python
"""
|
|
Server connection dialog for adding/editing Navidrome servers
|
|
"""
|
|
|
|
from PySide6.QtWidgets import (
|
|
QDialog, QVBoxLayout, QHBoxLayout, QFormLayout,
|
|
QLineEdit, QPushButton, QLabel, QMessageBox, QCheckBox
|
|
)
|
|
from PySide6.QtCore import Qt
|
|
|
|
from src.api.client import SubsonicClient, SubsonicError
|
|
from src.config.settings import Settings
|
|
|
|
|
|
class ServerDialog(QDialog):
|
|
"""Dialog for configuring a Navidrome server connection"""
|
|
|
|
def __init__(self, settings: Settings, serverName: str = None, parent=None):
|
|
"""
|
|
Initialize the server dialog
|
|
|
|
Args:
|
|
settings: Application settings instance
|
|
serverName: Name of existing server to edit (None for new server)
|
|
parent: Parent widget
|
|
"""
|
|
super().__init__(parent)
|
|
self.settings = settings
|
|
self.editingServer = serverName
|
|
self.isNew = serverName is None
|
|
|
|
self.setWindowTitle("Add Server" if self.isNew else "Edit Server")
|
|
self.setModal(True)
|
|
self.setMinimumWidth(400)
|
|
|
|
self.setupUi()
|
|
self.loadExistingData()
|
|
|
|
def setupUi(self):
|
|
"""Setup the dialog UI"""
|
|
layout = QVBoxLayout(self)
|
|
|
|
# Form layout for inputs
|
|
formLayout = QFormLayout()
|
|
|
|
# Server name
|
|
self.nameEdit = QLineEdit()
|
|
self.nameEdit.setAccessibleName("Server Name")
|
|
self.nameEdit.setAccessibleDescription("A friendly name for this server")
|
|
nameLabel = QLabel("&Name:")
|
|
nameLabel.setBuddy(self.nameEdit)
|
|
formLayout.addRow(nameLabel, self.nameEdit)
|
|
|
|
# Server URL
|
|
self.urlEdit = QLineEdit()
|
|
self.urlEdit.setAccessibleName("Server URL")
|
|
self.urlEdit.setAccessibleDescription("The full URL to your Navidrome server, for example https://music.example.com")
|
|
self.urlEdit.setPlaceholderText("https://music.example.com")
|
|
urlLabel = QLabel("&URL:")
|
|
urlLabel.setBuddy(self.urlEdit)
|
|
formLayout.addRow(urlLabel, self.urlEdit)
|
|
|
|
# Username
|
|
self.usernameEdit = QLineEdit()
|
|
self.usernameEdit.setAccessibleName("Username")
|
|
usernameLabel = QLabel("U&sername:")
|
|
usernameLabel.setBuddy(self.usernameEdit)
|
|
formLayout.addRow(usernameLabel, self.usernameEdit)
|
|
|
|
# Password
|
|
self.passwordEdit = QLineEdit()
|
|
self.passwordEdit.setEchoMode(QLineEdit.Password)
|
|
self.passwordEdit.setAccessibleName("Password")
|
|
passwordLabel = QLabel("&Password:")
|
|
passwordLabel.setBuddy(self.passwordEdit)
|
|
formLayout.addRow(passwordLabel, self.passwordEdit)
|
|
|
|
# Set as default checkbox
|
|
self.defaultCheckbox = QCheckBox("Set as &default server")
|
|
self.defaultCheckbox.setAccessibleName("Set as default server")
|
|
formLayout.addRow("", self.defaultCheckbox)
|
|
|
|
layout.addLayout(formLayout)
|
|
|
|
# Status label for connection test
|
|
self.statusLabel = QLabel("")
|
|
self.statusLabel.setAccessibleName("Connection Status")
|
|
self.statusLabel.setWordWrap(True)
|
|
layout.addWidget(self.statusLabel)
|
|
|
|
# Button layout
|
|
buttonLayout = QHBoxLayout()
|
|
|
|
self.testButton = QPushButton("&Test Connection")
|
|
self.testButton.setAccessibleName("Test Connection")
|
|
self.testButton.clicked.connect(self.testConnection)
|
|
buttonLayout.addWidget(self.testButton)
|
|
|
|
buttonLayout.addStretch()
|
|
|
|
self.cancelButton = QPushButton("&Cancel")
|
|
self.cancelButton.setAccessibleName("Cancel")
|
|
self.cancelButton.clicked.connect(self.reject)
|
|
buttonLayout.addWidget(self.cancelButton)
|
|
|
|
self.saveButton = QPushButton("&Save")
|
|
self.saveButton.setAccessibleName("Save")
|
|
self.saveButton.setDefault(True)
|
|
self.saveButton.clicked.connect(self.saveServer)
|
|
buttonLayout.addWidget(self.saveButton)
|
|
|
|
layout.addLayout(buttonLayout)
|
|
|
|
# Set initial focus
|
|
self.nameEdit.setFocus()
|
|
|
|
def loadExistingData(self):
|
|
"""Load existing server data if editing"""
|
|
if not self.isNew and self.editingServer:
|
|
server = self.settings.getServer(self.editingServer)
|
|
if server:
|
|
self.nameEdit.setText(self.editingServer)
|
|
self.nameEdit.setReadOnly(True) # Can't change name when editing
|
|
self.urlEdit.setText(server.get('url', ''))
|
|
self.usernameEdit.setText(server.get('username', ''))
|
|
self.passwordEdit.setText(server.get('password', ''))
|
|
|
|
# Check if this is the default server
|
|
defaultServer = self.settings.getDefaultServer()
|
|
self.defaultCheckbox.setChecked(defaultServer == self.editingServer)
|
|
|
|
def testConnection(self):
|
|
"""Test connection to the server"""
|
|
url = self.urlEdit.text().strip()
|
|
username = self.usernameEdit.text().strip()
|
|
password = self.passwordEdit.text()
|
|
|
|
if not url or not username or not password:
|
|
self.statusLabel.setText("Please fill in all fields")
|
|
return
|
|
|
|
self.statusLabel.setText("Testing connection...")
|
|
self.testButton.setEnabled(False)
|
|
|
|
try:
|
|
client = SubsonicClient(url, username, password)
|
|
if client.ping():
|
|
self.statusLabel.setText("Connection successful!")
|
|
else:
|
|
self.statusLabel.setText("Connection failed: Invalid response")
|
|
except SubsonicError as e:
|
|
self.statusLabel.setText(f"Connection failed: {e.message}")
|
|
except Exception as e:
|
|
self.statusLabel.setText(f"Connection failed: {str(e)}")
|
|
finally:
|
|
self.testButton.setEnabled(True)
|
|
|
|
def saveServer(self):
|
|
"""Save the server configuration"""
|
|
name = self.nameEdit.text().strip()
|
|
url = self.urlEdit.text().strip()
|
|
username = self.usernameEdit.text().strip()
|
|
password = self.passwordEdit.text()
|
|
|
|
# Validate inputs
|
|
if not name:
|
|
QMessageBox.warning(self, "Validation Error", "Please enter a server name")
|
|
self.nameEdit.setFocus()
|
|
return
|
|
|
|
if not url:
|
|
QMessageBox.warning(self, "Validation Error", "Please enter the server URL")
|
|
self.urlEdit.setFocus()
|
|
return
|
|
|
|
if not username:
|
|
QMessageBox.warning(self, "Validation Error", "Please enter a username")
|
|
self.usernameEdit.setFocus()
|
|
return
|
|
|
|
if not password:
|
|
QMessageBox.warning(self, "Validation Error", "Please enter a password")
|
|
self.passwordEdit.setFocus()
|
|
return
|
|
|
|
# Check for duplicate name when adding new server
|
|
if self.isNew and self.settings.getServer(name):
|
|
QMessageBox.warning(
|
|
self, "Validation Error",
|
|
f"A server named '{name}' already exists. Please choose a different name."
|
|
)
|
|
self.nameEdit.setFocus()
|
|
return
|
|
|
|
# Save the server
|
|
self.settings.addServer(name, url, username, password)
|
|
|
|
# Set as default if checked
|
|
if self.defaultCheckbox.isChecked():
|
|
self.settings.setDefaultServer(name)
|
|
|
|
self.accept()
|
|
|
|
def getServerName(self) -> str:
|
|
"""Get the name of the saved server"""
|
|
return self.nameEdit.text().strip()
|