From 77c3c115568c882c23ffa6ccfc9b88599b14c97f Mon Sep 17 00:00:00 2001 From: Mow910 Date: Wed, 4 Mar 2026 19:38:05 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20gestion=20de=20l'=C3=A9dition?= =?UTF-8?q?=20des=20commandes=20Twitch=20et=20des=20logs=20de=20mod=C3=A9r?= =?UTF-8?q?ation.=20Impl=C3=A9mentation=20d'un=20endpoint=20pour=20modifie?= =?UTF-8?q?r=20les=20commandes=20existantes=20avec=20validation=20des=20do?= =?UTF-8?q?nn=C3=A9es=20et=20gestion=20des=20permissions.=20Ajout=20d'un?= =?UTF-8?q?=20endpoint=20pour=20r=C3=A9cup=C3=A9rer=20les=20logs=20de=20mo?= =?UTF-8?q?d=C3=A9ration=20r=C3=A9cents,=20am=C3=A9liorant=20ainsi=20la=20?= =?UTF-8?q?tra=C3=A7abilit=C3=A9=20des=20actions.=20Mise=20=C3=A0=20jour?= =?UTF-8?q?=20de=20l'interface=20pour=20int=C3=A9grer=20un=20syst=C3=A8me?= =?UTF-8?q?=20de=20notifications=20et=20des=20animations.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- twitchbot/live_alert.py | 12 +- webapp/templates/twitch-moderation.html | 1115 +++++++++++------------ webapp/twitch_moderation.py | 82 ++ 3 files changed, 598 insertions(+), 611 deletions(-) diff --git a/twitchbot/live_alert.py b/twitchbot/live_alert.py index 6029884..25b3cc7 100644 --- a/twitchbot/live_alert.py +++ b/twitchbot/live_alert.py @@ -47,7 +47,13 @@ async def checkOnlineStreamer(twitch: Twitch) : global _live_alert_first_check with webapp.app_context() : alerts : list[LiveAlert] = LiveAlert.query.all() - streams = await _retreiveStreams(twitch, alerts) + + try: + streams = await _retreiveStreams(twitch, alerts) + except Exception as e: + logger.error(f'Erreur lors de la récupération des streams, on conserve l\'état actuel : {e}') + return + watch_stream = None # Récupération du statut du live principal (channel configuré) @@ -69,7 +75,7 @@ async def checkOnlineStreamer(twitch: Twitch) : if _live_alert_first_check: logger.info('Live Alert: première vérification, synchronisation sans notification') for alert in alerts: - stream = next((s for s in streams if s.user_login == alert.login), None) + stream = next((s for s in streams if s.user_login.lower() == (alert.login or '').lower()), None) if stream: alert.online = True if alert.watch_activity and alert.enable: @@ -83,7 +89,7 @@ async def checkOnlineStreamer(twitch: Twitch) : # Vérifications normales ensuite for alert in alerts : - stream = next((s for s in streams if s.user_login == alert.login), None) + stream = next((s for s in streams if s.user_login.lower() == (alert.login or '').lower()), None) if stream : logger.info(f'Streamer en ligne : {alert.login}') if not alert.online and alert.enable : diff --git a/webapp/templates/twitch-moderation.html b/webapp/templates/twitch-moderation.html index 18a968f..e795a70 100644 --- a/webapp/templates/twitch-moderation.html +++ b/webapp/templates/twitch-moderation.html @@ -2,94 +2,6 @@ {% block content %} +
+
-

Modération Twitch

+

Modération Twitch

Commandes et logs de modération pour {{ twitch_channel }}

- +
-
- - - +

Live

@@ -181,15 +106,11 @@ {% endif %}
- -

Filtre de liens

@@ -199,15 +120,11 @@ Configurer
- -
- - - +

Mots interdits

@@ -218,9 +135,162 @@
- + {% if is_live %} + + +
+ +
+
+ +
+
+
+ + + + + EN DIRECT + • {{ viewer_count }} viewers +
+ + + Ouvrir sur Twitch + +
+
+ + +
+

+ + Nouvelle commande +

+
+ + + + +
+
+
+ + +
+ {% else %} + +
+ +
+

+ + Ajouter une commande +

+
+
+ + +
+ + +
+
+ + +
+ {% endif %} + + +
+
+

Chat en direct

+ + + + +
+ + + Ouvrir sur Twitch + +
+ +
+
+
+
+ +
+

Récupération du chat...

+

Les messages du chat Twitch apparaîtront ici en temps réel

+
+
+
+ +
+
+ + + + + + + + +
+ +
+ + +
+

Envoyé via le bot • Ouvrir le chat

+
+
+ {% if not is_live %}
{% endif %} + +
-
Commandes de modération @@ -253,7 +323,6 @@
-
Logs de modération ({{ logs|length }}) @@ -264,8 +333,7 @@ {% endif %}
-
- {% if logs %} +
@@ -278,7 +346,7 @@ {% for log in logs %} - + @@ -288,209 +356,20 @@ {% endfor %}
{{ log.created_at.strftime('%d/%m %H:%M') }} {{ log.action }} {{ log.moderator }}
- {% else %} -
Aucun log
+ {% if not logs %} +
Aucun log
{% endif %}
- -
- {% if is_live %} - -
- -
-
- -
-
-
- - - - - EN DIRECT - • {{ viewer_count }} viewers -
- - - - - Ouvrir sur Twitch - -
-
- - -
-

