- Interactive mission selector with metadata-driven design - 5 educational missions (basics + advanced) - AI assistant roles (Deepbit, Bugsy, Schnippsi, Tobi) - SnakeCam gesture recognition system - Token tracking utilities - CLAUDE.md documentation - .gitignore for logs and secrets
53 lines
1.4 KiB
Python
Executable File
53 lines
1.4 KiB
Python
Executable File
from flask import Flask, render_template, Response, request, redirect
|
|
import cv2
|
|
import json
|
|
from datetime import datetime
|
|
|
|
app = Flask(__name__)
|
|
|
|
def gen_frames():
|
|
cam = cv2.VideoCapture(0)
|
|
if not cam.isOpened():
|
|
print("[WARNUNG] Kamera konnte nicht geöffnet werden.")
|
|
return
|
|
|
|
try:
|
|
while True:
|
|
success, frame = cam.read()
|
|
if not success:
|
|
break
|
|
ret, buffer = cv2.imencode('.jpg', frame)
|
|
frame = buffer.tobytes()
|
|
yield (b'--frame\r\n'
|
|
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
|
|
finally:
|
|
cam.release()
|
|
print("[info] Kamera wurde sauber freigegeben.")
|
|
|
|
@app.route('/')
|
|
def index():
|
|
return render_template('index.html')
|
|
|
|
@app.route('/video_feed')
|
|
def video_feed():
|
|
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
|
|
|
|
@app.route('/log_answer', methods=['POST'])
|
|
def log_answer():
|
|
user_input = request.form.get('antwort', 'nichts gesagt')
|
|
mood = request.form.get('mood', 'unspecified')
|
|
gesture = request.form.get('gesture', 'none')
|
|
timestamp = datetime.now().isoformat()
|
|
|
|
log_entry = {
|
|
'timestamp': timestamp,
|
|
'antwort': user_input,
|
|
'mood': mood,
|
|
'gesture': gesture
|
|
}
|
|
|
|
with open("snake_log.jsonl", "a") as log_file:
|
|
log_file.write(json.dumps(log_entry) + "\n")
|
|
|
|
return redirect("/")
|