interface web

This commit is contained in:
gpatruno
2025-07-20 01:50:24 +02:00
parent bb743c5722
commit 2041e72342
34 changed files with 2813 additions and 141 deletions
+312
View File
@@ -0,0 +1,312 @@
from flask import Flask, render_template, request, jsonify, redirect, url_for
from flask_socketio import SocketIO, emit
import json
import os
import threading
import time
from datetime import datetime
import sys
# Import des classes du bot
sys.path.append('.')
from fonction.first_class import RecordTwitch, Subtitle_translation, IA_generator, messageTwitch, TwitchChatBot, storage
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-here'
socketio = SocketIO(app, cors_allowed_origins="*")
class BotController:
def __init__(self):
self.bots = {} # Stockage des instances de bots (pour l'utilisation interne)
self.flux_list = [] # Liste des flux surveillés (pour l'API JSON)
self.config = self.load_config()
def load_config(self):
try:
with open('config/config.json', 'r') as file:
return json.load(file)
except FileNotFoundError:
return {}
def save_config(self):
with open('config/config.json', 'w') as file:
json.dump(self.config, file, indent=4, ensure_ascii=False)
def add_flux(self, channel_name, record_audio=True):
flux_id = len(self.flux_list) + 1
# Créer l'objet flux pour l'API (sans les instances de bots)
flux_data = {
'id': flux_id,
'name': channel_name,
'twitchname': channel_name,
'record_audio': record_audio,
'active': True,
'created_at': datetime.now().isoformat(),
'status': 'starting'
}
try:
# Créer le bot de chat pour ce flux
chat_bot = TwitchChatBot(channel_name)
self.bots[flux_id] = {
'chat_bot': chat_bot,
'record_bot': None
}
chat_bot.start_background()
# Si enregistrement audio activé
if record_audio:
record_bot = RecordTwitch(channel_name, 60)
self.bots[flux_id]['record_bot'] = record_bot
threading.Thread(target=record_bot.main, daemon=True).start()
# Mettre à jour le statut
flux_data['status'] = 'active'
self.flux_list.append(flux_data)
return flux_id
except Exception as e:
print(f"Erreur lors de l'ajout du flux {channel_name}: {str(e)}")
# Nettoyer en cas d'erreur
if flux_id in self.bots:
try:
if self.bots[flux_id]['chat_bot']:
self.bots[flux_id]['chat_bot'].stop()
if self.bots[flux_id]['record_bot']:
self.bots[flux_id]['record_bot'].stop()
except:
pass
del self.bots[flux_id]
flux_data['status'] = 'error'
flux_data['error'] = str(e)
self.flux_list.append(flux_data)
raise e
def remove_flux(self, flux_id):
for i, flux in enumerate(self.flux_list):
if flux['id'] == flux_id:
# Arrêter les bots si ils existent
if flux_id in self.bots:
try:
if self.bots[flux_id]['chat_bot']:
self.bots[flux_id]['chat_bot'].stop()
if self.bots[flux_id]['record_bot']:
self.bots[flux_id]['record_bot'].stop()
except Exception as e:
print(f"Erreur lors de l'arrêt des bots: {e}")
del self.bots[flux_id]
del self.flux_list[i]
return True
return False
def get_flux_list(self):
# Retourner seulement les données JSON (pas les instances de bots)
return self.flux_list
bot_controller = BotController()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/api/flux', methods=['GET'])
def get_flux():
return jsonify(bot_controller.get_flux_list())
@app.route('/api/flux', methods=['POST'])
def add_flux():
data = request.json
channel_name = data.get('channel_name')
record_audio = data.get('record_audio', True)
if not channel_name:
return jsonify({'error': 'Nom du canal requis'}), 400
try:
flux_id = bot_controller.add_flux(channel_name, record_audio)
return jsonify({'success': True, 'flux_id': flux_id})
except Exception as e:
error_msg = f"Erreur lors de l'ajout du flux: {str(e)}"
print(f"Erreur API add_flux: {error_msg}")
return jsonify({'error': error_msg}), 500
@app.route('/api/flux/<int:flux_id>', methods=['DELETE'])
def remove_flux(flux_id):
if bot_controller.remove_flux(flux_id):
return jsonify({'success': True})
return jsonify({'error': 'Flux non trouvé'}), 404
@app.route('/api/flux/<int:flux_id>/status', methods=['GET'])
def get_flux_status(flux_id):
"""Obtenir le statut détaillé d'un flux spécifique"""
for flux in bot_controller.flux_list:
if flux['id'] == flux_id:
status = {
'id': flux_id,
'name': flux['name'],
'active': flux['active'],
'status': flux.get('status', 'unknown'),
'created_at': flux['created_at'],
'bots': {}
}
# Ajouter les informations des bots si disponibles
if flux_id in bot_controller.bots:
bots = bot_controller.bots[flux_id]
if bots['chat_bot']:
status['bots']['chat'] = {
'running': bots['chat_bot'].is_running if hasattr(bots['chat_bot'], 'is_running') else True
}
if bots['record_bot']:
status['bots']['record'] = {
'running': bots['record_bot'].running if hasattr(bots['record_bot'], 'running') else True
}
return jsonify(status)
return jsonify({'error': 'Flux non trouvé'}), 404
@app.route('/api/flux/<int:flux_id>/toggle', methods=['POST'])
def toggle_flux(flux_id):
"""Activer/désactiver un flux"""
for flux in bot_controller.flux_list:
if flux['id'] == flux_id:
flux['active'] = not flux['active']
# Arrêter/démarrer les bots selon le nouveau statut
if flux_id in bot_controller.bots:
bots = bot_controller.bots[flux_id]
if not flux['active']:
# Arrêter les bots
try:
if bots['chat_bot']:
bots['chat_bot'].stop()
if bots['record_bot']:
bots['record_bot'].stop()
except Exception as e:
print(f"Erreur lors de l'arrêt des bots: {e}")
else:
# Redémarrer les bots
try:
if bots['chat_bot']:
bots['chat_bot'].start_background()
if bots['record_bot']:
threading.Thread(target=bots['record_bot'].main, daemon=True).start()
except Exception as e:
print(f"Erreur lors du redémarrage des bots: {e}")
return jsonify({'success': True, 'active': flux['active']})
return jsonify({'error': 'Flux non trouvé'}), 404
@app.route('/api/config/prompts', methods=['GET'])
def get_prompts():
return jsonify(bot_controller.config.get('list_prompt', []))
@app.route('/api/config/prompts', methods=['POST'])
def update_prompts():
data = request.json
prompts = data.get('prompts', [])
bot_controller.config['list_prompt'] = prompts
bot_controller.save_config()
return jsonify({'success': True})
@app.route('/api/subtitles', methods=['GET'])
def get_subtitles():
data = storage.read("subtitle_data")
return jsonify(data)
@app.route('/api/generations', methods=['GET'])
def get_generations():
data = storage.read("IA_generator")
return jsonify(data)
@app.route('/api/send-message', methods=['POST'])
def send_message():
data = request.json
message = data.get('message')
channel = data.get('channel', 'default')
if not message:
return jsonify({'error': 'Message requis'}), 400
# Trouver le bot de message pour ce canal
try:
msg_bot = messageTwitch("config/user.json", channel)
msg_bot.send_message(message)
return jsonify({'success': True})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/api/generate-response', methods=['POST'])
def generate_response():
data = request.json
text = data.get('text', '')
try:
ia_gen = IA_generator("config/config.json")
ia_gen.main_ask(text)
return jsonify({'success': True})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/api/status', methods=['GET'])
def get_status():
status = {
'flux_count': len(bot_controller.flux_list),
'active_recordings': sum(1 for f in bot_controller.flux_list if f['record_audio'] and f['active']),
'chat_connections': sum(1 for f in bot_controller.flux_list if f['active']),
'last_subtitle': '',
'next_message': '',
'recent_messages': []
}
# Récupérer le dernier sous-titre
subtitle_data = storage.read("subtitle_data")
if subtitle_data:
sorted_keys = sorted(subtitle_data.keys())
if sorted_keys:
status['last_subtitle'] = subtitle_data[sorted_keys[-1]]
# Récupérer la dernière génération
generation_data = storage.read("IA_generator")
if generation_data:
sorted_keys = sorted(generation_data.keys())
if sorted_keys:
status['next_message'] = generation_data[sorted_keys[-1]]
return jsonify(status)
@socketio.on('connect')
def handle_connect():
print('Client connecté')
emit('status', {'message': 'Connecté au serveur'})
@socketio.on('disconnect')
def handle_disconnect():
print('Client déconnecté')
# Thread pour envoyer les mises à jour en temps réel
def background_updates():
while True:
try:
status = {
'timestamp': datetime.now().isoformat(),
'flux_count': len(bot_controller.flux_list),
'active_recordings': sum(1 for f in bot_controller.flux_list if f['record_audio'] and f['active']),
}
socketio.emit('status_update', status)
time.sleep(5) # Mise à jour toutes les 5 secondes
except Exception as e:
print(f"Erreur dans background_updates: {e}")
time.sleep(10)
if __name__ == '__main__':
# Démarrer les mises à jour en arrière-plan
update_thread = threading.Thread(target=background_updates, daemon=True)
update_thread.start()
# Démarrer l'application Flask
socketio.run(app, host='0.0.0.0', port=5000, debug=True)