129 lines
3.8 KiB
Python
129 lines
3.8 KiB
Python
from flask import Flask, render_template, request, redirect, url_for, g, jsonify
|
|
import sqlite3
|
|
import os
|
|
|
|
DB = os.environ.get("DB_PATH", "queue.db")
|
|
ADMIN_SUFFIX = os.environ.get("ADMIN_URL", "admin").strip("/")
|
|
ADMIN_PATH = f"/{ADMIN_SUFFIX}" if ADMIN_SUFFIX else "/admin"
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
def get_db():
|
|
db = getattr(g, "_db", None)
|
|
if db is None:
|
|
need_init = not os.path.exists(DB)
|
|
db = g._db = sqlite3.connect(DB, check_same_thread=False)
|
|
db.row_factory = sqlite3.Row
|
|
if need_init:
|
|
init_db(db)
|
|
return db
|
|
|
|
|
|
def init_db(db):
|
|
cur = db.cursor()
|
|
cur.execute(
|
|
"""CREATE TABLE items (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
number TEXT,
|
|
status TEXT -- 'waiting', 'called', 'done'
|
|
)"""
|
|
)
|
|
db.commit()
|
|
|
|
|
|
@app.teardown_appcontext
|
|
def close_db(exc):
|
|
db = getattr(g, "_db", None)
|
|
if db:
|
|
db.close()
|
|
|
|
|
|
# Main display for clients
|
|
@app.route("/")
|
|
def index():
|
|
db = get_db()
|
|
cur = db.execute(
|
|
"SELECT number FROM items WHERE status='called' ORDER BY id DESC LIMIT 1"
|
|
)
|
|
row = cur.fetchone()
|
|
current = row["number"] if row else ""
|
|
return render_template("index.html", current=current)
|
|
|
|
|
|
# API endpoint used by clients to poll current number (JSON)
|
|
@app.route("/current")
|
|
def current_api():
|
|
db = get_db()
|
|
cur_called = db.execute("SELECT number FROM items WHERE status='called' ORDER BY id").fetchall()
|
|
nums = [r["number"] for r in cur_called]
|
|
cur_wait = db.execute("SELECT COUNT(*) AS cnt FROM items WHERE status='waiting'").fetchone()
|
|
waiting_count = cur_wait["cnt"] if cur_wait else 0
|
|
return jsonify(current=nums, waiting=waiting_count)
|
|
|
|
|
|
# Admin UI: start/reset system by providing count of tickets (1..N)
|
|
# @app.route("/admin", methods=["GET", "POST"])
|
|
def admin():
|
|
db = get_db()
|
|
|
|
if request.method == "POST":
|
|
action = request.form.get("action")
|
|
if action == "add":
|
|
# dodaj nowy numer na końcu puli
|
|
cur = db.execute("SELECT number FROM items ORDER BY id DESC LIMIT 1").fetchone()
|
|
if cur:
|
|
try:
|
|
last = int(cur["number"])
|
|
except:
|
|
last = 0
|
|
new = last + 1
|
|
else:
|
|
new = 1
|
|
db.execute("INSERT INTO items (number, status) VALUES (?, 'waiting')", (str(new),))
|
|
db.commit()
|
|
|
|
elif action == "call":
|
|
num = request.form.get("num")
|
|
db.execute("UPDATE items SET status='called' WHERE number=? AND status='waiting'", (num,))
|
|
db.commit()
|
|
|
|
elif action == "done":
|
|
num = request.form.get("num")
|
|
db.execute("UPDATE items SET status='done' WHERE number=? AND status='called'", (num,))
|
|
db.commit()
|
|
|
|
elif action == "return":
|
|
num = request.form.get("num")
|
|
if num:
|
|
db.execute("UPDATE items SET status='waiting' WHERE number=? AND status='called'", (num,))
|
|
db.commit()
|
|
|
|
elif action == "reset":
|
|
db.execute("DELETE FROM items")
|
|
db.commit()
|
|
|
|
return redirect(url_for("admin"))
|
|
|
|
cur_wait = db.execute(
|
|
"SELECT number FROM items WHERE status='waiting' ORDER BY id"
|
|
).fetchall()
|
|
cur_called = db.execute(
|
|
"SELECT number FROM items WHERE status='called' ORDER BY id"
|
|
).fetchall()
|
|
cur_done = db.execute(
|
|
"SELECT number FROM items WHERE status='done' ORDER BY id"
|
|
).fetchall()
|
|
return render_template(
|
|
"admin.html",
|
|
waiting=[r["number"] for r in cur_wait],
|
|
called=[r["number"] for r in cur_called],
|
|
done=[r["number"] for r in cur_done],
|
|
)
|
|
|
|
app.add_url_rule(ADMIN_PATH, endpoint="admin", view_func=admin, methods=["GET", "POST"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app.run(host="0.0.0.0", port=5000, debug=True)
|