📚 Improved configuration files & documentation 📚

This commit is contained in:
Till Tomczak 2025-06-01 02:18:16 +02:00
parent 47d0e291fb
commit 5aa7da2aa9
13 changed files with 316 additions and 60 deletions

View File

@ -26,7 +26,7 @@ class Config:
SESSION_COOKIE_SAMESITE = 'Lax' SESSION_COOKIE_SAMESITE = 'Lax'
# Database configuration # Database configuration
DATABASE_URL = os.environ.get('DATABASE_URL') or f'sqlite:///{os.path.join(PROJECT_ROOT, "data", "myp_platform.db")}' DATABASE_URL = os.environ.get('DATABASE_URL') or f'sqlite:///{os.path.join(PROJECT_ROOT, "database", "myp.db")}'
SQLALCHEMY_DATABASE_URI = DATABASE_URL SQLALCHEMY_DATABASE_URI = DATABASE_URL
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ENGINE_OPTIONS = { SQLALCHEMY_ENGINE_OPTIONS = {

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,118 @@
# Datenbank-Konfiguration MYP Platform
## Übersicht
Die MYP Platform verwendet **ausschließlich** eine SQLite-Datenbank:
```
database/myp.db
```
## Konfiguration
### Haupt-Konfiguration
- **Datei**: `config/settings.py`
- **Variable**: `DATABASE_PATH = os.path.join(BASE_DIR, "database", "myp.db")`
- **Engine**: SQLite mit WAL-Modus (Write-Ahead Logging)
### Sichergestellte Konsistenz
Alle folgenden Dateien wurden korrigiert, um ausschließlich `database/myp.db` zu verwenden:
#### ✅ Konfigurationsdateien
- `config/settings.py` - Haupt-Konfiguration
- `config/app_config.py` - Alternative Flask-Konfiguration (korrigiert)
#### ✅ Model- und Datenbankdateien
- `models.py` - Hauptmodelle und Engine-Konfiguration
- `database/db_manager.py` - Datenbank-Manager
#### ✅ Utilities und Tools
- `utils/migrate_db.py` - Datenbank-Migration (Legacy-Fallbacks entfernt)
- `utils/quick_fix.py` - Schnelle Reparatur-Tools (korrigiert)
- `utils/debug_drucker_erkennung.py` - Debug-Tools (korrigiert)
- `utils/database_utils.py` - Backup und Wartung
- `utils/database_cleanup.py` - Cleanup-Manager
- `utils/database_schema_migration.py` - Schema-Migration
### Entfernte/Korrigierte Inkonsistenzen
#### 🗑️ Gelöschte Dateien
- `database/production.db` (leer, 0KB) - entfernt
#### 🔧 Korrigierte Fallbacks
- **Entfernt**: Referenzen zu `app.db`, `database.db`, `data/myp_platform.db`
- **Korrigiert**: Tabellennamen von `printer` zu `printers`
- **Vereinheitlicht**: Alle Import-Pfade verwenden `config.settings.DATABASE_PATH`
## Verwendung
### Datenbank initialisieren
```python
from models import init_db
init_db()
```
### Session verwenden
```python
from models import get_cached_session
with get_cached_session() as session:
# Datenbankoperationen
pass
```
### Backup erstellen
```python
from utils.database_utils import DatabaseBackupManager
backup_manager = DatabaseBackupManager()
backup_manager.create_backup()
```
## Optimierungen
Die Datenbank ist für Produktionsumgebung optimiert:
- **WAL-Modus**: Write-Ahead Logging für bessere Performance
- **Connection Pooling**: Optimierte Verbindungsverwaltung
- **Caching**: Intelligent caching system für häufige Abfragen
- **Auto-Vacuum**: Automatische Speicherbereinigung
- **Indizierung**: Optimierte Indizes für bessere Performance
## Wartung
### Automatische Wartung
- WAL-Checkpoints alle 1000 Seiten
- Incremental Vacuum alle 60 Minuten
- Statistik-Updates alle 30 Minuten
### Manuelle Wartung
```bash
# Migration ausführen
python utils/migrate_db.py
# Schnelle Reparatur
python utils/quick_fix.py
# Diagnose
python utils/debug_drucker_erkennung.py
```
## Wichtige Hinweise
⚠️ **NUR `database/myp.db` verwenden!**
- Keine anderen Datenbankdateien verwenden
- Alle Tools und Scripts sind auf diese Datei konfiguriert
- Bei Problemen: Backup aus `database/backups/` verwenden
🔒 **Backup-Strategie**
- Automatische Backups in `database/backups/`
- Vor größeren Operationen manuelles Backup erstellen
- WAL- und SHM-Dateien gehören zur Datenbank (nicht löschen!)
📊 **Monitoring**
- Log-Dateien in `logs/app/`
- Performance-Monitoring via `utils/database_utils.py`
- Health-Checks über API-Endpunkte verfügbar

View File

@ -0,0 +1,119 @@
# MYP Platform - Windows Installation
## Überblick
Das MYP (Multi-User-Print) System ist ein Flask-basiertes Backend für Druckerverwaltung, das vollständig auf Windows kompatibel ist.
## Systemanforderungen
- Windows 10/11
- Python 3.8+
- Git (optional)
- Internetverbindung für Paketinstallation
## Installation
### 1. Python-Abhängigkeiten installieren
```powershell
# Im Projektverzeichnis
pip install -r requirements.txt
```
### 2. Datenbank initialisieren
```powershell
python -c "from models import init_database, create_initial_admin; init_database(); create_initial_admin()"
```
### 3. Anwendung starten
```powershell
python app.py
```
## Automatischer Start (Windows Service)
### Service-Wrapper erstellen
Das System kann als Windows-Service installiert werden.
### PowerShell-Skript für automatischen Start
```powershell
# start-myp.ps1
$env:FLASK_ENV = "production"
$env:FLASK_APP = "app.py"
python app.py
```
## Verfügbare Endpunkte
- **Frontend**: http://localhost:5000
- **API**: http://localhost:5000/api/
- **Admin**: http://localhost:5000/admin
## Standard-Login
- **Benutzername**: admin@admin.de
- **Passwort**: admin
## Konfiguration
### Ports anpassen
In `app.py` am Ende der Datei:
```python
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=False)
```
### SSL/HTTPS aktivieren
```python
# SSL-Kontext für HTTPS
ssl_context = ('cert.pem', 'key.pem')
app.run(host="0.0.0.0", port=443, ssl_context=ssl_context)
```
## Fehlerbehebung
### Port bereits in Verwendung
```powershell
# Prozess finden und beenden
netstat -ano | findstr :5000
taskkill /PID [PID] /F
```
### Python-Module fehlen
```powershell
pip install --upgrade pip
pip install -r requirements.txt --force-reinstall
```
### Datenbankfehler
```powershell
# Datenbank zurücksetzen
del database\myp.db
python -c "from models import init_database, create_initial_admin; init_database(); create_initial_admin()"
```
## Entwicklungsmodus
```powershell
$env:FLASK_ENV = "development"
$env:FLASK_DEBUG = "1"
python app.py
```
## Logs
- **Anwendung**: `logs/app/`
- **Authentifizierung**: `logs/auth/`
- **Fehler**: `logs/errors/`
- **Jobs**: `logs/jobs/`
## Windows-spezifische Features
- Automatische Windows-Kompatibilitätsfixes
- WMI-Integration für Systemüberwachung
- Windows-Event-Log-Integration
- Windows-Service-Support
## Sicherheit
- CSRF-Schutz aktiviert
- Rate-Limiting implementiert
- Sichere Session-Verwaltung
- SQL-Injection-Schutz
## Performance-Optimierung
- SQLite-Optimierungen für Windows
- Caching-Strategien
- Asynchrone Task-Verarbeitung
- Memory-Management

View File

@ -84026,3 +84026,4 @@ WHERE printers.active = 1 AND printers.status = ?) AS anon_1]
2025-06-01 01:59:51 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für system_alerts: '>' not supported between instances of 'NoneType' and 'int' 2025-06-01 01:59:51 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für system_alerts: '>' not supported between instances of 'NoneType' and 'int'
2025-06-01 02:00:01 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für online_printers: tuple index out of range 2025-06-01 02:00:01 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für online_printers: tuple index out of range
2025-06-01 02:01:31 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für online_printers: tuple index out of range 2025-06-01 02:01:31 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für online_printers: tuple index out of range
2025-06-01 02:03:31 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für system_alerts: '>' not supported between instances of 'NoneType' and 'int'

