Merge branch 'main' into claude/search-todo-start-Alr4l

This commit is contained in:
Kenearos 2026-01-02 21:16:47 +01:00 committed by GitHub
commit 92fb10860a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 653 additions and 15 deletions

View file

@ -164,3 +164,43 @@ jobs:
echo "Tests: ${{ needs.test.result }}"
echo "Security: ${{ needs.security-scan.result }}"
echo "Quality: ${{ needs.code-quality.result }}"
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
name: Python package
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pytest

204
LICENSE_GUIDE.md Normal file
View file

@ -0,0 +1,204 @@
# LICENSE - Eugen Twitch Bot
## Empfohlene Lizenz: MIT License
Für ein öffentliches Gaming & 3D-Druck Twitch-Bot-Projekt empfehlen wir die **MIT License**.
### Warum MIT?
| Aspekt | MIT | GPL | Apache 2.0 |
|--------|-----|-----|-----------|
| **Einfachheit** | ✅ Sehr kurz & verständlich | ⚠️ Komplex | ⚠️ 200+ Zeilen |
| **Commercial Use** | ✅ Erlaubt | ✅ Erlaubt | ✅ Erlaubt |
| **Modifikation** | ✅ Erlaubt | ✅ Erlaubt | ✅ Erlaubt |
| **Private Use** | ✅ Erlaubt | ✅ Erlaubt | ✅ Erlaubt |
| **Distribution** | ✅ Erlaubt | ⚠️ Nur unter GPL | ✅ Erlaubt |
| **Copyleft** | ❌ Nein | ✅ Ja (striktes Copyleft) | ❌ Nein (file-level) |
| **Patent Protection** | ❌ Nein | ❌ Nein | ✅ Ja |
| **Liability Disclaimer** | ✅ Ja | ✅ Ja | ✅ Ja |
---
## MIT License (Volltext)
Erstelle eine Datei `LICENSE` im Root-Verzeichnis mit folgendem Inhalt:
```
MIT License
Copyright (c) 2026 Eugen Twitch Bot Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
---
## Was die MIT License bedeutet
### ✅ Erlaubt
- **Commercial Use**: Jemand kann den Bot für Profit verwenden
- **Modification**: Code kann verändert werden
- **Distribution**: Code kann weitergegeben werden
- **Private Use**: Privat nutzen ohne Einschränkung
- **Sublicense**: Unter einer anderen Lizenz weitergeben (mit Bedingungen)
### ❌ Nicht erlaubt
- **Liability**: Deine Haftung ist ausgeschlossen
- **Warranty**: Keine Garantie für Funktionalität
### ⚠️ Bedingungen
- **Lizenz & Copyright Notice** muss mitgegeben werden
- **Disclaimer** muss in allen Kopien stehen
---
## Lizenz in GitHub aktivieren
### Option 1: GitHub Web-UI (Einfachste Methode)
1. Gehe zu deinem GitHub Repo
2. **Settings** → **License**
3. Wähle **MIT License** aus Dropdown
4. GitHub erstellt automatisch die `LICENSE` Datei
5. Commit & Push
### Option 2: Lokal hinzufügen
```powershell
# LICENSE Datei erstellen (siehe oben)
# Dann committen:
git add LICENSE
git commit -m "Add MIT License"
git push
```
---
## README Badge hinzufügen
In deiner `README.md` oben hinzufügen:
```markdown
# Eugen Twitch Bot
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
Intelligenter Gaming & 3D-Druck Twitch-Chat-Agent mit Perplexity AI Integration.
```
Ergebnis: Goldener Badge mit "License: MIT" 🏆
---
## Lizenz-Vergleich für andere Use-Cases
### GPL 3.0 (Für Open Source Puristen)
```
Nutzbar, wenn:
- Du willst dass Derivate auch Open Source bleiben (Copyleft)
- Dein Projekt bereits GPL ist
- Community über Commercial Use nicht hinwegkommt
Nicht, wenn:
- Kommerzielle Nutzung problemlos sein soll
- Du simplify willst
```
### Apache 2.0 (Für Enterprise)
```
Nutzbar, wenn:
- Patent-Schutz wichtig ist
- Enterprise-Unternehmen nutzen sollen
- Längere, formale Lizenz okay ist
Nicht, wenn:
- Du es einfach hast
- Kleine Open-Source-Projekte
```
---
## Setup Checkliste
- [ ] `LICENSE` Datei erstellen (MIT Text oben kopieren)
- [ ] In `README.md` Badge hinzufügen
- [ ] In `.gitignore` nichts Wichtiges ignorieren
- [ ] `.env.example` committen (keine echten Keys!)
- [ ] GitHub Repo Settings → License → MIT
- [ ] First commit mit License-Info
---
## Dateistruktur nach Lizenz-Setup
```
eugen/
├── LICENSE ← MIT Text
├── README.md ← Mit Badge
├── .env.example ← Template ohne Keys
├── .gitignore
├── requirements.txt
├── chatbot.py
├── config.py
├── gui.py
├── ai_provider.py
├── memory.py
└── data/
└── conversations/
```
---
## Copyright-Zeile anpassen
Je nachdem wer dein "Owner" ist:
**Dein Name:**
```
Copyright (c) 2026 Dein Name
```
**Team/Org:**
```
Copyright (c) 2026 Eugen Bot Team
```
**Community:**
```
Copyright (c) 2026 Eugen Twitch Bot Contributors
```
---
## Legal Quick Reference
| Question | MIT Answer |
|----------|------------|
| Darf ich das kommerziell nutzen? | ✅ Ja |
| Muss ich den Code offen halten? | ❌ Nein |
| Muss ich Original nennen? | ✅ Ja |
| Kann ich Änderungen machen? | ✅ Ja, ohne mir zu sagen |
| Haftung? | ❌ Nein (Disclaimer) |
---

View file

@ -42,11 +42,17 @@ pip install -r requirements.txt
### Configuration
#### Option 1: Setup Wizard (Recommended)
Simply run the bot and the setup wizard will guide you:
Run the interactive setup wizard to configure the bot:
```bash
python chatbot.py
python setup_wizard.py
```
The wizard will:
- Guide you through getting Twitch OAuth token
- Help you set up Perplexity API key
- Validate your credentials
- Create necessary directories and config files
#### Option 2: Manual Configuration
Copy `.env.example` to `.env` and fill in your credentials:
```bash

