🎉 Improved backend configuration and documentation 🖥️📚
This commit is contained in:
230
backend/app.py
230
backend/app.py
@@ -8367,6 +8367,236 @@ def refresh_dashboard():
|
||||
'details': str(e) if app.debug else None
|
||||
}), 500
|
||||
|
||||
# ===== STECKDOSEN-MONITORING API-ROUTEN =====
|
||||
|
||||
@app.route("/api/admin/plug-monitoring/logs", methods=['GET'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def api_admin_plug_monitoring_logs():
|
||||
"""
|
||||
API-Endpoint für Steckdosen-Monitoring-Logs.
|
||||
Unterstützt Filterung nach Drucker, Zeitraum und Status.
|
||||
"""
|
||||
try:
|
||||
# Parameter aus Request
|
||||
printer_id = request.args.get('printer_id', type=int)
|
||||
hours = request.args.get('hours', default=24, type=int)
|
||||
status_filter = request.args.get('status')
|
||||
page = request.args.get('page', default=1, type=int)
|
||||
per_page = request.args.get('per_page', default=100, type=int)
|
||||
|
||||
# Maximale Grenzen setzen
|
||||
hours = min(hours, 168) # Maximal 7 Tage
|
||||
per_page = min(per_page, 1000) # Maximal 1000 Einträge pro Seite
|
||||
|
||||
db_session = get_db_session()
|
||||
|
||||
try:
|
||||
# Basis-Query
|
||||
cutoff_time = datetime.now() - timedelta(hours=hours)
|
||||
query = db_session.query(PlugStatusLog)\
|
||||
.filter(PlugStatusLog.timestamp >= cutoff_time)\
|
||||
.join(Printer)
|
||||
|
||||
# Drucker-Filter
|
||||
if printer_id:
|
||||
query = query.filter(PlugStatusLog.printer_id == printer_id)
|
||||
|
||||
# Status-Filter
|
||||
if status_filter:
|
||||
query = query.filter(PlugStatusLog.status == status_filter)
|
||||
|
||||
# Gesamtanzahl für Paginierung
|
||||
total = query.count()
|
||||
|
||||
# Sortierung und Paginierung
|
||||
logs = query.order_by(PlugStatusLog.timestamp.desc())\
|
||||
.offset((page - 1) * per_page)\
|
||||
.limit(per_page)\
|
||||
.all()
|
||||
|
||||
# Daten serialisieren
|
||||
log_data = []
|
||||
for log in logs:
|
||||
log_dict = log.to_dict()
|
||||
# Zusätzliche berechnete Felder
|
||||
log_dict['timestamp_relative'] = get_relative_time(log.timestamp)
|
||||
log_dict['status_icon'] = get_status_icon(log.status)
|
||||
log_dict['status_color'] = get_status_color(log.status)
|
||||
log_data.append(log_dict)
|
||||
|
||||
# Paginierungs-Metadaten
|
||||
has_next = (page * per_page) < total
|
||||
has_prev = page > 1
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"logs": log_data,
|
||||
"pagination": {
|
||||
"page": page,
|
||||
"per_page": per_page,
|
||||
"total": total,
|
||||
"total_pages": (total + per_page - 1) // per_page,
|
||||
"has_next": has_next,
|
||||
"has_prev": has_prev
|
||||
},
|
||||
"filters": {
|
||||
"printer_id": printer_id,
|
||||
"hours": hours,
|
||||
"status": status_filter
|
||||
},
|
||||
"generated_at": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
finally:
|
||||
db_session.close()
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Abrufen der Steckdosen-Logs: {str(e)}")
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": "Fehler beim Laden der Steckdosen-Logs",
|
||||
"details": str(e) if current_user.is_admin else None
|
||||
}), 500
|
||||
|
||||
@app.route("/api/admin/plug-monitoring/statistics", methods=['GET'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def api_admin_plug_monitoring_statistics():
|
||||
"""
|
||||
API-Endpoint für Steckdosen-Monitoring-Statistiken.
|
||||
"""
|
||||
try:
|
||||
hours = request.args.get('hours', default=24, type=int)
|
||||
hours = min(hours, 168) # Maximal 7 Tage
|
||||
|
||||
# Statistiken abrufen
|
||||
stats = PlugStatusLog.get_status_statistics(hours=hours)
|
||||
|
||||
# Drucker-Namen für die Top-Liste hinzufügen
|
||||
if stats.get('top_printers'):
|
||||
db_session = get_db_session()
|
||||
try:
|
||||
printer_ids = list(stats['top_printers'].keys())
|
||||
printers = db_session.query(Printer.id, Printer.name)\
|
||||
.filter(Printer.id.in_(printer_ids))\
|
||||
.all()
|
||||
|
||||
printer_names = {p.id: p.name for p in printers}
|
||||
|
||||
# Top-Drucker mit Namen anreichern
|
||||
top_printers_with_names = []
|
||||
for printer_id, count in stats['top_printers'].items():
|
||||
top_printers_with_names.append({
|
||||
"printer_id": printer_id,
|
||||
"printer_name": printer_names.get(printer_id, f"Drucker {printer_id}"),
|
||||
"log_count": count
|
||||
})
|
||||
|
||||
stats['top_printers_detailed'] = top_printers_with_names
|
||||
|
||||
finally:
|
||||
db_session.close()
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"statistics": stats
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Abrufen der Steckdosen-Statistiken: {str(e)}")
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": "Fehler beim Laden der Statistiken",
|
||||
"details": str(e) if current_user.is_admin else None
|
||||
}), 500
|
||||
|
||||
@app.route("/api/admin/plug-monitoring/cleanup", methods=['POST'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def api_admin_plug_monitoring_cleanup():
|
||||
"""
|
||||
API-Endpoint zum Bereinigen alter Steckdosen-Logs.
|
||||
"""
|
||||
try:
|
||||
data = request.get_json() or {}
|
||||
days = data.get('days', 30)
|
||||
days = max(1, min(days, 365)) # Zwischen 1 und 365 Tagen
|
||||
|
||||
# Bereinigung durchführen
|
||||
deleted_count = PlugStatusLog.cleanup_old_logs(days=days)
|
||||
|
||||
# Erfolg loggen
|
||||
SystemLog.log_system_event(
|
||||
level="INFO",
|
||||
message=f"Steckdosen-Logs bereinigt: {deleted_count} Einträge gelöscht (älter als {days} Tage)",
|
||||
module="admin_plug_monitoring",
|
||||
user_id=current_user.id
|
||||
)
|
||||
|
||||
app_logger.info(f"Admin {current_user.name} berinigte {deleted_count} Steckdosen-Logs (älter als {days} Tage)")
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"deleted_count": deleted_count,
|
||||
"days": days,
|
||||
"message": f"Erfolgreich {deleted_count} alte Einträge gelöscht"
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Bereinigen der Steckdosen-Logs: {str(e)}")
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": "Fehler beim Bereinigen der Logs",
|
||||
"details": str(e) if current_user.is_admin else None
|
||||
}), 500
|
||||
|
||||
def get_relative_time(timestamp):
|
||||
"""
|
||||
Hilfsfunktion für relative Zeitangaben.
|
||||
"""
|
||||
if not timestamp:
|
||||
return "Unbekannt"
|
||||
|
||||
now = datetime.now()
|
||||
diff = now - timestamp
|
||||
|
||||
if diff.total_seconds() < 60:
|
||||
return "Gerade eben"
|
||||
elif diff.total_seconds() < 3600:
|
||||
minutes = int(diff.total_seconds() / 60)
|
||||
return f"vor {minutes} Minute{'n' if minutes != 1 else ''}"
|
||||
elif diff.total_seconds() < 86400:
|
||||
hours = int(diff.total_seconds() / 3600)
|
||||
return f"vor {hours} Stunde{'n' if hours != 1 else ''}"
|
||||
else:
|
||||
days = int(diff.total_seconds() / 86400)
|
||||
return f"vor {days} Tag{'en' if days != 1 else ''}"
|
||||
|
||||
def get_status_icon(status):
|
||||
"""
|
||||
Hilfsfunktion für Status-Icons.
|
||||
"""
|
||||
icons = {
|
||||
'connected': '🔌',
|
||||
'disconnected': '❌',
|
||||
'on': '🟢',
|
||||
'off': '🔴'
|
||||
}
|
||||
return icons.get(status, '❓')
|
||||
|
||||
def get_status_color(status):
|
||||
"""
|
||||
Hilfsfunktion für Status-Farben (CSS-Klassen).
|
||||
"""
|
||||
colors = {
|
||||
'connected': 'text-blue-600',
|
||||
'disconnected': 'text-red-600',
|
||||
'on': 'text-green-600',
|
||||
'off': 'text-orange-600'
|
||||
}
|
||||
return colors.get(status, 'text-gray-600')
|
||||
|
||||
# ===== STARTUP UND MAIN =====
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
Reference in New Issue
Block a user