feat: Hinzufügen neuer API-Endpunkte zur erweiterten Drucker-Status-Verwaltung und Verbesserung der Benutzeroberfläche durch optimierte Lade- und Filtermechanismen. Implementierung von Caching für Online-Drucker und Live-Status sowie Auto-Update-Funktionalität zur Echtzeit-Überwachung. Anpassungen in den Templates zur Anzeige von Status-Übersichten und Filteroptionen für eine verbesserte Benutzererfahrung.
This commit is contained in:
@@ -3226,6 +3226,307 @@ def admin_update_printer_form(printer_id):
|
||||
flash("Fehler beim Aktualisieren des Druckers.", "error")
|
||||
return redirect(url_for("admin_printer_settings_page", printer_id=printer_id))
|
||||
|
||||
# Neue API-Endpunkte für erweiterte Drucker-Status-Verwaltung hinzufügen
|
||||
@app.route("/api/printers/online", methods=["GET"])
|
||||
@login_required
|
||||
def get_online_printers():
|
||||
"""Gibt nur die online/verfügbaren Drucker zurück - optimiert für schnelle Anzeige."""
|
||||
db_session = get_db_session()
|
||||
printers_logger = get_logger("printers")
|
||||
|
||||
try:
|
||||
# Session-Cache für Online-Drucker prüfen
|
||||
cache_key = f"online_printers_{current_user.id}"
|
||||
cached_data = session.get(cache_key)
|
||||
cache_timestamp = session.get(f"{cache_key}_timestamp")
|
||||
|
||||
# Cache ist 30 Sekunden gültig
|
||||
if cached_data and cache_timestamp:
|
||||
cache_age = (datetime.now() - datetime.fromisoformat(cache_timestamp)).total_seconds()
|
||||
if cache_age < 30:
|
||||
printers_logger.info(f"Online-Drucker aus Session-Cache geladen (Alter: {cache_age:.1f}s)")
|
||||
return jsonify({
|
||||
"printers": cached_data,
|
||||
"count": len(cached_data),
|
||||
"cached": True,
|
||||
"cache_age": cache_age
|
||||
})
|
||||
|
||||
# Nur verfügbare/online Drucker aus Datenbank laden
|
||||
printers = db_session.query(Printer).filter(
|
||||
Printer.status.in_(["available", "online", "idle"]),
|
||||
Printer.active == True
|
||||
).all()
|
||||
|
||||
current_time = datetime.now()
|
||||
online_printers = []
|
||||
|
||||
for printer in printers:
|
||||
printer_data = {
|
||||
"id": printer.id,
|
||||
"name": printer.name,
|
||||
"model": printer.model or 'Unbekanntes Modell',
|
||||
"location": printer.location or 'Unbekannter Standort',
|
||||
"mac_address": printer.mac_address,
|
||||
"plug_ip": printer.plug_ip,
|
||||
"status": printer.status,
|
||||
"active": printer.active,
|
||||
"ip_address": printer.plug_ip if printer.plug_ip else getattr(printer, 'ip_address', None),
|
||||
"created_at": printer.created_at.isoformat() if printer.created_at else current_time.isoformat(),
|
||||
"last_checked": printer.last_checked.isoformat() if hasattr(printer, 'last_checked') and printer.last_checked else None,
|
||||
"is_online": True # Alle Drucker in dieser Liste sind online
|
||||
}
|
||||
online_printers.append(printer_data)
|
||||
|
||||
# In Session-Cache speichern
|
||||
session[cache_key] = online_printers
|
||||
session[f"{cache_key}_timestamp"] = current_time.isoformat()
|
||||
session.permanent = True
|
||||
|
||||
db_session.close()
|
||||
|
||||
printers_logger.info(f"Online-Drucker geladen: {len(online_printers)} verfügbare Drucker")
|
||||
|
||||
return jsonify({
|
||||
"printers": online_printers,
|
||||
"count": len(online_printers),
|
||||
"cached": False,
|
||||
"message": f"{len(online_printers)} online Drucker gefunden"
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
db_session.rollback()
|
||||
db_session.close()
|
||||
printers_logger.error(f"Fehler beim Abrufen der Online-Drucker: {str(e)}")
|
||||
return jsonify({
|
||||
"error": f"Fehler beim Laden der Online-Drucker: {str(e)}",
|
||||
"printers": []
|
||||
}), 500
|
||||
|
||||
@app.route("/api/printers/status/live", methods=["GET"])
|
||||
@login_required
|
||||
def get_live_printer_status():
|
||||
"""Gibt Live-Status aller Drucker zurück mit Session-Caching und Echtzeit-Updates."""
|
||||
db_session = get_db_session()
|
||||
printers_logger = get_logger("printers")
|
||||
|
||||
try:
|
||||
# Session-Cache für Live-Status prüfen
|
||||
cache_key = f"live_printer_status_{current_user.id}"
|
||||
cached_data = session.get(cache_key)
|
||||
cache_timestamp = session.get(f"{cache_key}_timestamp")
|
||||
|
||||
# Cache ist 15 Sekunden gültig für Live-Status
|
||||
if cached_data and cache_timestamp:
|
||||
cache_age = (datetime.now() - datetime.fromisoformat(cache_timestamp)).total_seconds()
|
||||
if cache_age < 15:
|
||||
printers_logger.info(f"Live-Status aus Session-Cache geladen (Alter: {cache_age:.1f}s)")
|
||||
return jsonify({
|
||||
"printers": cached_data,
|
||||
"cached": True,
|
||||
"cache_age": cache_age,
|
||||
"next_update": 15 - cache_age
|
||||
})
|
||||
|
||||
# Alle Drucker aus der Datenbank laden
|
||||
printers = db_session.query(Printer).all()
|
||||
|
||||
if not printers:
|
||||
return jsonify({
|
||||
"printers": [],
|
||||
"count": 0,
|
||||
"message": "Keine Drucker in der Datenbank gefunden"
|
||||
})
|
||||
|
||||
# Drucker-Daten für Status-Check vorbereiten
|
||||
printer_data = []
|
||||
for printer in printers:
|
||||
printer_data.append({
|
||||
'id': printer.id,
|
||||
'name': printer.name,
|
||||
'ip_address': printer.plug_ip if printer.plug_ip else getattr(printer, 'ip_address', None)
|
||||
})
|
||||
|
||||
# Paralleler Status-Check mit kürzerem Timeout für Live-Updates
|
||||
try:
|
||||
status_results = check_multiple_printers_status(printer_data, timeout=3)
|
||||
except Exception as e:
|
||||
printers_logger.warning(f"Status-Check fehlgeschlagen, verwende letzte bekannte Status: {str(e)}")
|
||||
# Fallback: verwende letzte bekannte Status
|
||||
status_results = {p['id']: (p.get('last_status', 'offline'), False) for p in printer_data}
|
||||
|
||||
# Live-Status-Daten zusammenstellen
|
||||
live_status_data = []
|
||||
current_time = datetime.now()
|
||||
online_count = 0
|
||||
|
||||
for printer in printers:
|
||||
if printer.id in status_results:
|
||||
status, active = status_results[printer.id]
|
||||
frontend_status = "available" if status == "online" else "offline"
|
||||
if frontend_status == "available":
|
||||
online_count += 1
|
||||
else:
|
||||
frontend_status = printer.status or "offline"
|
||||
active = printer.active if hasattr(printer, 'active') else False
|
||||
|
||||
# Status in Datenbank aktualisieren (asynchron)
|
||||
printer.status = frontend_status
|
||||
printer.active = active
|
||||
if hasattr(printer, 'last_checked'):
|
||||
printer.last_checked = current_time
|
||||
|
||||
live_status_data.append({
|
||||
"id": printer.id,
|
||||
"name": printer.name,
|
||||
"model": printer.model or 'Unbekanntes Modell',
|
||||
"location": printer.location or 'Unbekannter Standort',
|
||||
"mac_address": printer.mac_address,
|
||||
"plug_ip": printer.plug_ip,
|
||||
"status": frontend_status,
|
||||
"active": active,
|
||||
"ip_address": printer.plug_ip if printer.plug_ip else getattr(printer, 'ip_address', None),
|
||||
"created_at": printer.created_at.isoformat() if printer.created_at else current_time.isoformat(),
|
||||
"last_checked": current_time.isoformat(),
|
||||
"is_online": frontend_status == "available",
|
||||
"status_changed": True # Für Frontend-Animationen
|
||||
})
|
||||
|
||||
# Änderungen in Datenbank speichern
|
||||
try:
|
||||
db_session.commit()
|
||||
except Exception as e:
|
||||
printers_logger.warning(f"Fehler beim Speichern der Live-Status-Updates: {str(e)}")
|
||||
|
||||
# In Session-Cache speichern
|
||||
session[cache_key] = live_status_data
|
||||
session[f"{cache_key}_timestamp"] = current_time.isoformat()
|
||||
session.permanent = True
|
||||
|
||||
# Online-Drucker-Cache invalidieren
|
||||
online_cache_key = f"online_printers_{current_user.id}"
|
||||
if online_cache_key in session:
|
||||
del session[online_cache_key]
|
||||
del session[f"{online_cache_key}_timestamp"]
|
||||
|
||||
db_session.close()
|
||||
|
||||
printers_logger.info(f"Live-Status aktualisiert: {online_count} von {len(live_status_data)} Drucker online")
|
||||
|
||||
return jsonify({
|
||||
"printers": live_status_data,
|
||||
"count": len(live_status_data),
|
||||
"online_count": online_count,
|
||||
"offline_count": len(live_status_data) - online_count,
|
||||
"cached": False,
|
||||
"timestamp": current_time.isoformat(),
|
||||
"next_update": 15
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
db_session.rollback()
|
||||
db_session.close()
|
||||
printers_logger.error(f"Fehler beim Live-Status-Check: {str(e)}")
|
||||
return jsonify({
|
||||
"error": f"Fehler beim Live-Status-Check: {str(e)}",
|
||||
"printers": []
|
||||
}), 500
|
||||
|
||||
@app.route("/api/printers/status/summary", methods=["GET"])
|
||||
@login_required
|
||||
def get_printer_status_summary():
|
||||
"""Gibt eine Zusammenfassung des Drucker-Status zurück - sehr schnell."""
|
||||
db_session = get_db_session()
|
||||
|
||||
try:
|
||||
# Session-Cache für Status-Zusammenfassung
|
||||
cache_key = f"printer_summary_{current_user.id}"
|
||||
cached_data = session.get(cache_key)
|
||||
cache_timestamp = session.get(f"{cache_key}_timestamp")
|
||||
|
||||
# Cache ist 60 Sekunden gültig
|
||||
if cached_data and cache_timestamp:
|
||||
cache_age = (datetime.now() - datetime.fromisoformat(cache_timestamp)).total_seconds()
|
||||
if cache_age < 60:
|
||||
return jsonify({
|
||||
**cached_data,
|
||||
"cached": True,
|
||||
"cache_age": cache_age
|
||||
})
|
||||
|
||||
# Status-Zusammenfassung aus Datenbank
|
||||
total_printers = db_session.query(Printer).count()
|
||||
online_printers = db_session.query(Printer).filter(
|
||||
Printer.status.in_(["available", "online", "idle"]),
|
||||
Printer.active == True
|
||||
).count()
|
||||
offline_printers = total_printers - online_printers
|
||||
|
||||
# Letzte Aktualisierung ermitteln
|
||||
last_checked = db_session.query(func.max(Printer.last_checked)).scalar()
|
||||
|
||||
summary_data = {
|
||||
"total": total_printers,
|
||||
"online": online_printers,
|
||||
"offline": offline_printers,
|
||||
"percentage_online": round((online_printers / total_printers * 100) if total_printers > 0 else 0, 1),
|
||||
"last_checked": last_checked.isoformat() if last_checked else None,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
# In Session-Cache speichern
|
||||
session[cache_key] = summary_data
|
||||
session[f"{cache_key}_timestamp"] = datetime.now().isoformat()
|
||||
session.permanent = True
|
||||
|
||||
db_session.close()
|
||||
|
||||
return jsonify({
|
||||
**summary_data,
|
||||
"cached": False
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
db_session.close()
|
||||
return jsonify({
|
||||
"error": f"Fehler beim Laden der Status-Zusammenfassung: {str(e)}",
|
||||
"total": 0,
|
||||
"online": 0,
|
||||
"offline": 0
|
||||
}), 500
|
||||
|
||||
# Session-Cache-Management
|
||||
@app.route("/api/printers/cache/clear", methods=["POST"])
|
||||
@login_required
|
||||
def clear_printer_cache():
|
||||
"""Löscht den Drucker-Cache für den aktuellen Benutzer."""
|
||||
try:
|
||||
cache_keys = [
|
||||
f"online_printers_{current_user.id}",
|
||||
f"live_printer_status_{current_user.id}",
|
||||
f"printer_summary_{current_user.id}"
|
||||
]
|
||||
|
||||
cleared_count = 0
|
||||
for key in cache_keys:
|
||||
if key in session:
|
||||
del session[key]
|
||||
cleared_count += 1
|
||||
timestamp_key = f"{key}_timestamp"
|
||||
if timestamp_key in session:
|
||||
del session[timestamp_key]
|
||||
|
||||
return jsonify({
|
||||
"message": f"Cache erfolgreich geleert ({cleared_count} Einträge)",
|
||||
"cleared_keys": cleared_count
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
"error": f"Fehler beim Löschen des Cache: {str(e)}"
|
||||
}), 500
|
||||
|
||||
|
||||
# ===== STARTUP UND MAIN =====
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
@@ -3282,4 +3583,4 @@ if __name__ == "__main__":
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Starten der Anwendung: {str(e)}")
|
||||
sys.exit(1)
|
||||
sys.exit(1)
|
||||
|
Reference in New Issue
Block a user