From 10dd78f6306b03e98e1927bd39ae9594821e48a2 Mon Sep 17 00:00:00 2001 From: Mow910 Date: Fri, 6 Mar 2026 13:48:43 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20gestion=20des=20informations?= =?UTF-8?q?=20de=20stream=20dans=20le=20bot=20Twitch.=20Impl=C3=A9mentatio?= =?UTF-8?q?n=20de=20la=20fonction=20de=20remplacement=20des=20variables=20?= =?UTF-8?q?de=20commande=20pour=20inclure=20des=20informations=20dynamique?= =?UTF-8?q?s=20telles=20que=20le=20titre=20du=20stream,=20le=20nom=20du=20?= =?UTF-8?q?jeu,=20le=20nombre=20de=20viewers=20et=20l'uptime.=20Mise=20?= =?UTF-8?q?=C3=A0=20jour=20de=20l'interface=20utilisateur=20pour=20affiche?= =?UTF-8?q?r=20ces=20informations=20en=20temps=20r=C3=A9el=20dans=20la=20m?= =?UTF-8?q?od=C3=A9ration=20Twitch.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- twitchbot/__init__.py | 38 +++- twitchbot/live_alert.py | 6 + webapp/__init__.py | 3 + webapp/templates/twitch-moderation.html | 255 +++++++++++++++++++----- webapp/twitch_moderation.py | 20 ++ 5 files changed, 273 insertions(+), 49 deletions(-) diff --git a/twitchbot/__init__.py b/twitchbot/__init__.py index 0418957..7c6aa1f 100644 --- a/twitchbot/__init__.py +++ b/twitchbot/__init__.py @@ -104,11 +104,45 @@ async def _handleCustomCommand(msg: ChatMessage): if commande: permission = commande.twitch_permission or 'viewer' if not _user_has_twitch_permission(msg, permission): - return # Pas de réponse = l'utilisateur n'a pas la permission - response = commande.response.replace('{user}', msg.user.name) + return + response = _replace_command_variables(commande.response, msg) await msg.reply(response) +def _replace_command_variables(text: str, msg: ChatMessage) -> str: + """Remplace les variables de template dans la réponse d'une commande.""" + from datetime import datetime + + result = text + result = result.replace('{user}', msg.user.name) + result = result.replace('{username}', msg.user.name) + result = result.replace('{channel}', msg.room.name) + + bot_status = webapp.config.get("BOT_STATUS", {}) + result = result.replace('{title}', bot_status.get("twitch_stream_title", "")) + result = result.replace('{game}', bot_status.get("twitch_game_name", "")) + result = result.replace('{viewers}', str(bot_status.get("twitch_viewer_count", 0))) + + uptime_str = "hors ligne" + started_at_str = bot_status.get("twitch_started_at") + if started_at_str and bot_status.get("twitch_is_live", False): + try: + started_at = datetime.fromisoformat(started_at_str) + delta = datetime.now(started_at.tzinfo) - started_at + total_seconds = int(delta.total_seconds()) + hours, remainder = divmod(max(0, total_seconds), 3600) + minutes, _ = divmod(remainder, 60) + if hours > 0: + uptime_str = f"{hours}h {minutes:02d}min" + else: + uptime_str = f"{minutes}min" + except (ValueError, TypeError): + pass + result = result.replace('{uptime}', uptime_str) + + return result + + async def _helloCommand(msg: ChatMessage): await msg.reply(f'Bonjour {msg.user.name}') diff --git a/twitchbot/live_alert.py b/twitchbot/live_alert.py index 25b3cc7..830da64 100644 --- a/twitchbot/live_alert.py +++ b/twitchbot/live_alert.py @@ -67,9 +67,15 @@ async def checkOnlineStreamer(twitch: Twitch) : if main_stream: webapp.config["BOT_STATUS"]["twitch_is_live"] = True webapp.config["BOT_STATUS"]["twitch_viewer_count"] = getattr(main_stream, 'viewer_count', 0) + webapp.config["BOT_STATUS"]["twitch_stream_title"] = getattr(main_stream, 'title', '') or '' + webapp.config["BOT_STATUS"]["twitch_game_name"] = getattr(main_stream, 'game_name', '') or '' + webapp.config["BOT_STATUS"]["twitch_started_at"] = main_stream.started_at.isoformat() if getattr(main_stream, 'started_at', None) else None else: webapp.config["BOT_STATUS"]["twitch_is_live"] = False webapp.config["BOT_STATUS"]["twitch_viewer_count"] = 0 + webapp.config["BOT_STATUS"]["twitch_stream_title"] = "" + webapp.config["BOT_STATUS"]["twitch_game_name"] = "" + webapp.config["BOT_STATUS"]["twitch_started_at"] = None # Premier check : synchronisation sans notification if _live_alert_first_check: diff --git a/webapp/__init__.py b/webapp/__init__.py index b37149c..b8b6029 100644 --- a/webapp/__init__.py +++ b/webapp/__init__.py @@ -15,6 +15,9 @@ webapp.config["BOT_STATUS"] = { "twitch_channel_name": None, "twitch_is_live": False, "twitch_viewer_count": 0, + "twitch_stream_title": "", + "twitch_game_name": "", + "twitch_started_at": None, "twitch_chat_messages": [], # Derniers messages du chat (max 100) "shoutbox_heartbeats": {}, # {"username": datetime} — présence des modos } diff --git a/webapp/templates/twitch-moderation.html b/webapp/templates/twitch-moderation.html index 505e303..0644b9b 100644 --- a/webapp/templates/twitch-moderation.html +++ b/webapp/templates/twitch-moderation.html @@ -71,10 +71,10 @@ max-width: 380px; } #notificationStack > div { pointer-events: auto; } - #editModal { + #editModal, #addCommandModal { transition: opacity 0.2s; } - #editModal.hidden { display: none; } + #editModal.hidden, #addCommandModal.hidden { display: none; }
@@ -137,9 +137,9 @@ {% if is_live %} - +
- +
+
+
+
+ + HORS LIGNE
- - - + + + Ouvrir sur Twitch + +
@@ -402,8 +416,12 @@
-
+

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

