Webseite überarbeitet und Telegram Bot funktion hinzugefügt #1

Merged
pi-farm merged 59 commits from dev into main 2026-03-07 23:50:03 +00:00
Showing only changes of commit b90d216067 - Show all commits

90
main.py
View File

@@ -9,6 +9,8 @@ import re
import httpx import httpx
import struct import struct
import termios import termios
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, MessageHandler, filters
from google import genai from google import genai
from google.genai import types from google.genai import types
import json import json
@@ -44,6 +46,11 @@ OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-4o")
OLLAMA_MODEL = os.getenv("OLLAMA_MODEL", "llama3") OLLAMA_MODEL = os.getenv("OLLAMA_MODEL", "llama3")
NVIDIA_MODEL = os.getenv("NVIDIA_MODEL", "moonshotai/kimi-k2.5") NVIDIA_MODEL = os.getenv("NVIDIA_MODEL", "moonshotai/kimi-k2.5")
# Telegram Bot Konfiguration
TELEGRAM_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "")
ALLOWED_ID = os.getenv("ALLOWED_TELEGRAM_USER_ID", "")
telegram_app = None
# --- DATENBANK INITIALISIERUNG (ERWEITERT) --- # --- DATENBANK INITIALISIERUNG (ERWEITERT) ---
def init_db(): def init_db():
conn = sqlite3.connect(DB_PATH) conn = sqlite3.connect(DB_PATH)
@@ -163,6 +170,89 @@ async def get_ai_response(user_input, system_prompt):
return ai_msg return ai_msg
async def handle_telegram_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
# Sicherheits-Check: Nur deine Chat-ID wird akzeptiert
if str(update.effective_chat.id) != ALLOWED_ID:
await update.message.reply_text("Zugriff verweigert. 🔒")
return
user_msg = update.message.text
# "Tippt..." Status in Telegram anzeigen (schöne UX)
await update.message.reply_chat_action(action="typing")
# 1. KI Antwort holen
ai_response = await get_ai_response(user_msg, get_system_prompt())
# 2. Befehle extrahieren
commands = re.findall(r'<EXECUTE target="(.*?)">(.*?)</EXECUTE>', ai_response, re.I | re.S)
clean_msg = re.sub(r'<EXECUTE.*?>.*?</EXECUTE>', '', ai_response, flags=re.I | re.S).strip()
# KI Text-Antwort senden
if clean_msg:
await update.message.reply_text(clean_msg)
# 3. Befehle ausführen und Ergebnisse als Telegram-Nachricht senden
if commands:
for target, cmd in commands:
await update.message.reply_text(f"⏳ Führe aus auf *{target}*:\n`{cmd}`", parse_mode='Markdown')
# Node in DB suchen
conn = get_db()
n = conn.execute('SELECT * FROM nodes WHERE ip=? OR name=?', (target.strip(), target.strip())).fetchone()
conn.close()
if n:
# Befehl ausführen und Output abfangen
try:
proc = await asyncio.create_subprocess_shell(
f"ssh -o StrictHostKeyChecking=no {n['user']}@{n['ip']} '{cmd}'",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT
)
stdout, _ = await proc.communicate()
output = stdout.decode('utf-8', errors='ignore').strip()
# Ergebnis an Telegram senden (abgeschnitten auf 4000 Zeichen, da Telegram Limits hat)
result_text = output[:4000] if output else "✅ Befehl ohne Output ausgeführt."
await update.message.reply_text(f"💻 **Output von {n['name']}:**\n```\n{result_text}\n```", parse_mode='Markdown')
# Auch ins KI-Gedächtnis schreiben
chat_history.append({"role": "user", "content": f"[SYSTEM] Befehl '{cmd}' auf {target} fertig:\n{result_text}"})
except Exception as e:
await update.message.reply_text(f"❌ Fehler bei der Ausführung: {e}")
else:
await update.message.reply_text(f"⚠️ Node '{target}' nicht in der Datenbank gefunden.")
# --- FASTAPI LIFESPAN EVENTS (Bot starten/stoppen) ---
@app.on_event("startup")
async def startup_event():
global telegram_app
if TELEGRAM_TOKEN and ALLOWED_ID:
print("🤖 Starte Telegram Bot im Hintergrund...")
telegram_app = ApplicationBuilder().token(TELEGRAM_TOKEN).build()
# Leitet alle Text-Nachrichten an unsere Funktion weiter
telegram_app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_telegram_message))
# Bot asynchron in die FastAPI Event-Loop einhängen
await telegram_app.initialize()
await telegram_app.start()
await telegram_app.updater.start_polling()
print("✅ Telegram Bot lauscht!")
else:
print(" Telegram Bot inaktiv (Token oder ID fehlen in der .env).")
@app.on_event("shutdown")
async def shutdown_event():
global telegram_app
if telegram_app:
print("🛑 Stoppe Telegram Bot...")
await telegram_app.updater.stop()
await telegram_app.stop()
await telegram_app.shutdown()
# --- WebSocket Manager --- # --- WebSocket Manager ---
class ConnectionManager: class ConnectionManager:
def __init__(self): self.active_connections = [] def __init__(self): self.active_connections = []