Merge branch 'main' into claude/search-todo-start-Alr4l
This commit is contained in:
commit
92fb10860a
6 changed files with 653 additions and 15 deletions
40
.github/workflows/python-package.yml
vendored
40
.github/workflows/python-package.yml
vendored
|
|
@ -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
204
LICENSE_GUIDE.md
Normal 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
|
||||
|
||||
[](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) |
|
||||
|
||||
---
|
||||
10
README.md
10
README.md
|
|
@ -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
|
||||
|
|
|
|||
31
config.py
31
config.py
|
|
@ -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"""
|
||||
|
|
|
|||
|
|
@ -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
381
setup_wizard.py
Normal 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()
|
||||
Loading…
Add table
Add a link
Reference in a new issue