Référence de l’API

LGBot (classe principale)

class lgrez.LGBot(command_prefix='!', description=None, case_insensitive=True, intents=<Intents value=32767>, member_cache_flags=<MemberCacheFlags value=7>, **kwargs)[source]

Bot Discord pour parties de Loup-Garou à la PCéenne.

Classe fille de discord.ext.commands.Bot, utilisable exactement de la même manière.

GUILD_ID

L’ID du serveur sur lequel tourne le bot. Vaut None avant l’appel à run(), puis la valeur de la variable d’environnement LGREZ_SERVER_ID.

Type

int

config

Personalisation du bot (à définir avant l’appel à run()), utilisable par les différentes fonctionnalités (exemples : bot.config["debut_saison"], bot.config["demande_porte"]…)

Type

dict

in_command

IDs des salons dans lequels une commande est en cours d’exécution.

Type

list[int]

in_stfu

IDs des salons en mode STFU.

Type

list[int]

in_fals

IDs des salons en mode Foire à la saucisse.

Type

list[int]

tasks

Tâches planifiées actuellement en attente.

Type

dict[int (bdd.Taches.id), asyncio.TimerHandle])

async on_ready()[source]

Méthode appellée par Discord au démarrage du bot.

Vérifie le serveur, log et affiche publiquement que le bot est fonctionnel ; restaure les tâches planifiées éventuelles et exécute celles manquées.

Si bot.config ["output_liveness"] vaut True, lance bot.i_am_alive (écriture chaque minute sur un fichier disque)

async on_member_join(member)[source]

Méthode appellée par Discord à l’arrivée d’un joueur sur le serveur.

Log et lance le processus d’inscription.

Ne fait rien si l’arrivée n’est pas sur le serveur GUILD_ID.

Paramètres

member (discord.Member) – Le joueur qui vient d’arriver.

async on_member_remove(member)[source]

Méthode appellée par Discord au départ d’un joueur du serveur.

Log en mentionnant les MJs.

Ne fait rien si le départ n’est pas du serveur GUILD_ID.

Paramètres

member (discord.Member) – Le joueur qui vient de partir.

async on_message(message)[source]

Méthode appellée par Discord à la réception d’un message.

