Igen
This commit is contained in:
@@ -107,19 +107,35 @@ class LibraryManagerDialog(QDialog):
|
||||
layout.addLayout(btn_row)
|
||||
|
||||
def _load(self):
|
||||
# Ryd eksisterende widgets
|
||||
while self._libs_layout.count():
|
||||
item = self._libs_layout.takeAt(0)
|
||||
if item.widget():
|
||||
item.widget().deleteLater()
|
||||
|
||||
try:
|
||||
from local.local_db import get_libraries, get_db
|
||||
import sqlite3
|
||||
from local.local_db import DB_PATH, get_libraries
|
||||
libs = get_libraries(active_only=True)
|
||||
for lib in libs:
|
||||
self._libs_layout.addWidget(self._make_lib_row(lib))
|
||||
conn = sqlite3.connect(str(DB_PATH))
|
||||
conn.row_factory = sqlite3.Row
|
||||
count = conn.execute(
|
||||
"SELECT COUNT(*) FROM songs WHERE library_id=? AND file_missing=0",
|
||||
(lib["id"],)
|
||||
).fetchone()[0]
|
||||
missing_bpm = conn.execute(
|
||||
"SELECT COUNT(*) FROM songs WHERE library_id=? AND file_missing=0 "
|
||||
"AND (bpm IS NULL OR bpm=0)",
|
||||
(lib["id"],)
|
||||
).fetchone()[0]
|
||||
conn.close()
|
||||
lib_dict = dict(lib)
|
||||
lib_dict["_count"] = count
|
||||
lib_dict["_missing_bpm"] = missing_bpm
|
||||
self._libs_layout.addWidget(self._make_lib_row(lib_dict))
|
||||
except Exception as e:
|
||||
pass
|
||||
lbl = QLabel(f"Fejl: {e}")
|
||||
self._libs_layout.addWidget(lbl)
|
||||
|
||||
def _make_lib_row(self, lib: dict) -> QFrame:
|
||||
from pathlib import Path
|
||||
@@ -137,21 +153,8 @@ class LibraryManagerDialog(QDialog):
|
||||
last_scan = lib.get("last_full_scan") or "aldrig"
|
||||
if isinstance(last_scan, str) and len(last_scan) > 10:
|
||||
last_scan = last_scan[:10]
|
||||
try:
|
||||
from local.local_db import get_db
|
||||
with get_db() as conn:
|
||||
total = conn.execute(
|
||||
"SELECT COUNT(*) FROM songs WHERE library_id=? AND file_missing=0",
|
||||
(lib_id,)
|
||||
).fetchone()[0]
|
||||
missing_bpm = conn.execute(
|
||||
"SELECT COUNT(*) FROM songs WHERE library_id=? AND file_missing=0 "
|
||||
"AND (bpm IS NULL OR bpm=0)",
|
||||
(lib_id,)
|
||||
).fetchone()[0]
|
||||
except Exception:
|
||||
total = 0
|
||||
missing_bpm = 0
|
||||
total = lib.get("_count", 0)
|
||||
missing_bpm = lib.get("_missing_bpm", 0)
|
||||
|
||||
lbl_path = QLabel(("⚠ " if not exists else "") + path)
|
||||
lbl_path.setObjectName("track_title" if exists else "result_count")
|
||||
@@ -175,13 +178,13 @@ class LibraryManagerDialog(QDialog):
|
||||
btn_row.setSpacing(6)
|
||||
|
||||
btn_scan = QPushButton("⟳ Fil-scan")
|
||||
btn_scan.setFixedHeight(24)
|
||||
btn_scan.setFixedHeight(30)
|
||||
btn_scan.setToolTip("Scan for nye og ændrede filer")
|
||||
btn_scan.clicked.connect(lambda _, lid=lib_id, p=path: self._scan_files(lid, p))
|
||||
btn_row.addWidget(btn_scan)
|
||||
|
||||
btn_bpm = QPushButton(f"♩ BPM manglende ({missing_bpm})")
|
||||
btn_bpm.setFixedHeight(24)
|
||||
btn_bpm.setFixedHeight(30)
|
||||
btn_bpm.setToolTip("Analysér BPM på sange der mangler det")
|
||||
btn_bpm.setEnabled(missing_bpm > 0)
|
||||
btn_bpm.clicked.connect(
|
||||
@@ -190,7 +193,7 @@ class LibraryManagerDialog(QDialog):
|
||||
btn_row.addWidget(btn_bpm)
|
||||
|
||||
btn_bpm_all = QPushButton("♩ BPM alle")
|
||||
btn_bpm_all.setFixedHeight(24)
|
||||
btn_bpm_all.setFixedHeight(30)
|
||||
btn_bpm_all.setToolTip("Genanalysér BPM på alle sange (overskriver eksisterende)")
|
||||
btn_bpm_all.clicked.connect(
|
||||
lambda _, lid=lib_id, b=btn_bpm_all, s=lbl_status: self._start_bpm(lid, True, b, s)
|
||||
@@ -200,7 +203,7 @@ class LibraryManagerDialog(QDialog):
|
||||
btn_row.addStretch()
|
||||
|
||||
btn_remove = QPushButton("✕ Fjern")
|
||||
btn_remove.setFixedHeight(24)
|
||||
btn_remove.setFixedHeight(30)
|
||||
btn_remove.clicked.connect(lambda _, l=lib: self._remove_library(l))
|
||||
btn_row.addWidget(btn_remove)
|
||||
|
||||
|
||||
131
linedance-app/ui/register_dialog.py
Normal file
131
linedance-app/ui/register_dialog.py
Normal file
@@ -0,0 +1,131 @@
|
||||
"""
|
||||
register_dialog.py — Opret ny konto på LineDance API.
|
||||
"""
|
||||
from PyQt6.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QFormLayout, QLabel, QLineEdit,
|
||||
QPushButton, QGroupBox, QMessageBox,
|
||||
)
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
|
||||
class RegisterDialog(QDialog):
|
||||
def __init__(self, server_url: str = "http://localhost:8000", parent=None):
|
||||
super().__init__(parent)
|
||||
self._server_url = server_url.rstrip("/")
|
||||
self.setWindowTitle("Opret konto")
|
||||
self.setMinimumWidth(400)
|
||||
self._build_ui()
|
||||
|
||||
def _build_ui(self):
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(16, 16, 16, 16)
|
||||
layout.setSpacing(12)
|
||||
|
||||
lbl = QLabel(f"Opret konto på:\n{self._server_url}")
|
||||
lbl.setObjectName("result_count")
|
||||
lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(lbl)
|
||||
|
||||
grp = QGroupBox("Kontooplysninger")
|
||||
form = QFormLayout(grp)
|
||||
|
||||
self._name = QLineEdit()
|
||||
self._name.setPlaceholderText("Dit fulde navn")
|
||||
form.addRow("Navn:", self._name)
|
||||
|
||||
self._username = QLineEdit()
|
||||
self._username.setPlaceholderText("brugernavn (ingen mellemrum)")
|
||||
form.addRow("Brugernavn:", self._username)
|
||||
|
||||
self._email = QLineEdit()
|
||||
self._email.setPlaceholderText("din@email.dk")
|
||||
form.addRow("E-mail:", self._email)
|
||||
|
||||
self._password = QLineEdit()
|
||||
self._password.setEchoMode(QLineEdit.EchoMode.Password)
|
||||
self._password.setPlaceholderText("mindst 8 tegn")
|
||||
form.addRow("Kodeord:", self._password)
|
||||
|
||||
self._password2 = QLineEdit()
|
||||
self._password2.setEchoMode(QLineEdit.EchoMode.Password)
|
||||
self._password2.setPlaceholderText("gentag kodeord")
|
||||
form.addRow("Gentag kodeord:", self._password2)
|
||||
|
||||
layout.addWidget(grp)
|
||||
|
||||
self._status = QLabel("")
|
||||
self._status.setObjectName("result_count")
|
||||
self._status.setWordWrap(True)
|
||||
self._status.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(self._status)
|
||||
|
||||
btn_row = QVBoxLayout()
|
||||
self._btn_register = QPushButton("✚ Opret konto")
|
||||
self._btn_register.setObjectName("btn_play")
|
||||
self._btn_register.clicked.connect(self._register)
|
||||
btn_row.addWidget(self._btn_register)
|
||||
|
||||
btn_cancel = QPushButton("Annuller")
|
||||
btn_cancel.clicked.connect(self.reject)
|
||||
btn_row.addWidget(btn_cancel)
|
||||
layout.addLayout(btn_row)
|
||||
|
||||
def _register(self):
|
||||
name = self._name.text().strip()
|
||||
username = self._username.text().strip()
|
||||
email = self._email.text().strip()
|
||||
password = self._password.text()
|
||||
password2 = self._password2.text()
|
||||
|
||||
# Validering
|
||||
if not all([username, email, password]):
|
||||
self._status.setText("⚠ Udfyld alle felter.")
|
||||
return
|
||||
if " " in username:
|
||||
self._status.setText("⚠ Brugernavnet må ikke indeholde mellemrum.")
|
||||
return
|
||||
if "@" not in email:
|
||||
self._status.setText("⚠ Ugyldig e-mailadresse.")
|
||||
return
|
||||
if len(password) < 8:
|
||||
self._status.setText("⚠ Kodeordet skal være mindst 8 tegn.")
|
||||
return
|
||||
if password != password2:
|
||||
self._status.setText("⚠ Kodeordene er ikke ens.")
|
||||
return
|
||||
|
||||
self._btn_register.setEnabled(False)
|
||||
self._status.setText("Opretter konto...")
|
||||
|
||||
try:
|
||||
import urllib.request, json
|
||||
data = json.dumps({
|
||||
"username": username,
|
||||
"email": email,
|
||||
"full_name": name,
|
||||
"password": password,
|
||||
}).encode("utf-8")
|
||||
req = urllib.request.Request(
|
||||
f"{self._server_url}/auth/register",
|
||||
data=data,
|
||||
headers={"Content-Type": "application/json"},
|
||||
method="POST"
|
||||
)
|
||||
with urllib.request.urlopen(req, timeout=10) as resp:
|
||||
result = json.loads(resp.read())
|
||||
|
||||
self._status.setText(
|
||||
f"✓ Konto oprettet!\n\n"
|
||||
f"Tjek din e-mail ({email}) for at bekræfte kontoen.\n"
|
||||
f"Herefter kan du logge ind."
|
||||
)
|
||||
self._btn_register.setEnabled(False)
|
||||
|
||||
except urllib.error.HTTPError as e:
|
||||
body = json.loads(e.read())
|
||||
msg = body.get("detail", str(e))
|
||||
self._status.setText(f"⚠ {msg}")
|
||||
self._btn_register.setEnabled(True)
|
||||
except Exception as e:
|
||||
self._status.setText(f"⚠ Kunne ikke forbinde til server:\n{e}")
|
||||
self._btn_register.setEnabled(True)
|
||||
@@ -20,6 +20,7 @@ SETTINGS_KEY_MAIL_PATH = "mail/custom_path"
|
||||
SETTINGS_KEY_AUTO_LOGIN = "online/auto_login"
|
||||
SETTINGS_KEY_USERNAME = "online/username"
|
||||
SETTINGS_KEY_PASSWORD = "online/password"
|
||||
SETTINGS_KEY_SERVER_URL = "online/server_url"
|
||||
SETTINGS_KEY_LANGUAGE = "appearance/language"
|
||||
SETTINGS_KEY_BETWEEN_SEC = "playback/between_seconds"
|
||||
SETTINGS_KEY_WORKSHOP_MIN = "playback/workshop_minutes"
|
||||
@@ -37,6 +38,7 @@ def load_settings() -> dict:
|
||||
"auto_login": s.value(SETTINGS_KEY_AUTO_LOGIN, False, type=bool),
|
||||
"username": s.value(SETTINGS_KEY_USERNAME, ""),
|
||||
"password": s.value(SETTINGS_KEY_PASSWORD, ""),
|
||||
"server_url": s.value(SETTINGS_KEY_SERVER_URL, "http://localhost:8000"),
|
||||
"language": s.value(SETTINGS_KEY_LANGUAGE, "da"),
|
||||
"between_seconds": s.value(SETTINGS_KEY_BETWEEN_SEC, 60, type=int),
|
||||
"workshop_minutes": s.value(SETTINGS_KEY_WORKSHOP_MIN, 10, type=int),
|
||||
@@ -54,6 +56,7 @@ def save_settings(values: dict):
|
||||
s.setValue(SETTINGS_KEY_AUTO_LOGIN, values.get("auto_login", False))
|
||||
s.setValue(SETTINGS_KEY_USERNAME, values.get("username", ""))
|
||||
s.setValue(SETTINGS_KEY_PASSWORD, values.get("password", ""))
|
||||
s.setValue(SETTINGS_KEY_SERVER_URL, values.get("server_url", "http://localhost:8000"))
|
||||
s.setValue(SETTINGS_KEY_LANGUAGE, values.get("language", "da"))
|
||||
s.setValue(SETTINGS_KEY_BETWEEN_SEC, values.get("between_seconds", 60))
|
||||
s.setValue(SETTINGS_KEY_WORKSHOP_MIN,values.get("workshop_minutes", 10))
|
||||
@@ -230,15 +233,31 @@ class SettingsDialog(QDialog):
|
||||
layout = QVBoxLayout(tab)
|
||||
layout.setSpacing(12)
|
||||
|
||||
grp = QGroupBox("Automatisk login ved opstart")
|
||||
# Server URL
|
||||
grp_server = QGroupBox("Server")
|
||||
grp_server_layout = QFormLayout(grp_server)
|
||||
self._server_url = QLineEdit()
|
||||
self._server_url.setPlaceholderText("http://localhost:8000")
|
||||
grp_server_layout.addRow("API-adresse:", self._server_url)
|
||||
note_server = QLabel("Adressen på LineDance API-serveren.")
|
||||
note_server.setObjectName("result_count")
|
||||
grp_server_layout.addRow(note_server)
|
||||
layout.addWidget(grp_server)
|
||||
|
||||
# Login
|
||||
grp = QGroupBox("Konto")
|
||||
grp_layout = QFormLayout(grp)
|
||||
|
||||
btn_register = QPushButton("✚ Opret ny konto...")
|
||||
btn_register.clicked.connect(self._open_register)
|
||||
grp_layout.addRow(btn_register)
|
||||
|
||||
self._chk_auto_login = QCheckBox("Log automatisk ind når programmet starter")
|
||||
self._chk_auto_login.stateChanged.connect(self._on_auto_login_changed)
|
||||
grp_layout.addRow(self._chk_auto_login)
|
||||
|
||||
self._user_input = QLineEdit()
|
||||
self._user_input.setPlaceholderText("dit-brugernavn")
|
||||
self._user_input.setPlaceholderText("brugernavn eller e-mail")
|
||||
grp_layout.addRow("Brugernavn:", self._user_input)
|
||||
|
||||
self._pass_input = QLineEdit()
|
||||
@@ -257,6 +276,12 @@ class SettingsDialog(QDialog):
|
||||
layout.addStretch()
|
||||
return tab
|
||||
|
||||
def _open_register(self):
|
||||
from ui.register_dialog import RegisterDialog
|
||||
server_url = self._server_url.text().strip() or "http://localhost:8000"
|
||||
dlg = RegisterDialog(server_url=server_url, parent=self)
|
||||
dlg.exec()
|
||||
|
||||
def _build_language_tab(self) -> QWidget:
|
||||
tab = QWidget()
|
||||
layout = QVBoxLayout(tab)
|
||||
@@ -311,6 +336,7 @@ class SettingsDialog(QDialog):
|
||||
self._chk_auto_login.setChecked(auto)
|
||||
self._user_input.setText(v.get("username", ""))
|
||||
self._pass_input.setText(v.get("password", ""))
|
||||
self._server_url.setText(v.get("server_url", "http://localhost:8000"))
|
||||
self._user_input.setEnabled(auto)
|
||||
self._pass_input.setEnabled(auto)
|
||||
|
||||
@@ -328,6 +354,7 @@ class SettingsDialog(QDialog):
|
||||
"auto_login": self._chk_auto_login.isChecked(),
|
||||
"username": self._user_input.text().strip(),
|
||||
"password": self._pass_input.text(),
|
||||
"server_url": self._server_url.text().strip() or "http://localhost:8000",
|
||||
"language": self._lang_combo.currentData(),
|
||||
}
|
||||
save_settings(values)
|
||||
|
||||
Reference in New Issue
Block a user