Inhalt

Aktueller Ordner: duesseldorfer-schuelerinventar-python-client
⬅ Übergeordnet

duesk_client_minimal.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
DÜSK - Minimale Testversion
"""

import sys
import requests
import math

try:
    from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                                  QHBoxLayout, QLabel, QLineEdit, QPushButton, 
                                  QTableWidget, QTableWidgetItem, QMessageBox,
                                  QHeaderView, QDialog, QDialogButtonBox, 
                                  QFormLayout, QProgressDialog, QGroupBox,
                                  QTabWidget, QComboBox, QScrollArea, QTextEdit)
    from PyQt6.QtCore import Qt, QThread, pyqtSignal
    from PyQt6.QtGui import QFont
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", "PyQt6", "requests"])
    from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                                  QHBoxLayout, QLabel, QLineEdit, QPushButton, 
                                  QTableWidget, QTableWidgetItem, QMessageBox,
                                  QHeaderView, QDialog, QDialogButtonBox, 
                                  QFormLayout, QProgressDialog, QGroupBox,
                                  QTabWidget, QComboBox, QScrollArea, QTextEdit)
    from PyQt6.QtCore import Qt, QThread, pyqtSignal
    from PyQt6.QtGui import QFont

API_BASE_URL = "https://paul-koop.org/api/"


class APIWorker(QThread):
    finished = pyqtSignal(object)
    error = pyqtSignal(str)
    
    def __init__(self, endpoint, method="GET", data=None, params=None, user_id=None, session=None):
        super().__init__()
        self.endpoint = endpoint
        self.method = method
        self.data = data
        self.params = params
        self.user_id = user_id
        self.session = session
        
    def run(self):
        try:
            url = API_BASE_URL + self.endpoint
            headers = {'Content-Type': 'application/json'}
            if self.user_id and self.session:
                headers['X-User-ID'] = str(self.user_id)
                headers['X-Session'] = self.session
                
            if self.method == "GET":
                response = requests.get(url, headers=headers, params=self.params, timeout=30)
            elif self.method == "POST":
                response = requests.post(url, json=self.data, headers=headers, timeout=30)
            else:
                self.error.emit(f"Unbekannte Methode: {self.method}")
                return
                
            if response.status_code == 200:
                self.finished.emit(response.json())
            else:
                self.error.emit(f"HTTP {response.status_code}")
        except Exception as e:
            self.error.emit(str(e))


class LoginDialog(QDialog):
    def __init__(self):
        super().__init__()
        self.user_id = self.session = None
        self.setWindowTitle("DÜSK - Anmeldung")
        self.setModal(True)
        self.setMinimumSize(350, 200)
        
        layout = QVBoxLayout()
        layout.addWidget(QLabel("DÜSK - Düsseldorfer Schülerinventar", 
                                alignment=Qt.AlignmentFlag.AlignCenter,
                                font=QFont("Arial", 16, QFont.Weight.Bold)))
        
        form = QFormLayout()
        self.user_edit = QLineEdit()
        self.user_edit.setText("gast")
        self.pw_edit = QLineEdit()
        self.pw_edit.setText("gast")
        self.pw_edit.setEchoMode(QLineEdit.EchoMode.Password)
        form.addRow("Benutzername:", self.user_edit)
        form.addRow("Passwort:", self.pw_edit)
        layout.addLayout(form)
        
        btns = QDialogButtonBox()
        login = btns.addButton("Anmelden", QDialogButtonBox.ButtonRole.AcceptRole)
        cancel = btns.addButton("Abbrechen", QDialogButtonBox.ButtonRole.RejectRole)
        login.clicked.connect(self.do_login)
        cancel.clicked.connect(self.reject)
        layout.addWidget(btns)
        
        self.setLayout(layout)
        
    def do_login(self):
        worker = APIWorker("api_login.php", "POST", 
                          {"username": self.user_edit.text().strip(), 
                           "password": self.pw_edit.text().strip()})
        worker.finished.connect(self.on_success)
        worker.error.connect(lambda e: QMessageBox.critical(self, "Fehler", e))
        worker.start()
        
        self.progress = QProgressDialog("Anmeldung...", None, 0, 0, self)
        self.progress.show()
        
    def on_success(self, resp):
        self.progress.close()
        if resp.get('success') or resp.get('userID'):
            self.user_id = resp['userID']
            self.session = resp['session']
            self.accept()
        else:
            QMessageBox.warning(self, "Fehler", "Anmeldung fehlgeschlagen")


class MainWindow(QMainWindow):
    def __init__(self, user_id, session):
        super().__init__()
        self.user_id = user_id
        self.session = session
        self.setWindowTitle("DÜSK - Düsseldorfer Schülerinventar")
        self.setMinimumSize(800, 500)
        
        central = QWidget()
        self.setCentralWidget(central)
        layout = QVBoxLayout(central)
        
        # Header
        header = QLabel("DÜSK - Düsseldorfer Schülerinventar")
        header.setAlignment(Qt.AlignmentFlag.AlignCenter)
        header.setStyleSheet("font-size: 20px; font-weight: bold; background-color: #6699CC; color: white; padding: 10px;")
        layout.addWidget(header)
        
        # Info-Label
        info = QLabel(f"Eingeloggt als User {user_id}")
        info.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(info)
        
        # Refresh Button
        refresh_btn = QPushButton("Profile laden")
        refresh_btn.clicked.connect(self.load_profiles)
        layout.addWidget(refresh_btn)
        
        # Tabelle
        self.table = QTableWidget()
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels(["Name", "Gruppe", "ProfilID"])
        self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        layout.addWidget(self.table)
        
        # Footer
        footer = QLabel("Paul Koop M.A. - Thomashofstrasse 19, 52070 Aachen")
        footer.setAlignment(Qt.AlignmentFlag.AlignCenter)
        footer.setStyleSheet("background-color: #6699CC; color: white; padding: 8px; margin-top: 10px;")
        layout.addWidget(footer)
        
        # Profile laden
        self.load_profiles()
        
    def load_profiles(self):
        print("Lade Profile...")
        worker = APIWorker("api_profiles.php", "GET", user_id=self.user_id, session=self.session)
        worker.finished.connect(self.on_profiles)
        worker.error.connect(lambda e: QMessageBox.critical(self, "Fehler", e))
        worker.start()
        
    def on_profiles(self, resp):
        print(f"Antwort erhalten: {type(resp)}")
        if isinstance(resp, list):
            self.table.setRowCount(len(resp))
            for i, p in enumerate(resp):
                self.table.setItem(i, 0, QTableWidgetItem(p.get('name', '')))
                self.table.setItem(i, 1, QTableWidgetItem(p.get('gruppename', '')))
                self.table.setItem(i, 2, QTableWidgetItem(str(p.get('profilID', ''))))
            print(f"{len(resp)} Profile geladen")
        else:
            print(f"Unerwarteter Antwort-Typ: {type(resp)}")


def main():
    print("Starte DÜSK Client...")
    app = QApplication(sys.argv)
    login = LoginDialog()
    if login.exec() == QDialog.DialogCode.Accepted:
        print(f"Login erfolgreich - UserID: {login.user_id}")
        window = MainWindow(login.user_id, login.session)
        window.show()
        print("Hauptfenster wird angezeigt")
        sys.exit(app.exec())
    else:
        print("Login abgebrochen")
        sys.exit(0)

if __name__ == "__main__":
    main()