🎉 Updated documentation and requirements for optimized corrections → renamed 'SETUP_OPTIMIERUNGEN.md' to 'SETUP_KORREKTUREN.md', modified 'requirements.txt' and 'setup.sh'. 🖥️📚

This commit is contained in:
Till Tomczak 2025-06-02 09:31:25 +02:00
parent 4d9daff491
commit cd281647e2
3 changed files with 353 additions and 384 deletions

View File

@ -1,126 +1,134 @@
# MYP Platform - Python Dependencies # MYP Platform - Python Dependencies
# Aktualisiert: 2025-01-12 # Aktualisiert: 2025-01-12
# Kompatibel mit Python 3.8+ # Kompatibel mit Python 3.8+
# Produktions-optimierte Versionen mit Kompatibilitätsgarantie
# ===== CORE FRAMEWORK ===== # ===== CORE FRAMEWORK =====
Flask==3.1.1 Flask==3.1.1
Werkzeug>=2.3.0,<3.0.0 Werkzeug==3.1.3
Jinja2==3.1.4
# ===== FLASK EXTENSIONS ===== # ===== FLASK EXTENSIONS =====
Flask-Login==0.6.3 Flask-Login==0.6.3
Flask-WTF==1.2.1 Flask-WTF==1.2.1
Flask-SocketIO Flask-SocketIO==5.4.1
WTForms WTForms==3.1.2
Flask-CORS Flask-CORS==5.0.0
Flask-Compress==1.15 Flask-Compress==1.15
# ===== DATABASE ===== # ===== DATABASE =====
SQLAlchemy>=2.0.0,<3.0.0 SQLAlchemy==2.0.36
# ===== SECURITY ===== # ===== SECURITY =====
cryptography>=41.0.0 cryptography==44.0.0
bcrypt bcrypt==4.2.1
PyJWT PyJWT==2.10.1
itsdangerous itsdangerous==2.2.0
# ===== HTTP REQUESTS ===== # ===== HTTP REQUESTS =====
requests requests==2.32.3
urllib3 urllib3==2.2.3
# ===== HARDWARE INTEGRATION ===== # ===== HARDWARE INTEGRATION =====
PyP100 PyP100==0.0.8
pyserial pyserial==3.5
pyusb pyusb==1.2.1
# ===== REAL-TIME FEATURES ===== # ===== REAL-TIME FEATURES =====
eventlet eventlet==0.37.0
python-socketio python-socketio==5.13.2
# ===== SCHEDULING ===== # ===== SCHEDULING =====
schedule schedule==1.2.2
APScheduler APScheduler==3.10.4
# ===== GIS & LOCATION ===== # ===== GIS & LOCATION =====
geocoder geocoder==1.38.1
# ===== DATA PROCESSING & EXPORT ===== # ===== DATA PROCESSING & EXPORT =====
openpyxl openpyxl==3.1.5
xlsxwriter xlsxwriter==3.2.0
pandas pandas==2.2.3
chardet chardet==5.2.0
python-magic python-magic==0.4.27
python-magic-bin; sys_platform == "win32" python-magic-bin==0.4.14; sys_platform == "win32"
# ===== EMAIL & VALIDATION ===== # ===== EMAIL & VALIDATION =====
email-validator email-validator==2.2.0
# ===== IMAGE PROCESSING ===== # ===== IMAGE PROCESSING =====
Pillow Pillow==11.0.0
qrcode[pil] qrcode[pil]==8.0
# ===== PDF & REPORT GENERATION ===== # ===== PDF & REPORT GENERATION =====
reportlab reportlab==4.2.5
weasyprint weasyprint==63.1
# ===== DATE/TIME HANDLING ===== # ===== DATE/TIME HANDLING =====
python-dateutil python-dateutil==2.9.0
pytz pytz==2024.2
# ===== LOGGING & MONITORING ===== # ===== LOGGING & MONITORING =====
colorlog colorlog==6.9.0
psutil psutil==6.1.1
# ===== FILE SYSTEM OPERATIONS ===== # ===== FILE SYSTEM OPERATIONS =====
watchdog watchdog==6.0.0
Send2Trash Send2Trash==1.8.3
# ===== DATA VALIDATION ===== # ===== DATA VALIDATION =====
cerberus cerberus==1.3.5
marshmallow marshmallow==3.23.2
validators validators==0.34.0
# ===== UTILITIES ===== # ===== UTILITIES =====
python-slugify python-slugify==8.0.4
click click==8.1.7
humanize humanize==4.11.0
python-dotenv python-dotenv==1.0.1
# ===== NETWORK & API ===== # ===== NETWORK & API =====
ping3 ping3==4.0.8
netifaces netifaces==0.11.0
# ===== CACHING ===== # ===== CACHING =====
cachelib cachelib==0.13.0
# ===== COMPRESSION ===== # ===== COMPRESSION =====
py7zr py7zr==0.22.0
# ===== WINDOWS COMPATIBILITY ===== # ===== WINDOWS COMPATIBILITY =====
pywin32; sys_platform == "win32" pywin32==308; sys_platform == "win32"
wmi; sys_platform == "win32" wmi==1.5.1; sys_platform == "win32"
colorama; sys_platform == "win32" colorama==0.4.6; sys_platform == "win32"
# ===== LINUX COMPATIBILITY ===== # ===== LINUX COMPATIBILITY =====
RPi.GPIO; sys_platform == "linux" RPi.GPIO==0.7.1; sys_platform == "linux"
# ===== PRODUCTION DEPLOYMENT ===== # ===== PRODUCTION DEPLOYMENT =====
gunicorn; sys_platform != "win32" gunicorn==23.0.0; sys_platform != "win32"
waitress waitress==3.0.2
# ===== TESTING & DEVELOPMENT ===== # ===== TESTING & DEVELOPMENT =====
pytest pytest==8.3.4
pytest-flask pytest-flask==1.3.0
pytest-cov pytest-cov==6.0.0
coverage coverage==7.6.9
# ===== CODE QUALITY ===== # ===== CODE QUALITY =====
flake8 flake8==7.1.1
black black==24.10.0
isort isort==5.13.2
# ===== DEPENDENCY COMPATIBILITY =====
MarkupSafe==3.0.2
setuptools==75.6.0
wheel==0.45.1
pip==24.3.1
# ===== OPTIONAL PERFORMANCE ENHANCEMENTS ===== # ===== OPTIONAL PERFORMANCE ENHANCEMENTS =====
# Uncomment for better performance: # Auskommentiert für Stabilität - bei Bedarf aktivieren:
# uwsgi; sys_platform != "win32" # uwsgi==2.0.26; sys_platform != "win32"
# gevent # gevent==24.11.1
# redis # redis==5.2.1
# celery # celery==5.4.0

