Compare commits

...
42 Commits
Author SHA1 Message Date
Namonay f7cfd94c7e fix: docker skill issue 2026-05-27 13:19:23 +00:00
Namonay 6bca320f92 add: case insensitive 2026-05-27 11:47:41 +00:00
Namonay 6fbc63cbf4 a 2026-03-26 13:40:55 +00:00
Namonay 12e9b3552e fix: remove millisecs 2026-03-26 13:29:18 +00:00
Namonay 20fac5368d add: frontend 2026-03-26 13:26:58 +00:00
Namonay 307199258b fix: triple typo 2026-03-26 12:53:36 +00:00
Namonay 4e2aea1f2e fix: double typo 💀 2026-03-26 11:00:45 +00:00
Namonay 8bbe624f8a fix: typo... 2026-03-26 10:52:32 +00:00
Namonay 3e00258cfe add: new formating 2026-03-26 10:19:16 +00:00
Namonay f8edc84579 i got my swag 2026-03-04 15:39:21 +00:00
Namonay 946244bda9 a! 2026-03-04 15:36:44 +00:00
Namonay 86b9729fdc a 2026-03-04 15:35:04 +00:00
Namonay 2364221780 a 2026-03-04 15:33:39 +00:00
Namonay 552a45c1a8 a 2026-03-04 15:32:45 +00:00
Namonay 06a311f8c0 a 2026-03-04 15:31:48 +00:00
Namonay aee0b6399a a 2026-03-04 15:30:42 +00:00
Namonay 8dfd683880 a 2026-03-04 15:17:18 +00:00
Namonay 0c75eb7d3c a 2026-03-04 15:14:33 +00:00
Namonay 948af50461 a 2026-03-04 15:11:03 +00:00
Namonay 20a5627444 a? 2026-03-04 15:06:19 +00:00
Namonay 2bc3a0916c a 2026-03-03 13:56:31 +00:00
Namonay a2d91691a0 remove notif 2026-03-03 13:55:03 +00:00
Namonay 665df23108 aaa 2026-03-02 14:36:56 +00:00
Namonay 1c6903b3c0 add: timer & reboot 2026-03-02 14:35:19 +00:00
Namonay 94184aea03 a 2026-03-02 12:31:49 +00:00
Namonay 5975ea48f7 i got my swag back 2026-03-02 12:24:03 +00:00
Namonay 7a23612ee5 they nerfed my swag 2026-03-02 12:06:45 +00:00
Namonay aafe082406 a 2026-03-02 12:00:43 +00:00
Namonay 9536bb9157 z 2026-03-02 09:34:56 +00:00
Namonay 20aa3d6246 a 2026-03-02 09:32:52 +00:00
Namonay 9d62d44bc4 d 2026-03-02 09:32:26 +00:00
Namonay 19b72a8f5c aa 2026-03-02 09:28:37 +00:00
Namonay 3835ae16b3 & 2026-03-02 09:11:51 +00:00
Namonay 17957e03ee b 2026-03-02 08:44:06 +00:00
Namonay a421151d13 a 2026-03-02 08:42:41 +00:00
Namonay 504d237405 swag 2026-02-25 15:53:41 +00:00
Namonay 6696bcc4e7 a 2026-02-25 15:36:18 +00:00
Namonay 32a1458218 a 2026-02-25 15:33:42 +00:00
Namonay 4697086f86 a 2026-02-25 15:32:36 +00:00
Namonay c4b9e5f360 w 2026-02-25 15:14:30 +00:00
Namonay 0a9934b889 b 2026-02-25 15:14:07 +00:00
Namonay 8ad1650079 a 2026-02-25 15:13:51 +00:00
5 changed files with 161 additions and 57 deletions
+10 -8
View File
@@ -1,4 +1,6 @@
import urllib.request
import sys
sys.path = [p for p in sys.path if 'Python27' not in p] # uglyfix
from urllib import request
import json
import socket
from datetime import datetime
@@ -18,7 +20,7 @@ payload = {
def get_data():
data = json.dumps(payload).encode("utf-8")
req = urllib.request.Request(
req = request.Request(
url,
headers={"Content-Type": "application/json"},
data=data,
@@ -26,7 +28,7 @@ def get_data():
)
try:
with urllib.request.urlopen(req, timeout=10) as response:
with request.urlopen(req, timeout=10) as response:
data = response.read()
json_data = json.loads(data)
print(json_data)
@@ -44,12 +46,12 @@ def set_shutdown(time, now):
return
LAST_VALUE = time
print("[BS Shutdown] shutting down in " + str(time - now) + " seconds")
# subprocess.run(["shutdown", "/s", "/t", (time - now), " "])
subprocess.run(["shutdown", "-r", "-f", "-t", str(time - now)])
def remove_shutdown():
print("[BS Shutdown] Removed shutdown")
# subprocess.run(["shutdown", "/a"])
subprocess.run(["shutdown", "-a"])
def update():
global LAST_VALUE
@@ -77,10 +79,10 @@ def update():
if (LAST_VALUE != 0):
remove_shutdown()
print("[BS Shutdown] New value")
LAST_VALUE = time
set_shutdown(time, now)
if (time - now) < 1800:
set_shutdown(time, now)
if __name__ == '__main__':
while True:
update()
time.sleep(30)
time.sleep(900)
+3
View File
@@ -4,5 +4,8 @@ services:
build: ./src
volumes:
- "./src/data:/data"
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"
ports:
- "5000:5000"
+25 -7
View File
@@ -1,16 +1,19 @@
from flask import Flask, render_template, request, redirect, url_for, jsonify
import sqlite3
import re
from datetime import datetime
# -- INIT --
app = Flask(__name__)
pattern = re.compile(r"^(?:[01]\d|2[0-3]):[0-5]\d$") # Regex "XX:XX"
# -- GLOBAL VAR --
DB_PATH = "data.db"
DEFAULT_TIME = "21:00"
## -- INIT DB --
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -24,29 +27,35 @@ CREATE TABLE IF NOT EXISTS val (
default_time TEXT NOT NULL DEFAULT '21:00'
)
""")
cursor.execute("SELECT COUNT(*) FROM val")
count = cursor.fetchone()[0]
if count == 0:
cursor.execute("INSERT INTO val (default_time) VALUES (?)", ('21:00',))
conn.commit()
conn.close()
# -- END --
def get_db_connection():
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
return conn
# --- MAIN ---
@app.route("/")
def mainpage():
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("SELECT name, time, noshutdown FROM items ORDER BY name")
cursor.execute("SELECT name, time, noshutdown, last_connection FROM items ORDER BY name")
items = cursor.fetchall()
cursor.execute("SELECT default_time FROM val")
default_time_row = cursor.fetchone()
default_time = default_time_row[0] if default_time_row else None
default_time = default_time_row[0] if default_time_row else DEFAULT_TIME
conn.close()
return render_template('index.html', title='BS Shutdown', items=items, default_time=default_time)
@app.route('/submit', methods =['POST'])
def submit():
value = request.form.get("query")
value = request.form.get("query").upper()
time_value = request.form.get("time")
noshutdown = 1 if request.form.get("noshutdown") == "on" else 0
if not value:
@@ -100,12 +109,14 @@ def delete():
conn.close()
return redirect(url_for("mainpage"))
# --- END MAIN ---
# --- API ---
@app.route("/lookup", methods=["POST"])
def lookup():
data = request.get_json()
if not data or "name" not in data:
return jsonify({"error": "Not found"}), 404
name = data["name"]
name = data["name"].upper()
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute(
@@ -113,9 +124,16 @@ def lookup():
(name,)
)
item = cursor.fetchone()
cursor.execute("SELECT default_time FROM val")
default_time_row = cursor.fetchone()
default_time = default_time_row[0] if default_time_row else DEFAULT_TIME
if item:
cursor.execute("UPDATE items SET last_connection = ? WHERE name = ?", (datetime.now().replace(microsecond=0), item["name"]))
conn.commit()
conn.close()
if item:
return jsonify({"name": item["name"], "noshutdown": item["noshutdown"], "time": item["time"]}), 200
else:
return jsonify({"error": "Not found"}), 404
return jsonify({"noshutdown": 0, "time": default_time}), 200
# --- END API ---
+4 -1
View File
@@ -42,7 +42,10 @@
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link {% if title=='BG Shutdown' %}active{% endif %}" href="{{ url_for('mainpage') }}">Accueil</a>
<a class="nav-link {% if title=='BS Shutdown' %}active{% endif %}" href="{{ url_for('mainpage') }}">Accueil</a>
</li>
<li class="nav-item">
<a class="nav-link {% if title=='BG Shutdown' %}active{% endif %}" href="{{ url_for('mainpage') }}">Groupes</a>
</li>
</ul>
</div>
+119 -41
View File
@@ -10,14 +10,14 @@
<div class="col-10">
<form method="post" action="/submit" class="row g-2 align-items-center">
<div class="col-md-3">
<div class="col-md-2">
<input
type="text"
name="query"
class="form-control bg-dark text-white"
placeholder="Nom de la machine">
</div>
<div class="col-md-3">
<div class="col-md-2">
<select name="time" class="form-select bg-dark text-white" id="time-select">
{% for hour in range(0, 24) %}
<option value="{{ '%02d:00'|format(hour) }}">{{ '%02d:00'|format(hour) }}</option>
@@ -33,14 +33,14 @@
</div>
<div class="col-md-1">
<button type="submit" class="btn btn-sm btn-primary w-100">
<i class="bi bi-plus-lg"> Save</i>
<i class="bi bi-plus-lg"> Add</i>
</button>
</div>
</form>
</div>
<div class="col-auto gap-1 ms-auto">
<form method="post" action="/submit-default" class="d-flex gap-1">
<form method="post" action="/submit-default" class="d-flex align-items-center gap-1">
<select name="default-time" class="form-select bg-dark text-white flex-grow-1" id="default-time-select">
{% for hour in range(0, 24) %}
{% set h1 = '%02d:00'|format(hour) %}
@@ -57,7 +57,7 @@
</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-sm btn-primary">
<button type="submit" class="btn btn-sm btn-primary w-100">
<i class="bi bi-save"> Save</i>
</button>
</form>
@@ -66,48 +66,105 @@
</div>
</div>
<div class="card bg-dark bg-opacity-75 p-3">
<h5 class="text-white mb-3">Liste des éléments</h5>
<div class="row fw-bold text-white mb-2">
<div class="col-4">Nom</div>
<div class="col-3">Whitelist</div>
<div class="col-3">Time</div>
<div class="col-2 text-end">Actions</div>
</div>
<div class="table-items">
{% for item in items %}
<div class="row align-items-center py-2">
<div class="col-4 text-white">
{{ item.name }}
<div class="card bg-dark bg-opacity-75 p-3">
<h5 class="text-white mb-3">Liste des éléments</h5>
<div class="row fw-bold text-white mb-2">
<div class="col-4">Nom</div>
<div class="col-3">Dernier ping</div>
<div class="col-2">Whitelist</div>
<div class="col-2">Time</div>
<div class="col-1 text-end">Actions</div>
</div>
<div class="table-items">
{% for item in items %}
<div class="row align-items-center py-2">
<div class="col-4 text-white">
{{ item.name }}
</div>
<div class="col-3 text-white">
{% if item.last_connection %}
{{ item.last_connection }}
{% endif %}
</div>
<div class="col-2">
{% if item.noshutdown == 1 %}
<span class="text-success">OUI</span>
{% else %}
<span class="text-danger">NON</span>
{% endif %}
</div>
<div class="col-2 text-white">
{% if item.noshutdown == 0 %}
{{ item.time }}
{% endif %}
</div>
<div class="col-1 text-end d-flex justify-content-end gap-1">
<button
type="button"
class="btn btn-sm btn-warning edit-btn"
data-name="{{ item.name }}"
data-noshutdown="{{ item.noshutdown }}"
data-time="{{ item.time }}"
data-bs-toggle="modal"
data-bs-target="#editModal">
<i class="bi bi-pencil"></i>
</button>
<form method="post" action="/delete" class="m-0">
<input type="hidden" name="item_name" value="{{ item.name }}">
<button type="submit" class="btn btn-sm btn-danger">
<i class="bi bi-x-lg"></i>
</button>
</form>
</div>
</div>
{% if not loop.last %}
<hr class="border-secondary my-1">
{% endif %}
{% endfor %}
<div class="modal fade" id="editModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content bg-dark text-white">
<form method="post" action="/submit">
<div class="modal-header">
<h5 class="modal-title">Modifier l'élément</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Nom</label>
<input type="text" class="form-control" name="query" id="editName" readonly>
</div>
<div class="mb-3">
<label class="form-label">No Shutdown</label>
<input class="form-check-input" type="checkbox" name="noshutdown" id="editNoshutdown">
</div>
<div class="mb-3">
<label class="form-label">Time</label>
<select class="form-select" name="time" id="editTime">
{% for hour in range(0, 24) %}
{% set h1 = '%02d:00'|format(hour) %}
{% set h2 = '%02d:30'|format(hour) %}
<option value="{{ h1 }}">{{ h1 }}</option>
<option value="{{ h2 }}">{{ h2 }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-3">
{% if item.noshutdown == 1 %}
<span class="text-success">OUI</span>
{% else %}
<span class="text-danger">NON</span>
{% endif %}
<div class="modal-footer">
<button type="submit" class="btn btn-success">Enregistrer</button>
</div>
<div class="col-3 text-white">
{% if item.noshutdown == 0 %}
{{ item.time }}
{% endif %}
</div>
<div class="col-2 text-end">
<form method="post" action="/delete" class="m-0">
<input type="hidden" name="item_name" value="{{ item.name }}">
<button type="submit" class="btn btn-sm btn-danger">
<i class="bi bi-x-lg"></i>Supprimer
</button>
</form>
</form>
</div>
</div>
{% if not loop.last %}
<hr class="border-secondary my-1">
{% endif %}
{% endfor %}
</div>
</div>
</div>
@@ -122,6 +179,27 @@ timeSelect.disabled = tickCheckbox.checked;
tickCheckbox.addEventListener('change', function() {
timeSelect.disabled = this.checked;
});
document.querySelectorAll('.edit-btn').forEach(button => {
button.addEventListener('click', function () {
const name = this.dataset.name;
const noshutdown = this.dataset.noshutdown;
const time = this.dataset.time;
document.getElementById('editName').value = name;
document.getElementById('editNoshutdown').checked = (noshutdown == 1);
document.getElementById('editTime').value = time;
const timeSelect = document.getElementById('editTime');
const noshutdownSelect = document.getElementById('editNoshutdown');
timeSelect.disabled = noshutdownSelect.checked;
noshutdownSelect.addEventListener('change', function () {
timeSelect.disabled = this.checked;
});
});
});
</script>
{% endblock %}