patch
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
"""Compteurs messages / vocal par membre pour la webapp (table guild_member_stats)."""
|
"""Compteurs messages / vocal par membre pour la webapp (table guild_member_stats)."""
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import concurrent.futures
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
@@ -114,9 +115,14 @@ async def fetch_guild_members_snapshot(bot: discord.Client, guild_id: int | None
|
|||||||
{"guilds": [{"id": g.id, "name": g.name} for g in guilds]},
|
{"guilds": [{"id": g.id, "name": g.name} for g in guilds]},
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
await chosen.chunk(cache=True)
|
await asyncio.wait_for(chosen.chunk(cache=True), timeout=120.0)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
logger.warning(
|
||||||
|
"guild.chunk timeout (%s), suite avec le cache membres partiel",
|
||||||
|
chosen.name,
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning("guild.chunk: %s", e)
|
logger.warning("guild.chunk: %s", e, exc_info=True)
|
||||||
members_out = []
|
members_out = []
|
||||||
for m in chosen.members:
|
for m in chosen.members:
|
||||||
if m.bot:
|
if m.bot:
|
||||||
@@ -144,17 +150,34 @@ async def fetch_guild_members_snapshot(bot: discord.Client, guild_id: int | None
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_discord_members_snapshot_sync(bot: discord.Client, guild_id: int | None = None, timeout: float = 90.0) -> tuple[bool, str | None, dict]:
|
def get_discord_members_snapshot_sync(bot: discord.Client, guild_id: int | None = None, timeout: float = 180.0) -> tuple[bool, str | None, dict]:
|
||||||
"""Appel thread-safe depuis Flask (run_coroutine_threadsafe sur la boucle du bot)."""
|
"""Appel thread-safe depuis Flask (run_coroutine_threadsafe sur la boucle du bot)."""
|
||||||
if bot.loop is None or not bot.is_ready():
|
loop = getattr(bot, "loop", None)
|
||||||
return False, "Bot Discord non connecté.", {}
|
if loop is None:
|
||||||
|
logger.error("get_discord_members_snapshot_sync: bot.loop est None (bot non démarré ?)")
|
||||||
|
return False, "Bot Discord non démarré (aucune boucle événements).", {}
|
||||||
|
if not bot.is_ready():
|
||||||
|
return False, "Bot Discord pas encore prêt (connexion en cours). Réessayez dans quelques secondes.", {}
|
||||||
try:
|
try:
|
||||||
future = asyncio.run_coroutine_threadsafe(
|
future = asyncio.run_coroutine_threadsafe(
|
||||||
fetch_guild_members_snapshot(bot, guild_id),
|
fetch_guild_members_snapshot(bot, guild_id),
|
||||||
bot.loop,
|
loop,
|
||||||
)
|
)
|
||||||
ok, err, payload = future.result(timeout=timeout)
|
ok, err, payload = future.result(timeout=timeout)
|
||||||
return ok, err, payload
|
return ok, err, payload
|
||||||
|
except (concurrent.futures.TimeoutError, TimeoutError) as e:
|
||||||
|
logger.error(
|
||||||
|
"get_discord_members_snapshot_sync: délai dépassé après %.0fs (%s)",
|
||||||
|
timeout,
|
||||||
|
type(e).__name__,
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
False,
|
||||||
|
"Délai dépassé pendant le chargement des membres (serveur volumineux ou bot occupé). Réessayez dans un instant.",
|
||||||
|
{},
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("get_discord_members_snapshot_sync: %s", e)
|
logger.exception("get_discord_members_snapshot_sync: %s", type(e).__name__)
|
||||||
return False, str(e), {}
|
msg = str(e) if str(e) else repr(e)
|
||||||
|
return False, msg or "Erreur lors de l’appel au bot Discord.", {}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from flask import render_template, request
|
from flask import redirect, render_template, request, url_for
|
||||||
from sqlalchemy import text
|
from sqlalchemy import text
|
||||||
|
|
||||||
from webapp import webapp
|
from webapp import webapp
|
||||||
@@ -71,6 +71,13 @@ def _load_sanctions_by_user(user_ids: list[str]) -> dict[str, list]:
|
|||||||
return by_user
|
return by_user
|
||||||
|
|
||||||
|
|
||||||
|
@webapp.route("/discord-members")
|
||||||
|
@webapp.route("/discord-members.html")
|
||||||
|
def discord_members_redirect():
|
||||||
|
"""Redirection : l’URL réelle de la page est /discord-membres (route Flask, pas un fichier .html)."""
|
||||||
|
return redirect(url_for("discord_members", **request.args), code=302)
|
||||||
|
|
||||||
|
|
||||||
@webapp.route("/discord-membres")
|
@webapp.route("/discord-membres")
|
||||||
@require_page("discord_members")
|
@require_page("discord_members")
|
||||||
def discord_members():
|
def discord_members():
|
||||||
|
|||||||
Reference in New Issue
Block a user