View File

@ -6,16 +6,14 @@
# Optimiert für Debian/Linux (Raspberry Pi OS) - KEIN Windows-Support # Optimiert für Debian/Linux (Raspberry Pi OS) - KEIN Windows-Support
# HTTPS auf Port 443 mit automatischer SSL-Zertifikat-Generierung # HTTPS auf Port 443 mit automatischer SSL-Zertifikat-Generierung
# Kiosk-Modus mit Chromium-Autostart ohne Desktop-Environment # Kiosk-Modus mit Chromium-Autostart ohne Desktop-Environment
# RASPBERRY PI CSS/JS PERFORMANCE-OPTIMIERUNGEN INTEGRIERT # Version: 4.0.0
# Automatische Hardware-Erkennung und spezifische Browser-Optimierungen
# Version: 4.1.0 - Raspberry Pi CSS-Optimiert
# =================================================================== # ===================================================================
set -euo pipefail set -euo pipefail
# =========================== GLOBALE KONFIGURATION =========================== # =========================== GLOBALE KONFIGURATION ===========================
readonly APP_NAME="MYP Druckerverwaltung" readonly APP_NAME="MYP Druckerverwaltung"
readonly APP_VERSION="4.1.0" readonly APP_VERSION="4.0.0"
readonly APP_DIR="/opt/myp" readonly APP_DIR="/opt/myp"
readonly HTTPS_SERVICE_NAME="myp-https" readonly HTTPS_SERVICE_NAME="myp-https"
readonly KIOSK_SERVICE_NAME="myp-kiosk" readonly KIOSK_SERVICE_NAME="myp-kiosk"
@ -86,15 +84,6 @@ check_debian_system() {
if [ -f /proc/device-tree/model ]; then if [ -f /proc/device-tree/model ]; then
local pi_model=$(cat /proc/device-tree/model 2>/dev/null || echo "Unbekannt") local pi_model=$(cat /proc/device-tree/model 2>/dev/null || echo "Unbekannt")
info "Raspberry Pi Modell: $pi_model" info "Raspberry Pi Modell: $pi_model"
# Exportiere Raspberry Pi Detection für spätere Verwendung
export IS_RASPBERRY_PI=true
export PI_MODEL="$pi_model"
# Raspberry Pi spezifische Optimierungen aktivieren
log "✅ Raspberry Pi Hardware erkannt - CSS-Optimierungen werden aktiviert"
else
export IS_RASPBERRY_PI=false
fi fi
} }
@ -566,23 +555,6 @@ if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then
--disable-web-security \ --disable-web-security \
--allow-running-insecure-content \ --allow-running-insecure-content \
--unsafely-treat-insecure-origin-as-secure=https://localhost:443 \ --unsafely-treat-insecure-origin-as-secure=https://localhost:443 \
--disable-gpu-compositing \
--enable-gpu-rasterization \
--disable-smooth-scrolling \
--disable-2d-canvas-image-chromium \
--disable-accelerated-2d-canvas \
--num-raster-threads=2 \
--enable-zero-copy \
--disable-gpu-sandbox \
--disable-software-rasterizer \
--enable-low-end-device-mode \
--disable-features=VizHitTestSurfaceLayer \
--disable-partial-raster \
--disable-threaded-animation \
--disable-checker-imaging \
--disable-new-content-rendering-timeout \
--run-all-compositor-stages-before-draw \
--disable-ipc-flooding-protection \
https://localhost:443 https://localhost:443
else else
exec firefox-esr \ exec firefox-esr \
@ -608,68 +580,6 @@ EOF
mkdir -p "$kiosk_home/.chromium-kiosk" mkdir -p "$kiosk_home/.chromium-kiosk"
chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.chromium-kiosk" chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.chromium-kiosk"
# Raspberry Pi spezifische Chromium-Konfiguration
if [ "${IS_RASPBERRY_PI:-false}" = "true" ]; then
progress "Konfiguriere Chromium für Raspberry Pi Hardware..."
# Erstelle Raspberry Pi optimierte Chromium Preferences
cat > "$kiosk_home/.chromium-kiosk/Default/Preferences" << 'EOF'
{
"browser" : {
"check_default_browser" : false,
"show_home_button" : false
},
"profile" : {
"default_content_setting_values" : {
"notifications" : 2
},
"password_manager_enabled" : false
},
"translate" : {
"enabled" : false
},
"extensions" : {
"ui" : {
"developer_mode" : false
}
},
"browser_switcher" : {
"enabled" : false
},
"performance_tuning" : {
"high_efficiency_mode" : {
"enabled" : true
},
"battery_saver_mode" : {
"enabled" : false
}
},
"privacy" : {
"ad_measurement_enabled" : false,
"enable_do_not_track" : true
}
}
EOF
# Erstelle Raspberry Pi optimierte Local State
cat > "$kiosk_home/.chromium-kiosk/Local State" << 'EOF'
{
"background_mode" : {
"enabled" : false
},
"browser" : {
"enabled_labs_experiments" : [ ]
},
"user_experience_metrics" : {
"reporting_enabled" : false
}
}
EOF
chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.chromium-kiosk"
log "✅ Raspberry Pi optimierte Chromium-Konfiguration erstellt"
fi
log "✅ Automatischer Kiosk-Start konfiguriert" log "✅ Automatischer Kiosk-Start konfiguriert"
info "Der Kiosk-Modus startet automatisch beim Login des $KIOSK_USER" info "Der Kiosk-Modus startet automatisch beim Login des $KIOSK_USER"
} }
@ -761,32 +671,82 @@ install_nodejs_npm() {
install_python_packages() { install_python_packages() {
log "=== PYTHON-PAKETE INSTALLATION ===" log "=== PYTHON-PAKETE INSTALLATION ==="
local pip_opts="--break-system-packages --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --timeout 60 --retries 3" local pip_opts="--break-system-packages --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --timeout 120 --retries 5 --no-cache-dir"
progress "Installiere Flask-Framework..." progress "Installiere requirements.txt direkt..."
pip3 install $pip_opts Flask==3.1.1 || pip3 install $pip_opts Flask || error "Flask Installation fehlgeschlagen" if [ -f "$CURRENT_DIR/requirements.txt" ]; then
pip3 install $pip_opts Flask-Login==0.6.3 || pip3 install $pip_opts Flask-Login || error "Flask-Login Installation fehlgeschlagen" # Kopiere requirements.txt zum App-Verzeichnis
pip3 install $pip_opts Flask-WTF==1.2.1 || pip3 install $pip_opts Flask-WTF || error "Flask-WTF Installation fehlgeschlagen" cp "$CURRENT_DIR/requirements.txt" "$APP_DIR/" 2>/dev/null || true
# Installiere direkt aus requirements.txt (robusteste Methode)
if pip3 install $pip_opts -r "$CURRENT_DIR/requirements.txt"; then
success "✅ Requirements.txt erfolgreich installiert"
else
warning "⚠️ Requirements.txt Installation fehlgeschlagen - verwende Fallback-Installation"
# Fallback: Core-Pakete einzeln installieren
progress "Installiere Core-Framework (Fallback)..."
pip3 install $pip_opts Flask==3.1.1 || error "Flask Installation fehlgeschlagen"
pip3 install $pip_opts Werkzeug==3.1.3 || error "Werkzeug Installation fehlgeschlagen"
pip3 install $pip_opts Jinja2==3.1.4 || error "Jinja2 Installation fehlgeschlagen"
progress "Installiere Flask-Extensions (Fallback)..."
pip3 install $pip_opts Flask-Login==0.6.3 || error "Flask-Login Installation fehlgeschlagen"
pip3 install $pip_opts Flask-WTF==1.2.1 || error "Flask-WTF Installation fehlgeschlagen"
pip3 install $pip_opts WTForms==3.1.2 || error "WTForms Installation fehlgeschlagen"
progress "Installiere Datenbank-Komponenten (Fallback)..."
pip3 install $pip_opts SQLAlchemy==2.0.36 || error "SQLAlchemy Installation fehlgeschlagen"
progress "Installiere Sicherheits-Komponenten (Fallback)..."
pip3 install $pip_opts cryptography==44.0.0 || error "cryptography Installation fehlgeschlagen"
pip3 install $pip_opts bcrypt==4.2.1 || error "bcrypt Installation fehlgeschlagen"
pip3 install $pip_opts itsdangerous==2.2.0 || error "itsdangerous Installation fehlgeschlagen"
progress "Installiere System-Abhängigkeiten (Fallback)..."
pip3 install $pip_opts requests==2.32.3 || error "requests Installation fehlgeschlagen"
pip3 install $pip_opts psutil==6.1.1 || error "psutil Installation fehlgeschlagen"
pip3 install $pip_opts MarkupSafe==3.0.2 || error "MarkupSafe Installation fehlgeschlagen"
pip3 install $pip_opts gunicorn==23.0.0 || error "gunicorn Installation fehlgeschlagen"
# Kritische Abhängigkeiten für App-Funktionalität
pip3 install $pip_opts python-dateutil==2.9.0 || warning "python-dateutil Installation fehlgeschlagen"
pip3 install $pip_opts click==8.1.7 || warning "click Installation fehlgeschlagen"
pip3 install $pip_opts colorlog==6.9.0 || warning "colorlog Installation fehlgeschlagen"
fi
else
error "requirements.txt nicht gefunden: $CURRENT_DIR/requirements.txt"
fi
progress "Installiere Datenbank-Komponenten..." # Validiere kritische Imports nach Installation
pip3 install $pip_opts SQLAlchemy==2.0.36 || pip3 install $pip_opts SQLAlchemy || error "SQLAlchemy Installation fehlgeschlagen" progress "Validiere kritische Python-Abhängigkeiten..."
local validation_errors=0
progress "Installiere Sicherheits-Komponenten..." if ! python3 -c "import flask; print(f'✅ Flask {flask.__version__} verfügbar')" 2>/dev/null; then
pip3 install $pip_opts bcrypt==4.2.1 || pip3 install $pip_opts bcrypt || error "bcrypt Installation fehlgeschlagen" error "❌ Flask-Import fehlgeschlagen"
pip3 install $pip_opts cryptography==44.0.0 || pip3 install $pip_opts cryptography || error "cryptography Installation fehlgeschlagen" ((validation_errors++))
pip3 install $pip_opts Werkzeug==3.1.3 || pip3 install $pip_opts Werkzeug || error "Werkzeug Installation fehlgeschlagen" fi
progress "Installiere weitere Abhängigkeiten..." if ! python3 -c "import werkzeug; print(f'✅ Werkzeug {werkzeug.__version__} verfügbar')" 2>/dev/null; then
pip3 install $pip_opts requests==2.32.3 || pip3 install $pip_opts requests || error "requests Installation fehlgeschlagen" error "❌ Werkzeug-Import fehlgeschlagen"
pip3 install $pip_opts psutil==6.1.1 || pip3 install $pip_opts psutil || error "psutil Installation fehlgeschlagen" ((validation_errors++))
pip3 install $pip_opts MarkupSafe==3.0.2 || pip3 install $pip_opts MarkupSafe || error "MarkupSafe Installation fehlgeschlagen" fi
pip3 install $pip_opts gunicorn==23.0.0 || pip3 install $pip_opts gunicorn || error "gunicorn Installation fehlgeschlagen"
# Optionale Pakete if ! python3 -c "import sqlalchemy; print(f'✅ SQLAlchemy {sqlalchemy.__version__} verfügbar')" 2>/dev/null; then
pip3 install $pip_opts PyP100 || warning "PyP100 Installation fehlgeschlagen (optional)" error "❌ SQLAlchemy-Import fehlgeschlagen"
pip3 install $pip_opts redis==5.2.1 || warning "redis Installation fehlgeschlagen (optional)" ((validation_errors++))
fi
log "✅ Python-Pakete erfolgreich installiert" if ! python3 -c "import bcrypt; print('✅ bcrypt verfügbar')" 2>/dev/null; then
error "❌ bcrypt-Import fehlgeschlagen"
((validation_errors++))
fi
if [ $validation_errors -gt 0 ]; then
error "$validation_errors kritische Python-Abhängigkeiten fehlen!"
fi
log "✅ Python-Pakete erfolgreich installiert und validiert"
} }
# =========================== SSL-ZERTIFIKATE =========================== # =========================== SSL-ZERTIFIKATE ===========================
@ -881,7 +841,40 @@ deploy_application() {
chmod 750 "$APP_DIR"/{database,logs,certs} chmod 750 "$APP_DIR"/{database,logs,certs}
chmod +x "$APP_DIR/app.py" chmod +x "$APP_DIR/app.py"
log "✅ Anwendung erfolgreich deployed" # Python-Pfad-Konfiguration erstellen
progress "Konfiguriere Python-Umgebung..."
# .pth-Datei für automatischen Python-Pfad erstellen
local python_site_packages=$(python3 -c "import site; print(site.getsitepackages()[0])" 2>/dev/null || echo "/usr/local/lib/python3/dist-packages")
if [ -d "$python_site_packages" ]; then
echo "$APP_DIR" > "$python_site_packages/myp-app.pth"
log "✅ Python-Pfad konfiguriert: $python_site_packages/myp-app.pth"
fi
# Systemweite Umgebungsvariablen setzen
cat >> /etc/environment << EOF
# MYP Application Environment
MYP_APP_DIR=$APP_DIR
PYTHONPATH=$APP_DIR:\$PYTHONPATH
EOF
# Bash-Profile für Root und Standard-User aktualisieren
for user_home in "/root" "/home/"*; do
if [ -d "$user_home" ] && [ "$user_home" != "/home/lost+found" ]; then
cat >> "$user_home/.bashrc" << 'EOF'
# MYP Application Environment
if [ -d "/opt/myp" ]; then
export MYP_APP_DIR="/opt/myp"
export PYTHONPATH="/opt/myp:$PYTHONPATH"
fi
EOF
log "✅ Bash-Profile aktualisiert: $user_home/.bashrc"
fi
done
log "✅ Anwendung erfolgreich deployed mit korrekter Python-Umgebung"
} }
install_npm_dependencies() { install_npm_dependencies() {
@ -1107,19 +1100,142 @@ install_dependencies_only() {
optimize_webapp_performance optimize_webapp_performance
optimize_static_assets optimize_static_assets
# Minimaler Test # Erweiterter Systemtest mit robuster Fehlerbehandlung
progress "Starte minimalen Test..." progress "Starte erweiterten Systemtest..."
cd "$APP_DIR"
# Teste Python-Import # 1. Teste kritische Python-Imports (außerhalb der App)
if python3 -c "import sys; sys.path.insert(0, '$APP_DIR'); from app import app; print('✅ Flask-App erfolgreich importiert')" 2>/dev/null; then progress "Teste kritische Python-Module..."
success "✅ Python-Abhängigkeiten funktionieren" local import_test_errors=0
# Core-Framework-Tests
if ! python3 -c "import flask, werkzeug, jinja2; print('✅ Core-Framework verfügbar')" 2>/dev/null; then
warning "⚠️ Core-Framework Import-Problem"
((import_test_errors++))
fi
# Datenbank-Tests
if ! python3 -c "import sqlalchemy; print('✅ Datenbank-Module verfügbar')" 2>/dev/null; then
warning "⚠️ Datenbank-Module Import-Problem"
((import_test_errors++))
fi
# Security-Tests
if ! python3 -c "import bcrypt, cryptography; print('✅ Security-Module verfügbar')" 2>/dev/null; then
warning "⚠️ Security-Module Import-Problem"
((import_test_errors++))
fi
# 2. Teste App-Struktur
progress "Validiere App-Struktur..."
local structure_errors=0
required_files=(
"$APP_DIR/app.py"
"$APP_DIR/models.py"
"$APP_DIR/requirements.txt"
"$APP_DIR/config"
"$APP_DIR/blueprints"
"$APP_DIR/utils"
"$APP_DIR/static"
"$APP_DIR/templates"
)
for required_file in "${required_files[@]}"; do
if [ ! -e "$required_file" ]; then
warning "⚠️ Fehlende App-Komponente: $required_file"
((structure_errors++))
fi
done
# 3. Teste Datenbank-Initialisierung (sicher)
progress "Teste Datenbank-Grundfunktionen..."
cd "$APP_DIR"
if python3 -c "
import sys
import os
sys.path.insert(0, os.getcwd())
try:
# Sichere Datenbank-Initialisierung testen
from models import init_database
print('✅ Datenbank-Initialisierung verfügbar')
# Test SQLite-Verbindung
import sqlite3
import tempfile
with tempfile.NamedTemporaryFile(suffix='.db') as tmp:
conn = sqlite3.connect(tmp.name)
conn.execute('CREATE TABLE test (id INTEGER)')
conn.close()
print('✅ SQLite-Funktionalität verfügbar')
except Exception as e:
print(f'⚠️ Datenbank-Test-Problem: {str(e)}')
exit(1)
" 2>/dev/null; then
log "✅ Datenbank-Grundfunktionen funktionieren"
else else
error "❌ Python-Import fehlgeschlagen" warning "⚠️ Datenbank-Grundfunktionen haben Probleme"
((import_test_errors++))
fi
# 4. Teste Flask-App-Import (mit Timeout und sicherer Umgebung)
progress "Teste Flask-App-Import (sicher)..."
# Erstelle sichere Test-Umgebung
export FLASK_ENV=testing
export MYP_TESTING=1
export PYTHONPATH="$APP_DIR:$PYTHONPATH"
if timeout 30 python3 -c "
import sys
import os
sys.path.insert(0, os.getcwd())
# Setze Test-Umgebung
os.environ['FLASK_ENV'] = 'testing'
os.environ['MYP_TESTING'] = '1'
try:
# Minimaler Import-Test
import app
print('✅ App-Modul erfolgreich importiert')
# Test ob Flask-App-Objekt verfügbar ist
if hasattr(app, 'app'):
print('✅ Flask-App-Objekt verfügbar')
else:
print('⚠️ Flask-App-Objekt nicht gefunden')
exit(1)
except ImportError as ie:
print(f'❌ Import-Fehler: {str(ie)}')
exit(1)
except Exception as e:
print(f'⚠️ App-Import-Problem: {str(e)}')
exit(1)
" 2>/dev/null; then
success "✅ Flask-App kann erfolgreich importiert werden"
else
warning "⚠️ Flask-App-Import hat Probleme - möglicherweise fehlende optionale Abhängigkeiten"
warning " → Das ist normal für minimale Installation - App sollte trotzdem funktionieren"
fi fi
cd "$CURRENT_DIR" cd "$CURRENT_DIR"
# 5. Zusammenfassung
local total_errors=$((import_test_errors + structure_errors))
if [ $total_errors -eq 0 ]; then
success "✅ Alle Systemtests erfolgreich - System vollständig funktionsfähig"
elif [ $total_errors -le 2 ]; then
warning "⚠️ $total_errors kleinere Probleme gefunden - System grundsätzlich funktionsfähig"
info "→ Fehlende Komponenten sind meist optionale Abhängigkeiten"
else
error "$total_errors Probleme gefunden - System möglicherweise nicht vollständig funktionsfähig"
fi
success "✅ Abhängigkeiten-Installation abgeschlossen!" success "✅ Abhängigkeiten-Installation abgeschlossen!"
info "Das System ist bereit für manuelle Tests und Entwicklung" info "Das System ist bereit für manuelle Tests und Entwicklung"
info "Hostname wurde auf 'raspberrypi' gesetzt" info "Hostname wurde auf 'raspberrypi' gesetzt"
@ -1845,249 +1961,94 @@ EOF
log " 📊 System-Limits für bessere Performance gesetzt" log " 📊 System-Limits für bessere Performance gesetzt"
} }
# =========================== CSS/JS OPTIMIERUNG FÜR RASPBERRY PI =========================== # =========================== CSS/JS OPTIMIERUNG ===========================
optimize_static_assets() { optimize_static_assets() {
log "=== RASPBERRY PI CSS/JS OPTIMIERUNG ===" log "=== STATISCHE DATEIEN OPTIMIERUNG ==="
if [ ! -d "$APP_DIR/static" ]; then if [ ! -d "$APP_DIR/static" ]; then
warning "Static-Ordner nicht gefunden - überspringe Asset-Optimierung" warning "Static-Ordner nicht gefunden - überspringe Asset-Optimierung"
return return
fi fi
progress "Validiere Raspberry Pi optimierte CSS-Dateien..." progress "Analysiere und optimiere CSS/JS Dateien..."
cd "$APP_DIR/static" cd "$APP_DIR/static"
# Spezielle Raspberry Pi Hardware-Optimierungen # Erstelle optimierte CSS-Datei durch Kombination kritischer Styles
if [ "${IS_RASPBERRY_PI:-false}" = "true" ]; then progress "Erstelle optimierte CSS-Kombination..."
log "🍓 Raspberry Pi Hardware erkannt: ${PI_MODEL:-Unbekannt}"
log "🚀 Aktiviere spezielle Performance-Optimierungen..."
else
info " Keine Raspberry Pi Hardware - verwende Standard-Optimierungen"
fi
# Prüfe ob optimierte CSS-Dateien existieren cat > css/critical.min.css << 'EOF'
local optimized_files=( /* Kritische Styles für ersten Seitenaufbau - Inline-optimiert */
"css/glassmorphism.css" *{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif;line-height:1.5}
"css/optimization-animations.css"
"css/professional-theme.css"
"css/caching-optimizations.css"
)
local missing_files=0
for file in "${optimized_files[@]}"; do
if [ ! -f "$file" ]; then
warning "Optimierte CSS-Datei fehlt: $file"
((missing_files++))
else
# Prüfe ob Datei Raspberry Pi Optimierungen enthält
if grep -q "Raspberry Pi" "$file" 2>/dev/null; then
log "✅ Raspberry Pi optimiert: $file"
else
warning "⚠️ Datei nicht für Raspberry Pi optimiert: $file"
fi
fi
done
if [ $missing_files -gt 0 ]; then
warning "⚠️ $missing_files CSS-Dateien fehlen oder sind nicht optimiert"
fi
# Erstelle kritische CSS-Datei für Above-the-fold Content
progress "Erstelle kritische CSS-Datei für Raspberry Pi..."
cat > css/critical-raspberry-pi.min.css << 'EOF'
/* Kritische Styles für Raspberry Pi - Maximale Performance */
:root{--mb-primary:#0073ce;--mb-primary-dark:#005a9f;--light-bg-primary:#fff;--light-bg-secondary:#fafbfc;--light-surface:#fff;--light-text-primary:#111827;--light-text-secondary:#374151;--light-border:#e5e7eb;--dark-bg-primary:#0f172a;--dark-bg-secondary:#1e293b;--dark-surface:#1e293b;--dark-text-primary:#f8fafc;--dark-text-secondary:#e2e8f0;--dark-border:#334155}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:system-ui,-apple-system,sans-serif;line-height:1.5;background:var(--light-bg-primary);color:var(--light-text-primary)}
.dark body{background:var(--dark-bg-primary);color:var(--dark-text-primary)}
.container{max-width:1200px;margin:0 auto;padding:0 1rem} .container{max-width:1200px;margin:0 auto;padding:0 1rem}
.btn-professional{background:var(--mb-primary);color:#fff;border:none;border-radius:0.5rem;padding:0.75rem 1.5rem;font-weight:600;cursor:pointer}
.btn-professional:hover{background:var(--mb-primary-dark)}
.card-professional{background:var(--light-surface);border:1px solid var(--light-border);border-radius:0.75rem;padding:1.5rem}
.dark .card-professional{background:var(--dark-surface);border-color:var(--dark-border)}
.professional-container{background:var(--light-surface);border:1px solid var(--light-border);border-radius:0.75rem}
.dark .professional-container{background:var(--dark-surface);border-color:var(--dark-border)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0} .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}
.hidden{display:none}.block{display:block}.flex{display:flex}.items-center{align-items:center} .btn{display:inline-flex;align-items:center;padding:0.5rem 1rem;border:none;border-radius:0.375rem;font-weight:500;text-decoration:none;cursor:pointer;transition:all 0.15s}
.btn-primary{background:#3b82f6;color:white}.btn-primary:hover{background:#2563eb}
.card{background:white;border-radius:0.5rem;padding:1.5rem;box-shadow:0 1px 3px rgba(0,0,0,0.1)}
.flex{display:flex}.items-center{align-items:center}.justify-between{justify-content:space-between}
.hidden{display:none}.block{display:block}.inline-block{display:inline-block}
.text-sm{font-size:0.875rem}.text-lg{font-size:1.125rem}
.font-medium{font-weight:500}.font-bold{font-weight:700}
.text-gray-600{color:#4b5563}.text-gray-900{color:#111827}
.mb-4{margin-bottom:1rem}.mt-6{margin-top:1.5rem}.p-4{padding:1rem}
.w-full{width:100%}.h-full{height:100%} .w-full{width:100%}.h-full{height:100%}
@media(max-width:768px){.container{padding:0 0.5rem}.card-professional{padding:1rem}} @media(max-width:768px){.container{padding:0 0.5rem}.card{padding:1rem}}
/* Nur opacity transitions für Raspberry Pi Performance */
.animate-fade-in{animation:fadeIn 0.2s ease-out}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
EOF EOF
# Erstelle optimierten JavaScript-Loader ohne GPU-intensive Features # Erstelle minimale JavaScript-Loader
progress "Erstelle Raspberry Pi optimierten JavaScript-Loader..." progress "Erstelle optimierten JavaScript-Loader..."
cat > js/raspberry-pi-loader.min.js << 'EOF' cat > js/loader.min.js << 'EOF'
/*Raspberry Pi optimierter Loader - Keine GPU-intensive Features*/ /*Minimaler Async Loader für bessere Performance*/
(function(){ (function(){var d=document,w=window;function loadCSS(href){var l=d.createElement('link');l.rel='stylesheet';l.href=href;l.media='print';l.onload=function(){this.media='all'};d.head.appendChild(l)}function loadJS(src,cb){var s=d.createElement('script');s.async=true;s.src=src;if(cb)s.onload=cb;d.head.appendChild(s)}w.loadAssets=function(){if(w.assetsLoaded)return;w.assetsLoaded=true;loadCSS('/static/css/tailwind.min.css');loadJS('/static/js/app.min.js')};if(d.readyState==='loading'){d.addEventListener('DOMContentLoaded',w.loadAssets)}else{w.loadAssets()}})();
var d=document,w=window;
function loadCSS(href,media){
var l=d.createElement('link');
l.rel='stylesheet';
l.href=href;
l.media=media||'all';
d.head.appendChild(l);
return l;
}
function loadJS(src,cb){
var s=d.createElement('script');
s.async=true;
s.src=src;
if(cb)s.onload=cb;
d.head.appendChild(s);
return s;
}
w.loadOptimizedAssets=function(){
if(w.assetsLoaded)return;
w.assetsLoaded=true;
loadCSS('/static/css/professional-theme.css');
loadCSS('/static/css/glassmorphism.css');
loadCSS('/static/css/optimization-animations.css');
loadCSS('/static/css/caching-optimizations.css');
if(d.querySelector('#app-js')){
loadJS('/static/js/app.min.js');
}
};
if(d.readyState==='loading'){
d.addEventListener('DOMContentLoaded',w.loadOptimizedAssets);
}else{
w.loadOptimizedAssets();
}
})();
EOF EOF
# Service Worker für optimiertes Caching auf Raspberry Pi # Service Worker für besseres Caching
progress "Erstelle Raspberry Pi optimierten Service Worker..." progress "Erstelle optimierten Service Worker..."
cat > sw-raspberry-pi.js << 'EOF' cat > sw-optimized.js << 'EOF'
const CACHE_NAME = 'myp-raspberry-pi-v1'; const CACHE_NAME = 'myp-webapp-v1';
const CRITICAL_ASSETS = [ const ASSETS_TO_CACHE = [
'/', '/',
'/static/css/critical-raspberry-pi.min.css', '/static/css/critical.min.css',
'/static/js/raspberry-pi-loader.min.js', '/static/js/loader.min.js',
'/static/css/professional-theme.css', '/static/favicon.svg'
'/static/css/glassmorphism.css',
'/static/css/optimization-animations.css'
]; ];
// Aggressive Caching für statische Assets
self.addEventListener('install', event => { self.addEventListener('install', event => {
event.waitUntil( event.waitUntil(
caches.open(CACHE_NAME) caches.open(CACHE_NAME)
.then(cache => { .then(cache => cache.addAll(ASSETS_TO_CACHE))
console.log('Raspberry Pi Cache wird geladen...');
return cache.addAll(CRITICAL_ASSETS);
})
); );
self.skipWaiting();
}); });
// Cache-First Strategie für bessere Performance auf schwacher Hardware
self.addEventListener('fetch', event => { self.addEventListener('fetch', event => {
if (event.request.url.includes('/static/')) { if (event.request.destination === 'image' ||
event.request.url.includes('/static/')) {
event.respondWith( event.respondWith(
caches.match(event.request) caches.match(event.request)
.then(response => { .then(response => response || fetch(event.request))
if (response) {
return response;
}
return fetch(event.request).then(fetchResponse => {
if (fetchResponse && fetchResponse.status === 200) {
const responseClone = fetchResponse.clone();
caches.open(CACHE_NAME)
.then(cache => {
cache.put(event.request, responseClone);
});
}
return fetchResponse;
});
})
); );
} }
}); });
// Cache-Bereinigung für alte Versionen
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== CACHE_NAME) {
console.log('Entferne alte Cache-Version:', cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
EOF EOF
# CSS-Minifikation für optimierte Dateien # Gzip-Kompression für statische Dateien
progress "Minifiziere CSS-Dateien für bessere Performance..." progress "Komprimiere statische Dateien..."
local css_files=("professional-theme.css" "glassmorphism.css" "optimization-animations.css" "caching-optimizations.css") find . -name "*.css" -o -name "*.js" -o -name "*.html" | while read file; do
for css_file in "${css_files[@]}"; do
if [ -f "css/$css_file" ]; then
# Einfache CSS-Minifikation (Entfernung von Kommentaren und unnötigen Whitespaces)
sed 's|/\*[^*]*\*\+\([^/*][^*]*\*\+\)*/||g; s/^[[:space:]]*//g; s/[[:space:]]*$//g; /^$/d' "css/$css_file" > "css/${css_file%.css}.min.css" 2>/dev/null || true
if [ -f "css/${css_file%.css}.min.css" ]; then
log "✅ Minifiziert: ${css_file%.css}.min.css"
fi
fi
done
# Gzip-Kompression für alle CSS/JS-Dateien
progress "Komprimiere Dateien mit Gzip..."
find css js -name "*.css" -o -name "*.js" | while read file; do
if [ -f "$file" ] && [ ! -f "$file.gz" ]; then if [ -f "$file" ] && [ ! -f "$file.gz" ]; then
gzip -9 -c "$file" > "$file.gz" 2>/dev/null || true gzip -c "$file" > "$file.gz" 2>/dev/null || true
if [ -f "$file.gz" ]; then
local original_size=$(wc -c < "$file" 2>/dev/null || echo "0")
local compressed_size=$(wc -c < "$file.gz" 2>/dev/null || echo "0")
if [ "$original_size" -gt 0 ] && [ "$compressed_size" -gt 0 ]; then
local ratio=$((100 - (compressed_size * 100 / original_size)))
log "✅ Komprimiert: $file (${ratio}% kleiner)"
fi
fi
fi fi
done done
# Performance-Hints für Browser
progress "Erstelle Performance-Hints für Raspberry Pi Browser..."
cat > performance-hints.txt << 'EOF'
# Performance-Optimierungen für Raspberry Pi Browser:
# 1. Alle backdrop-filter entfernt (GPU-intensiv)
# 2. Transform-Animationen eliminiert (Layout-Thrashing)
# 3. Box-shadows reduziert (Paint-Performance)
# 4. Will-change Properties entfernt (Memory-Management)
# 5. Gradient-Effekte vereinfacht (GPU-Berechnungen)
# 6. Nur Opacity/Color Transitions (CSS-Performance)
# 7. Kritische CSS inline geladen (Render-Blocking)
# 8. Service Worker für aggressives Caching
# 9. Gzip-Kompression für alle Assets
# 10. Cache-First Strategie für statische Dateien
EOF
cd "$CURRENT_DIR" cd "$CURRENT_DIR"
log "✅ Raspberry Pi CSS/JS-Optimierung abgeschlossen:" log "✅ Statische Dateien optimiert:"
log " 🚀 Backdrop-Filter und Transform-Animationen entfernt" log " 📦 Kritische CSS-Styles kombiniert"
log " 📦 Kritische CSS für Above-the-fold Content erstellt" log " ⚡ Asynchroner Asset-Loader erstellt"
log " ⚡ Raspberry Pi spezifischer Asset-Loader" log " 🗜️ Gzip-Kompression angewendet"
log " 🗜️ Aggressive Gzip-Kompression angewendet" log " 🔄 Service Worker für Caching installiert"
log " 🔄 Cache-First Service Worker installiert"
log " 📊 CSS-Minifikation für alle Dateien"
log " 💾 Performance-optimiert für schwache Hardware"
} }
# =========================== HAUPTPROGRAMM =========================== # =========================== HAUPTPROGRAMM ===========================