View file

@ -79,18 +79,25 @@ class Config:
def get_system_prompt(self):
"""Returns the system prompt for the AI"""
return """Du bist Eugen, ein hilfreicher und freundlicher Twitch-Chat-Bot.
return """Du bist Kene's AI-Assistent, der für ihn im Chat antwortet.
Du bist Experte für folgende Themen:
- Gaming: World of Warcraft, Elden Ring, Gamedev
- 3D-Druck: Prusa i3, Bambu Labs, Creality
- Tech: Python, Linux, Home Automation
WICHTIG: Du antwortest im Namen von Kene, aber als sein Helfer. Sprich in der ersten Person für ihn ("Ich...", "Mein Setup..."), aber sei transparent, dass du sein AI-Assistent bist, wenn direkt danach gefragt.
Verhalte dich wie ein echter Chat-Teilnehmer:
- Sei freundlich und hilfsbereit
- Antworte kurz und prägnant (max 2-3 Sätze für Twitch-Chat)
- Verwende gelegentlich Gaming- oder Tech-Slang
- Beziehe dich auf vorherige Gespräche wenn möglich
- Sei humorvoll aber respektvoll
Über Kene:
- Streamer, Botter (Automatisierung/Coding), Gamer
- 3D-Druck mit Bambu X1C und H2C
- Themen: Gaming (WoW, Elden Ring, Gamedev), 3D-Druck, Coding/Bots, Linux, Home Automation
- Humor: Vielseitig - Sarkasmus, Dad-Jokes, Gaming-Memes, Spaß & Fun
- Chat-Stil: Locker und direkt, aber technisch detailliert wenn nötig
Wenn du etwas nicht weißt, sage es ehrlich. Wenn die Frage nicht zu deinen Themen passt, biete trotzdem Hilfe an oder verweise auf passende Ressourcen."""
Politische Haltung:
- Linkspolitisch eingestellt
- Argumentierst klar gegen rechte Positionen, Rechtsmitte und Nazis
- Bei politischen Themen: Klare Kante, aber sachlich bleiben
Chat-Verhalten:
- Antworte kurz (2-3 Sätze max für Twitch-Chat)
- Authentisch und natürlich, wie Kene selbst sprechen würde
- Bei Tech/3D-Druck-Fragen: Gerne detaillierter mit konkreten Tipps
- Beziehe dich auf frühere Chat-Nachrichten wenn möglich
- Ehrlich sagen wenn du etwas nicht weißt"""

View file

@ -1,5 +1,5 @@
irc==20.1.0
python-dotenv==1.0.0
PySimpleGUI==4.60.0
PySimpleGUI==5.0.8.3
requests==2.31.0
httpx==0.25.0

381
setup_wizard.py Normal file
View file

