Dashboard zeigt Realdaten
Dieser Commit ist enthalten in:
@@ -24,14 +24,21 @@ def dashboard():
|
|||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
try:
|
try:
|
||||||
# Hole Statistiken mit sicheren Defaults
|
# Hole Statistiken mit sicheren Defaults
|
||||||
# Anzahl aktiver Lizenzen
|
# Anzahl aktiver Lizenzen (nur echte Daten, keine Testdaten)
|
||||||
cur.execute("SELECT COUNT(*) FROM licenses WHERE is_active = true")
|
cur.execute("SELECT COUNT(*) FROM licenses WHERE is_active = true AND is_test = false")
|
||||||
active_licenses = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
active_licenses = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
||||||
|
|
||||||
# Anzahl Kunden
|
# Anzahl Kunden (nur echte Kunden, keine Testkunden)
|
||||||
cur.execute("SELECT COUNT(*) FROM customers")
|
cur.execute("SELECT COUNT(*) FROM customers WHERE is_test = false")
|
||||||
total_customers = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
total_customers = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
||||||
|
|
||||||
|
# Testdaten separat zählen für optionale Anzeige
|
||||||
|
cur.execute("SELECT COUNT(*) FROM customers WHERE is_test = true")
|
||||||
|
test_customers_count = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
||||||
|
|
||||||
|
cur.execute("SELECT COUNT(*) FROM licenses WHERE is_test = true")
|
||||||
|
test_licenses_count = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
||||||
|
|
||||||
# Anzahl aktiver Sessions (Admin-Panel)
|
# Anzahl aktiver Sessions (Admin-Panel)
|
||||||
cur.execute("SELECT COUNT(*) FROM sessions WHERE is_active = true")
|
cur.execute("SELECT COUNT(*) FROM sessions WHERE is_active = true")
|
||||||
active_sessions = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
active_sessions = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
||||||
@@ -50,9 +57,11 @@ def dashboard():
|
|||||||
|
|
||||||
if table_exists:
|
if table_exists:
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
SELECT COUNT(DISTINCT license_id)
|
SELECT COUNT(DISTINCT lh.license_id)
|
||||||
FROM license_heartbeats
|
FROM license_heartbeats lh
|
||||||
WHERE timestamp > NOW() - INTERVAL '15 minutes'
|
JOIN licenses l ON l.id = lh.license_id
|
||||||
|
WHERE lh.timestamp > NOW() - INTERVAL '15 minutes'
|
||||||
|
AND l.is_test = false
|
||||||
""")
|
""")
|
||||||
active_usage = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
active_usage = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -64,7 +73,7 @@ def dashboard():
|
|||||||
conn = get_connection()
|
conn = get_connection()
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
|
|
||||||
# Top 10 Lizenzen - vereinfacht
|
# Top 10 Lizenzen - nur echte Lizenzen
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
SELECT
|
SELECT
|
||||||
l.license_key,
|
l.license_key,
|
||||||
@@ -73,6 +82,7 @@ def dashboard():
|
|||||||
FROM licenses l
|
FROM licenses l
|
||||||
LEFT JOIN customers c ON l.customer_id = c.id
|
LEFT JOIN customers c ON l.customer_id = c.id
|
||||||
LEFT JOIN sessions s ON l.id = s.license_id
|
LEFT JOIN sessions s ON l.id = s.license_id
|
||||||
|
WHERE l.is_test = false AND c.is_test = false
|
||||||
GROUP BY l.license_key, c.name
|
GROUP BY l.license_key, c.name
|
||||||
ORDER BY session_count DESC
|
ORDER BY session_count DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
@@ -93,54 +103,157 @@ def dashboard():
|
|||||||
""")
|
""")
|
||||||
recent_activities = cur.fetchall() if cur.rowcount > 0 else []
|
recent_activities = cur.fetchall() if cur.rowcount > 0 else []
|
||||||
|
|
||||||
|
# Lizenztypen zählen (nur echte Lizenzen)
|
||||||
|
# Note: This assumes you have a license_type field or similar to distinguish between full and test versions
|
||||||
|
# For now, counting all non-test licenses as full licenses
|
||||||
|
cur.execute("""
|
||||||
|
SELECT COUNT(*) as full_licenses
|
||||||
|
FROM licenses
|
||||||
|
WHERE is_test = false
|
||||||
|
""")
|
||||||
|
license_count = cur.fetchone()
|
||||||
|
full_licenses = license_count[0] if license_count and license_count[0] else 0
|
||||||
|
# For now, we don't distinguish between full and test versions
|
||||||
|
test_version_licenses = 0
|
||||||
|
|
||||||
|
# Lizenzstatus zählen (nur echte Lizenzen)
|
||||||
|
cur.execute("""
|
||||||
|
SELECT
|
||||||
|
COUNT(CASE WHEN is_active = true AND (valid_until IS NULL OR valid_until > NOW()) THEN 1 END) as active,
|
||||||
|
COUNT(CASE WHEN valid_until < NOW() THEN 1 END) as expired,
|
||||||
|
COUNT(CASE WHEN is_active = false THEN 1 END) as inactive
|
||||||
|
FROM licenses
|
||||||
|
WHERE is_test = false
|
||||||
|
""")
|
||||||
|
license_status = cur.fetchone()
|
||||||
|
active_licenses_count = license_status[0] if license_status and license_status[0] else 0
|
||||||
|
expired_licenses = license_status[1] if license_status and license_status[1] else 0
|
||||||
|
inactive_licenses = license_status[2] if license_status and license_status[2] else 0
|
||||||
|
|
||||||
|
# Bald ablaufende Lizenzen (nur echte Lizenzen)
|
||||||
|
cur.execute("""
|
||||||
|
SELECT
|
||||||
|
l.id,
|
||||||
|
l.license_key,
|
||||||
|
c.name as customer_name,
|
||||||
|
l.valid_until,
|
||||||
|
EXTRACT(DAY FROM (l.valid_until - NOW())) as days_remaining
|
||||||
|
FROM licenses l
|
||||||
|
JOIN customers c ON l.customer_id = c.id
|
||||||
|
WHERE l.is_test = false
|
||||||
|
AND c.is_test = false
|
||||||
|
AND l.is_active = true
|
||||||
|
AND l.valid_until IS NOT NULL
|
||||||
|
AND l.valid_until > NOW()
|
||||||
|
AND l.valid_until < NOW() + INTERVAL '30 days'
|
||||||
|
ORDER BY l.valid_until ASC
|
||||||
|
LIMIT 10
|
||||||
|
""")
|
||||||
|
expiring_licenses = cur.fetchall() if cur.rowcount > 0 else []
|
||||||
|
|
||||||
|
# Zuletzt erstellte Lizenzen (nur echte Lizenzen)
|
||||||
|
cur.execute("""
|
||||||
|
SELECT
|
||||||
|
l.id,
|
||||||
|
l.license_key,
|
||||||
|
c.name as customer_name,
|
||||||
|
l.created_at,
|
||||||
|
CASE
|
||||||
|
WHEN l.is_active = false THEN 'deaktiviert'
|
||||||
|
WHEN l.valid_until < NOW() THEN 'abgelaufen'
|
||||||
|
WHEN l.valid_until < NOW() + INTERVAL '30 days' THEN 'läuft bald ab'
|
||||||
|
ELSE 'aktiv'
|
||||||
|
END as status
|
||||||
|
FROM licenses l
|
||||||
|
JOIN customers c ON l.customer_id = c.id
|
||||||
|
WHERE l.is_test = false
|
||||||
|
AND c.is_test = false
|
||||||
|
ORDER BY l.created_at DESC
|
||||||
|
LIMIT 5
|
||||||
|
""")
|
||||||
|
recent_licenses = cur.fetchall() if cur.rowcount > 0 else []
|
||||||
|
|
||||||
# Stats Objekt für Template erstellen
|
# Stats Objekt für Template erstellen
|
||||||
stats = {
|
stats = {
|
||||||
'total_customers': total_customers,
|
'total_customers': total_customers,
|
||||||
'total_licenses': active_licenses,
|
'total_licenses': active_licenses, # This was already filtered for is_test = false
|
||||||
'active_sessions': active_sessions, # Admin-Panel Sessions
|
'active_sessions': active_sessions, # Admin-Panel Sessions
|
||||||
'active_usage': active_usage, # Aktive Kunden-Nutzung
|
'active_usage': active_usage, # Aktive Kunden-Nutzung
|
||||||
'active_licenses': active_licenses,
|
'active_licenses': active_licenses_count,
|
||||||
'full_licenses': 0,
|
'full_licenses': full_licenses,
|
||||||
'test_licenses': 0,
|
'test_licenses': test_version_licenses, # Test versions, not test data
|
||||||
'test_data_count': 0,
|
'test_data_count': test_licenses_count, # Actual test data count
|
||||||
'test_customers_count': 0,
|
'test_customers_count': test_customers_count,
|
||||||
'test_resources_count': 0,
|
'test_resources_count': 0,
|
||||||
'expired_licenses': 0,
|
'expired_licenses': expired_licenses,
|
||||||
'inactive_licenses': 0,
|
'inactive_licenses': inactive_licenses,
|
||||||
'last_backup': None,
|
'last_backup': None,
|
||||||
'security_level': 'success',
|
'security_level': 'success',
|
||||||
'security_level_text': 'Sicher',
|
'security_level_text': 'Sicher',
|
||||||
'blocked_ips_count': 0,
|
'blocked_ips_count': 0,
|
||||||
'failed_attempts_today': 0,
|
'failed_attempts_today': 0,
|
||||||
'recent_security_events': [],
|
'recent_security_events': [],
|
||||||
'expiring_licenses': [],
|
'expiring_licenses': expiring_licenses,
|
||||||
'recent_licenses': []
|
'recent_licenses': recent_licenses
|
||||||
}
|
}
|
||||||
|
|
||||||
# Resource stats als Dictionary mit allen benötigten Feldern
|
# Resource Pool Statistics (nur echte Ressourcen, keine Testdaten)
|
||||||
resource_stats = {
|
resource_stats = {}
|
||||||
'domain': {
|
resource_types = ['domain', 'ipv4', 'phone']
|
||||||
'available': 0,
|
|
||||||
'allocated': 0,
|
for resource_type in resource_types:
|
||||||
'quarantine': 0,
|
try:
|
||||||
'total': 0,
|
cur.execute("""
|
||||||
'available_percent': 100
|
SELECT
|
||||||
},
|
COUNT(CASE WHEN status = 'available' THEN 1 END) as available,
|
||||||
'ipv4': {
|
COUNT(CASE WHEN status = 'allocated' THEN 1 END) as allocated,
|
||||||
'available': 0,
|
COUNT(CASE WHEN status = 'quarantine' THEN 1 END) as quarantine,
|
||||||
'allocated': 0,
|
COUNT(*) as total
|
||||||
'quarantine': 0,
|
FROM resource_pool
|
||||||
'total': 0,
|
WHERE type = %s AND is_test = false
|
||||||
'available_percent': 100
|
""", (resource_type,))
|
||||||
},
|
|
||||||
'phone': {
|
result = cur.fetchone()
|
||||||
'available': 0,
|
if result:
|
||||||
'allocated': 0,
|
available = result[0] or 0
|
||||||
'quarantine': 0,
|
allocated = result[1] or 0
|
||||||
'total': 0,
|
quarantine = result[2] or 0
|
||||||
'available_percent': 100
|
total = result[3] or 0
|
||||||
|
available_percent = int((available / total * 100)) if total > 0 else 0
|
||||||
|
|
||||||
|
resource_stats[resource_type] = {
|
||||||
|
'available': available,
|
||||||
|
'allocated': allocated,
|
||||||
|
'quarantine': quarantine,
|
||||||
|
'total': total,
|
||||||
|
'available_percent': available_percent
|
||||||
}
|
}
|
||||||
|
else:
|
||||||
|
resource_stats[resource_type] = {
|
||||||
|
'available': 0,
|
||||||
|
'allocated': 0,
|
||||||
|
'quarantine': 0,
|
||||||
|
'total': 0,
|
||||||
|
'available_percent': 0
|
||||||
}
|
}
|
||||||
|
except Exception as e:
|
||||||
|
# Falls die Tabelle nicht existiert
|
||||||
|
current_app.logger.warning(f"Could not get resource stats for {resource_type}: {str(e)}")
|
||||||
|
resource_stats[resource_type] = {
|
||||||
|
'available': 0,
|
||||||
|
'allocated': 0,
|
||||||
|
'quarantine': 0,
|
||||||
|
'total': 0,
|
||||||
|
'available_percent': 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Count test resources separately
|
||||||
|
try:
|
||||||
|
cur.execute("SELECT COUNT(*) FROM resource_pool WHERE is_test = true")
|
||||||
|
test_resources_count = cur.fetchone()[0] if cur.rowcount > 0 else 0
|
||||||
|
stats['test_resources_count'] = test_resources_count
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
license_distribution = []
|
license_distribution = []
|
||||||
hourly_sessions = []
|
hourly_sessions = []
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren