140 lines
4.9 KiB
Python
140 lines
4.9 KiB
Python
"""
|
|
login_dialog.py — Login-dialog til at gå online.
|
|
Server-URL er hardcodet i config.
|
|
"""
|
|
|
|
from PyQt6.QtWidgets import (
|
|
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
|
|
QLineEdit, QPushButton, QFrame, QCheckBox,
|
|
)
|
|
from PyQt6.QtCore import Qt, QSettings
|
|
|
|
# ── Hardcodet server-URL ──────────────────────────────────────────────────────
|
|
API_URL = "https://api.linedanceplayer.dk"
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
class LoginDialog(QDialog):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.setWindowTitle("Gå online")
|
|
self.setFixedWidth(340)
|
|
self.setModal(True)
|
|
|
|
self._token: str | None = None
|
|
self._username: str | None = None
|
|
self._api_url = API_URL
|
|
|
|
self._build_ui()
|
|
self._load_saved_settings()
|
|
|
|
def _build_ui(self):
|
|
layout = QVBoxLayout(self)
|
|
layout.setSpacing(10)
|
|
layout.setContentsMargins(20, 20, 20, 20)
|
|
|
|
title = QLabel("Log ind på LineDance")
|
|
title.setObjectName("track_title")
|
|
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
layout.addWidget(title)
|
|
|
|
sub = QLabel("Synkroniser projekter og alternativ-danse med andre brugere")
|
|
sub.setObjectName("track_meta")
|
|
sub.setWordWrap(True)
|
|
sub.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
layout.addWidget(sub)
|
|
|
|
line = QFrame()
|
|
line.setFrameShape(QFrame.Shape.HLine)
|
|
layout.addWidget(line)
|
|
|
|
layout.addWidget(QLabel("Brugernavn:"))
|
|
self._user_input = QLineEdit()
|
|
self._user_input.setPlaceholderText("dit-brugernavn")
|
|
layout.addWidget(self._user_input)
|
|
|
|
layout.addWidget(QLabel("Kodeord:"))
|
|
self._pass_input = QLineEdit()
|
|
self._pass_input.setEchoMode(QLineEdit.EchoMode.Password)
|
|
self._pass_input.setPlaceholderText("••••••••")
|
|
self._pass_input.returnPressed.connect(self._on_login)
|
|
layout.addWidget(self._pass_input)
|
|
|
|
self._remember = QCheckBox("Husk brugernavn")
|
|
self._remember.setChecked(True)
|
|
layout.addWidget(self._remember)
|
|
|
|
self._status_label = QLabel("")
|
|
self._status_label.setObjectName("track_meta")
|
|
self._status_label.setWordWrap(True)
|
|
layout.addWidget(self._status_label)
|
|
|
|
btn_row = QHBoxLayout()
|
|
btn_cancel = QPushButton("Annuller")
|
|
btn_cancel.clicked.connect(self.reject)
|
|
btn_row.addWidget(btn_cancel)
|
|
|
|
self._btn_login = QPushButton("Log ind")
|
|
self._btn_login.setObjectName("btn_play")
|
|
self._btn_login.setDefault(True)
|
|
self._btn_login.clicked.connect(self._on_login)
|
|
btn_row.addWidget(self._btn_login)
|
|
|
|
layout.addLayout(btn_row)
|
|
|
|
def _load_saved_settings(self):
|
|
settings = QSettings("LineDance", "Player")
|
|
self._user_input.setText(settings.value("username", ""))
|
|
|
|
def _save_settings(self):
|
|
if self._remember.isChecked():
|
|
settings = QSettings("LineDance", "Player")
|
|
settings.setValue("username", self._user_input.text().strip())
|
|
|
|
def _on_login(self):
|
|
username = self._user_input.text().strip()
|
|
password = self._pass_input.text()
|
|
|
|
if not username or not password:
|
|
self._set_status("Udfyld brugernavn og kodeord", error=True)
|
|
return
|
|
|
|
self._btn_login.setEnabled(False)
|
|
self._set_status("Forbinder...")
|
|
|
|
try:
|
|
import urllib.request, urllib.parse, json
|
|
|
|
data = urllib.parse.urlencode({
|
|
"username": username,
|
|
"password": password,
|
|
}).encode()
|
|
|
|
req = urllib.request.Request(
|
|
f"{API_URL}/auth/login",
|
|
data=data,
|
|
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
method="POST",
|
|
)
|
|
with urllib.request.urlopen(req, timeout=8) as resp:
|
|
body = json.loads(resp.read())
|
|
self._token = body.get("access_token")
|
|
self._username = username
|
|
|
|
self._save_settings()
|
|
self._set_status("Logget ind!", error=False)
|
|
self.accept()
|
|
|
|
except Exception as e:
|
|
self._set_status(f"Fejl: {e}", error=True)
|
|
self._btn_login.setEnabled(True)
|
|
|
|
def _set_status(self, text: str, error: bool = False):
|
|
self._status_label.setText(text)
|
|
color = "#e74c3c" if error else "#2ecc71"
|
|
self._status_label.setStyleSheet(f"color: {color};")
|
|
|
|
def get_credentials(self) -> tuple[str, str, str]:
|
|
"""Returnerer (api_url, username, token) efter succesfuldt login."""
|
|
return self._api_url, self._username, self._token
|