Add complete Crumbforest mission system

- 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
This commit is contained in:
Branko May Trinkwald
2025-12-21 01:16:48 +01:00
parent ffea50b4b0
commit 2915828adf
121 changed files with 11851 additions and 0 deletions

52
snake_camera_vision/app.py Executable file
View File

@@ -0,0 +1,52 @@
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("/")

View File

@@ -0,0 +1,13 @@
import cv2
def gen_frames():
cap = cv2.VideoCapture(0)
while True:
success, frame = cap.read()
if not success:
break
else:
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')

3
snake_camera_vision/run.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
echo "🐍 Starte SnakeCam ..."
exec python3 app.py

View File

@@ -0,0 +1,15 @@
# snakecam_module.py
import cv2
def init_camera(index=0):
cam = cv2.VideoCapture(index)
if not cam.isOpened():
print("[WARNUNG] Kamera konnte nicht geöffnet werden.")
return None
print("[OK] Kamera erfolgreich geöffnet.")
return cam
def release_camera(cam):
if cam and cam.isOpened():
cam.release()
print("[INFO] Kamera wurde freigegeben.")

View File

@@ -0,0 +1,9 @@
body {
background-color: #f0fff0;
font-family: 'Comic Sans MS', cursive, sans-serif;
text-align: center;
color: #006400;
}
h1 {
margin-top: 20px;
}

View File

@@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>🐍 SnakeCam Krümelblick ins Versteck</title>
<style>
body {
font-family: 'Comic Sans MS', sans-serif;
background-color: #e9f5e9;
color: #333;
text-align: center;
padding: 2rem;
}
img {
border: 4px dashed #4caf50;
border-radius: 12px;
max-width: 100%;
height: auto;
}
form {
margin-top: 2rem;
}
input, select {
padding: 0.5rem;
font-size: 1rem;
margin: 0.5rem;
border-radius: 6px;
border: 1px solid #ccc;
}
button {
padding: 0.7rem 1.2rem;
font-size: 1rem;
background-color: #4caf50;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
}
button:hover {
background-color: #388e3c;
}
</style>
</head>
<body>
<h1>🐍 SnakeCam</h1>
<p>Willkommen kleiner Krümel! Hier siehst du, was deine Kamera entdeckt.</p>
<!-- Live-Stream -->
<img src="/video_feed" alt="Live-Übertragung von SnakeCam 🐍" />
<!-- Eingabeformular -->
<form action="/log_answer" method="POST">
<p><strong>Was fühlst du gerade?</strong></p>
<input type="text" name="antwort" placeholder="Ich sehe einen ... 🐞🌳🤖" required>
<p><strong>Wie ist deine Stimmung?</strong></p>
<select name="mood">
<option value="happy">😊 Glücklich</option>
<option value="curious">🤔 Neugierig</option>
<option value="calm">😌 Ruhig</option>
<option value="excited">😃 Aufgeregt</option>
<option value="unspecified">🤷 Keine Angabe</option>
</select>
<p><strong>Hast du eine Geste gemacht?</strong></p>
<select name="gesture">
<option value="none">🚫 Keine</option>
<option value="wave">👋 Winken</option>
<option value="thumbs_up">👍 Daumen hoch</option>
<option value="peace">✌️ Peace</option>
<option value="other">✨ Etwas anderes</option>
</select>
<br><br>
<button type="submit">🎯 Eintragen</button>
</form>
</body>
</html>