This commit is contained in:
2025-09-30 15:14:26 +00:00
parent a10343d37e
commit 28a436df16
6 changed files with 121 additions and 94 deletions

3
.gitignore vendored
View File

@@ -39,7 +39,8 @@ __pycache__/
!/srv/poe_manager/static/css/*
!/srv/poe_manager/static/js/
!/srv/poe_manager/static/js/*
!/srv/poe_manager/static/images/
!/srv/poe_manager/static/images/*
# Optional: SQLite DB ignorieren (falls du nicht willst, dass Passwörter im Repo landen)
# /srv/poe_manager/sqlite.db

View File

@@ -47,7 +47,7 @@ def get_devices():
Liefert eine Liste aller Devices aus der Datenbank als Dictionaries.
"""
conn = get_db_connection()
devices = conn.execute("SELECT mac, rpi_ip, port, name, switch_hostname, is_active FROM devices").fetchall()
devices = conn.execute("SELECT mac, rpi_ip, port, name, switch_hostname, is_active FROM devices ORDER BY name ASC").fetchall()
conn.close()
return devices
@@ -87,7 +87,7 @@ def index():
conn = sqlite3.connect("sqlite.db")
c = conn.cursor()
# is_active mit abfragen
c.execute("SELECT mac, name, is_active FROM devices")
c.execute("SELECT mac, name, is_active FROM devices ORDER BY name ASC")
devices = c.fetchall()
conn.close()
@@ -146,19 +146,26 @@ def devices():
conn = get_db_connection()
switches = conn.execute("SELECT hostname FROM switches").fetchall()
if request.method == 'POST':
# -----------------------
# Inline-Add
if request.method == 'POST' and 'add_device' in request.form:
# -----------------------
if 'add_device' in request.form:
if not current_user.is_admin:
flash("Zugriff verweigert!")
return redirect(url_for('devices'))
mac = request.form['mac']
rpi_ip = request.form['rpi_ip']
port = request.form['port']
name = request.form['name']
switch_hostname = request.form['switch_hostname']
mac = request.form.get('mac')
rpi_ip = request.form.get('rpi_ip')
port = request.form.get('port')
name = request.form.get('name')
switch_hostname = request.form.get('switch_hostname')
is_active = 1 if 'is_active' in request.form else 0
if not all([mac, rpi_ip, port, name, switch_hostname]):
flash("Alle Felder müssen ausgefüllt sein!")
return redirect(url_for('devices'))
try:
conn.execute("""
INSERT INTO devices (mac, rpi_ip, port, name, switch_hostname, is_active)
@@ -169,20 +176,26 @@ def devices():
except sqlite3.IntegrityError:
flash("MAC existiert bereits oder Eingabefehler!")
# -----------------------
# Inline-Edit
if request.method == 'POST' and 'edit_device' in request.form:
# -----------------------
elif 'edit_device' in request.form:
if not current_user.is_admin:
flash("Zugriff verweigert!")
return redirect(url_for('devices'))
old_mac = request.form['old_mac']
mac = request.form['mac']
rpi_ip = request.form['rpi_ip']
port = request.form['port']
name = request.form['name']
switch_hostname = request.form['switch_hostname']
old_mac = request.form.get('old_mac')
mac = request.form.get('mac')
rpi_ip = request.form.get('rpi_ip')
port = request.form.get('port')
name = request.form.get('name')
switch_hostname = request.form.get('switch_hostname')
is_active = 1 if 'is_active' in request.form else 0
if not all([old_mac, mac, rpi_ip, port, name, switch_hostname]):
flash("Alle Felder müssen ausgefüllt sein!")
return redirect(url_for('devices'))
try:
conn.execute("""
UPDATE devices
@@ -194,25 +207,38 @@ def devices():
except sqlite3.IntegrityError:
flash("MAC existiert bereits oder Eingabefehler!")
# -----------------------
# Inline-Delete
if request.method == 'POST' and 'delete_device' in request.form:
# -----------------------
elif 'delete_device' in request.form:
if not current_user.is_admin:
flash("Zugriff verweigert!")
return redirect(url_for('devices'))
del_mac = request.form['delete_device']
del_mac = request.form.get('delete_device')
if del_mac:
device = conn.execute("SELECT name FROM devices WHERE mac=?", (del_mac,)).fetchone()
hostname = device['name'] if device else del_mac
conn.execute("DELETE FROM devices WHERE mac=?", (del_mac,))
conn.commit()
flash(f"Gerät {del_mac} gelöscht.")
flash(f"Gerät {hostname} gelöscht.")
else:
flash("Keine MAC-Adresse übermittelt!")
return redirect(url_for('devices'))
# -----------------------
# Devices für Anzeige
# -----------------------
devices = conn.execute("""
SELECT devices.mac, devices.rpi_ip, devices.port, devices.name, devices.is_active,
switches.hostname AS switch_hostname
FROM devices
JOIN switches ON devices.switch_hostname = switches.hostname
LEFT JOIN switches ON devices.switch_hostname = switches.hostname
ORDER BY switches.hostname ASC
""").fetchall()
conn.close()
interval_min = get_interval_seconds() // 60
return render_template('devices.html', devices=devices, switches=switches)
@app.route('/switches', methods=['GET', 'POST'])
@@ -264,6 +290,7 @@ def switches():
flash("Zugriff verweigert!")
return redirect(url_for('switches'))
del_hostname = request.form['delete_switch']
conn.execute("UPDATE devices SET switch_hostname=NULL WHERE switch_hostname=?", (del_hostname,))
conn.execute("DELETE FROM switches WHERE hostname=?", (del_hostname,))
conn.commit()
flash(f"Switch {del_hostname} gelöscht.")

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -20,7 +20,7 @@
</select>
</div>
<div class="col d-flex align-items-center">
<input type="checkbox" name="is_active" value="1" checked id="new_is_active">
<input type="checkbox" name="is_active" value="0" unchecked id="new_is_active">
<label for="new_is_active" class="ms-2 mb-0 text-white">Aktiv</label>
</div>
<div class="col"><button class="btn btn-success w-100">Hinzufügen</button></div>
@@ -42,19 +42,9 @@
<tbody>
{% for d in devices %}
<tr>
<form method="post">
<input type="hidden" name="edit_device" value="1">
<input type="hidden" name="old_mac" value="{{ d['mac'] }}">
<td class="col-small">
<input name="name" value="{{ d['name'] }}" class="form-control" required disabled>
</td>
<td class="col-ip">
<input name="rpi_ip" value="{{ d['rpi_ip'] }}" class="form-control" required disabled>
</td>
<td class="col-mac">
<input name="mac" value="{{ d['mac'] }}" class="form-control" required disabled>
</td>
<td class="col-small"><input name="name" value="{{ d['name'] }}" class="form-control" required disabled></td>
<td class="col-ip"><input name="rpi_ip" value="{{ d['rpi_ip'] }}" class="form-control" required disabled></td>
<td class="col-mac"><input name="mac" value="{{ d['mac'] }}" class="form-control" required disabled></td>
<td>
<select name="switch_hostname" class="form-control" disabled required>
{% for sw in switches %}
@@ -64,21 +54,30 @@
{% endfor %}
</select>
</td>
<td class="col-small">
<input name="port" value="{{ d['port'] }}" class="form-control" required disabled>
</td>
<td class="col-small"><input name="port" value="{{ d['port'] }}" class="form-control" required disabled></td>
<td class="custom-checkbox">
<input type="checkbox" name="is_active" value="1" {% if d['is_active'] %}checked{% endif %} disabled class="checkbox-visible">
</td>
{% if current_user.is_admin %}
<td class="custom-actions">
<!-- Bearbeiten Button -->
<button type="button" class="btn btn-warning btn-sm" onclick="enableEdit(this)">Bearbeiten</button>
<button type="submit" class="btn btn-primary btn-sm d-none">Speichern</button>
<button name="delete_device" value="{{ d['mac'] }}" class="btn btn-danger btn-sm"
<!-- Speichern Button -->
<form method="post" style="display:inline;">
<input type="hidden" name="edit_device" value="1">
<input type="hidden" name="old_mac" value="{{ d['mac'] }}">
<button class="btn btn-primary btn-sm d-none" type="submit">Speichern</button>
</form>
<!-- Löschen Button in eigenem Formular -->
<form method="post" style="display:inline;">
<input type="hidden" name="delete_device" value="{{ d['mac'] }}">
<button class="btn btn-danger btn-sm"
onclick="return confirm('Willst du das Gerät wirklich löschen?');">Löschen</button>
</form>
</td>
{% endif %}
</form>
</tr>
{% endfor %}
</tbody>

View File

@@ -11,8 +11,8 @@
<table class="table table-bordered custom-table">
<thead>
<tr>
<th class="col-small">Username</th>
<th class="col-small">Rolle</th>
<th class="col-ip">Username</th>
<th class="col-ip">Rolle</th>
{% if current_user.is_admin %}<th>Aktionen</th>{% endif %}
</tr>
</thead>