- - - - Nouvelle commande -

-
- - - - -
-
-
- - -
- {% else %} - -
- -
-

- - - - Ajouter une commande -

-
-
- - -
- - -
-
- - -
- {% endif %} -
-
-

Chat en direct

- - - - -
- - - - - Ouvrir sur Twitch - -
- - -
-
-
-
- - - -
-

Récupération du chat...

-

Les messages du chat Twitch apparaîtront ici en temps réel

-
-
-
- - -
- -
- - - - - - - - - - - -
- - -
- - -
-

Envoyé via le bot • Ouvrir le chat

-
-
-
-
- - {% if custom_commands %} -
+ +
-

Commandes personnalisées Twitch ({{ custom_commands|length }})

+

Commandes personnalisées Twitch ({{ custom_commands|length }})

- +
@@ -499,28 +378,33 @@ - + {% for cmd in custom_commands %} - - - - - + + + + + {% endfor %}
CommandeActions
{{ cmd.trigger }}{{ cmd.response }}{{ twitch_permissions.get(cmd.twitch_permission or 'viewer', 'Tous') }}Supprimer
{{ cmd.trigger }}{{ cmd.response }}{{ twitch_permissions.get(cmd.twitch_permission or 'viewer', 'Tous') }} +
+ + Supprimer +
+
+ {% if not custom_commands %} +
Aucune commande personnalisée
+ {% endif %}
- {% endif %} -
+

Mots interdits ({{ banned_words|length }})

- -
@@ -536,8 +420,6 @@
- - {% if banned_words %}
@@ -567,39 +449,44 @@ + + + {% endblock %} diff --git a/webapp/twitch_moderation.py b/webapp/twitch_moderation.py index 75bcb80..e573e11 100644 --- a/webapp/twitch_moderation.py +++ b/webapp/twitch_moderation.py @@ -182,6 +182,52 @@ def add_twitch_commande(): return redirect(url_for('twitch_moderation')) +@webapp.route("/twitch-moderation/edit/", methods=['POST']) +@require_page("twitch_moderation") +def edit_twitch_commande(cmd_id): + if not can_write_page("twitch_moderation"): + return jsonify({"success": False, "error": "Permission refusée"}), 403 + + data = request.get_json() + if not data: + return jsonify({"success": False, "error": "Données invalides"}), 400 + + commande = Commande.query.get_or_404(cmd_id) + + trigger = (data.get('trigger') or '').strip() + response = (data.get('response') or '').strip() + twitch_permission = data.get('twitch_permission', commande.twitch_permission or 'viewer') + + if not trigger or not response: + return jsonify({"success": False, "error": "Commande et réponse requises"}), 400 + + if not trigger.startswith('!'): + trigger = '!' + trigger + + if twitch_permission not in TWITCH_PERMISSIONS: + twitch_permission = 'viewer' + + duplicate = Commande.query.filter(Commande.trigger == trigger, Commande.id != cmd_id).first() + if duplicate: + return jsonify({"success": False, "error": f"La commande {trigger} existe déjà"}), 409 + + commande.trigger = trigger + commande.response = response + commande.twitch_permission = twitch_permission + db.session.commit() + + return jsonify({ + "success": True, + "command": { + "id": commande.id, + "trigger": commande.trigger, + "response": commande.response, + "twitch_permission": commande.twitch_permission, + "permission_label": TWITCH_PERMISSIONS.get(commande.twitch_permission, 'Tous'), + } + }) + + @webapp.route("/twitch-moderation/banned-word/add", methods=['POST']) @require_page("twitch_moderation") def add_banned_word(): @@ -262,6 +308,42 @@ def get_twitch_messages(): messages = webapp.config["BOT_STATUS"].get("twitch_chat_messages", []) return jsonify({"messages": messages}) +@webapp.route("/twitch-moderation/logs/poll") +@require_page("twitch_moderation") +def poll_twitch_logs(): + """Retourne les logs de modération plus récents qu'un timestamp donné.""" + since_str = request.args.get('since', '') + since = None + if since_str: + try: + since = datetime.fromisoformat(since_str) + except ValueError: + pass + + query = TwitchModerationLog.query.order_by(TwitchModerationLog.created_at.desc()) + if since: + query = query.filter(TwitchModerationLog.created_at > since) + logs = query.limit(20).all() + + now = datetime.now().isoformat() + return jsonify({ + "logs": [ + { + "id": log.id, + "action": log.action, + "moderator": log.moderator, + "target": log.target or '-', + "details": log.details or '-', + "created_at": log.created_at.strftime('%d/%m %H:%M') if log.created_at else '', + "created_at_iso": log.created_at.isoformat() if log.created_at else '', + } + for log in logs + ], + "timestamp": now, + "total": TwitchModerationLog.query.count(), + }) + + @webapp.route("/twitch-moderation/execute-action", methods=['POST']) @require_page("twitch_moderation") def execute_moderation_action():