Invoque l’ensemble des commandes, ou les règles d’IA si
  • Le message n’est pas une commande

  • Le message est posté dans un channel privé (#conv-bot-…)

  • Il n’y a pas déjà de commande en cours dans ce channel

  • Le channel n’est pas en mode STFU

Ne fait rien si le message n’est pas sur le serveur GUILD_ID ou qu’il est envoyé par le bot lui-même ou par un membre sans aucun rôle affecté.

Paramètres

member (discord.Member) – Le joueur qui vient d’arriver.

async on_raw_reaction_add(payload)[source]

Méthode appellée par Discord à l’ajout d’une réaction sur un message.

Appelle la fonction adéquate si le joueur est en base et a cliqué sur « :bucher: », « :maire: », « :lune: » ou « :action: ».

Ne fait rien si la réaction n’est pas sur le serveur GUILD_ID.

Paramètres

payload (discord.RawReactionActionEvent) – Paramètre « statique » (car le message n’est pas forcément dans le cache du bot, par exemple si il a été reboot depuis).

Quelques attributs utiles :
  • payload.member (discord.Member) : Membre ayant posé la réaction

  • payload.emoji (discord.PartialEmoji) : PartialEmoji envoyé

  • payload.message_id (int) : ID du message réacté

async on_command_error(ctx, exc)[source]

Méthode appellée par Discord à chaque exception levée dans une commande.

Analyse l’erreur survenue et informe le joueur de manière adéquate en fonction, en mentionnant les MJs si besoin.

Ne fait rien si l’exception n’a pas eu lieu sur le serveur GUILD_ID.

Paramètres
async on_error(event, *args, **kwargs)[source]

Méthode appellée par Discord à chaque exception remontant au-delà d’une commande.

Log en mentionnant les MJs. Cette méthode permet de gérer les exceptions sans briser la loop du bot (i.e. il reste en ligne).

Paramètres
  • event (str) – Nom de l’évènement ayant généré une erreur ("member_join", "message"…)

  • *args – Arguments passés à la fonction traitant l’évènement : member, message

  • **kwargs – Arguments passés à la fonction traitant l’évènement : member, message

i_am_alive(filename='alive.log')[source]

Exporte le temps actuel (UTC) et planifie un nouvel appel dans 60s

Paramètres

filename (str) – fichier où exporter le temps actuel

run(*args, **kwargs)[source]

Prépare puis lance le bot (bloquant).

Récupère les informations de connection, établit la connection à la base de données puis lance le bot.

Paramètres

lgrez.bot (fonctions centrales)

Système d’unicité

async lgrez.bot.already_in_command(ctx)[source]

Check (discord.ext.commands.Check) : vérifie si le joueur est actuellement dans une commande.

Si non, raise une exception AlreadyInCommand.

Paramètres

ctx (discord.ext.commands.Context) – contexte d’invocation de la commande.

exception lgrez.bot.AlreadyInCommand(message=None, *args)[source]

Exception levée lorsq’un member veut lancer une commande dans un salon déjà occupé.

Classe fille de discord.ext.commands.CheckFailure.

async lgrez.bot.add_to_in_command(ctx)[source]

Ajoute le channel de ctx à la liste des channels dans une commande.

Cette fonction est appellée avant chaque appel de fonction. Elle est appellée seulement si les checks sont OK, donc pas si le salon est déjà dans ctx.bot.in_command.

Paramètres

ctx (discord.ext.commands.Context) – contexte d’invocation de la commande.

async lgrez.bot.remove_from_in_command(ctx)[source]

Retire le channel de ctx de la liste des channels dans une commande.

Cette fonction est appellée après chaque appel de fonction. Elle attend 0.5 secondes avant d’enlever le joueur afin d’éviter que le bot réagisse « nativement » (IA) à un message déjà traité par un tools.wait_for_message() ayant mené à la fin de la commande.

Paramètres

ctx (discord.ext.commands.Context) – contexte d’invocation de la commande.

Commandes spéciales

class lgrez.bot.Special(*args, **kwargs)[source]

Special - Commandes spéciales (méta-commandes, imitant ou impactant le déroulement des autres)

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !panik (alias !kill
    async panik.callback(ctx)

    Tue instantanément le bot, sans confirmation (COMMANDE MJ)

    PAAAAANIK

  • Commande !do 
    async do.callback(ctx, *, code)

    Exécute du code Python et affiche le résultat (COMMANDE MJ)

    Paramètres

    code – instructions valides dans le contexte du fichier bot.py (utilisables notemment : ctx, bdd.session, Tables…)

    Si code est une coroutine, elle sera awaited (ne pas inclure await dans code).

    Aussi connue sous le nom de « faille de sécurité », cette commande permet de faire environ tout ce qu’on veut sur le bot (y compris le crasher, importer des modules, exécuter des fichiers .py… même si c’est un peu compliqué) voire d’impacter le serveur sur lequel le bot tourne si on est motivé.

    À utiliser avec parcimonie donc, et QUE pour du développement/debug !

  • Commande !shell 
    async shell.callback(ctx)

    Lance un pseudo-terminal Python (COMMANDE MJ)

    Envoyer help dans le pseudo-terminal pour plus d’informations sur son fonctionnement.

    Évidemment, les avertissements dans !do s’appliquent ici : ne pas faire n’imp avec cette commande !! (même si ça peut être très utile, genre pour ajouter des gens en masse à un channel)

  • Commande !co 
    async co.callback(ctx, cible=None)

    Lance la procédure d’inscription comme si on se connectait au serveur pour la première fois (COMMANDE MJ)

    Paramètres

    cible – la MENTION (@joueur) du joueur à inscrire, par défaut le lançeur de la commande.

    Cette commande est principalement destinée aux tests de développement, mais peut être utile si un joueur chibre son inscription (à utiliser dans son channel, ou #bienvenue (avec !autodestruct) si même le début a chibré).

  • Commande !doas 
    async doas.callback(ctx, *, qui_quoi)

    Exécute une commande en tant qu’un autre joueur (COMMANDE MJ)

    Paramètres

    qui_quoi – nom de la cible (nom ou mention d’un joueur INSCRIT) suivi de la commande à exécuter (commençant par un !).

    Exemple

    !doas Vincent Croquette !vote Annie Colin

  • Commande !secret (alias !autodestruct, !ad
    async secret.callback(ctx, *, quoi)

    Supprime le message puis exécute la commande (COMMANDE MJ)

    Paramètres

    quoi – commande à exécuter, commençant par un !

    Utile notemment pour faire des commandes dans un channel public, pour que la commande (moche) soit immédiatement supprimée.

  • Commande !stop 
    async stop.callback(ctx)

    Peut débloquer des situations compliquées (beta)

    Ne pas utiliser cette commande sauf en cas de force majeure où plus rien ne marche, et sur demande d’un MJ (après c’est pas dit que ça marche mieux après l’avoir utilisée)

  • Commande !help (alias !aide, !aled, !oskour
    async help.callback(ctx, *, command=None)

    Affiche la liste des commandes utilisables et leur utilisation

    Paramètres

    command (optionnel) – nom exact d’une commande à expliquer (ou un de ses alias)

    Si command n’est pas précisée, liste l’ensemble des commandes accessibles à l’utilisateur.

lgrez.features (Commandes et autres fonctionnalités)

lg-rez / Commandes et autres fonctionnalités

Chaque module de lgrez.features implémente une fonctionnalité spécifique des LGBots. La majorité implémentent un Cog (discord.ext.commands.Cog) contenant une ou plusieurs commandes Discord, mais peuvent aussi définir des fonctions pour un usage public.

Note

Les Cogs et leurs commandes peuvent être vus en envoyant !help à un LGBot fonctionnel (en possédant les rôles MJ et Joueur en vie)

Actions publiques

lg-rez / features / Actions publiques

Gestion des haros, candidatures à la mairie, résultats des votes

class lgrez.features.actions_publiques.ActionsPubliques(*args, **kwargs)[source]

ActionsPubliques - Commandes pour gérer les actions vous engageant publiquement

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !haro 
    async haro.callback(ctx, *, cible=None)

    Lance publiquement un haro contre un autre joueur

    Paramètres

    cible – nom du joueur à accuser

    Cette commande n’est utilisable que lorsqu’un vote pour le condamné est en cours.

  • Commande !candid 
    async candid.callback(ctx)

    Candidate à l’élection du nouveau maire

    Cette commande n’est utilisable que lorsqu’un vote pour le nouveau maire est en cours.

  • Commande !wipe 
    async wipe.callback(ctx, quoi)

    Efface les haros / candidatures du jour (COMMANDE MJ)

    Paramètres

    quoi (str) –

    peut être

    • haros : Supprimer les haros

    • candids : Supprimer les candicatures

  • Commande !listharo 
    async listharo.callback(ctx)

    Liste les gens qui ont subi un haro aujourd’hui

  • Commande !listcandid 
    async listcandid.callback(ctx)

    Liste les candidats à la mairie aujourd’hui

Commandes annexes

lg-rez / features / Commandes annexes

Commandes diverses qu’on ne savait pas où ranger

class lgrez.features.annexe.Annexe(*args, **kwargs)[source]

Annexe - Commandes annexes aux usages divers

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !roll 
    async roll.callback(ctx, *, XdY)

    Lance un ou plusieurs dés

    Paramètres

    XdY – dés à lancer + modifieurs, au format XdY + XdY + ... + Z - Z ... avec X le nombre de dés, Y le nombre de faces et Z les modifieurs (constants).

    Exemples

    • !roll 1d6 -> lance un dé à 6 faces

    • !roll 1d20 +3 -> lance un dé à 20 faces, ajoute 3 au résultat

    • !roll 1d20 + 2d6 -8 -> lance un dé 20 plus deux dés 6, enlève 8 au résultat

  • Commande !coinflip (alias !cf, !pf
    async coinflip.callback(ctx)

    Renvoie le résultat d’un tirage à Pile ou Face (aléatoire)

    Pile je gagne, face tu perds.

  • Commande !ping (alias !pong
    async ping.callback(ctx)

    Envoie un ping au bot

    Pong

  • Commande !addhere 
    async addhere.callback(ctx, *joueurs)

    Ajoute les membres au chan courant (COMMANDE MJ)

    Paramètres

    *joueurs – membres à ajouter, chacun entouré par des guillemets si nom + prénom

    Si *joueurs est un seul élément, il peut être de la forme <crit>=<filtre> tel que décrit dans l’aide de !send.

  • Commande !purge 
    async purge.callback(ctx, N=None)

    Supprime tous les messages de ce chan (COMMANDE MJ)

    Paramètres

    N – nombre de messages à supprimer (défaut : tous)

  • Commande !akinator 
    async akinator.callback(ctx)

    J’ai glissé chef

    Implémentation directe de https://pypi.org/project/akinator.py

  • Commande !xkcd 
    async xkcd.callback(ctx, N)

    J’ai aussi glissé chef, mais un peu moins

    Paramètres

    N – numéro du comic

Gestion des actions

lg-rez / features / Gestion des actions

Liste, création, suppression, ouverture, fermeture d’actions

async lgrez.features.gestion_actions.get_actions(quoi, trigger, heure=None)[source]

Renvoie la liste des actions répondant à un déclencheur donné

Paramètres
  • quoi (str) –

    Type d’opération en cours :

    • "open" : ouverture : Actions.decision_ doit être None

    • "close" : fermeture : Actions.decision_ ne doit pas être None

    • "remind" : rappel : Actions.decision_ doit être « rien »

  • trigger (str) – valeur de Actions.trigger_debut/fin à détecter

  • heure (datetime.time) – si trigger == "temporel", ajoute la condition Actions.heure_debut/fin == heure

async lgrez.features.gestion_actions.open_action(ctx, action, chan=None)[source]

Ouvre une action

Paramètres
  • ctx (Context) – contexte quelconque (de !open, !sync)

  • action (bdd.Actions) – action à ouvrir

  • chan (TextChannel) – salon ou informer le joueur concerné, par défaut son chan privé

Opérations réalisées :
  • Vérification des conditions (cooldown, charges…) et reprogrammation si nécessaire ;

  • Gestion des tâches planifiées (planifie remind/close si applicable) ;

  • Information joueur dans chan.

async lgrez.features.gestion_actions.close_action(ctx, action, chan=None)[source]

Ferme une action

Paramètres
Opérations réalisées :
  • Suppression si nécessaire ;

  • Gestion des tâches planifiées (planifie prochaine ouverture si applicable) ;

  • Information joueur dans <chan>.

lgrez.features.gestion_actions.add_action(ctx, action)[source]

Enregistre et programme l’ouverture d’une action

Paramètres
  • ctx (Context) – contexte quelconque (de !open, !sync…)

  • action (bdd.Actions) – action à enregistrer

lgrez.features.gestion_actions.delete_action(ctx, action)[source]

Supprime une action et annule les tâches en cours liées

Paramètres
  • ctx (Context) – contexte quelconque (de !open, !sync…)

  • action (bdd.Actions) – action à supprimer

IA des réponses

lg-rez / features / IA des réponses

Tout ce qui concerne la manière dont le bot réagit aux messages : détermination de la meilleure réaction, gestion des réactions, activation/désactivation des modes de chat

lgrez.features.IA.fetch_tenor(trigger)[source]

Renvoie le GIF Tenor le plus pertinent (d’après Tenor) pour un texte donnée

Paramètres

trigger (str) – texte auquel réagir

Renvoie

str (URL du GIF) ou None

async lgrez.features.IA.trigger_at_mj(message)[source]

Réaction si le message mentionne les MJs

Paramètres

message (Message) – message auquel réagir

Renvoie

True si le message mentionne les MJ et qu’une réponse a été envoyée, False sinon

async lgrez.features.IA.trigger_roles(message, sensi=0.8)[source]

Réaction si un nom de rôle est donné

Paramètres

Trouve l’entrée la plus proche de message.content dans la table bdd.Roles.

Renvoie

True si un rôle a été trouvé (sensibilité > sensi) et qu’une réponse a été envoyée, False sinon

async lgrez.features.IA.trigger_reactions(bot, message, chain=None, sensi=0.7, debug=False)[source]

Réaction à partir de la base Reactions

Paramètres

Trouve l’entrée la plus proche de chain dans la table bdd.Reactions ; si il contient des accolades, évalue le message selon le contexte de message.

Renvoie

True si une réaction a été trouvée (sensibilité > sensi) et qu’une réponse a été envoyée, False sinon

async lgrez.features.IA.trigger_sub_reactions(bot, message, sensi=0.9, debug=False)[source]

Réaction à partir de la base Reactions sur les mots

Appelle trigger_reactions(bot, message, mot, sensi, debug) pour tous les mots mot composant message.content (mots de plus de 4 lettres, essayés des plus longs aux plus courts).

Renvoie

True si une réaction a été trouvée (sensibilité > sensi) et qu’une réponse a été envoyée, False sinon

async lgrez.features.IA.trigger_di(message)[source]

Réaction aux messages en di… / cri…

Paramètres

message (Message) – message auquel réagir

Renvoie

True si le message correspond et qu’une réponse a été envoyée, False sinon

async lgrez.features.IA.trigger_gif(bot, message)[source]

Réaction par GIF en mode Foire à la saucisse

Paramètres

message (Message) – message auquel réagir

Renvoie

True si le message correspond et qu’une réponse a été envoyée, False sinon

async lgrez.features.IA.trigger_mot_unique(message)[source]

Réaction à un mot unique : le répète

Paramètres

message (Message) – message auquel réagir

Renvoie

True si le message correspond et qu’une réponse a été envoyée, False sinon

async lgrez.features.IA.trigger_a_ou_b(message)[source]

Réaction à un motif type « a ou b » : répond « b »

Paramètres

message (Message) – message auquel réagir

Renvoie

True si le message correspond et qu’une réponse a été envoyée, False sinon

async lgrez.features.IA.default(message)[source]

Réponse par défaut

Renvoie

True (réponse par défaut envoyée)

async lgrez.features.IA.process_IA(bot, message, debug=False)[source]

Exécute les règles d’IA

Paramètres
  • bot (LGBot) – bot

  • message (Message) – message auquel réagir

  • debug (bool) – si True, affiche les erreurs lors de l’évaluation des messages (voir tools.eval_accols())

class lgrez.features.IA.GestionIA(*args, **kwargs)[source]

GestionIA - Commandes relatives à l’IA (réponses automatiques du bot)

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !stfu 
    async stfu.callback(ctx, force=None)

    Active/désactive la réponse automatique du bot sur ton channel privé

    Paramètres

    force"start"/"on" / "stop"/"off" permet de forcer l’activation / la désactivation.

    Sans argument, la commande agit comme un toggle (active les réactions si désactivées et vice-versa).

    N’agit que sur les messages classiques envoyés dans le channel : les commandes restent reconnues.

    Si vous ne comprenez pas le nom de la commande, demandez à Google.

  • Commande !fals (alias !cancer, !214
    async fals.callback(ctx, force=None)

    Active/désactive le mode « foire à la saucisse »

    Paramètres

    force"start"/"on" / "stop"/"off" permet de forcer l’activation / la désactivation.

    Sans argument, la commande agit comme un toggle (active le mode si désactivé et vice-versa).

    En mode « foire à la saucisse », le bot réagira à (presque) tous les messages, pas seulement sur les motifs qu’on lui a appris.

    À utiliser à vos risques et périls !

  • Commande !react (alias !r
    async react.callback(ctx, *, trigger)

    Force le bot à réagir à un message

    Paramètres

    trigger – texte auquel le bot doit réagir

    Permet de faire appel à l’IA du bot même sur les chans publics, ou en mode STFU, etc.

    Si utilisée par un MJ, active aussi le mode débug des évaluations Python (messages d’erreur).

  • Commande !reactfals (alias !rf
    async reactfals.callback(ctx, *, trigger)

    Force le bot à réagir à un message comme en mode Foire à la saucisse

    Paramètres

    trigger – texte auquel le bot doit réagir

    Permet de faire appel directement au mode Foire à la saucisse, même si il n’est pas activé / sur un chan public.

  • Commande !addIA 
    async addIA.callback(ctx, *, triggers=None)

    Ajoute au bot une règle d’IA : mots ou expressions déclenchant une réaction (COMMANDE MJ/RÉDACTEURS)

    Paramètres

    *triggers – mot(s), phrase(s), ou expression(s) séparées par des points-virgules ou sauts de lignes

    Dans le cas où plusieurs expressions sont spécifiées, toutes déclencheront l’action demandée.

  • Commande !listIA 
    async listIA.callback(ctx, trigger=None, sensi=0.5)

    Liste les règles d’IA actuellement reconnues par le bot (COMMANDE MJ/RÉDACTEURS)

    Args

    trigger (optionnel): mot/expression permettant de filter et trier les résultats. SI trigger FAIT PLUS D’UN MOT, IL DOIT ÊTRE ENTOURÉ PAR DES GUILLEMETS ! sensi: sensibilité de détection (ratio des caractères correspondants, entre 0 et 1) si trigger est précisé.

  • Commande !modifIA 
    async modifIA.callback(ctx, *, trigger=None)

    Modifie/supprime une règle d’IA (COMMANDE MJ/RÉDACTEURS)

    Paramètres

    trigger – mot/expression déclenchant la réaction à modifier/supprimer

    Permet d’ajouter et supprimer des triggers, de modifier la réaction du bot (construction d’une séquence de réponses successives ou aléatoires) ou de supprimer la réaction.

Commandes informatives

lg-rez / features / Commandes informatives

Commandes donnant aux joueurs des informations sur le jeu, leurs actions, les joueurs en vie et morts…

class lgrez.features.informations.Informations(*args, **kwargs)[source]

Informations - Commandes disponibles pour en savoir plus sur soi et les autres

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !roles (alias !role, !rôles, !rôle, !camp, !camps
    async roles.callback(ctx, *, filtre=None)

    Affiche la liste des rôles / des informations sur un rôle

    Paramètres

    filtre

    peut être

    •  »Villageois », « Loups », « Nécros », « Autres » pour les rôles d’un camp ;

    • Un nom de rôle pour les informations sur ce rôle.

    Sans argument liste tous les rôles existants.

  • Commande !rolede 
    async rolede.callback(ctx, *, cible)

    Donne le rôle d’un joueur (COMMANDE MJ)

    Paramètres

    cible – le joueur dont on veut connaître le rôle

  • Commande !quiest 
    async quiest.callback(ctx, *, nomrole)

    Liste les joueurs ayant un rôle donné (COMMANDE MJ)

    Paramètres

    nomrole – le rôle qu’on cherche (doit être un slug ou nom de rôle valide)

  • Commande !menu 
    async menu.callback(ctx)

    Affiche des informations et boutons sur les votes / actions en cours

    Le menu a une place beaucoup moins importante ici que sur Messenger, vu que tout est accessible par commandes.

  • Commande !infos 
    async infos.callback(ctx)

    Affiche tes informations de rôle / actions

    Toutes les actions liées à ton rôle (et parfois d’autres) sont indiquées, même celles que tu ne peux pas utiliser pour l’instant (plus de charges, déclenchées automatiquement…)

  • Commande !actions 
    async actions.callback(ctx, *, cible)

    Affiche et modifie les actions d’un joueur (COMMANDE MJ)

    Paramètres

    cible – le joueur dont on veut voir ou modifier les actions

  • Commande !vivants (alias !joueurs, !vivant
    async vivants.callback(ctx)

    Affiche la liste des joueurs vivants

    Aussi dite : « liste des joueurs qui seront bientôt morts »

  • Commande !morts (alias !mort
    async morts.callback(ctx)

    Affiche la liste des joueurs morts

    Aussi dite : « liste des joueurs qui mangent leurs morts »

Process d’inscription

lg-rez / features / Process d’inscription

Étapes préliminaires pour les joueurs avant le début de saison

async lgrez.features.inscription.main(bot, member)[source]

Exécute le processus d’inscription d’un joueur

Paramètres
  • bot (LGBot) – bot connecté au serveur

  • member (Member) – joueur à inscrire

Crée et paramètre le salon privé du joueur, lui pose des questions et l’inscrit en base.

Personalisation :
  • Si bot.config ["demande_chambre"] vaut False, ne demande pas la chambre

  • Sinon bot.config ["chambre_mj"] indique la chambre par défaut (défaut : "[chambre MJ]")

  • bot.config ["debut_saison"] permet de personnaliser la date de début de saison indiquée à la fin du processus (défaut : "32 plopembre")

Commande appellée à l’arrivée sur le serveur, utiliser !co pour trigger cette commande depuis Discord.

Ouverture / fermeture

lg-rez / features / Gestion des votes et actions

Ouverture / fermeture / rappels des votes et actions (+ refill)

async lgrez.features.open_close.recup_joueurs(quoi, qui, heure=None)[source]

Renvoie les joueurs concernés par la tâche !quoi <qui> [heure]

Paramètres
  • quoi (str) – évènement, "open" / "close" / "remind"

  • qui (str) – cible, "cond" / "maire" / "loups" / "action"

  • heure (str) – si qui == "action", heure associée (au format HHhMM)

Renvoie

list[bdd.Joueurs]

Exemples

!open cond -> joueurs avec droit de vote !close action 17h -> joueurs dont l’action se termine à 17h

class lgrez.features.open_close.OpenClose(*args, **kwargs)[source]

OpenClose - Commandes de lancement, rappel et fermeture des votes et actions

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !open 
    async open.callback(ctx, qui, heure=None, heure_chain=None)

    Lance un vote / des actions de rôle (COMMANDE BOT / MJ)

    Paramètres
    • qui

      cond

      pour le vote du condamné

      maire

      pour le vote du maire

      loups

      pour le vote des loups

      action

      pour les actions commençant à heure

      {id}

      pour une action spécifique (paramètre bdd.Actions.id)

    • heure

      • si qui == "cond", "maire" ou "loup", programme en plus la fermeture à heure (et un rappel 30 minutes avant) ;

      • si qui == "action", il est obligatoire : heure des actions à lancer (cf plus haut). Pour les actions, la fermeture est de toute façon programmée le cas échéant (trigger_fin temporel ou delta).

      Dans tous les cas, format HHh ou HHhMM.

    • heure_chain – permet de chaîner des votes : lance le vote immédiatement et programme sa fermeture à heure, en appellant !close de sorte à programmer une nouvelle ouverture le lendemain à heure_chain, et ainsi de suite. Format HHh ou HHhMM.

    Une sécurité empêche de lancer un vote ou une action déjà en cours.

    Cette commande a pour vocation première d’être exécutée automatiquement par des tâches planifiées. Elle peut être utilisée à la main, mais attention à ne pas faire n’importe quoi (penser à envoyer / planifier la fermeture des votes, par exemple).

    Exemples

    • !open maire lance un vote condamné maintenant

    • !open cond 19h lance un vote condamné maintenant et programme sa fermeture à 19h00 (ex. Juge Bègue)

    • !open cond 18h 10h lance un vote condamné maintenant, programme sa fermeture à 18h00, et une prochaine ouverture à 10h, etc

    • !open action 19h lance toutes les actions commençant à 19h00

    • !open 122 lance l’action d’ID 122

  • Commande !close 
    async close.callback(ctx, qui, heure=None, heure_chain=None)

    Ferme un vote / des actions de rôle (COMMANDE BOT / MJ)

    Paramètres
    • qui

      cond

      pour le vote du condamné

      maire

      pour le vote du maire

      loups

      pour le vote des loups

      action

      pour les actions se terminant à heure

      {id}

      pour une action spécifique (paramètre bdd.Actions.id)

    • heure

      • si qui == "cond", "maire" ou "loup", programme en plus une prochaine ouverture à heure (et un rappel 30 minutes avant) ;

      • si qui == "action", il est obligatoire : heure des actions à lancer (cf plus haut). Pour les actions, la prochaine est de toute façon programmée le cas échéant (cooldown à 0 et reste des charges).

      Dans tous les cas, format HHh ou HHhMM.

    • heure_chain – permet de chaîner des votes : ferme le vote immédiatement et programme une prochaine ouverture à heure, en appellant !close de sorte à programmer une nouvelle fermeture le lendemain à heure_chain, et ainsi de suite. Format HHh ou HHhMM.

    Une sécurité empêche de fermer un vote ou une action qui n’est pas en cours.

    Cette commande a pour vocation première d’être exécutée automatiquement par des tâches planifiées. Elle peut être utilisée à la main, mais attention à ne pas faire n’importe quoi (penser à envoyer / planifier la fermeture des votes, par exemple).

    Exemples

    • !close maire ferme le vote condamné maintenant

    • !close cond 10h ferme le vote condamné maintenant et programme une prochaine ouverture à 10h00

    • !close cond 10h 18h ferme le vote condamné maintenant, programme une prochaine ouverture à 10h00, qui sera fermé à 18h, etc

    • !close action 22h ferme toutes les actions se terminant à 22h00

    • !close 122 ferme l’action d’ID 122

  • Commande !remind 
    async remind.callback(ctx, qui, heure=None)

    Envoi un rappel de vote / actions de rôle (COMMANDE BOT / MJ)

    Paramètres
    • qui

      cond

      pour le vote du condamné

      maire

      pour le vote du maire

      loups

      pour le vote des loups

      action

      pour les actions se terminant à heure

      {id}

      pour une action spécifique (paramètre bdd.Actions.id)

    • heure – ne sert que dans le cas où <qui> == « action » (il est alors obligatoire), contrairement à !open et !close. Format HHh ou HHhMM.

    Le bot n’envoie un message qu’aux joueurs n’ayant pas encore voté / agi, si le vote ou l’action est bien en cours.

    Cette commande a pour vocation première d’être exécutée automatiquement par des tâches planifiées. Elle peut être utilisée à la main, mais attention à ne pas faire n’importe quoi !.

    Exemples

    • !remind maire rappelle le vote condamné maintenant

    • !remind action 22h rappelle toutes les actions se terminant à 22h00

    • !remind 122 rappelle l’action d’ID 122

  • Commande !refill 
    async refill.callback(ctx, motif, *, cible=None)

    Permet de recharger le/les pouvoirs rechargeables (COMMANDE BOT / MJ)

    Paramètres
    • motif"weekends", "forgeron", "rebouteux" ou "divin" (forcer le refill car les MJs tout-puissants l’ont décidé)

    • cible"all" ou le nom d’un joueur

  • Commande !cparti 
    async cparti.callback(ctx)

    Lance le jeu (COMMANDE MJ)

    • Crée (et programme) les actions associées aux rôles de tous les joueurs ==> EN FAIT NON, plus besoin vu que c’est fait à la synchro des rôles

    • Programme les votes condamnés quotidiens (avec chaînage) 10h-18h

    • Programme un vote maire 10h-18h

    • Programme les actions au lancement du jeu (choix de mentor…) et permanentes (forgeron)… à 19h

    À utiliser le jour du lancement après 10h (lance les premières actions le soir et les votes le lendemain)

Synchronisation GSheets

lg-rez / features / Synchronisation GSheets

Récupération et application des données des GSheets : modifications décidées via le Tableau de bord et rôles

class lgrez.features.sync.TDBModif(id, col, val, row, column)[source]

Modification flag sur le Tableau de bord, à appliquer

id

ID Discord du joueur concerné

Type

int

col

Colonne de Joueurs à modifier

Type

str

val

Nouvelle valeur

Type

object

row

Numéro de la ligne sur le TDB

Type

int

column

Numéro de la colonne TAMPON sur le TDB

Type

int

lgrez.features.sync.get_sync()[source]

Récupère les modifications en attente sur le TDB

Charge les données du Tableau de bord (variable d’environment LGREZ_TDB_SHEET_ID), compare les informations qui y figurent avec celles de la base de données (bdd.Joueurs)

Renvoie

liste des modifications à apporter

Type renvoyé

list[TDBModif]

lgrez.features.sync.validate_sync(modifs)[source]

Valide des modificatons sur le Tableau de bord (case plus en rouge)

Paramètres

modifs (list[TDBModif]) – liste des modifications à apporter

Modifie sur le Tableau de bord (variable d’environment LGREZ_TDB_SHEET_ID) et applique les modifications contenues dans modifs

async lgrez.features.sync.modif_joueur(ctx, joueur_id, modifs, silent=False)[source]

Attribue les modifications demandées au joueur

Paramètres
  • ctx (Context) – contexte quelconque du bot

  • joueur_id (int) – id Discord du joueur concerné

  • modifs (list[TDBModif]) – liste des modifications à apporter

  • silent (bool) – si True, no notifie pas le joueur des modifications

Pour chaque modifications de modif, applique les conséquences adéquates (rôles, nouvelles actions, tâches planifiées…) et informe le joueur si silent vaut False.

class lgrez.features.sync.Sync(*args, **kwargs)[source]

Sync - Commandes de synchronisation des GSheets vers la BDD et les joueurs

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !sync 
    async sync.callback(ctx, silent=False)

    Récupère et applique les modifications du Tableau de bord (COMMANDE MJ)

    Paramètres

    silent – si spécifié (quelque soit sa valeur), les joueurs ne sont pas notifiés des modifications.

    Cette commande va récupérer les modifications en attente sur le Tableau de bord (lignes en rouge), modifer la BDD Joueurs, et appliquer les modificatons dans Discord le cas échéant : renommage des utilisateurs, modification des rôles…

  • Commande !fillroles 
    async fillroles.callback(ctx)

    Remplit les tables des rôles / actions et #roles depuis le GSheet ad hoc (COMMANDE MJ)

    • Remplit les tables bdd.Roles, bdd.BaseActions et bdd.BaseActionsRoles avec les informations du Google Sheets « Rôles et actions » (variable d’environnement LGREZ_ROLES_SHEET_ID) ;

    • Vide le chan #roles puis le remplit avec les descriptifs de chaque rôle.

    Utile à chaque début de saison / changement dans les rôles/actions. Écrase toutes les entrées déjà en base, mais ne supprime pas celles obsolètes.

Tâches planifiées

lg-rez / features / Tâches planifiées

Planification, liste, annulation, exécution de tâches planifiées

lgrez.features.taches.execute(tache, loop)[source]

Exécute une tâche planifiée

Paramètres

Envoie un webhook (variable d’environnement LGREZ_WEBHOOK_URL) avec la commande (bdd.Taches.commande) et nettoie

Limitation interne de 2 secondes minimum entre deux appels (reprogramme si appelé trop tôt), pour se conformer à la rate limit Discord (30 messages / minute) et ne pas engoncer la loop

lgrez.features.taches.add_task(bot, timestamp, commande, action=None)[source]

Crée une nouvelle tâche planifiée sur le bot + en base, renvoie l’objet Tâche

Paramètres
  • bot (LGBot) – bot connecté

  • timestamp (datetime.datetime) – timestamp de la tâche à ajouter

  • commande (str) – commande à exécuter à timestamp

  • action (int) – si tâche planifiée liée à une commande, son ID (bdd.Actions.id)

Renvoie

bdd.Taches

(fonction pour usage ici et dans d’autres features)

lgrez.features.taches.cancel_task(bot, tache)[source]

Supprime (annule) une tâche (fonction pour usage ici et dans d’autres features)

Paramètres
class lgrez.features.taches.GestionTaches(*args, **kwargs)[source]

GestionTaches - Commandes de planification, exécution, annulation de tâches

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !taches 
    async taches.callback(ctx)

    Liste les tâches en attente (COMMANDE MJ)

    Affiche les commandes en attente d’exécution (dans la table bdd.Taches) et le timestamp d’exécution associé. Lorsque la tâche est liée à une action, affiche le nom de l’action et du joueur concerné.

  • Commande !planif (alias !doat
    async planif.callback(ctx, quand, *, commande)

    Planifie une tâche au moment voulu (COMMANDE MJ)

    Paramètres
    • quand – format [<J>/<M>[/<AAAA>]-]<H>:<M>[:<S>], avec <J> (jours), <M> (mois), <AAAA> (année sur 4 chiffres), <H> (heures) et <M> (minutes) des entiers et <S> (secondes) un entier ou un flottant, optionnel (défaut : 0) La date est optionnelle (défaut : date du jour). Si elle est précisée, elle doit être séparée de l’heure par un tiret et l’année peut être omise (défaut : année actuelle) ;

    • commande – commande à exécuter (commençant par un !). La commande sera exécutée PAR UN WEBHOOK dans LE CHAN #logs : toutes les commandes qui sont liées au joueur ou réservées au chan privé sont à proscrire (ou doivent a minima être précédées de !doas cible)

    Cette commande repose sur l’architecture en base de données, ce qui garantit l’exécution de la tâche même si le bot plante entre temps.

    Si le bot est down à l’heure d’exécution prévue, la commande sera exécutée dès le bot de retour en ligne.

    Si la date est dans le passé, la commande est exécutée immédiatement.

    Exemples

    • !planif 18:00 !close maire

    • !planif 13/06-10:00 !open maire

    • !planif 13/06/2020-10:00 !open maire

    • !planif 23:25:12 !close maire

  • Commande !delay (alias !retard, !doin
    async delay.callback(ctx, duree, *, commande)

    Exécute une commande après XhYmZs (COMMANDE MJ)

    Paramètres
    • quand – format [<X>h][<Y>m][<Z>s], avec <X> (heures) et <Y> (minutes) des entiers et <Z> (secondes) un entier ou un flottant. Chacune des trois composantes est optionnelle, mais au moins une d’entre elle doit être présente ;

    • commande – commande à exécuter (commençant par un !). La commande sera exécutée PAR UN WEBHOOK dans LE CHAN #logs : toutes les commandes qui sont liées au joueur ou réservées au chan privé sont à proscrire (ou doivent a minima être précédées d’un !doas <cible>)

    Cette commande repose sur l’architecture en base de données, ce qui garantit l’exécution de la commande même si le bot plante entre temps.

    Si le bot est down à l’heure d’exécution prévue, la commande sera exécutée dès le bot de retour en ligne.

    Exemples

    • !delay 2h !close maire

    • !delay 1h30m !doas @moi !vote Yacine Oussar

  • Commande !cancel 
    async cancel.callback(ctx, *ids)

    Annule une ou plusieurs tâche(s) planifiée(s) (COMMANDE MJ)

    Paramètres

    *ids – IDs des tâches à annuler, séparées par des espaces.

    Utiliser !taches pour voir la liste des IDs.

Commandes de votes et d’action

lg-rez / features / Tâches planifiées

Planification, liste, annulation, exécution de tâches planifiées

class lgrez.features.voter_agir.VoterAgir(*args, **kwargs)[source]

VoterAgir - Commandes de vote et d’action de rôle

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !vote 
    async vote.callback(ctx, *, cible=None)

    Vote pour le condamné du jour

    Paramètres

    cible – nom du joueur contre qui tu veux diriger ton vote.

    Cette commande n’est utilisable que lorsqu’un vote pour le condamné est en cours, pour les joueurs ayant le droit de voter.

    Le bot t’enverra un message à l’ouverture de chaque vote.

    La commande peut être utilisée autant que voulu pour changer de cible tant que le vote est en cours.

  • Commande !votemaire 
    async votemaire.callback(ctx, *, cible=None)

    Vote pour le nouveau maire

    Paramètres

    cible – nom du joueur pour lequel tu souhaites voter.

    Cette commande n’est utilisable que lorsqu’une élection pour le maire est en cours, pour les joueurs ayant le droit de voter.

    Le bot t’enverra un message à l’ouverture de chaque vote.

    La commande peut être utilisée autant que voulu pour changer de cible tant que le vote est en cours.

  • Commande !voteloups 
    async voteloups.callback(ctx, *, cible=None)

    Vote pour la victime de l’attaque des loups

    Paramètres

    cible – nom du joueur que tu souhaites éliminer.

    Cette commande n’est utilisable que lorsqu’une vote pour la victime du soir est en cours, pour les joueurs concernés.

    Le bot t’enverra un message à l’ouverture de chaque vote.

    La commande peut être utilisée autant que voulu pour changer de cible tant que le vote est en cours.

  • Commande !action 
    async action.callback(ctx, *, decision=None)

    Utilise l’action de ton rôle / une des actions associées

    Paramètres

    decision

    ce que tu souhaites faire.

    Dans le cas où tu as plusieurs actions disponibles, ce paramètre n’est pas pris en compte pour éviter toute ambiguïté.

    Cette commande n’est utilisable que si tu as au moins une action ouverte. Action = pouvoir associé à ton rôle, mais aussi pouvoirs ponctuels (Lame Vorpale, Chat d’argent…) Le bot t’enverra un message à l’ouverture de chaque action.

    La commande peut être utilisée autant que voulu pour changer d’action tant que la fenêtre d’action est en cours, SAUF pour certaines actions (dites « instantanées ») ayant une conséquence immédiate (Barbier, Licorne…). Le bot mettra dans ce cas un message d’avertissement.

Communication

lg-rez / features / Communication

Envoi de messages, d’embeds…

class lgrez.features.communication.Communication(*args, **kwargs)[source]

Communication - Envoi de messages, d’embeds…

Note

Cette classe est un Cog, i.e. un rassemblements de commandes.

L’ensemble des commandes qu’elle contient, créées par le décorateur @discord.ext.commands.command, sont des objets discord.ext.commands.Command accessibles comme cog.cmd_name.

Pour plus de lisiblité, seules les fonctions appellées lors de l’invoquation des commandes (Command.callback) sont décrites ci-après, mais toutes les méthodes de Command sont évidemment accessibles.

Ces callbacks ont tous comme signature (sans compter self si définies dans un Cog) :

async def command(ctx, [ arg1, [..., argN,] ] [{*args | *, rest}]) -> None
avec
  • ctx (discord.ext.commands.Context) le contexte d’invocation de la commande, construit automatiquement par discord.py à l’appel de Bot.process_commands ou Bot.get_context, puis

  • arg1, ..., argN (str) zéro, un ou plusieurs arguments(s) positionnels parsés à partir du texte entré par l’utilisateur (mots séparés par des espaces) ;

  • args (list[str]) un nombre arbitraire d’arguments, OU

  • rest (str) le texte restant après le traitement des arguments positionnels.

Une exception dérivant de discord.ext.commands.UserInputError est levée en cas d’utilisation incorrecte (puis traitée par LGBot.on_command_error()).

  • Commande !embed 
    async embed.callback(ctx, key=None, *, val=None)

    Prépare un embed (message riche) et l’envoie (COMMANDE MJ)

    Paramètres
    • key – sous-commande (voir ci-dessous). Si omis, prévisualise le brouillon d’embed actuellement en préparation ;

    • val – valeur associée. Pour les sous-commandes de construction d’élement, supprime ledit élément si omis.

    • Sous-commandes générales :
      • !embed create <titre> : Créer un nouveau brouillon d’embed (un seul brouillon en parallèle, pour tous les utilisateurs)

      • !embed delete : Supprimer le brouillon d’embed

      • !embed preview : Voir l’embed sans les rappels de commande

      • !embed post [#channel] : Envoyer l’embed sur #channel (chan courant si omis)

    • Sous-commandes de construction d’éléments :
      • Éléments généraux :
        • !embed title [titre]

        • !embed description [texte]

        • !embed url [url*]

        • !embed color [#ffffff] (barre de gauche, code hexadécimal)

      • Auteur :
        • !embed author [nom]

        • !embed author_url [url*]

        • !embed author_icon [url**]

      • Talon :
        • !embed footer [texte]

        • !embed footer_icon [url**]

      • Images :
        • !embed image [url**] (grande image)

        • !embed thumb [url**] (en haut à droite)

      • Champssyntaxe spéciale
        • !embed field <i> <skey> [val]
          • i : Numéro du champ (commençant à 0). Si premier champ non existant, le crée.

          • skey :
            • name : Nom du champ

            • value : Valeur du champ

            • delete : Supprime le champ

        Les champs sont (pour l’instant) forcément de type inline (côte à côte).

    * Les URL doivent commencer par http(s):// pour être reconnues comme telles.

    ** Ces URL doivent correspondre à une image.

  • Commande !send (alias !tell
    async send.callback(ctx, cible, *, message)

    Envoie un message à tous ou certains joueurs (COMMANDE MJ)

    Paramètres
    • cible – destinataires

    • message – message, éventuellement formaté

    cible peut être :
    • all : Tous les joueurs inscrits, vivants et morts

    • vivants : Les joueurs en vie

    • morts : Les joueurs morts

    • <crit>=<filtre> : Les joueurs répondant au critère Joueurs.<crit> == <filtre>. crit peut être "nom", "chambre", "statut", "role", "camp"… L’ensemble doit être entouré de guillements si filtre contient un espace.

    • le nom d’un joueur (raccourci pour nom=X, doit être entouré de guillements si nom + prénom)

    message peut contenir un ou plusieurs bouts de code Python à évaluer, entourés d’accolades.

    L’évaluation est faite séparément pour chaque joueur, ce qui permet de personnaliser le message grâce aux variables particulières dépendant du joueur :
    • joueur : objet BDD du joueur recevant le message ==> joueur.nom, joueur.role

    • member : objet discord.Member associé ==> member.mention

    • chan : objet discord.TextChannel du chan privé du joueur

    Attention :

    Les différentes tables de données sont accessibles sous leur nom (Joueurs, Roles…)

    Il est impossible d’appeller des coroutines (await) dans le code à évaluer.

    Exemples

    • !send all Bonsoir à tous c'est Fanta

    • !send vivants Attention {member.mention}, derrière toi c'est affreux !

    • !send "role=Servante Dévouée" Ça va vous ? Vous êtes bien {joueur.role} ?

  • Commande !post 
    async post.callback(ctx, chan, *, message)

    Envoie un message dans un salon (COMMANDE MJ)

    Paramètres
    • chan – nom du salon ou sa mention

    • message – message à envoyer (peut être aussi long que nécessaire, contenir des sauts de lignes…)

  • Commande !plot 
    async plot.callback(ctx, type)

    Trace le résultat du vote et l’envoie sur #annonces (COMMANDE MJ)

    Paramètres

    type

    peut être

    • cond pour le vote pour le condamné

    • maire pour l’élection à la Mairie

    Trace les votes sous forme d’histogramme à partir du Tableau de bord, en fait un embed en présisant les résultats détaillés et l’envoie sur le chan #annonces.

    Si type == "cond", déclenche aussi les actions liées au mot des MJs.

  • Commande !annoncemort 
    async annoncemort.callback(ctx, *, victime=None)

    Annonce un mort hors-vote (COMMANDE MJ)

    Paramètres

    victime – mort à annoncer

    Envoie un embed dans #annonces

lgrez.blocs (Blocs transversaux)

lg-rez / Blocs transversaux

Chaque module de lgrez.blocs réalise une tâche non liée à une fonctionnalité spécifique du bot : connection à un service, outils divers…

Gestion des données

lg-rez / blocs / Gestion des données

Déclaration de toutes les tables et leurs colonnes, et connection à la BDD

exception lgrez.blocs.bdd.SQLAlchemyError(*arg, **kw)[source]

Generic error class.

lgrez.blocs.bdd.DriverOperationalError

alias de psycopg2.OperationalError

lgrez.blocs.bdd.Tables = {'Actions': <class 'lgrez.blocs.bdd.Actions'>, 'BaseActions': <class 'lgrez.blocs.bdd.BaseActions'>, 'BaseActionsRoles': <class 'lgrez.blocs.bdd.BaseActionsRoles'>, 'CandidHaro': <class 'lgrez.blocs.bdd.CandidHaro'>, 'Joueurs': <class 'lgrez.blocs.bdd.Joueurs'>, 'Reactions': <class 'lgrez.blocs.bdd.Reactions'>, 'Roles': <class 'lgrez.blocs.bdd.Roles'>, 'Taches': <class 'lgrez.blocs.bdd.Taches'>, 'Triggers': <class 'lgrez.blocs.bdd.Triggers'>}

Dictionnaire {nom de la base -> table}

Type

dict[str, Base]

lgrez.blocs.bdd.engine = None

Moteur de connection à la BDD Vaut None avant l’appel à connect().

Type

sqlalchemy.engine.Engine

lgrez.blocs.bdd.session = None

Session de transaction avec la BDD. Vaut None avant l’appel à connect().

Type

sqlalchemy.orm.session.Session

class lgrez.blocs.bdd.Joueurs(**kwargs)[source]

Table de données des joueurs inscrits

Les instances de cette classe correspondent aux lignes du Tableau de bord ; elles sont crées par l’inscription (inscription.main()) et synchronisées par !sync.

Classe de données (sous-classe de Base) représentant la table joueurs.

Tous les attributs ci-dessous sont du type indiqué pour les instances (entrées de BDD), mais de type sqlalchemy.orm.attributes.InstrumentedAttribute pour la classe elle-même.

discord_id

ID Discord du joueur (clé primaire)

Type

int

chan_id_

ID du chan privé Discord du joueur (NOT NULL) Le _ final indique que ce champ n’est pas synchnisé avec le Tableau de bord.

Type

int

nom

nom du joueur (demandé à l’inscription) (NOT NULL, len <= 32)

Type

str

chambre

emplacement du joueur (demandé à l’inscription) (len <= 200)

Type

str

statut

statut RP (généralement « vivant », « mort » ou « MV ») (NOT NULL, len <= 32)

Type

str

role

doit correspondre à une valeur de Roles.slug (NOT NULL, len <= 32)

Type

str

Type

rôle du joueur

camp

camp du joueur (généralement « village », « loups », « nécro ») (NOT NULL, len <= 32)

Type

str

votant_village

si le joueur participe aux votes du village ou non

Type

bool

votant_loups

si le joueur participe au vote des loups ou non

Type

bool

role_actif

si le peut agir ou non (chatgarouté…) (NOT NULL)

Type

bool

vote_condamne_

vote actuel au vote condamné (None si pas de vote en cours) (len <= 200) Le _ final indique que ce champ n’est pas synchnisé avec le Tableau de bord.

Type

str

vote_maire_

vote actuel au vote maire (None si pas de vote en cours) (len <= 200) Le _ final indique que ce champ n’est pas synchnisé avec le Tableau de bord.

Type

str

vote_loups_

vote actuel au vote loups (None si pas de vote en cours) (len <= 200) Le _ final indique que ce champ n’est pas synchnisé avec le Tableau de bord.

Type

str

class lgrez.blocs.bdd.Roles(**kwargs)[source]

Table de données des rôles

Cette table est remplie automatiquement à partir du Google Sheet « Rôles et actions » par la commande !fillroles.

Classe de données (sous-classe de Base) représentant la table roles.

Tous les attributs ci-dessous sont du type indiqué pour les instances (entrées de BDD), mais de type sqlalchemy.orm.attributes.InstrumentedAttribute pour la classe elle-même.

slug

identifiant unique du rôle (clé primaire, len <= 32)

Type

str

prefixe

article du nom du rôle ("Le", "La", "L'"…) (NOT NULL, len <= 8)

Type

str

nom

nom du rôle (NOT NULL, len <= 32)

Type

str

camp

camp de base du rôle (NOT NULL, len <= 32)

Type

str

description_courte

description en une ligne (NOT NULL, len <= 140)

Type

str

description_longue

règles et background complets (NOT NULL, len <= 2000)

Type

str

class lgrez.blocs.bdd.BaseActions(**kwargs)[source]

Table de données des actions définies de bases (non liées à un joueur)

Cette table est remplie automatiquement à partir du Google Sheet « Rôles et actions » par la commande !fillroles.

Classe de données (sous-classe de Base) représentant la table baseactions.

Tous les attributs ci-dessous sont du type indiqué pour les instances (entrées de BDD), mais de type sqlalchemy.orm.attributes.InstrumentedAttribute pour la classe elle-même.

action

slug identifiant uniquement l’action (primary key, len <= 2000)

Type

str

trigger_debut

type de déclencheur du début de l’action ("temporel", "mort", …) (NOT NULL, len <= 2000)

Type

str

trigger_fin

type de déclencheur de la fin (NOT NULL, len <= 2000)

Type

str

instant

si l’action est instantannée (conséquences dès la prise de décision) ou non (conséquence à la fin du créneau d’action)

Type

bool

heure_debut

si trigger_debut vaut "temporel" ou "delta", l’horaire / la durée associée

Type

datetime.time

heure_fin

si trigger_fin vaut "temporel" ou "delta", l’horaire / la durée associée

Type

datetime.time

base_cooldown

temps de rechargement entre deux utilisations du pouvoir (0 si pas de cooldown) (NOT NULL)

Type

int

base_charges

nombre de charges initiales du pouvoir (None si illimitée)

Type

int

refill

évènements pouvant recharger le pouvoir, séparés par des virgules (parmi "weekends", "forgeron", …) (NOT NULL, len <= 32)

Type

str

lieu

attribut informatif (Distance/Physique/Lieu/Contact/Conditionnel/None/Public) (len <= 32)

Type

str

interaction_notaire

attribut informatif (Oui, Non, Conditionnel, Potion, Rapport; None si récursif) (len <= 32)

Type

str

interaction_gardien

attribut informatif (Oui, Non, Conditionnel, Taverne, Feu, MaisonClose, Précis, Cimetière, Loups, None si recursif) (len <= 32)

Type

str

mage

attribut informatif (Oui, Non, changement de cible, etc) (len <= 100 32)

Type

str

changement_cible

si la cible doit changer entre deux utilisations consécutives (informatif uniquement pour l’instant)

Type

bool

class lgrez.blocs.bdd.Actions(**kwargs)[source]

Table de données des actions attribuées (liées à un joueur et actives)

Les instances doivent être enregistrées via gestion_actions.open_action() et supprimées via gestion_actions.close_action().

Classe de données (sous-classe de Base) représentant la table actions.

Tous les attributs ci-dessous sont du type indiqué pour les instances (entrées de BDD), mais de type sqlalchemy.orm.attributes.InstrumentedAttribute pour la classe elle-même.

id

identifiant unique de l’action, sans signification (auto-incrémental) (primary key)

Type

int

player_id

clé étrangère liée à Joueurs.id (NOT NULL)

Type

int

action

clé étrangère liée à BaseActions.slug (NOT NULL, len <= 32)

Type

str

trigger_debut

et trigger_fin, instant, heure_debut, heure_fin, instant, heure_debut, heure_fin, cooldown, charges, refill, lieu, interaction_notaire, interaction_gardien, mage, changement_cible sont les mêmes que pour Actions.

decision_

Décision prise par le joueur pour l’action actuelle (None si action non en cours). Le _ final indique que ce champ n’est pas synchnisé avec le Tableau de bord. (len <= 200)

class lgrez.blocs.bdd.BaseActionsRoles(**kwargs)[source]

Table de données mettant en relation les rôles et les actions de base

Cette table est remplie automatiquement à partir du Google Sheet « Rôles et actions » par la commande !fillroles.

Classe de données (sous-classe de Base) représentant la table baseactionsroles.

Tous les attributs ci-dessous sont du type indiqué pour les instances (entrées de BDD), mais de type sqlalchemy.orm.attributes.InstrumentedAttribute pour la classe elle-même.

id

identifiant unique de l’action, sans signification (auto-incrémental) (primary key)

Type

int

role

clé étrangère liée à Roles.slug (NOT NULL, len <= 32)

Type

str

action

clé étrangère liée à BaseActions.slug (NOT NULL, len <= 32)

Type

str

class lgrez.blocs.bdd.Taches(**kwargs)[source]

Table de données des tâches planifiées du bot

Les instances doivent être enregistrées via taches.add_task() et supprimées via taches.cancel_task().

Classe de données (sous-classe de Base) représentant la table taches.

Tous les attributs ci-dessous sont du type indiqué pour les instances (entrées de BDD), mais de type sqlalchemy.orm.attributes.InstrumentedAttribute pour la classe elle-même.

id

identifiant unique de la tâche, sans signification (auto-incrémental) (primary key)

Type

int

timestamp

moment où sera exécutée la tâche (NOT NULL)

Type

datetime.datetime

commande

texte à envoyer via le webhook (généralement une commande) (NOT NULL, len <= 200)

Type

str

action

si la tâche est liée à une action, clé étrangère liée à Actions.id

Type

int

class lgrez.blocs.bdd.Reactions(**kwargs)[source]

Table de données des réactions d’IA connues du bot

Les instances doivent être enregistrées via !addIA et supprimées via !modifIA.

Classe de données (sous-classe de Base) représentant la table reactions.

Tous les attributs ci-dessous sont du type indiqué pour les instances (entrées de BDD), mais de type sqlalchemy.orm.attributes.InstrumentedAttribute pour la classe elle-même.

id

identifiant unique de la réaction, sans signification (auto-incrémental) (primary key)

Type

int

reponse

réponse, suivant le format (mini-langage) personnalisé ("txt <||> txt <&&> <##>react") (NOT NULL, <2000)

Type

str

class lgrez.blocs.bdd.Triggers(**kwargs)[source]

Table de données des mots et expressions déclenchant l’IA du bot

Les instances doivent être enregistrées via !addIA et supprimées via !modifIA.

Classe de données (sous-classe de Base) représentant la table triggers.

Tous les attributs ci-dessous sont du type indiqué pour les instances (entrées de BDD), mais de type sqlalchemy.orm.attributes.InstrumentedAttribute pour la classe elle-même.

id

identifiant unique du trigger, sans signification (auto-incrémental) (primary key)

Type

int

trigger

mots-clés / expressions, séparés par des ; éventuellement (NOT NULL, len <= 500)

Type

str

reac_id

réaction associée, clé étrangère de Reactions.id (NOT NULL)

Type

int

class lgrez.blocs.bdd.CandidHaro(**kwargs)[source]

Table de données des candidatures et haros en cours #PhilippeCandidHaro

Les instances doivent être enregistrées via !haro / !candid et supprimées via !wipe.

Classe de données (sous-classe de Base) représentant la table candidharo.

Tous les attributs ci-dessous sont du type indiqué pour les instances (entrées de BDD), mais de type sqlalchemy.orm.attributes.InstrumentedAttribute pour la classe elle-même.

id

identifiant unique de la réaction, sans signification (auto-incrémental) (primary key)

Type

int

player_id

joueur associé, clé étrangère de Joueurs.discord_id (NOT NULL)

Type

int

type

"haro" ou "candidature" (flemme de enum mais faudrait, vraiment) (NOT NULL, len <= 11)

Type

str

lgrez.blocs.bdd.connect()[source]

Se connecte à la base de données (variable d’environment LGREZ_DATABASE_URI), crée les tables si nécessaire, construit bdd.engine et ouvre bdd.session

Outils pour tables de données

lg-rez / blocs / Outils pour tables de données

Modification, récupération d’informations sur la structure de la table…

lgrez.blocs.bdd_tools.modif(item, col, value)[source]

Utilitaire : fait <item>.<col> = <value> et le marque (flag_modified()) pour le commit

Paramètres
  • item (bdd.Base) – entrée de BDD à modifier

  • col (str) – colonne à modifier (doit être un attribut valide de la table)

  • value (type(`item`.`col`)) – nouvelle valeur

lgrez.blocs.bdd_tools.transtype(value, col, SQL_type, nullable)[source]

Utilitaire : type un input brut selon le type de sa colonne

Paramètres
  • value (object) – valeur à transtyper

  • col (str) – nom de la colonne associée

  • SQL_type (str) – type SQL associé, (tel que retourné par get_SQL_types() avec detail=False). Types pris en charge : "String", "Integer", "BigInteger", "Boolean", "Time", "DateTime"

  • nullable (bool) – True si la value peut être None (cf get_SQL_nullable()), False sinon

Renvoie

L’objet Python correspondant au type de la colonne (str, int, bool, datetime.time, datetime.datetime) ou None (si autorisé)

Lève
  • ValueError – si la conversion n’est pas possible (ou si value vaut None et nullable est False)

  • KeyError – pour un type de colonne non pris en compte

lgrez.blocs.bdd_tools.get_cols(table)[source]

Renvoie la liste des noms des colonnes d’une table

Paramètres

table (bdd.Base subclass) – table de données

Renvoie

list[str]

lgrez.blocs.bdd_tools.get_primary_col(table)[source]

Renvoie le nom de la colonne clé primaire de <table>

Paramètres

table (bdd.Base subclass) – table de données

Renvoie

str

lgrez.blocs.bdd_tools.get_SQL_types(table, detail=False)[source]

Renvoie un dictionnaire {colonne: type SQL}

Paramètres
  • table (bdd.Base subclass) – table de données

  • detail (bool) –

    • Si True, renvoie l’objet type SQL (col.type, sqlalchemy.sql.sqltypes) : String(length=32), BigInteger

    • Si False, renvoie le nom du type (col.type.__name__) : "String", "BigInteger"

Renvoie

Renvoie

lgrez.blocs.bdd_tools.get_SQL_nullable(table)[source]

Renvoie un dictionnaire {colonne: accepte les NULL ?}

Paramètres

table (bdd.Base subclass) – table de données

Renvoie

lgrez.blocs.bdd_tools.find_nearest(chaine, table, sensi=0.25, filtre=None, carac=None, solo_si_parfait=True, match_first_word=False)[source]

Recherche le(s) plus proche résultat(s) dans une table

Paramètres
  • chaine (str) – motif à rechercher

  • table (bdd.Base subclass) – table de données dans laquelle rechercher

  • sensi (float) – ratio minimal pour retenir une entrée

  • filtre (sqlalchemy.sql.elements.BinaryExpression) – argument de filter() (Table.colonne == valeur)

  • carac (str) – colonne selon laquelle rechercher (défaut : colonne primaire de la table)

  • solo_si_parfait (bool) – si True, renvoie uniquement le premier élément de score 1 trouvé s’il existe (ignore les autres éléments, même si >= sensi)

  • match_first_word (bool) – si True, teste aussi chaine vis à vis du premier mot (caractères précédent la première espace) de chaque entrée, et conserve ce score si il est supérieur (table.carac doit être de type String).

Renvoie

La/les entrée(s) correspondant le mieux à chaine, sous forme de liste de tuples (element, score*) triés par score* décroissant

Type renvoyé

list[(bdd.Base, float)]

*Score = ratio de difflib.SequenceMatcher, i.e. proportion de caractères communs aux deux chaînes

Interfaçage Google Sheets

lg-rez / blocs / Interfaçage Google Sheets

Connection, récupération de classeurs, modifications (implémentation de https://pypi.org/project/gspread)

lgrez.blocs.gsheets.connect(key)[source]

Charge les credentials GSheets (variable d’environment LGREZ_GCP_CREDENTIALS) et renvoie le classeur demandé

Paramètres

key (str) – ID du classeur à charger (25 caractères)

Renvoie

gspread.models.Spreadsheet

lgrez.blocs.gsheets.update(sheet, modifs)[source]

Met à jour une feuille GSheets avec les modifications demandées

Paramètres

Les IDs sont indexés à partir de 0 (cellule A1 en (0, 0).

Le type de la nouvelle valeur sera interpreté par gspread pour donner le type GSheets adéquat à la cellule (texte, numérique, temporel…)

Lecture des variables d’environnement

lg-rez / blocs / Lecture des variables d’environnement

lgrez.blocs.env.load(VAR_NAME)[source]

Lit une variable depuis les variables d’environnement / le .env demandé à l’appel de bot.py (.env par défaut)

Équivaut globalement à os.getenv() suivi d’une assertion vérifiant que la variable existe.

Paramètres

VAR_NAME (str) – nom de la variable à charger (LGREZ_...)

Renvoie

str

Envoi de webhooks

lg-rez / blocs / Envoi de webhooks

(Implémentation de https://pypi.org/project/discord-webhook)

lgrez.blocs.webhook.send(message, url)[source]

Envoie un webhook Discord

Paramètres
  • message (str) – message à envoyer

  • url (str) – adresse du webhook ("https://discordapp.com/api/webhooks/.../...")

Renvoie

requests.Response | False

Seuls les webhooks textuels sont pris en charge.

Outils divers et variés

lg-rez / blocs / Outils divers et variés

Récupération d’objets Discord, décorateurs pour commandes, structures d’interaction dans les channels, utilitaires d’emojis, de date/temps, de formatage…

lgrez.blocs.tools.get(iterable, **attrs)[source]

Raccourci pour discord.utils.get()

lgrez.blocs.tools.channel(arg, nom, must_be_found=True)[source]

Renvoie l’objet associé au salon #nom.

Paramètres
  • nom (str) – nom du channel (texte/vocal/catégorie) ou sa mention (détection directe par regex)

  • arg (Context | Guild | Member | GuildChannel) – argument « connecté » au serveur, permettant de remonter aux channels

  • must_be_found (bool) – si True (défaut), raise une AssertionError si le channel #nom n’existe pas (si False, renvoie None)

Renvoie

discord.abc.GuildChannel

lgrez.blocs.tools.role(arg, nom, must_be_found=True)[source]

Renvoie l’objet associé au rôle @&nom.

Paramètres
  • nom (str) – nom du rôle ou sa mention (détection directe par regex)

  • arg (Context | Guild | Member | GuildChannel) – argument « connecté » au serveur, permettant de remonter aux rôles

  • must_be_found (bool) – si True (défaut), raise une AssertionError si le channel @&nom n’existe pas (si False, renvoie None)

Renvoie

discord.Role

lgrez.blocs.tools.member(arg, nom, must_be_found=True)[source]

Renvoie l’objet associé au membre @nom.

Paramètres
  • nom (str) – nom du joueur ou sa mention (détection directe par regex)

  • arg (Context | Guild | Member | GuildChannel) – argument « connecté » au serveur, permettant de remonter aux membres

  • must_be_found (bool) – si True (défaut), raise une AssertionError si le membre @nom n’existe pas (si False, renvoie None)

Renvoie

discord.Member

lgrez.blocs.tools.emoji(arg, nom, must_be_found=True)[source]

Renvoie l’objet associé à l’emoji :nom:.

Paramètres
  • nom (str) – nom de l’emoji (texte/vocal/catégorie) ou son utilisation (détection directe par regex)

  • arg (Context | Guild | Member | GuildChannel) – argument « connecté » au serveur, permettant de remonter aux emojis

  • must_be_found (bool) – si True (défaut), raise une AssertionError si l’emoji :nom: n’existe pas (si False, renvoie None)

Renvoie

discord.Emoji

lgrez.blocs.tools.private_chan(member, must_be_found=True)[source]

Renvie le channel privé d’un joueur

Paramètres
  • member (discord.Member) – membre du serveur

  • must_be_found (bool) – si True (défaut), raise une AssertionError si le channel n’existe pas (si False, renvoie None)

Renvoie

discord.TextChannel

lgrez.blocs.tools.mention_MJ(arg)[source]

Renvoie la mention du rôle « MJ » si le joueur n’est pas un MJ, "@MJ" sinon.

Paramètres

arg (Member | Context) – membre ou contexte d’un message envoyé par un membre

exception lgrez.blocs.tools.CommandExit[source]

Lever cette exception force l’arrêt immédiat d’une commande, et empêche le bot de réagir à nouveau

Sous-classe de RuntimeError

lgrez.blocs.tools.mjs_only(func)

décorateur pour commande (discord.ext.commands.check()) : commandes exécutables uniquement par un MJ ou un webhook

lgrez.blocs.tools.mjs_et_redacteurs(func)

décorateur pour commande (discord.ext.commands.check()) : commandes exécutables par un MJ, un rédacteur ou un webhook (pour IA)

lgrez.blocs.tools.joueurs_only(func)

décorateur pour commande (discord.ext.commands.check()) : commandes exécutables uniquement par un joueur (inscrit en base), vivant ou mort

lgrez.blocs.tools.vivants_only(func)

décorateur pour commande (discord.ext.commands.check()) : commandes exécutables uniquement par un joueur vivant

lgrez.blocs.tools.private(cmd)[source]

Décorateur pour commande : lors d’une invocation de la commande décorée hors d’un channel privé (#conv-bot-), supprime le message d’invocation et exécute la commande dans le channel privée de l’invoqueur.

Ce décorateur n’est utilisable que sur une commande définie dans un Cog. Si le joueur ayant utilisé la commande n’a pas de chan privé (pas en base), raise une AssertionError.

Utilisable en combinaison avec joueurs_only() et vivants_only() (pas avec les autres attention, vu que seuls les joueurs ont un channel privé)

async lgrez.blocs.tools.wait_for_message(bot, check, trigger_on_commands=False)[source]

Attend et renvoie le premier message reçu rencontrant les critères demandés.

Surcouche de discord.ext.commands.Bot.wait_for() permettant d’ignorer les commandes et de réagir au mot-clé stop.

Paramètres
  • bot (LGBot) – bot connecté au serveur

  • check (function(discord.Message -> bool)) – fonction validant ou non chaque message

  • trigger_on_commands (bool) – si False (défaut), un message respectant check sera ignoré si c’est une commande.

Renvoie

discord.Message

Si le message est "stop" ou "!stop" (ou autre casse), raise une exception CommandExit (même si le message respecte check).

async lgrez.blocs.tools.wait_for_message_here(ctx, trigger_on_commands=False)[source]

Attend et renvoie le premier message reçu dans <ctx>.

Surcouche de wait_for_message() filtrant uniquement les messages envoyés dans ctx.channel par quelqu’un d’autre que le bot

Paramètres
Renvoie

discord.Message

async lgrez.blocs.tools.boucle_message(bot, chan, in_message, condition_sortie, rep_message=None)[source]

Permet de lancer une boucle question/réponse tant que la réponse ne vérifie pas une condition

Paramètres
  • bot (LGBot) – bot connecté au serveur

  • chan (discord.TextChannel) – channel dans lequel lancer la boucle

  • condition_sortie (function(discord.Message -> bool)) – fonction validant ou non chaque message

  • in_message (str) – si défini, message à envoyer avant la boucle

  • rep_message (str) – si défini, permet de définir un message de boucle différent de in_message (identique si None). Doit être défini si in_message n’est pas défini.

Renvoie

discord.Message

async lgrez.blocs.tools.boucle_query_joueur(ctx, cible=None, message=None, sensi=0.5)[source]

Retourne un joueur (entrée de BDD) d’après son nom

Paramètres
  • ctx (discord.ext.commands.Context) – contexte d’une commande

  • cible (str) – premier essai de cible (donnée par le joueur dans l’appel à une commande, par exemple)

  • message (str) – si défini (et cible non définie), message à envoyer avant la boucle

  • sensi (float) – sensibilité de la recherche (c.f. bdd_tools.find_nearest())

Renvoie

bdd.Joueurs

Attend que le joueur entre un nom de joueur, et boucle 5 fois au max (avant de l’insulter et de raise une erreur) pour chercher le plus proche joueur dans la table bdd.Joueurs.

async lgrez.blocs.tools.wait_for_react_clic(bot, message, emojis={}, *, process_text=False, text_filter=<function <lambda>>, post_converter=None, trigger_all_reacts=False, trigger_on_commands=False)[source]

Ajoute des reacts à un message et attend que quelqu’un appuie sur une

Paramètres
  • bot (LGBot) – bot connecté au serveur

  • message (discord.Message) – message où ajouter les réactions

  • emojis (list | dict) – reacts à ajouter, éventuellement associés à une valeur qui sera retournée au clic sur l’emoji

  • process_text (bool) – si True, détecte aussi la réponse par message et retourne ledit message (défaut : False)

  • text_filter (function(str -> bool)) – si process_text, ne réagit qu’aux messages pour lesquels text_filter(message) renvoie True (défaut : tous)

  • post_converter (function(str -> object)) – si process_text et que l’argument est défini, le message détecté est passé dans cette fonction avant d’être renvoyé

  • trigger_all_reacts (bool) – si True, détecte l’ajout des toutes les réactions (et pas seulement celles dans emojis) et renvoie l’emoji directement si il n’est pas dans emojis (défaut : False)

  • trigger_on_commands (bool) – passé directement à wait_for_message().

Renvoie

str, représentant

  • le nom de l’emoji si emojis est une liste et clic sur une des reacts, ou si trigger_all_reacts vaut True et ajout d’une autre react ;

  • le message reçu si process_text vaut True, que post_converter n’est pas défini et réaction à un message

OU

object, représentant

  • la valeur associée si emojis est un dictionnaire et clic sur une des reacts ;

  • la valeur retournée par post_converter si il est défini, que process_text vaut True et réaction à un message

async lgrez.blocs.tools.yes_no(bot, message)[source]

Ajoute les reacts ✅ et ❎ à message et renvoie True ou False en fonction de l’emoji cliqué OU de la réponse textuelle détectée

Surcouche de wait_for_react_clic() pour demander une confirmation / question fermée simplement.

Paramètres
  • bot (LGBot) – bot connecté au serveur

  • message (discord.Message) – message où ajouter les réactions

Réponses textuelles reconnues :
  • Pour True : ["oui", "o", "yes", "y", "1", "true"]

  • Pour False : ["non", "n", "no", "n", "0", "false"]

ainsi que toutes leurs variations de casse.

Renvoie

bool

async lgrez.blocs.tools.choice(bot, message, N, start=1, *, additionnal={})[source]

Ajoute des reacts chiffres (1️⃣, 2️⃣, 3️⃣…) à message et renvoie le numéro cliqué OU détecté par réponse textuelle

Surcouche de wait_for_react_clic() pour demander de choisir dans une liste simplement.

Paramètres
  • bot (LGBot) – bot connecté au serveur

  • message (discord.Message) – message où ajouter les réactions

  • N (int) – chiffre jusqu’auquel aller, inclus (<= 10)

  • start (int) – chiffre auquel commencer (<= N, défaut 1)

  • additionnal (dict) – dictionnaire emoji à ajouter après les chiffres -> valeur renvoyée si cliqué

Réponses textuelles reconnues : nombres seuls entre start et N

Renvoie

int

async lgrez.blocs.tools.sleep(chan, x)[source]

Pause l’exécution d’une commande en affichant l’indicateur typing (« LGBot est en train d’écrire… ») sur un salon

Permat d’afficher plusieurs messages d’affillée en laissant le temps de lire, tout en indiquant que le bot n’a pas fini d’écrire

Paramètres
lgrez.blocs.tools.emoji_camp(arg, camp)[source]

Renvoie l’emoji associé à un camp donné.

Paramètres
  • arg (Context | Guild | Member | GuildChannel) – argument « connecté » au serveur, permettant de remonter aux emojis

  • camp (str) – parmis "village", "loups", "nécro", "solitaire", "autre"

Renvoie

discord.Emoji or «  »

lgrez.blocs.tools.montre(heure=None)[source]

Renvoie l’emoji horloge (🕧, 🕓, 🕝…) le plus proche d’une heure donnée

Paramètres

heure (str) – heure à représenter au format "XXh" ou "XXhMM" (défaut : heure actuelle)

Renvoie

str

lgrez.blocs.tools.emoji_chiffre(chiffre, multi=False)[source]

Renvoie l’emoji / les emojis 0️⃣, 1️⃣, 2️⃣… correspond à un chiffre/nombre

Paramètres
  • chiffre (int) – chiffre/nombre à représenter

  • multi (bool) – si True, chiffre peut être n’importe quel entier positif, dont les chiffres seront convertis séparément ; sinon (par défaut), chiffre doit être un entier entre 0 et 10.

Renvoie

str

lgrez.blocs.tools.super_chiffre(chiffre, multi=False)[source]

Renvoie le(s) caractère(s) Unicode ⁰, ¹, ²… correspond à un chiffre/nombre

Paramètres
  • chiffre (int) – chiffre/nombre à représenter

  • multi (bool) – si True, chiffre peut être n’importe quel entier positif, dont les chiffres seront convertis séparément ; sinon (par défaut), chiffre doit être un entier entre 0 et 9.

Renvoie

str

lgrez.blocs.tools.sub_chiffre(chiffre, multi=False)[source]

Renvoie le(s) caractère(s) unicode ₀, ₁, ₂… correspond à un chiffre/nombre

Paramètres
  • chiffre (int) – chiffre/nombre à représenter

  • multi (bool) – si True, chiffre peut être n’importe quel entier positif, dont les chiffres seront convertis séparément ; sinon (par défaut), chiffre doit être un entier entre 0 et 9.

Renvoie

str

lgrez.blocs.tools.heure_to_time(heure)[source]

Convertit l’écriture d’une heure en objet datetime.time

Paramètres

heure (str) – heure au format HHh, HHhMM ou HH:MM

Renvoie

datetime.time

lgrez.blocs.tools.time_to_heure(tps, sep='h', force_minutes=False)[source]

Convertit un objet datetime.time en heure (version maison de datetime.time.strftime())

Paramètres
  • tps (datetime.time) – temps à convertir

  • sep (str) – séparateur heures / minutes à utiliser (défaut "h")

  • force_minutes (bool) – si False (défaut), les minutes ne sont indiquées que si différentes de 0.

Renvoie

str ("" si tps est None)

lgrez.blocs.tools.next_occurence(tps)[source]

Renvoie le timestamp correspondant à la prochaine occurence d’une heure donnée

Renvoie le prochain timestamp arrivant DANS LES HORAIRES DU JEU : du dimanche 19:00:00 au vendredi 18:59:59.

Paramètres

tps (datetime.time) – heure dont on veut connaître la prochaine occurence

Renvoie

datetime.datetime

lgrez.blocs.tools.debut_pause()[source]

Renvoie le timestamp correspondant au prochain vendredi 19h

Renvoie

datetime.datetime

lgrez.blocs.tools.fin_pause()[source]

Renvoie le timestamp correspondant au prochain dimanche 19h

Renvoie

datetime.datetime

lgrez.blocs.tools.smooth_split(mess, N=1990, sep='\n', rep='')[source]

Sépare un message en une liste de messages moins longs qu’un nombre de caractères donné

Très utile pour envoyer des messages de (potentiellement) plus de 2000 caractères (limitation Discord)

Paramètres
  • mess (str) – message à couper

  • N (int) – taille maximale des messages formés (défaut 1990, pour avoir un peu de marge et permettre d’entourer de ``` par exemple)

  • sep (str) – caractères où séparer préférentiellement le texte (défaut : sauts de ligne). Si mess contient une sous-chaîne plus longue que N ne contenant pas sep, le message est tronqué à la limite.

  • rep (str) – chaîne ajoutée à la fin de chaque message formé (tronqué du séparateur final) (défaut : aucune)

Renvoie

list[str]

async lgrez.blocs.tools.send_blocs(messageable, mess, *, N=1990, sep='\n', rep='')[source]

Envoie un (potentiellement long) message en le coupant en blocs si nécaissaire

Surcouche de smooth_split() envoyant directement les messages formés

Retourne la liste des messages envoyés

Paramètres
Renvoie

list[discord.Message]

async lgrez.blocs.tools.send_code_blocs(messageable, mess, *, N=1990, sep='\n', rep='', prefixe='', langage='')[source]

Envoie un (potentiellement long) message sous forme de bloc(s) de code

Retourne la liste des messages envoyés

Paramètres

messageable, mess, N, sep, rep: identiques à :func:`.send_blocs` prefixe (str): texte à mettre hors des code blocs, au début du premier message language: identique à code_bloc()

Renvoie

list[discord.Message]

async lgrez.blocs.tools.log(arg, message, *, code=False, N=1990, sep='\n', rep='', prefixe='', langage='')[source]

Envoie un message dans le channel #logs

Retourne la liste des messages envoyés

Paramètres
Renvoie

list[discord.Message]

async lgrez.blocs.tools.create_context(bot, member, content)[source]

Simule qu’un membre a envoyé une message dans son chan privé et « génère » le contexte associé

Paramètres
  • bot (LGBot) – bot connecté au serveur

  • member (discord.Member) – membre dont on veut simuler l’action. Doit être inscrit en base (pour avoir un chan privé)

  • content (str) – message à « faire envoyer » au joueur, généralement une commande

Utile notemment pour simuler des commandes à partir de clics sur des réactions.

Renvoie

discord.ext.commands.Context

lgrez.blocs.tools.nom_role(role, prefixe=False)[source]

Retourne le nom d’un rôle à partir de son slug

Paramètres
Renvoie

str (bdd.Roles.slug) | None (si non trouvé)

lgrez.blocs.tools.remove_accents(s)[source]

Enlève les accents d’un chaîne, mais conserve les caractères spéciaux non linguistiques (emojis…)

Version plus douce de unidecode.unidecode.

Paramètres

s (str) – chaîne à désaccentuer

Renvoie

str

lgrez.blocs.tools.eval_accols(rep, globals_=None, locals_=None, debug=False)[source]

Replace chaque bloc entouré par des {} par leur évaluation Python.

Paramètres
  • globals (dict) – variables globales du contexte d’évaluation (passé à eval())

  • locals (dict) – variables locales du contexte d’évaluation (passé à eval())

  • debug (bool) – si True, insère le message d’erreur (type et texte de l’exception dans le message) ensuite si une exception est levée durant l’évaluation (défaut False)

Penser à passer les globals() et locals() si besoin. Généralement, il faut passer locals() qui contient ctx, etc… mais pas globals() si on veut bénéficier de tous les modules importés dans tools.py (tous les modules du projet ou presque).

lgrez.blocs.tools.bold(s)[source]

Formate une chaîne comme texte en gras dans Discord

Paramètres

s (str) – chaîne à formater

Renvoie

str

lgrez.blocs.tools.ital(s)[source]

Formate une chaîne comme texte en italique dans Discord

Paramètres

s (str) – chaîne à formater

Renvoie

str

lgrez.blocs.tools.soul(s)[source]

Formate une chaîne comme texte souligné dans Discord

Paramètres

s (str) – chaîne à formater

Renvoie

str

lgrez.blocs.tools.strike(s)[source]

Formate une chaîne comme texte barré dans Discord

Paramètres

s (str) – chaîne à formater

Renvoie

str

lgrez.blocs.tools.code(s)[source]

Formate une chaîne comme code (inline) dans Discord

Paramètres

s (str) – chaîne à formater

Renvoie

str

lgrez.blocs.tools.code_bloc(s, langage='')[source]

Formate une chaîne comme un bloc de code dans Discord

Paramètres
  • s (str) – chaîne à formater

  • langage (str) – langage du code, permet la coloration syntaxique (sur ordinateur uniquement)

Langages supportés (non exhaustif ?) : asciidoc, autohotkey, bash, coffeescript, cpp (C++), cs (C#), css, diff, fix, glsl, ini, json, md, (markdown), ml, prolog, py, tex, xl, xml

Renvoie

str

lgrez.blocs.tools.quote(s)[source]

Formate une chaîne comme citation (inline) dans Discord

Paramètres

s (str) – chaîne à formater

Renvoie

str

lgrez.blocs.tools.quote_bloc(s)[source]

Formate une chaîne comme bloc de citation (multiline) dans Discord

Paramètres

s (str) – chaîne à formater

Renvoie

str

lgrez.blocs.tools.spoiler(s)[source]

Formate une chaîne comme spoiler (cliquer pour afficher) dans Discord

Paramètres

s (str) – chaîne à formater

Renvoie

str

Émulation de terminal Python (avancé)

lg-rez / blocs / Émulation de terminal Python (avancé)

Ce module n’a pas grand chose à voir avec le projet dans son ensemble, et était plus une expérimentation personnelle qu’autre chose. Il est néanmoins implémenté par la commande !shell.

Globalement, il s’agit d’une version (très incomplète) du module code de Python, ajoutant un fonctionnement dans un environnement asynchrone. Il y aurait moyen de le réécrire beaucoup plus simplement (et beaucoup plus puissamment) en enveloppant le code à exécuter dans une fonction async, en l’envoyant dans un InteractiveInterpreter et en awaitant le résultat.

Par conséquent, ce module n’est pas considéré comme part de l’API publique lgrez et non documenté ici. Les plus curieux iront voir le code source !