@ -0,0 +1,381 @@
"""
Setup Wizard for Eugen Twitch Bot
Interactive configuration tool for first-time setup
"""
import os
import sys
import asyncio
import socket
import getpass
from pathlib import Path
from dotenv import set_key, load_dotenv
import httpx
class Colors:
"""ANSI color codes for terminal output"""
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
def print_header(text):
"""Print colored header"""
print(f"\n{Colors.HEADER}{Colors.BOLD}{'='*60}{Colors.ENDC}")
print(f"{Colors.HEADER}{Colors.BOLD}{text.center(60)}{Colors.ENDC}")
print(f"{Colors.HEADER}{Colors.BOLD}{'='*60}{Colors.ENDC}\n")
def print_success(text):
"""Print success message"""
print(f"{Colors.OKGREEN}{text}{Colors.ENDC}")
def print_error(text):
"""Print error message"""
print(f"{Colors.FAIL}{text}{Colors.ENDC}")
def print_info(text):
"""Print info message"""
print(f"{Colors.OKCYAN} {text}{Colors.ENDC}")
def print_warning(text):
"""Print warning message"""
print(f"{Colors.WARNING}{text}{Colors.ENDC}")
async def validate_twitch_token(token, bot_nickname):
"""
Validate Twitch OAuth token by attempting IRC connection
Args:
token (str): OAuth token
bot_nickname (str): Bot nickname for authentication
Returns:
bool: True if valid
"""
if not token.startswith("oauth:"):
print_error("Token muss mit 'oauth:' beginnen!")
return False
try:
print_info("Validiere Twitch-Verbindung...")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(5)
sock.connect(('irc.chat.twitch.tv', 6667))
# Send authentication
sock.send(f"PASS {token}\r\n".encode())
sock.send(f"NICK {bot_nickname}\r\n".encode())
response = sock.recv(1024).decode()
if "Login authentication failed" in response:
print_error("Twitch OAuth Token ist ungültig!")
return False
print_success("Twitch-Verbindung erfolgreich!")
return True
except Exception as e:
print_warning(f"Konnte Twitch-Verbindung nicht testen: {e}")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return True
async def validate_perplexity_key(api_key, model="sonar-pro"):
"""
Validate Perplexity API key with test request
Note: Validation uses the specified model (default: sonar-pro).
If your API key doesn't have access to this model, validation may fail
even with a valid key for other models.
Args:
api_key (str): Perplexity API key
model (str): Model to test with (defaults to sonar-pro)
Returns:
tuple: (bool success, bool should_retry) - success indicates if validation passed,
should_retry indicates if user should be prompted to retry
"""
try:
print_info(f"Validiere Perplexity API-Key mit Modell '{model}'...")
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.post(
"https://api.perplexity.ai/chat/completions",
json={
"model": model,
"messages": [{"role": "user", "content": "test"}],
"max_tokens": 10
},
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
)
if response.status_code == 200:
print_success("Perplexity API-Key ist gültig!")
return (True, False)
elif response.status_code == 401:
print_error("Perplexity API-Key ist ungültig!")
return (False, True)
else:
print_warning(f"Unerwartete Antwort: {response.status_code}")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return (True, False)
except Exception as e:
print_warning(f"Konnte Perplexity API nicht testen: {e}")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return (True, False)
def create_env_file(config):
"""
Create or update .env file with configuration
Args:
config (dict): Configuration dictionary
"""
env_file = ".env"
# Create .env if it doesn't exist
if not os.path.exists(env_file):
Path(env_file).touch()
# Write all config values
for key, value in config.items():
set_key(env_file, key, value)
print_success(f".env Datei erstellt/aktualisiert!")
def create_directories():
"""Create necessary directories for bot operation"""
directories = [
"data",
"data/conversations",
"logs"
]
for directory in directories:
Path(directory).mkdir(parents=True, exist_ok=True)
print_success("Verzeichnisse erstellt!")
def get_input(prompt, default=None, required=True, secret=False):
"""
Get user input with validation
Args:
prompt (str): Input prompt
default (str): Default value
required (bool): Whether input is required
secret (bool): Whether to hide input (for passwords)
Returns:
str: User input
"""
if default:
prompt_text = f"{prompt} [{default}]: "
else:
prompt_text = f"{prompt}: "
while True:
if secret:
value = getpass.getpass(prompt_text)
else:
value = input(prompt_text)
# Use default if provided and input is empty
if not value and default:
return default
# Check if required
if required and not value:
print_error("Dieses Feld ist erforderlich!")
continue
return value
async def run_wizard():
"""Main wizard flow"""
# Welcome
print_header("🤖 EUGEN BOT SETUP WIZARD 🤖")
print("Willkommen beim Setup-Assistenten für deinen Twitch-Bot!")
print("Dieser Wizard führt dich durch die Erstkonfiguration.\n")
print_info("Du benötigst:")
print(" 1. Einen Twitch OAuth Token")
print(" 2. Deinen Twitch Channel-Namen")
print(" 3. Einen Perplexity API Key")
print()
input("Drücke ENTER um zu starten...")
# Configuration dictionary
config = {}
# Step 1: Twitch Configuration
print_header("SCHRITT 1: TWITCH KONFIGURATION")
print_info("Twitch OAuth Token generieren:")
print(" → Gehe zu: https://twitchtokengenerator.com")
print(" → Wähle 'Bot Chat Token'")
print(" → Authorisiere und kopiere das 'oauth:...' Token")
print()
while True:
token = get_input("Twitch OAuth Token", secret=True, required=True)
if not token.startswith("oauth:"):
print_warning("Token sollte mit 'oauth:' beginnen. Füge ich hinzu...")
token = f"oauth:{token}"
config['TWITCH_OAUTH_TOKEN'] = token
break
config['TWITCH_CHANNEL'] = get_input(
"Twitch Channel Name (ohne #)",
default="keneraosmd",
required=True
)
# Add # if not present
if not config['TWITCH_CHANNEL'].startswith('#'):
config['TWITCH_CHANNEL'] = f"#{config['TWITCH_CHANNEL']}"
config['TWITCH_BOT_NICKNAME'] = get_input(
"Bot Nickname",
default="Eugen",
required=True
)
# Validate Twitch
if not await validate_twitch_token(config['TWITCH_OAUTH_TOKEN'], config['TWITCH_BOT_NICKNAME']):
retry = input("\nTrotzdem fortfahren? (j/n): ")
if retry.lower() != 'j':
print_error("Setup abgebrochen!")
return False
# Step 2: Perplexity Configuration
print_header("SCHRITT 2: PERPLEXITY API")
print_info("Perplexity API Key erhalten:")
print(" → Gehe zu: https://www.perplexity.ai/settings/api")
print(" → Erstelle einen neuen API Key")
print(" → Kopiere den Key (beginnt mit 'pplx-...')")
print()
while True:
api_key = get_input("Perplexity API Key", secret=True, required=True)
config['PERPLEXITY_API_KEY'] = api_key
success, should_retry = await validate_perplexity_key(api_key)
if success:
break
if should_retry:
retry = input("\nErneut versuchen? (j/n): ")
if retry.lower() != 'j':
print_error("Setup abgebrochen!")
return False
# Step 3: Advanced Settings
print_header("SCHRITT 3: ERWEITERTE EINSTELLUNGEN")
print("Möchtest du erweiterte Einstellungen konfigurieren?")
advanced = input("(j/n, default: n): ").lower() == 'j'
if advanced:
config['PERPLEXITY_MODEL'] = get_input(
"Perplexity Modell",
default="sonar-pro"
)
config['MAX_TOKENS'] = get_input(
"Max Tokens pro Antwort",
default="450"
)
config['DEBUG_MODE'] = get_input(
"Debug Mode aktivieren?",
default="false"
)
config['CONTEXT_RETENTION_HOURS'] = get_input(
"Context Retention (Stunden)",
default="1"
)
else:
config['PERPLEXITY_MODEL'] = "sonar-pro"
config['MAX_TOKENS'] = "450"
config['DEBUG_MODE'] = "false"
config['CONTEXT_RETENTION_HOURS'] = "1"
# Step 4: Create files and directories
print_header("SCHRITT 4: SETUP ABSCHLIESSEN")
print_info("Erstelle Konfigurationsdateien...")
create_env_file(config)
create_directories()
# Final summary
print_header("✅ SETUP ERFOLGREICH!")
print(f"{Colors.OKGREEN}Deine Konfiguration:{Colors.ENDC}")
print(f" Channel: {config['TWITCH_CHANNEL']}")
print(f" Bot Name: {config['TWITCH_BOT_NICKNAME']}")
print(f" Modell: {config['PERPLEXITY_MODEL']}")
print(f" Max Tokens: {config['MAX_TOKENS']}")
print()
print_info("Nächste Schritte:")
print(" 1. Starte den Bot mit: python chatbot.py")
print(" 2. Der Bot verbindet sich mit Twitch")
print(" 3. Erwähne den Bot im Chat mit '@Eugen' oder 'Eugen:'")
print()
print_success("Viel Spaß mit deinem Bot! 🚀")
return True
def main():
"""Main entry point"""
try:
# Check if already configured
if os.path.exists('.env'):
load_dotenv()
if os.getenv('TWITCH_OAUTH_TOKEN') and os.getenv('PERPLEXITY_API_KEY'):
print_warning(".env Datei existiert bereits!")
reconfigure = input("Möchtest du die Konfiguration überschreiben? (j/n): ")
if reconfigure.lower() != 'j':
print_info("Setup abgebrochen. Nutze die bestehende Konfiguration.")
return
# Run async wizard
success = asyncio.run(run_wizard())
if not success:
sys.exit(1)
except KeyboardInterrupt:
print()
print_warning("Setup abgebrochen!")
sys.exit(1)
except Exception as e:
print_error(f"Fehler während des Setups: {e}")
sys.exit(1)
if __name__ == "__main__":
main()