+
@@ -512,6 +530,17 @@
+
+
Variables disponibles (cliquer pour insérer)
+
+ + + + + + +
+
@@ -521,6 +550,56 @@
+ + + {% endblock %} diff --git a/webapp/twitch_moderation.py b/webapp/twitch_moderation.py index 160fdc0..388790e 100644 --- a/webapp/twitch_moderation.py +++ b/webapp/twitch_moderation.py @@ -136,6 +136,9 @@ def twitch_moderation(): bot_status = webapp.config.get("BOT_STATUS", {}) is_live = bot_status.get("twitch_is_live", False) viewer_count = bot_status.get("twitch_viewer_count", 0) + stream_title = bot_status.get("twitch_stream_title", "") + game_name = bot_status.get("twitch_game_name", "") + started_at = bot_status.get("twitch_started_at") return render_template( "twitch-moderation.html", @@ -149,6 +152,9 @@ def twitch_moderation(): banned_words=banned_words, is_live=is_live, viewer_count=viewer_count, + stream_title=stream_title, + game_name=game_name, + started_at=started_at, ) @webapp.route("/twitch-moderation/logs/clear") @@ -309,6 +315,20 @@ def get_twitch_messages(): messages = webapp.config["BOT_STATUS"].get("twitch_chat_messages", []) return jsonify({"messages": messages}) + +@webapp.route("/twitch-moderation/stream-info") +@require_page("twitch_moderation") +def twitch_stream_info(): + """Retourne les infos du stream en cours pour le polling dynamique.""" + bot_status = webapp.config.get("BOT_STATUS", {}) + return jsonify({ + "is_live": bot_status.get("twitch_is_live", False), + "viewer_count": bot_status.get("twitch_viewer_count", 0), + "title": bot_status.get("twitch_stream_title", ""), + "game_name": bot_status.get("twitch_game_name", ""), + "started_at": bot_status.get("twitch_started_at"), + }) + @webapp.route("/twitch-moderation/logs/poll") @require_page("twitch_moderation") def poll_twitch_logs():