async def new_callback(self, ctx, *args, **kwargs): try: Boudoir.from_channel(ctx.channel) except ValueError: await ctx.reply("Cette commande est invalide en dehors " "d'un boudoir.") else: # if ctx.authors return await callback(self, ctx, *args, **kwargs)
async def create(self, ctx, *, nom=None): """Crée un nouveau boudoir dont tu es gérant""" member = ctx.author joueur = Joueur.from_member(member) if not nom: await ctx.send("Comment veux-tu nommer ton boudoir ?\n" + tools.ital("(`stop` pour annuler)")) mess = await tools.wait_for_message_here(ctx) nom = mess.content if len(nom) > 32: await ctx.send("Le nom des boudoirs est limité à 32 caractères.") return await ctx.send("Création du boudoir...") async with ctx.typing(): now = datetime.datetime.now() categ = tools.channel(config.boudoirs_category_name) if len(categ.channels) >= 50: # Limitation Discord : 50 channels par catégorie ok = False N = 2 while not ok: nom_nouv_cat = f"{config.boudoirs_category_name} {N}" categ_new = tools.channel(nom_nouv_cat, must_be_found=False) if not categ_new: categ = await categ.clone(name=nom_nouv_cat) ok = True elif len(categ_new.channels) < 50: # Catégorie N pas pleine categ = categ_new ok = True N += 1 chan = await config.guild.create_text_channel( nom, topic=f"Boudoir crée le {now:%d/%m à %H:%M}. " f"Gérant(e) : {joueur.nom}", category=categ, ) boudoir = Boudoir(chan_id=chan.id, nom=nom, ts_created=now) boudoir.add() await boudoir.add_joueur(joueur, gerant=True) await chan.send( f"{member.mention}, voici ton boudoir ! " "Tu peux maintenant y inviter des gens avec la commande " "`!boudoir invite`.") await ctx.send(f"Ton boudoir a bien été créé : {chan.mention} !") await tools.log(f"Boudoir {chan.mention} créé par {joueur.nom}.")
async def invite(self, ctx, *, cible): """Invite un joueur à rejoindre ce boudoir""" boudoir = Boudoir.from_channel(ctx.channel) gerant = Joueur.from_member(ctx.author) if boudoir.gerant != gerant: await ctx.reply("Seul le gérant du boudoir peut y inviter " "de nouvelles personnes.") return joueur = await tools.boucle_query_joueur( ctx, cible=cible, message="Qui souhaites-tu inviter ?") if joueur in boudoir.joueurs: await ctx.send(f"{joueur.nom} est déjà dans ce boudoir !") return mess = await ctx.send(f"Invitation envoyée à {joueur.nom}.") asyncio.create_task(_invite(joueur, boudoir, mess))
async def expulse(self, ctx, *, cible): """Expulse un membre de ce boudoir""" boudoir = Boudoir.from_channel(ctx.channel) gerant = Joueur.from_member(ctx.author) if boudoir.gerant != gerant: await ctx.reply("Seul le gérant du boudoir peut en expulser " "des membres.") return joueur = await tools.boucle_query_joueur( ctx, cible=cible, message="Qui souhaites-tu expulser ?") if joueur not in boudoir.joueurs: await ctx.send(f"{joueur.nom} n'est pas membre du boudoir !") return await boudoir.remove_joueur(joueur) await joueur.private_chan.send(f"Tu as été expulsé(e) du boudoir " f"« {boudoir.nom} ».") await ctx.send(f"{joueur.nom} a bien été expulsé de ce boudoir.")
async def leave(self, ctx): """Quitte ce boudoir""" joueur = Joueur.from_member(ctx.author) boudoir = Boudoir.from_channel(ctx.channel) if boudoir.gerant == joueur: await ctx.send( "Tu ne peux pas quitter un boudoir que tu gères. " "Utilise `!boudoir transfer` pour passer les droits " "de gestion ou `!boudoir delete` pour le supprimer.") return mess = await ctx.reply("Veux-tu vraiment quitter ce boudoir ? Tu ne " "pourras pas y retourner sans invitation.") if not await tools.yes_no(mess): await ctx.send("Mission aborted.") return await boudoir.remove_joueur(joueur) await ctx.send(tools.ital(f"{joueur.nom} a quitté ce boudoir."))
async def rename(self, ctx, *, nom): """Renomme ce boudoir""" boudoir = Boudoir.from_channel(ctx.channel) gerant = Joueur.from_member(ctx.author) if boudoir.gerant != gerant: await ctx.reply("Seul le gérant du boudoir peut le renommer.") return if not nom: await ctx.send("Comment veux-tu renommer ce boudoir ?\n" + tools.ital("(`stop` pour annuler)")) mess = await tools.wait_for_message_here(ctx) nom = mess.content if len(nom) > 32: await ctx.send("Le nom des boudoirs est limité à 32 caractères.") return boudoir.nom = nom boudoir.update() await boudoir.chan.edit(name=nom) await ctx.send("Boudoir renommé avec succès.")
async def transfer(self, ctx, cible=None): """Transfère les droits de gestion de ce boudoir""" boudoir = Boudoir.from_channel(ctx.channel) gerant = Joueur.from_member(ctx.author) if boudoir.gerant != gerant: await ctx.reply("Seul le gérant du boudoir peut en transférer " "les droits de gestion.") return joueur = await tools.boucle_query_joueur( ctx, cible=cible, message=("À qui souhaites-tu confier " "la gestion de ce boudoir ?")) if joueur not in boudoir.joueurs: await ctx.send(f"{joueur.nom} n'est pas membre de ce boudoir !") return mess = await ctx.reply( "Veux-tu vraiment transférer les droits de ce boudoir ? " "Tu ne pourras pas les récupérer par toi-même.") if not await tools.yes_no(mess): await ctx.send("Mission aborted.") return bd_gerant = next(bd for bd in boudoir.bouderies if bd.joueur == gerant) bd_nouv = next(bd for bd in boudoir.bouderies if bd.joueur == joueur) bd_gerant.gerant = False bd_nouv.gerant = True bd_nouv.ts_promu = datetime.datetime.now() Bouderie.update() await boudoir.chan.edit( topic=f"Boudoir crée le {boudoir.ts_created:%d/%m à %H:%M}. " f"Gérant(e) : {joueur.nom}") await ctx.send(f"Boudoir transféré à {joueur.nom}.")
async def delete(self, ctx): """Supprime ce boudoir""" boudoir = Boudoir.from_channel(ctx.channel) gerant = Joueur.from_member(ctx.author) if boudoir.gerant != gerant: await ctx.reply("Seul le gérant du boudoir peut le supprimer.") return mess = await ctx.reply("Veux-tu vraiment supprimer ce boudoir ? " "Cette action est irréversible.") if not await tools.yes_no(mess): await ctx.send("Mission aborted.") return await ctx.send("Suppression...") for joueur in boudoir.joueurs: await boudoir.remove_joueur(joueur) await joueur.private_chan.send( f"Le boudoir « {boudoir.nom } » a été supprimé.") await boudoir.chan.edit(name=f"\N{CROSS MARK} {boudoir.nom}") await ctx.send( tools.ital("[Tous les joueurs ont été exclus de ce boudoir ; " "le channel reste présent pour archive.]"))