Die Dateien wurden in mehreren Log- und Cache-Ordnern geändert:

This commit is contained in:
Tomczak
2025-06-19 13:08:47 +02:00
parent 07acd2840b
commit 43d12fdf11
394 changed files with 3013 additions and 284 deletions

View File

@ -20,6 +20,7 @@ import os
import json
import time
import zipfile
import bcrypt
from datetime import datetime, timedelta
from functools import wraps
@ -380,6 +381,52 @@ def guest_requests():
"""Gäste-Anfragen-Übersicht"""
return render_template('admin_guest_requests.html')
@admin_blueprint.route("/requests")
@admin_required
def requests_overview():
"""Anträge-Übersicht für Admin-Dashboard"""
try:
with get_cached_session() as db_session:
# Grundlegende Statistiken sammeln für das Template
total_users = db_session.query(User).count()
total_printers = db_session.query(Printer).count()
total_jobs = db_session.query(Job).count()
# Aktive Jobs zählen
active_jobs = db_session.query(Job).filter(
Job.status.in_(['pending', 'printing', 'paused'])
).count()
# Online-Drucker zählen
online_printers = db_session.query(Printer).filter(
Printer.status.in_(['idle', 'busy'])
).count()
# Alle Anträge laden
requests = db_session.query(GuestRequest).order_by(
GuestRequest.created_at.desc()
).all()
stats = {
'total_users': total_users,
'total_printers': total_printers,
'total_jobs': total_jobs,
'active_jobs': active_jobs,
'online_printers': online_printers
}
admin_logger.info(f"Anträge-Übersicht geladen: {len(requests)} Anträge")
return render_template('admin.html',
active_tab='requests',
stats=stats,
requests=requests)
except Exception as e:
admin_logger.error(f"Fehler beim Laden der Anträge-Übersicht: {str(e)}")
flash("Fehler beim Laden der Anträge", "error")
return redirect(url_for('admin.dashboard'))
@admin_blueprint.route("/advanced-settings")
@admin_required
def advanced_settings():
@ -1762,6 +1809,110 @@ def get_pending_guest_otps_api():
admin_logger.error(f"Fehler beim Abrufen aktiver OTP-Codes: {str(e)}")
return jsonify({"error": "Fehler beim Laden der OTP-Codes"}), 500
@admin_api_blueprint.route("/guest-requests/<int:request_id>/approve", methods=["POST"])
@admin_required
def approve_guest_request_api(request_id):
"""API-Endpunkt zum Genehmigen einer Gastanfrage"""
try:
data = request.get_json() or {}
approval_notes = data.get('approval_notes', '').strip()
printer_id = data.get('printer_id') # Optional: Drucker zuweisen
with get_cached_session() as db_session:
guest_request = db_session.query(GuestRequest).filter_by(id=request_id).first()
if not guest_request:
return jsonify({"error": "Gastanfrage nicht gefunden"}), 404
if guest_request.status != 'pending':
return jsonify({"error": f"Gastanfrage ist bereits {guest_request.status}"}), 400
# Optional: Drucker validieren falls angegeben
if printer_id:
printer = db_session.query(Printer).filter_by(id=printer_id).first()
if not printer:
return jsonify({"error": "Angegebener Drucker nicht gefunden"}), 400
guest_request.assigned_printer_id = printer_id
# Gastanfrage genehmigen
guest_request.status = 'approved'
guest_request.processed_by = current_user.id
guest_request.processed_at = datetime.now()
guest_request.approved_by = current_user.id
guest_request.approved_at = datetime.now()
guest_request.approval_notes = approval_notes
guest_request.updated_at = datetime.now()
# OTP-Code generieren
import secrets
import string
otp_code = ''.join(secrets.choice(string.digits) for _ in range(6))
guest_request.otp_code_plain = otp_code
guest_request.otp_code = bcrypt.hashpw(otp_code.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
guest_request.otp_expires_at = datetime.now() + timedelta(hours=72) # 72h gültig
db_session.commit()
admin_logger.info(f"Gastanfrage {request_id} von Admin {current_user.name} genehmigt")
return jsonify({
"success": True,
"message": "Gastanfrage erfolgreich genehmigt",
"otp_code": otp_code,
"request_id": request_id,
"guest_name": guest_request.name,
"expires_at": guest_request.otp_expires_at.isoformat()
})
except Exception as e:
admin_logger.error(f"Fehler beim Genehmigen der Gastanfrage {request_id}: {str(e)}")
return jsonify({"error": "Fehler beim Genehmigen der Gastanfrage"}), 500
@admin_api_blueprint.route("/guest-requests/<int:request_id>/reject", methods=["POST"])
@admin_required
def reject_guest_request_api(request_id):
"""API-Endpunkt zum Ablehnen einer Gastanfrage"""
try:
data = request.get_json() or {}
rejection_reason = data.get('rejection_reason', '').strip()
if not rejection_reason:
return jsonify({"error": "Ablehnungsgrund ist erforderlich"}), 400
with get_cached_session() as db_session:
guest_request = db_session.query(GuestRequest).filter_by(id=request_id).first()
if not guest_request:
return jsonify({"error": "Gastanfrage nicht gefunden"}), 404
if guest_request.status != 'pending':
return jsonify({"error": f"Gastanfrage ist bereits {guest_request.status}"}), 400
# Gastanfrage ablehnen
guest_request.status = 'rejected'
guest_request.processed_by = current_user.id
guest_request.processed_at = datetime.now()
guest_request.rejected_by = current_user.id
guest_request.rejected_at = datetime.now()
guest_request.rejection_reason = rejection_reason
guest_request.updated_at = datetime.now()
db_session.commit()
admin_logger.info(f"Gastanfrage {request_id} von Admin {current_user.name} abgelehnt: {rejection_reason}")
return jsonify({
"success": True,
"message": "Gastanfrage erfolgreich abgelehnt",
"request_id": request_id,
"guest_name": guest_request.name,
"rejection_reason": rejection_reason
})
except Exception as e:
admin_logger.error(f"Fehler beim Ablehnen der Gastanfrage {request_id}: {str(e)}")
return jsonify({"error": "Fehler beim Ablehnen der Gastanfrage"}), 500
# ===== ADMIN-UI ROUTES FÜR GAST-OTP-VERWALTUNG =====
@admin_blueprint.route("/guest-otps")