File: //opt/qrcheckin/app.py
import os
import uuid
import qrcode
import time
import threading
from datetime import datetime, timedelta
from flask import Flask, render_template, request, redirect, url_for, session
from flask_sqlalchemy import SQLAlchemy
from models import db, User, CheckIn
app = Flask(__name__)
app.secret_key = os.urandom(24) # In Produktion sicher hinterlegen
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///checkin.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
# Thread zur regelmäßigen Aktualisierung des Tokens
current_token = None
token_expiry = None
def generate_new_token():
global current_token, token_expiry
current_token = str(uuid.uuid4()) # z.B. "fe2f1962-1c59-4cf1-bb14..."
token_expiry = datetime.utcnow() + timedelta(minutes=1) # Token läuft nach 1 Minute ab
# QR-Code generieren und ablegen
qr_data = f"http://localhost:5000/checkin/{current_token}"
img = qrcode.make(qr_data)
qr_file_path = os.path.join("static", "qr_codes", f"{current_token}.png")
img.save(qr_file_path)
# Alte QR-Codes ggf. löschen
cleanup_old_qr_codes()
def cleanup_old_qr_codes():
folder_path = os.path.join("static", "qr_codes")
for file_name in os.listdir(folder_path):
file_path = os.path.join(folder_path, file_name)
file_creation_time = os.path.getctime(file_path)
if time.time() - file_creation_time > 600: # Lösche Dateien älter als 10 Minuten
os.remove(file_path)
def token_refresher():
while True:
generate_new_token()
time.sleep(60) # Alle 60 Sekunden Token aktualisieren
# Starte den Token-Refresh-Thread
refresh_thread = threading.Thread(target=token_refresher, daemon=True)
refresh_thread.start()
@app.route('/')
def index():
if not current_token:
generate_new_token()
return render_template('index.html', token=current_token)
@app.route('/checkin/<string:token>', methods=['GET', 'POST'])
def checkin(token):
if token != current_token or datetime.utcnow() > token_expiry:
return "Dieser QR-Code ist nicht mehr gültig.", 400
if request.method == 'GET':
return render_template('login.html', token=token)
username = request.form.get('username')
password = request.form.get('password')
user = User.query.filter_by(username=username).first()
if not user or user.password != password:
return "Ungültige Anmeldedaten", 401
checkin_entry = CheckIn(user_id=user.id, dynamic_token=token)
db.session.add(checkin_entry)
db.session.commit()
return "Erfolgreich eingecheckt! Danke."
@app.route('/dashboard')
def dashboard():
all_checkins = CheckIn.query.order_by(CheckIn.timestamp.desc()).all()
return render_template('dashboard.html', checkins=all_checkins)
if __name__ == '__main__':
# Sicherstellen, dass die DB existiert und Tabellen angelegt werden
with app.app_context():
db.create_all()
app.run(debug=True)