View File

@ -1840,3 +1840,4 @@ WHERE printers.active = 1 AND printers.status = ?) AS anon_1]
2025-06-01 01:59:51 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für system_alerts: '>' not supported between instances of 'NoneType' and 'int' 2025-06-01 01:59:51 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für system_alerts: '>' not supported between instances of 'NoneType' and 'int'
2025-06-01 02:00:01 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für online_printers: tuple index out of range 2025-06-01 02:00:01 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für online_printers: tuple index out of range
2025-06-01 02:01:31 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für online_printers: tuple index out of range 2025-06-01 02:01:31 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für online_printers: tuple index out of range
2025-06-01 02:03:31 - myp.dashboard - ERROR - Fehler beim Laden der Widget-Daten für system_alerts: '>' not supported between instances of 'NoneType' and 'int'

View File

@ -47,7 +47,7 @@ __all__ = ['User', 'Printer', 'Job', 'Stats', 'SystemLog', 'Base', 'GuestRequest
# ===== DATENBANK-KONFIGURATION MIT WAL UND OPTIMIERUNGEN ===== # ===== DATENBANK-KONFIGURATION MIT WAL UND OPTIMIERUNGEN =====
def configure_sqlite_for_production(dbapi_connection, connection_record): def configure_sqlite_for_production(dbapi_connection, _connection_record):
""" """
Konfiguriert SQLite für Produktionsumgebung mit WAL-Modus und Optimierungen. Konfiguriert SQLite für Produktionsumgebung mit WAL-Modus und Optimierungen.
""" """

View File

@ -30,28 +30,34 @@ def test_database_connection():
log_message("Teste Datenbankverbindung...") log_message("Teste Datenbankverbindung...")
try: try:
# Versuche SQLite-Datenbank zu öffnen # Pfad zur App hinzufügen für korrekten Import
db_files = ['database.db', 'app.db', 'myp.db'] sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
try:
from config.settings import DATABASE_PATH
db_file = DATABASE_PATH
except ImportError:
# Fallback für lokale Ausführung
db_file = os.path.join('database', 'myp.db')
for db_file in db_files:
if os.path.exists(db_file): if os.path.exists(db_file):
log_message(f"Gefundene Datenbankdatei: {db_file}") log_message(f"Gefundene Datenbankdatei: {db_file}")
conn = sqlite3.connect(db_file) conn = sqlite3.connect(db_file)
cursor = conn.cursor() cursor = conn.cursor()
# Prüfe ob Printer-Tabelle existiert # Prüfe ob Printers-Tabelle existiert
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='printer';") cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='printers';")
if cursor.fetchone(): if cursor.fetchone():
log_message("✅ Printer-Tabelle gefunden") log_message("✅ Printers-Tabelle gefunden")
# Zähle Drucker # Zähle Drucker
cursor.execute("SELECT COUNT(*) FROM printer;") cursor.execute("SELECT COUNT(*) FROM printers;")
count = cursor.fetchone()[0] count = cursor.fetchone()[0]
log_message(f"📊 Anzahl Drucker in Datenbank: {count}") log_message(f"📊 Anzahl Drucker in Datenbank: {count}")
# Zeige Drucker-Details # Zeige Drucker-Details
cursor.execute("SELECT id, name, plug_ip, status FROM printer;") cursor.execute("SELECT id, name, plug_ip, status FROM printers;")
printers = cursor.fetchall() printers = cursor.fetchall()
for printer in printers: for printer in printers:
@ -60,10 +66,11 @@ def test_database_connection():
conn.close() conn.close()
return True return True
else: else:
log_message("❌ Printer-Tabelle nicht gefunden") log_message("❌ Printers-Tabelle nicht gefunden")
conn.close() conn.close()
else:
log_message(f"❌ Datenbankdatei nicht gefunden: {db_file}")
log_message("❌ Keine gültige Datenbank gefunden")
return False return False
except Exception as e: except Exception as e:
@ -125,17 +132,21 @@ def test_network_connectivity():
# Lade Drucker aus Datenbank # Lade Drucker aus Datenbank
try: try:
db_files = ['database.db', 'app.db', 'myp.db'] # Verwende konfigurierten Datenbankpfad
try:
from config.settings import DATABASE_PATH
db_file = DATABASE_PATH
except ImportError:
db_file = os.path.join('database', 'myp.db')
printers = [] printers = []
for db_file in db_files:
if os.path.exists(db_file): if os.path.exists(db_file):
conn = sqlite3.connect(db_file) conn = sqlite3.connect(db_file)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT name, plug_ip FROM printer WHERE plug_ip IS NOT NULL;") cursor.execute("SELECT name, plug_ip FROM printers WHERE plug_ip IS NOT NULL;")
printers = cursor.fetchall() printers = cursor.fetchall()
conn.close() conn.close()
break
if not printers: if not printers:
log_message("❌ Keine Drucker mit IP-Adressen gefunden") log_message("❌ Keine Drucker mit IP-Adressen gefunden")
@ -194,17 +205,21 @@ def test_tapo_connections():
# Lade Drucker aus Datenbank # Lade Drucker aus Datenbank
try: try:
db_files = ['database.db', 'app.db', 'myp.db'] # Verwende konfigurierten Datenbankpfad
try:
from config.settings import DATABASE_PATH
db_file = DATABASE_PATH
except ImportError:
db_file = os.path.join('database', 'myp.db')
printers = [] printers = []
for db_file in db_files:
if os.path.exists(db_file): if os.path.exists(db_file):
conn = sqlite3.connect(db_file) conn = sqlite3.connect(db_file)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT id, name, plug_ip, plug_username, plug_password FROM printer WHERE plug_ip IS NOT NULL;") cursor.execute("SELECT id, name, plug_ip, plug_username, plug_password FROM printers WHERE plug_ip IS NOT NULL;")
printers = cursor.fetchall() printers = cursor.fetchall()
conn.close() conn.close()
break
if not printers: if not printers:
log_message("❌ Keine Drucker mit Tapo-Konfiguration gefunden") log_message("❌ Keine Drucker mit Tapo-Konfiguration gefunden")

View File

@ -34,12 +34,7 @@ def get_database_path():
os.path.join('database', 'myp.db'), os.path.join('database', 'myp.db'),
'myp.db', 'myp.db',
'../database/myp.db', '../database/myp.db',
'./database/myp.db', './database/myp.db'
# Legacy-Pfade für Rückwärtskompatibilität
os.path.join('database', 'app.db'),
'app.db',
'../database/app.db',
'./database/app.db'
] ]
for path in alternative_paths: for path in alternative_paths:

View File

@ -5,9 +5,16 @@ Schnelle Datenbank-Reparatur für kritische Fehler
import sqlite3 import sqlite3
import os import os
import sys
from datetime import datetime from datetime import datetime
# Datenbankpfad # Pfad zur App hinzufügen
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
try:
from config.settings import DATABASE_PATH
except ImportError:
# Fallback falls Import fehlschlägt
DATABASE_PATH = "database/myp.db" DATABASE_PATH = "database/myp.db"
def quick_fix_database(): def quick_fix_database():