dev #1
3
.gitignore
vendored
3
.gitignore
vendored
@@ -39,7 +39,8 @@ __pycache__/
|
|||||||
!/srv/poe_manager/static/css/*
|
!/srv/poe_manager/static/css/*
|
||||||
!/srv/poe_manager/static/js/
|
!/srv/poe_manager/static/js/
|
||||||
!/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)
|
# Optional: SQLite DB ignorieren (falls du nicht willst, dass Passwörter im Repo landen)
|
||||||
# /srv/poe_manager/sqlite.db
|
# /srv/poe_manager/sqlite.db
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ def get_devices():
|
|||||||
Liefert eine Liste aller Devices aus der Datenbank als Dictionaries.
|
Liefert eine Liste aller Devices aus der Datenbank als Dictionaries.
|
||||||
"""
|
"""
|
||||||
conn = get_db_connection()
|
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()
|
conn.close()
|
||||||
return devices
|
return devices
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ def index():
|
|||||||
conn = sqlite3.connect("sqlite.db")
|
conn = sqlite3.connect("sqlite.db")
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
# is_active mit abfragen
|
# 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()
|
devices = c.fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
@@ -146,19 +146,26 @@ def devices():
|
|||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
switches = conn.execute("SELECT hostname FROM switches").fetchall()
|
switches = conn.execute("SELECT hostname FROM switches").fetchall()
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
# -----------------------
|
||||||
# Inline-Add
|
# Inline-Add
|
||||||
if request.method == 'POST' and 'add_device' in request.form:
|
# -----------------------
|
||||||
|
if 'add_device' in request.form:
|
||||||
if not current_user.is_admin:
|
if not current_user.is_admin:
|
||||||
flash("Zugriff verweigert!")
|
flash("Zugriff verweigert!")
|
||||||
return redirect(url_for('devices'))
|
return redirect(url_for('devices'))
|
||||||
|
|
||||||
mac = request.form['mac']
|
mac = request.form.get('mac')
|
||||||
rpi_ip = request.form['rpi_ip']
|
rpi_ip = request.form.get('rpi_ip')
|
||||||
port = request.form['port']
|
port = request.form.get('port')
|
||||||
name = request.form['name']
|
name = request.form.get('name')
|
||||||
switch_hostname = request.form['switch_hostname']
|
switch_hostname = request.form.get('switch_hostname')
|
||||||
is_active = 1 if 'is_active' in request.form else 0
|
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:
|
try:
|
||||||
conn.execute("""
|
conn.execute("""
|
||||||
INSERT INTO devices (mac, rpi_ip, port, name, switch_hostname, is_active)
|
INSERT INTO devices (mac, rpi_ip, port, name, switch_hostname, is_active)
|
||||||
@@ -169,20 +176,26 @@ def devices():
|
|||||||
except sqlite3.IntegrityError:
|
except sqlite3.IntegrityError:
|
||||||
flash("MAC existiert bereits oder Eingabefehler!")
|
flash("MAC existiert bereits oder Eingabefehler!")
|
||||||
|
|
||||||
|
# -----------------------
|
||||||
# Inline-Edit
|
# Inline-Edit
|
||||||
if request.method == 'POST' and 'edit_device' in request.form:
|
# -----------------------
|
||||||
|
elif 'edit_device' in request.form:
|
||||||
if not current_user.is_admin:
|
if not current_user.is_admin:
|
||||||
flash("Zugriff verweigert!")
|
flash("Zugriff verweigert!")
|
||||||
return redirect(url_for('devices'))
|
return redirect(url_for('devices'))
|
||||||
|
|
||||||
old_mac = request.form['old_mac']
|
old_mac = request.form.get('old_mac')
|
||||||
mac = request.form['mac']
|
mac = request.form.get('mac')
|
||||||
rpi_ip = request.form['rpi_ip']
|
rpi_ip = request.form.get('rpi_ip')
|
||||||
port = request.form['port']
|
port = request.form.get('port')
|
||||||
name = request.form['name']
|
name = request.form.get('name')
|
||||||
switch_hostname = request.form['switch_hostname']
|
switch_hostname = request.form.get('switch_hostname')
|
||||||
is_active = 1 if 'is_active' in request.form else 0
|
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:
|
try:
|
||||||
conn.execute("""
|
conn.execute("""
|
||||||
UPDATE devices
|
UPDATE devices
|
||||||
@@ -194,25 +207,38 @@ def devices():
|
|||||||
except sqlite3.IntegrityError:
|
except sqlite3.IntegrityError:
|
||||||
flash("MAC existiert bereits oder Eingabefehler!")
|
flash("MAC existiert bereits oder Eingabefehler!")
|
||||||
|
|
||||||
|
# -----------------------
|
||||||
# Inline-Delete
|
# Inline-Delete
|
||||||
if request.method == 'POST' and 'delete_device' in request.form:
|
# -----------------------
|
||||||
|
elif 'delete_device' in request.form:
|
||||||
if not current_user.is_admin:
|
if not current_user.is_admin:
|
||||||
flash("Zugriff verweigert!")
|
flash("Zugriff verweigert!")
|
||||||
return redirect(url_for('devices'))
|
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.execute("DELETE FROM devices WHERE mac=?", (del_mac,))
|
||||||
conn.commit()
|
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("""
|
devices = conn.execute("""
|
||||||
SELECT devices.mac, devices.rpi_ip, devices.port, devices.name, devices.is_active,
|
SELECT devices.mac, devices.rpi_ip, devices.port, devices.name, devices.is_active,
|
||||||
switches.hostname AS switch_hostname
|
switches.hostname AS switch_hostname
|
||||||
FROM devices
|
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()
|
""").fetchall()
|
||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
interval_min = get_interval_seconds() // 60
|
|
||||||
return render_template('devices.html', devices=devices, switches=switches)
|
return render_template('devices.html', devices=devices, switches=switches)
|
||||||
|
|
||||||
@app.route('/switches', methods=['GET', 'POST'])
|
@app.route('/switches', methods=['GET', 'POST'])
|
||||||
@@ -264,6 +290,7 @@ def switches():
|
|||||||
flash("Zugriff verweigert!")
|
flash("Zugriff verweigert!")
|
||||||
return redirect(url_for('switches'))
|
return redirect(url_for('switches'))
|
||||||
del_hostname = request.form['delete_switch']
|
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.execute("DELETE FROM switches WHERE hostname=?", (del_hostname,))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
flash(f"Switch {del_hostname} gelöscht.")
|
flash(f"Switch {del_hostname} gelöscht.")
|
||||||
|
|||||||
Binary file not shown.
BIN
srv/poe_manager/static/images/logo.png
Normal file
BIN
srv/poe_manager/static/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
@@ -20,7 +20,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col d-flex align-items-center">
|
<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>
|
<label for="new_is_active" class="ms-2 mb-0 text-white">Aktiv</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col"><button class="btn btn-success w-100">Hinzufügen</button></div>
|
<div class="col"><button class="btn btn-success w-100">Hinzufügen</button></div>
|
||||||
@@ -42,19 +42,9 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for d in devices %}
|
{% for d in devices %}
|
||||||
<tr>
|
<tr>
|
||||||
<form method="post">
|
<td class="col-small"><input name="name" value="{{ d['name'] }}" class="form-control" required disabled></td>
|
||||||
<input type="hidden" name="edit_device" value="1">
|
<td class="col-ip"><input name="rpi_ip" value="{{ d['rpi_ip'] }}" class="form-control" required disabled></td>
|
||||||
<input type="hidden" name="old_mac" value="{{ d['mac'] }}">
|
<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>
|
<td>
|
||||||
<select name="switch_hostname" class="form-control" disabled required>
|
<select name="switch_hostname" class="form-control" disabled required>
|
||||||
{% for sw in switches %}
|
{% for sw in switches %}
|
||||||
@@ -64,21 +54,30 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td class="col-small">
|
<td class="col-small"><input name="port" value="{{ d['port'] }}" class="form-control" required disabled></td>
|
||||||
<input name="port" value="{{ d['port'] }}" class="form-control" required disabled>
|
|
||||||
</td>
|
|
||||||
<td class="custom-checkbox">
|
<td class="custom-checkbox">
|
||||||
<input type="checkbox" name="is_active" value="1" {% if d['is_active'] %}checked{% endif %} disabled class="checkbox-visible">
|
<input type="checkbox" name="is_active" value="1" {% if d['is_active'] %}checked{% endif %} disabled class="checkbox-visible">
|
||||||
</td>
|
</td>
|
||||||
{% if current_user.is_admin %}
|
{% if current_user.is_admin %}
|
||||||
<td class="custom-actions">
|
<td class="custom-actions">
|
||||||
|
<!-- Bearbeiten Button -->
|
||||||
<button type="button" class="btn btn-warning btn-sm" onclick="enableEdit(this)">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>
|
onclick="return confirm('Willst du das Gerät wirklich löschen?');">Löschen</button>
|
||||||
|
</form>
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
<table class="table table-bordered custom-table">
|
<table class="table table-bordered custom-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="col-small">Username</th>
|
<th class="col-ip">Username</th>
|
||||||
<th class="col-small">Rolle</th>
|
<th class="col-ip">Rolle</th>
|
||||||
{% if current_user.is_admin %}<th>Aktionen</th>{% endif %}
|
{% if current_user.is_admin %}<th>Aktionen</th>{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
Reference in New Issue
Block a user