diff --git a/cleaning_logs.db b/cleaning_logs.db new file mode 100644 index 0000000..99a8d6c Binary files /dev/null and b/cleaning_logs.db differ diff --git a/dashboard.py b/dashboard.py new file mode 100644 index 0000000..04cbd3f --- /dev/null +++ b/dashboard.py @@ -0,0 +1,323 @@ +import sqlite3 +from flask import Flask, render_template_string, jsonify +from datetime import datetime, date + +app = Flask(__name__) +DB_FILE = "cleaning_logs.db" + +# Room definitions +BUILDINGS = { + "Haus A-C": [ + list(range(101, 131)), + list(range(201, 231)), + list(range(301, 331)) + ], + "Haus D-F": [ + list(range(131, 151)), + list(range(231, 251)), + list(range(331, 351)) + ], + "Haus O": [ + list(range(401, 413)), + list(range(420, 436)), + list(range(440, 457)) + ] +} + +def get_all_defined_rooms(): + """Get a set of all room numbers defined in buildings""" + rooms = set() + for floors in BUILDINGS.values(): + for floor in floors: + rooms.update(str(r) for r in floor) + return rooms + +def get_room_statuses(): + """Returns dict: {room_number: (last_cleaned_time, is_today)}""" + today = date.today().strftime("%Y-%m-%d") + + with sqlite3.connect(DB_FILE) as conn: + cursor = conn.execute(""" + SELECT room_number, MAX(cleaned_at) as last_cleaned + FROM cleaning_events + GROUP BY room_number + """) + rows = cursor.fetchall() + + statuses = {} + for room, last_cleaned in rows: + is_today = last_cleaned.startswith(today) if last_cleaned else False + statuses[room] = { + "is_today": is_today, + "last_cleaned": last_cleaned + } + + return statuses + +def get_special_rooms(statuses): + """Get rooms that aren't in any defined building""" + defined_rooms = get_all_defined_rooms() + special_rooms = [] + + for room_number in statuses.keys(): + if room_number not in defined_rooms: + special_rooms.append(room_number) + + return sorted(special_rooms) + +@app.route('/') +def dashboard(): + statuses = get_room_statuses() + special_rooms = get_special_rooms(statuses) + return render_template_string( + TEMPLATE, + buildings=BUILDINGS, + statuses=statuses, + special_rooms=special_rooms + ) + +@app.route('/api/status') +def api_status(): + """API endpoint for live updates""" + statuses = get_room_statuses() + special_rooms = get_special_rooms(statuses) + return jsonify({ + "statuses": statuses, + "special_rooms": special_rooms + }) + +TEMPLATE = ''' + + + + Room Cleaning Dashboard + + + +

đŸ§¹ Room Cleaning Status

+ +
+ +
+ + {% for building_name, floors in buildings.items() %} +
+

{{ building_name }}

+ {% for floor in floors %} +
+
Etage {{ loop.index }}
+
+ {% for room in floor %} + {% set room_str = room|string %} + {% set status = statuses.get(room_str, {"is_today": False, "last_cleaned": None}) %} +
+ {{ room }} + + {% if status.last_cleaned %} + {{ status.last_cleaned[5:10] }}
{{ status.last_cleaned[11:16] }} + {% else %}Never{% endif %} +
+
+ {% endfor %} +
+
+ {% endfor %} +
+ {% endfor %} + + {% if special_rooms %} +
+

Sonderräume

+
+
+ {% for room in special_rooms %} + {% set status = statuses.get(room, {"is_today": False, "last_cleaned": None}) %} +
+ {{ room }} + + {% if status.last_cleaned %} + {{ status.last_cleaned[5:10] }}
{{ status.last_cleaned[11:16] }} + {% else %}Never{% endif %} +
+
+ {% endfor %} +
+
+
+ {% endif %} + + + + +''' + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5001, debug=True) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..6f6bfa6 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1769461804, + "narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/test.py b/test.py index 7f5d4ea..eee6bce 100644 --- a/test.py +++ b/test.py @@ -3,37 +3,42 @@ from flask import Flask, request from datetime import datetime app = Flask(__name__) -DB_FILE = "logs.db" +DB_FILE = "cleaning_logs.db" def init_db(): with sqlite3.connect(DB_FILE) as conn: conn.execute(''' - CREATE TABLE IF NOT EXISTS post_logs ( + CREATE TABLE IF NOT EXISTS cleaning_events ( id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp TEXT, - content_type TEXT, - body TEXT + room_number TEXT, + cleaned_at TEXT ) ''') @app.route('/', methods=['POST']) def handle_post(): - content_type = request.headers.get('Content-Type') - body = request.get_data(as_text=True) - timestamp = datetime.now().isoformat() + # Extract the room number from the POST body + # .strip('"') removes extra quotes if the sender includes them + room_number = request.get_data(as_text=True).strip().strip('"') + + if not room_number: + return "Missing room number", 400 - # Log to Console - print(f"[{timestamp}] Logging POST: {body[:50]}...") + timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - # Log to SQLite + # Log to Console for your visibility + print(f"Room {room_number} marked as cleaned at {timestamp}") + + # Save to SQLite with sqlite3.connect(DB_FILE) as conn: conn.execute( - "INSERT INTO post_logs (timestamp, content_type, body) VALUES (?, ?, ?)", - (timestamp, content_type, body) + "INSERT INTO cleaning_events (room_number, cleaned_at) VALUES (?, ?)", + (room_number, timestamp) ) - return "Logged successfully", 200 + return f"Room {room_number} logged.", 200 if __name__ == '__main__': init_db() - app.run(host='0.0.0.0', port=5000, debug=True) + # Binding to 0.0.0.0 so devices on your network can reach it + app.run(host='0.0.0.0', port=5000)