Passeport
BIN
.DS_Store
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
#Don't track user data
|
||||
data/users/
|
||||
|
||||
#Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.env
|
||||
config.py
|
39
README
Normal file
|
@ -0,0 +1,39 @@
|
|||
TuxBot, un bot discord écrit en Python.
|
||||
Ici ce trouve le code source du bot provenant du serveur Discord [Aide GNU/Linux-Fr"](https://discord.gg/79943dJ "Rejoindre le serveur"), il à été créé spécialement pour ce discord, si vous souhaitez l'utiliser il vous faudra modifier ``params.json`` et ``cogs/utils/checks.py`` ;)
|
||||
|
||||
### Pré-requis
|
||||
|
||||
Il vous faut :
|
||||
|
||||
- Un ordinateur sous **GNU/Linux** avec une connexion à internet;
|
||||
- Python3.5 ou + ;
|
||||
- Installer ``requirements.txt`` (avec ``pip install -r requirements.txt`` par ex)
|
||||
|
||||
### Installation
|
||||
|
||||
Une fois les pré-requis installés et ``params.json`` édité, placez vous dans le repertoire de tuxbot et lancez ``bot.py`` avec python3 (ex: ``python3 bot.py``)
|
||||
|
||||
## Démarrage
|
||||
|
||||
Placez vous dans le repertoire de tuxbot et exécutez ``bot.py`` avec python3 (ex: ``python3 bot.py``)
|
||||
|
||||
## Fabriqué avec
|
||||
* [PyCharm](https://www.jetbrains.com/pycharm/) - Editeur de texte payant :3
|
||||
* [discord.py](https://github.com/Rapptz/discord.py) - API Python pour discord
|
||||
|
||||
## Versions
|
||||
Liste des versions : [Cliquer pour afficher](https://github.com/outout14/tuxbot-bot/tags)
|
||||
|
||||
## Auteurs
|
||||
* **Maël** _alias_ [@outout14](https://github.com/outout14)
|
||||
* **Romain** _alias_ [Romain le malchanceux](https://github.com/Rom194)
|
||||
|
||||
## License
|
||||
|
||||
Ce projet est sous licence ``Creative Commons BY-NC-SA 4.0`` - voir le fichier [LICENSE.md](LICENSE.md) pour plus d'informations
|
||||
|
||||
|
||||
|
||||
## Support on Beerpay
|
||||
Hey dude! Help me out for a couple of :beers:!
|
||||
|
165
bot.py
|
@ -1,100 +1,109 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
__author__ = "Maël / Outout"
|
||||
__author__ = ["Romain", "Maël / Outout"]
|
||||
__licence__ = "WTFPL Licence 2.0"
|
||||
|
||||
from discord.ext import commands
|
||||
import discord
|
||||
from cogs.utils import checks
|
||||
import datetime, re
|
||||
import json, asyncio
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import copy
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
import traceback
|
||||
import sys
|
||||
from collections import Counter
|
||||
import os
|
||||
import aiohttp
|
||||
|
||||
description = """
|
||||
Je suis TuxBot, le bot qui vit de l'OpenSource ! ;)
|
||||
"""
|
||||
import config
|
||||
import cogs.utils.cli_colors as colors
|
||||
|
||||
l_extensions = [
|
||||
|
||||
'cogs.basics',
|
||||
#'cogs.test',
|
||||
'cogs.admin',
|
||||
# 'cogs.afk',
|
||||
'cogs.basics',
|
||||
'cogs.ci',
|
||||
'cogs.cog_manager',
|
||||
'cogs.filter_messages',
|
||||
'cogs.funs',
|
||||
'cogs.utility',
|
||||
'cogs.passport',
|
||||
'cogs.role',
|
||||
'cogs.search',
|
||||
'cogs.ci'
|
||||
'cogs.send_logs',
|
||||
'cogs.sondage',
|
||||
'cogs.utility'
|
||||
]
|
||||
|
||||
# DISCORD LOGGER #
|
||||
discord_logger = logging.getLogger('discord')
|
||||
discord_logger.setLevel(logging.CRITICAL)
|
||||
log = logging.getLogger()
|
||||
log.setLevel(logging.INFO)
|
||||
handler = logging.FileHandler(filename='logs/discord.log', encoding='utf-8', mode='w')
|
||||
log.addHandler(handler)
|
||||
|
||||
help_attrs = dict(hidden=True, in_help=True, name="DONOTUSE")
|
||||
|
||||
|
||||
# CREDENTIALS #
|
||||
class TuxBot(commands.Bot):
|
||||
def __init__ (self):
|
||||
self.config = config
|
||||
super().__init__(command_prefix=self.config.prefix[0],
|
||||
description=self.config.description,
|
||||
pm_help=None,
|
||||
help_attrs=help_attrs)
|
||||
|
||||
self.client_id = self.config.client_id
|
||||
self.session = aiohttp.ClientSession(loop=self.loop)
|
||||
self._events = []
|
||||
|
||||
|
||||
self.add_command(self.do)
|
||||
|
||||
for extension in l_extensions:
|
||||
try:
|
||||
def load_credentials():
|
||||
with open('params.json') as f:
|
||||
return json.load(f)
|
||||
except:
|
||||
print("Le fichier de paramètre est introuvable, veuillez le créer et le configurer.")
|
||||
self.load_extension(extension)
|
||||
print(f"{colors.text_colors.GREEN}\"{extension}\" chargé !{colors.ENDC}")
|
||||
except Exception as e:
|
||||
print(f"{colors.text_colors.RED}Impossible de charger l'extension {extension}\n{type(e).__name__}: {e}{colors.ENDC}", file=sys.stderr)
|
||||
|
||||
credentials = load_credentials()
|
||||
prefix = credentials.get("prefix", ["."])
|
||||
bot = commands.Bot(command_prefix=prefix, description=description, pm_help=None, help_attrs=help_attrs)
|
||||
|
||||
@bot.event
|
||||
async def on_command_error(error, ctx):
|
||||
async def on_command_error(self, ctx, error):
|
||||
if isinstance(error, commands.NoPrivateMessage):
|
||||
await bot.send_message(ctx.message.author, 'Cette commande ne peut pas être utilisée en message privée.')
|
||||
await ctx.author.send('Cette commande ne peut pas être utilisee en message privee.')
|
||||
elif isinstance(error, commands.DisabledCommand):
|
||||
await bot.send_message(ctx.message.author, 'Désoler mais cette commande est désactivé, elle ne peut donc pas être utilisée.')
|
||||
await ctx.author.send('Desoler mais cette commande est desactive, elle ne peut donc pas être utilisée.')
|
||||
elif isinstance(error, commands.CommandInvokeError):
|
||||
print('In {0.command.qualified_name}:'.format(ctx), file=sys.stderr)
|
||||
print(f'In {ctx.command.qualified_name}:', file=sys.stderr)
|
||||
traceback.print_tb(error.original.__traceback__)
|
||||
print('{0.__class__.__name__}: {0}'.format(error.original), file=sys.stderr)
|
||||
print(f'{error.original.__class__.__name__}: {error.original}', file=sys.stderr)
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
print('---------------------')
|
||||
async def on_ready(self):
|
||||
if not hasattr(self, 'uptime'):
|
||||
self.uptime = datetime.datetime.utcnow()
|
||||
|
||||
log_channel_id = self.get_channel(int(self.config.log_channel_id))
|
||||
|
||||
print('\n\n---------------------')
|
||||
print('CONNECTÉ :')
|
||||
print(""" Nom d\'utilisateur : {0.name}#{0.discriminator}
|
||||
ID : {0.id}""".format(bot.user))
|
||||
print(f'Nom d\'utilisateur: {self.user} {colors.text_style.DIM}(ID: {self.user.id}){colors.ENDC}')
|
||||
print(f'Channel de log: {log_channel_id} {colors.text_style.DIM}(ID: {log_channel_id.id}){colors.ENDC}')
|
||||
print(f'Prefix: {self.config.prefix[0]}')
|
||||
print('Merci d\'utiliser TuxBot')
|
||||
print('---------------------')
|
||||
await bot.change_presence(game=discord.Game(name=credentials.get("game", "Manger des pommes | .help")), status=discord.Status("dnd"), afk=False)
|
||||
if bot.client_id == None:
|
||||
bot.client_id = bot.user.id
|
||||
if not hasattr(bot, 'uptime'):
|
||||
bot.uptime = datetime.datetime.utcnow()
|
||||
print('---------------------\n\n')
|
||||
|
||||
await self.change_presence(status=discord.Status.dnd, activity=discord.Game(name=self.config.game))
|
||||
|
||||
@bot.event
|
||||
async def on_resumed():
|
||||
print('resumed...')
|
||||
|
||||
@bot.event
|
||||
async def on_message(message):
|
||||
async def on_message(self, message):
|
||||
if message.author.bot:
|
||||
return
|
||||
|
||||
try:
|
||||
await bot.process_commands(message)
|
||||
await self.process_commands(message)
|
||||
except Exception as e:
|
||||
print('Erreur rencontré : \n {}: {} \n \n'.format(type(e).__name__, e))
|
||||
print(f'{colors.text_colors.RED}Erreur rencontré : \n {type(e).__name__}: {e}{colors.ENDC} \n \n')
|
||||
|
||||
@bot.command(pass_context=True, hidden=True)
|
||||
@checks.is_owner()
|
||||
def run(self):
|
||||
super().run(self.config.token, reconnect=True)
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(pass_context=True, hidden=True)
|
||||
async def do(ctx, times: int, *, command):
|
||||
"""Repeats a command a specified number of times."""
|
||||
msg = copy.copy(ctx.message)
|
||||
|
@ -102,48 +111,10 @@ async def do(ctx, times : int, *, command):
|
|||
for i in range(times):
|
||||
await bot.process_commands(msg)
|
||||
|
||||
@bot.command(pass_context=True)
|
||||
async def github(ctx):
|
||||
"""Pour voir mon code"""
|
||||
text = "How tu veux voir mon repos Github pour me disséquer ? Pas de soucis ! Je suis un Bot, je ne ressens pas la douleur !\n https://github.com/outout14/tuxbot-bot"
|
||||
em = discord.Embed(title='Repos TuxBot-Bot', description=text, colour=0xE9D460)
|
||||
em.set_author(name='Outout', icon_url="https://avatars0.githubusercontent.com/u/14958554?v=3&s=400")
|
||||
await ctx.send(embed=em)
|
||||
|
||||
async def on_command_error(self, ctx, error):
|
||||
if isinstance(error, commands.NoPrivateMessage):
|
||||
await ctx.author.send('Cette commande ne peut pas être utilisée en message privée.')
|
||||
elif isinstance(error, commands.DisabledCommand):
|
||||
await ctx.author.send('Désoler mais cette commande est désactivé, elle ne peut donc pas être utilisée.')
|
||||
elif isinstance(error, commands.CommandInvokeError):
|
||||
print(f'In {ctx.command.qualified_name}:', file=sys.stderr)
|
||||
traceback.print_tb(error.original.__traceback__)
|
||||
print(f'{error.original.__class__.__name__}: {error.original}', file=sys.stderr)
|
||||
|
||||
## LOAD ##
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
credentials = load_credentials()
|
||||
token = credentials.get('token')
|
||||
if token is None:
|
||||
print("/!\ Le token est manquant dans le fichier params.json...")
|
||||
bot.client_id = credentials.get('client_id', None)
|
||||
except:
|
||||
print("Impossible de démarer TuxBot dû à une erreur inconnue.")
|
||||
if os.path.exists('config.py') is not True:
|
||||
print(f"{colors.text_colors.RED}Veuillez créer le fichier config.py{colors.ENDC}"); exit()
|
||||
|
||||
|
||||
for extension in l_extensions:
|
||||
try:
|
||||
bot.load_extension(extension)
|
||||
except Exception as e:
|
||||
print('Impossible de charger l\'extension {}\n{}: {}'.format(extension, type(e).__name__, e))
|
||||
|
||||
try:
|
||||
bot.run(token)
|
||||
except:
|
||||
print("Une erreur est survenue avec votre Token, merci de le vérifier.")
|
||||
|
||||
handlers = log.handlers[:]
|
||||
for hdlr in handlers:
|
||||
hdlr.close()
|
||||
log.removeHandler(hdlr)
|
||||
tuxbot = TuxBot()
|
||||
tuxbot.run()
|
||||
|
|
BIN
cogs/.DS_Store
vendored
Normal file
337
cogs/admin.py
|
@ -1,76 +1,85 @@
|
|||
from discord.ext import commands
|
||||
import discord
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import time
|
||||
import discord
|
||||
from .utils import checks
|
||||
|
||||
from .utils.checks import get_user
|
||||
|
||||
import json
|
||||
import random
|
||||
|
||||
import datetime
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
class Admin:
|
||||
"""Commandes secrètes d'administration."""
|
||||
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@checks.is_owner()
|
||||
@commands.command(name='unload_cog', hidden=True)
|
||||
async def _unload(self, ctx, module: str):
|
||||
"""Unloads a module."""
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(pass_context=True)
|
||||
async def ban(self, ctx, user, *, reason=""):
|
||||
"""Ban user"""
|
||||
user = get_user(ctx.message, user)
|
||||
if user:
|
||||
try:
|
||||
self.bot.unload_extension("cogs."+module)
|
||||
except Exception as e:
|
||||
await ctx.send('\N{PISTOL}')
|
||||
await ctx.send('{}: {}'.format(type(e).__name__, e))
|
||||
await user.ban(reason=reason)
|
||||
return_msg = "`{}` a été banni\n".format(user.mention)
|
||||
if reason:
|
||||
return_msg += "raison : `{}`".format(reason)
|
||||
return_msg += "."
|
||||
await ctx.send(return_msg)
|
||||
except discord.Forbidden:
|
||||
await ctx.send('Impossible de bannir cet user, probleme de permission.')
|
||||
else:
|
||||
await ctx.send('\N{OK HAND SIGN}')
|
||||
print("cog : " + str(module) + " activé")
|
||||
return await ctx.send('Impossible de trouver l\'user.')
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.is_owner()
|
||||
@commands.command(name='load_cog', hidden=True)
|
||||
async def _load(self, ctx, module: str):
|
||||
"""Unloads a module."""
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(pass_context=True)
|
||||
async def kick(self, ctx, user, *, reason=""):
|
||||
"""Kick a user"""
|
||||
user = get_user(ctx.message, user)
|
||||
if user:
|
||||
try:
|
||||
self.bot.load_extension("cogs."+module)
|
||||
except Exception as e:
|
||||
await ctx.send('\N{PISTOL}')
|
||||
await ctx.send('{}: {}'.format(type(e).__name__, e))
|
||||
await user.kick(reason=reason)
|
||||
return_msg = "`{}` a été kické\n".format(user.mention)
|
||||
if reason:
|
||||
return_msg += "raison : `{}`".format(reason)
|
||||
return_msg += "."
|
||||
await ctx.send(return_msg)
|
||||
except discord.Forbidden:
|
||||
await ctx.send('Impossible de kicker cet user, probleme de permission.')
|
||||
else:
|
||||
await ctx.send('\N{OK HAND SIGN}')
|
||||
print("cog : " + str(module) + " desactivé")
|
||||
return await ctx.send('Impossible de trouver l\'user.')
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.is_owner()
|
||||
@commands.command(name='reload_cog', hidden=True)
|
||||
async def _reload(self, ctx, *, module: str):
|
||||
"""Reloads a module."""
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(name='clear', pass_context=True)
|
||||
async def _clear(self, ctx, number: int, silent: str = True):
|
||||
"""Clear <number> of message(s)"""
|
||||
try:
|
||||
self.bot.unload_extension("cogs."+module)
|
||||
self.bot.load_extension("cogs."+module)
|
||||
await ctx.send("Je te reload ca")
|
||||
except Exception as e: #TODO : A virer dans l'event on_error
|
||||
await ctx.send(':( Erreur :')
|
||||
await ctx.send('{}: {}'.format(type(e).__name__, e))
|
||||
else:
|
||||
await ctx.send('\N{OK HAND SIGN}')
|
||||
print("cog : " + str(module) + " relancé")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.is_owner()
|
||||
@commands.command(name='clear', pass_context=True, hidden=True)
|
||||
async def _clear(self, ctx, number: int):
|
||||
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
if number < 1000:
|
||||
async for message in ctx.message.channel.history(limit=number):
|
||||
try:
|
||||
await message.delete()
|
||||
except Exception as e: #TODO : A virer dans l'event on_error
|
||||
if silent is not True:
|
||||
await ctx.send(':sob: Une erreur est survenue : \n {}: {}'.format(type(e).__name__, e))
|
||||
if silent is not True:
|
||||
await ctx.send("Hop voila j'ai viré des messages! Hello World")
|
||||
print(str(number)+" messages ont été supprimés")
|
||||
else:
|
||||
|
@ -78,28 +87,250 @@ class Admin:
|
|||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.is_owner()
|
||||
@commands.command(name='say', pass_context=True, hidden=True)
|
||||
async def _say(self, ctx, *direuh:str):
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(name='say', pass_context=True)
|
||||
async def _say(self, ctx, *, tosay:str):
|
||||
"""Say a message in the current channel"""
|
||||
try:
|
||||
try:
|
||||
dire = ctx.message.content.split("say ")
|
||||
await ctx.message.delete()
|
||||
await ctx.send(dire[1])
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
await ctx.send(tosay)
|
||||
except Exception as e: #TODO : A virer dans l'event on_error
|
||||
await ctx.send(':sob: Une erreur est survenue : \n {}: {}'.format(type(e).__name__, e))
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.is_owner()
|
||||
@commands.command(pass_context=True, hidden=True)
|
||||
async def _clearterm(self, ctx):
|
||||
clear = "\n" * 100
|
||||
print(clear)
|
||||
await ctx.send(":ok_hand: It's good")
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(name='sayto', pass_context=True)
|
||||
async def _sayto(self, ctx, id:int, *, tosay:str):
|
||||
"""Say a message in the <id> channel"""
|
||||
try:
|
||||
chan = self.bot.get_channel(id)
|
||||
try:
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
try:
|
||||
await chan.send(tosay)
|
||||
except Exception as e:
|
||||
print("Impossible d'envoyer le message dans " + str(id))
|
||||
except Exception as e: #TODO : A virer dans l'event on_error
|
||||
await ctx.send(':sob: Une erreur est survenue : \n {}: {}'.format(type(e).__name__, e))
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(name='sayto_dm', pass_context=True)
|
||||
async def _sayto_dm(self, ctx, id:int, *, tosay:str):
|
||||
"""Say a message to the <id> user"""
|
||||
try:
|
||||
user = self.bot.get_user(id)
|
||||
try:
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
try:
|
||||
await user.send(tosay)
|
||||
except Exception as e:
|
||||
print("Impossible d'envoyer le message dans " + str(id))
|
||||
except Exception as e: #TODO : A virer dans l'event on_error
|
||||
await ctx.send(':sob: Une erreur est survenue : \n {}: {}'.format(type(e).__name__, e))
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(name='editsay', pass_context=True)
|
||||
async def _editsay(self, ctx, id:int, *, new_content:str):
|
||||
"""Edit a bot's message"""
|
||||
try:
|
||||
try:
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
toedit = await ctx.channel.get_message(id)
|
||||
except discord.errors.NotFound:
|
||||
await ctx.send("Impossible de trouver le message avec l'id `{}` sur ce salon".format(id))
|
||||
return
|
||||
try:
|
||||
await toedit.edit(content=str(new_content))
|
||||
except discord.errors.Forbidden:
|
||||
await ctx.send("J'ai po les perms pour editer mes messages :(")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(name='addreaction', pass_context=True)
|
||||
async def _addreaction(self, ctx, id:int, reaction:str):
|
||||
"""Add reactions to a message"""
|
||||
try:
|
||||
try:
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
toadd = await ctx.channel.get_message(id)
|
||||
except discord.errors.NotFound:
|
||||
await ctx.send("Impossible de trouver le message avec l'id `{}` sur ce salon".format(id))
|
||||
return
|
||||
try:
|
||||
await toadd.add_reaction(reaction)
|
||||
except discord.errors.Forbidden:
|
||||
await ctx.send("J'ai po les perms pour ajouter des réactions :(")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(name='delete', pass_context=True)
|
||||
async def _delete(self, ctx, id:int):
|
||||
"""Delete message in current channel"""
|
||||
try:
|
||||
try:
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
todelete = await ctx.channel.get_message(id)
|
||||
except discord.errors.NotFound:
|
||||
await ctx.send("Impossible de trouver le message avec l'id `{}` sur ce salon".format(id))
|
||||
return
|
||||
try:
|
||||
await todelete.delete()
|
||||
except discord.errors.Forbidden:
|
||||
await ctx.send("J'ai po les perms pour supprimer des messages :(")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(name='deletefrom', pass_context=True)
|
||||
async def _deletefrom(self, ctx, chan_id:int, *, message_id:str):
|
||||
"""Delete message in <chan_id> channel"""
|
||||
try:
|
||||
chan = self.bot.get_channel(chan_id)
|
||||
try:
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
todelete = await chan.get_message(message_id)
|
||||
except discord.errors.NotFound:
|
||||
await ctx.send("Impossible de trouver le message avec l'id `{}` sur le salon".format(id))
|
||||
return
|
||||
try:
|
||||
await todelete.delete()
|
||||
except discord.errors.Forbidden:
|
||||
await ctx.send("J'ai po les perms pour supprimer le message :(")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.command(name='embed', pass_context=True)
|
||||
async def _embed(self, ctx, *, msg: str = "help"):
|
||||
"""Send an embed"""
|
||||
if msg != "help":
|
||||
ptext = title = description = image = thumbnail = color = footer = author = None
|
||||
timestamp = discord.Embed.Empty
|
||||
embed_values = msg.split('|')
|
||||
for i in embed_values:
|
||||
if i.strip().lower().startswith('ptext='):
|
||||
ptext = i.strip()[6:].strip()
|
||||
elif i.strip().lower().startswith('title='):
|
||||
title = i.strip()[6:].strip()
|
||||
elif i.strip().lower().startswith('description='):
|
||||
description = i.strip()[12:].strip()
|
||||
elif i.strip().lower().startswith('desc='):
|
||||
description = i.strip()[5:].strip()
|
||||
elif i.strip().lower().startswith('image='):
|
||||
image = i.strip()[6:].strip()
|
||||
elif i.strip().lower().startswith('thumbnail='):
|
||||
thumbnail = i.strip()[10:].strip()
|
||||
elif i.strip().lower().startswith('colour='):
|
||||
color = i.strip()[7:].strip()
|
||||
elif i.strip().lower().startswith('color='):
|
||||
color = i.strip()[6:].strip()
|
||||
elif i.strip().lower().startswith('footer='):
|
||||
footer = i.strip()[7:].strip()
|
||||
elif i.strip().lower().startswith('author='):
|
||||
author = i.strip()[7:].strip()
|
||||
elif i.strip().lower().startswith('timestamp'):
|
||||
timestamp = ctx.message.created_at
|
||||
else:
|
||||
if description is None and not i.strip().lower().startswith('field='):
|
||||
description = i.strip()
|
||||
|
||||
if color:
|
||||
if color.startswith('#'):
|
||||
color = color[1:]
|
||||
if not color.startswith('0x'):
|
||||
color = '0x' + color
|
||||
|
||||
if ptext is title is description is image is thumbnail is color is footer is author is None and 'field=' not in msg:
|
||||
try:
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
return await ctx.send(content=None,
|
||||
embed=discord.Embed(description=msg))
|
||||
|
||||
if color:
|
||||
em = discord.Embed(timestamp=timestamp, title=title, description=description, color=int(color, 16))
|
||||
else:
|
||||
em = discord.Embed(timestamp=timestamp, title=title, description=description)
|
||||
for i in embed_values:
|
||||
if i.strip().lower().startswith('field='):
|
||||
field_inline = True
|
||||
field = i.strip().lstrip('field=')
|
||||
field_name, field_value = field.split('value=')
|
||||
if 'inline=' in field_value:
|
||||
field_value, field_inline = field_value.split('inline=')
|
||||
if 'false' in field_inline.lower() or 'no' in field_inline.lower():
|
||||
field_inline = False
|
||||
field_name = field_name.strip().lstrip('name=')
|
||||
em.add_field(name=field_name, value=field_value.strip(), inline=field_inline)
|
||||
if author:
|
||||
if 'icon=' in author:
|
||||
text, icon = author.split('icon=')
|
||||
if 'url=' in icon:
|
||||
em.set_author(name=text.strip()[5:], icon_url=icon.split('url=')[0].strip(), url=icon.split('url=')[1].strip())
|
||||
else:
|
||||
em.set_author(name=text.strip()[5:], icon_url=icon)
|
||||
else:
|
||||
if 'url=' in author:
|
||||
em.set_author(name=author.split('url=')[0].strip()[5:], url=author.split('url=')[1].strip())
|
||||
else:
|
||||
em.set_author(name=author)
|
||||
|
||||
if image:
|
||||
em.set_image(url=image)
|
||||
if thumbnail:
|
||||
em.set_thumbnail(url=thumbnail)
|
||||
if footer:
|
||||
if 'icon=' in footer:
|
||||
text, icon = footer.split('icon=')
|
||||
em.set_footer(text=text.strip()[5:], icon_url=icon)
|
||||
else:
|
||||
em.set_footer(text=footer)
|
||||
|
||||
try:
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
print("Impossible de supprimer le message \"" + str(ctx.message.content) + "\"")
|
||||
await ctx.send(content=ptext, embed=em)
|
||||
|
||||
else:
|
||||
embed=discord.Embed(title="Aide sur l'utilisation de la commande .embed:")
|
||||
embed.add_field(name="Titre:", value="title=<le titre>", inline=True)
|
||||
embed.add_field(name="Description:", value="description=<la description>", inline=True)
|
||||
embed.add_field(name="Couleur:", value="color=<couleur en hexa>", inline=True)
|
||||
embed.add_field(name="Image:", value="image=<url de l'image (en https)>", inline=True)
|
||||
embed.add_field(name="Thumbnail:", value="thumbnail=<url de l'image>", inline=True)
|
||||
embed.add_field(name="Auteur:", value="author=<nom de l'auteur>", inline=True)
|
||||
embed.add_field(name="Icon", value="icon=<url de l'image>", inline=True)
|
||||
embed.add_field(name="Footer", value="footer=<le footer>", inline=True)
|
||||
embed.set_footer(text="Exemple: .embed title=Un titre | description=Une description | color=3AB35E | field=name=test value=test")
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Admin(bot))
|
||||
|
|
78
cogs/afk.py
Executable file
|
@ -0,0 +1,78 @@
|
|||
from discord.ext import commands
|
||||
import random
|
||||
|
||||
|
||||
class AFK:
|
||||
"""Commandes utilitaires."""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
"""---------------------------------------------------------------------"""
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
async def afk(self, ctx):
|
||||
|
||||
user = ctx.message.author
|
||||
|
||||
try:
|
||||
await user.edit(nick="[AFK] "+str(user.name))
|
||||
author = ctx.message.author
|
||||
channel = await author.create_dm()
|
||||
await channel.send("Ton pseudo a prit le prefix `[AFK]` pour "
|
||||
"monter que tu es absent,")
|
||||
await channel.send("tu auras juste a mettre un message pour que "
|
||||
"je signale ton retour parmis nous et que je "
|
||||
"retire le prefix `[AFK]` de ton pseudo 😉")
|
||||
|
||||
except KeyError:
|
||||
print('')
|
||||
author = ctx.message.author
|
||||
channel = await author.create_dm()
|
||||
await channel.send("Tu auras juste a mettre un message pour que "
|
||||
"je signale ton retour parmis nous 😉")
|
||||
|
||||
msgs = ["s'absente de discord quelques instants",
|
||||
"se casse de son pc",
|
||||
"va sortir son chien",
|
||||
"reviens bientôt",
|
||||
"va nourrir son cochon",
|
||||
"va manger des cookies",
|
||||
"va manger de la poutine",
|
||||
"va faire caca",
|
||||
"va faire pipi"]
|
||||
msg = random.choice(msgs)
|
||||
|
||||
await ctx.send("**{}** {}...".format(ctx.message.author.mention, msg))
|
||||
|
||||
"""---------------------------------------------------------------------"""
|
||||
|
||||
|
||||
async def on_message(message):
|
||||
|
||||
ni = str(message.author.nick)
|
||||
|
||||
if ni:
|
||||
ni2 = ni.split(" ")
|
||||
if "[AFK]" in ni2:
|
||||
user = message.author
|
||||
await user.edit(nick=None)
|
||||
|
||||
msgs = ["a réssuscité",
|
||||
"est de nouveau parmi nous",
|
||||
"a fini de faire caca",
|
||||
"a fini d'uriner",
|
||||
"n'est plus mort",
|
||||
"est de nouveau sur son PC",
|
||||
"a fini de manger sa poutine",
|
||||
"a fini de danser",
|
||||
"s'est réveillé",
|
||||
"est de retour dans ce monde cruel"]
|
||||
msg = random.choice(msgs)
|
||||
|
||||
await message.channel.send("**{}** {} !".format(
|
||||
message.author.mention, msg))
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(AFK(bot))
|
|
@ -1,15 +1,12 @@
|
|||
from discord.ext import commands
|
||||
from random import choice, shuffle
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import time
|
||||
import discord
|
||||
import platform, socket
|
||||
import os
|
||||
import platform
|
||||
import socket
|
||||
|
||||
import wikipedia, bs4
|
||||
import subprocess
|
||||
|
||||
class General:
|
||||
|
||||
class Basics:
|
||||
"""Commandes générales."""
|
||||
|
||||
def __init__(self, bot):
|
||||
|
@ -17,40 +14,54 @@ class General:
|
|||
|
||||
@commands.command()
|
||||
async def ping(self, ctx):
|
||||
t1 = time.perf_counter()
|
||||
await ctx.trigger_typing()
|
||||
t2 = time.perf_counter()
|
||||
ping_res = str(subprocess.Popen(["/bin/ping", "-c1", "discordapp.com"], stdout=subprocess.PIPE).stdout.read())
|
||||
formated_res = [item for item in ping_res.split() if 'time=' in item]
|
||||
result = str(formated_res[0])[5:]
|
||||
|
||||
result = round((t2-t1)*1000)
|
||||
|
||||
if int(result) >=200:
|
||||
em = discord.Embed(title="Ping : " + str(result) + "ms", description="... c'est quoi ce ping !", colour=0xFF1111)
|
||||
if float(result) >= 200:
|
||||
em = discord.Embed(title="Ping : " + str(result) + "ms",
|
||||
description="... c'est quoi ce ping !",
|
||||
colour=0xFF1111)
|
||||
await ctx.send(embed=em)
|
||||
elif int(result) > 100 and int(result) < 200:
|
||||
em = discord.Embed(title="Ping : " + str(result) + "ms", description="Ca va, ça peut aller, mais j'ai l'impression d'avoir 40 ans !", colour=0xFFA500)
|
||||
elif float(result) > 100 < 200:
|
||||
em = discord.Embed(title="Ping : " + str(result) + "ms",
|
||||
description="Ca va, ça peut aller, mais j'ai "
|
||||
"l'impression d'avoir 40 ans !",
|
||||
colour=0xFFA500)
|
||||
await ctx.send(embed=em)
|
||||
elif int(result) <= 100:
|
||||
em = discord.Embed(title="Ping : " + str(result) + "ms", description="Wow c'te vitesse de réaction, je m'épate moi-même !",colour=0x11FF11)
|
||||
else:
|
||||
em = discord.Embed(title="Ping : " + str(result) + "ms",
|
||||
description="Wow c'te vitesse de réaction, "
|
||||
"je m'épate moi-même !",
|
||||
colour=0x11FF11)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
##INFO##
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command()
|
||||
async def info(self, ctx):
|
||||
"""Affiches des informations sur le bot"""
|
||||
text = open('texts/info.md').read()
|
||||
os_info = str(platform.system()) + " / " + str(platform.release())
|
||||
em = discord.Embed(title='Informations sur TuxBot', description=text.format(os_info, platform.python_version(), socket.gethostname(), discord.__version__), colour=0x89C4F9)
|
||||
em.set_footer(text=os.getcwd() + "/bot.py")
|
||||
em = discord.Embed(title='Informations sur TuxBot',
|
||||
description=text.format(os_info,
|
||||
platform.python_version(),
|
||||
socket.gethostname(),
|
||||
discord.__version__),
|
||||
colour=0x89C4F9)
|
||||
em.set_footer(text="/home/****/bot.py")
|
||||
await ctx.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
## HELP PLZ ##
|
||||
@commands.command()
|
||||
async def help(self, ctx):
|
||||
"""Affiches l'aide du bot"""
|
||||
text = open('texts/help.md').read()
|
||||
em = discord.Embed(title='Commandes de TuxBot', description=text, colour=0x89C4F9)
|
||||
em = discord.Embed(title='Commandes de TuxBot', description=text,
|
||||
colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(General(bot))
|
||||
bot.add_cog(Basics(bot))
|
||||
|
|
277
cogs/ci.py
|
@ -1,37 +1,15 @@
|
|||
from discord.ext import commands
|
||||
from random import choice, shuffle
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import discord
|
||||
import platform, socket
|
||||
import os
|
||||
import sqlite3
|
||||
|
||||
import time
|
||||
import datetime, pytz
|
||||
from .utils import checks
|
||||
from .utils import db
|
||||
from .utils.checks import get_user, check_date
|
||||
|
||||
from datetime import date
|
||||
import calendar
|
||||
import datetime
|
||||
|
||||
#### SQL #####
|
||||
conn = sqlite3.connect('tuxbot.db') #Connexion SQL
|
||||
import pymysql
|
||||
import requests
|
||||
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS users(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
userid TEXT,
|
||||
username TEXT,
|
||||
os TEXT,
|
||||
config TEXT,
|
||||
useravatar TEXT,
|
||||
userbirth TEXT,
|
||||
pays TEXT,
|
||||
cidate TEXT,
|
||||
cibureau TEXT
|
||||
)
|
||||
""")# Creation table Utilisateur si premiere fois
|
||||
conn.commit()
|
||||
|
||||
class Identity:
|
||||
"""Commandes des cartes d'identité ."""
|
||||
|
@ -39,16 +17,39 @@ class Identity:
|
|||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
self.cursor.execute("""SHOW TABLES LIKE 'users'""")
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if not result:
|
||||
# Creation table Utilisateur si premiere fois
|
||||
sql = "CREATE TABLE users ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, userid TEXT null, username TEXT null, os TEXT null, config TEXT null, useravatar TEXT null, userbirth TEXT null, pays TEXT null, cidate TEXT null, cibureau TEXT null);"
|
||||
self.cursor.execute(sql)
|
||||
|
||||
@commands.group(name="ci", no_pm=True, pass_context=True)
|
||||
async def _ci(self, ctx):
|
||||
"""Cartes d'identité"""
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
text = open('texts/ci-info.md').read()
|
||||
em = discord.Embed(title='Commandes de carte d\'identité de TuxBot', description=text, colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@_ci.command(pass_context=True, name="show")
|
||||
async def ci_test(self, ctx, args : discord.Member):
|
||||
async def ci_show(self, ctx, args: str = None):
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
if args == None:
|
||||
user = get_user(ctx.message, ctx.message.author.name)
|
||||
else:
|
||||
user = get_user(ctx.message, args)
|
||||
|
||||
if user:
|
||||
self.cursor.execute("""SELECT userid, username, useravatar, userbirth, cidate, cibureau, os, config, pays, id FROM users WHERE userid=%s""",(str(user.id)))
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
def isexist(var):
|
||||
if not var:
|
||||
|
@ -56,133 +57,193 @@ class Identity:
|
|||
else:
|
||||
return var
|
||||
|
||||
cursor.execute("""SELECT userid, username, useravatar, userbirth, cidate, cibureau, os, config, pays, id FROM users WHERE userid=?""",(args.id,))
|
||||
result = cursor.fetchone()
|
||||
|
||||
if not result:
|
||||
await ctx.send(ctx.message.author.mention + "> :x: Désolé mais {} est sans papier !".format(args.mention))
|
||||
|
||||
await ctx.send(f"{ctx.message.author.mention}> :x: Désolé mais {user.mention} est sans papier !")
|
||||
else:
|
||||
try:
|
||||
userbirth = result[3].split(" ")
|
||||
cidate = result[4].split(" ")
|
||||
user_birth = datetime.datetime.fromisoformat(result[3])
|
||||
user_birth_day = check_date(str(user_birth.day))
|
||||
user_birth_month = check_date(str(user_birth.month))
|
||||
|
||||
formated_user_birth = str(user_birth_day) + "/" + str(user_birth_month) + "/" + str(user_birth.year)
|
||||
|
||||
try: ## a virer une fois le patch appliqué pour tout le monde
|
||||
cidate = datetime.datetime.fromisoformat(result[4])
|
||||
cidate_day = check_date(str(cidate.day)) ## a garder
|
||||
cidate_month = check_date(str(cidate.month)) ## a garder
|
||||
|
||||
formated_cidate = str(cidate_day) + "/" + str(cidate_month) + "/" + str(cidate.year) ## a garder
|
||||
except ValueError: ## a virer une fois le patch appliqué pour tout le monde
|
||||
formated_cidate = str(result[4]).replace('-', '/') ## a virer une fois le patch appliqué pour tout le monde
|
||||
await ctx.send(f"{user.mention} vous êtes prié(e) de faire la commande `.ci update` afin de regler un probleme de date coté bdd") ## a virer une fois le patch appliqué pour tout le monde
|
||||
|
||||
embed=discord.Embed(title="Carte d'identité | Communisme Linuxien")
|
||||
embed.set_author(name=result[1], icon_url=result[2])
|
||||
embed.set_thumbnail(url = result[2])
|
||||
embed.add_field(name="Nom :", value=result[1], inline=True)
|
||||
embed.add_field(name="Système d'exploitation :", value=isexist(result[6]), inline=True)
|
||||
embed.add_field(name="Configuration Système : ", value=isexist(result[7]), inline=True)
|
||||
embed.add_field(name="Date de naissance : ", value=userbirth[0], inline=True)
|
||||
embed.add_field(name="Date de naissance sur discord : ", value=formated_user_birth, inline=True)
|
||||
embed.add_field(name="Pays : ", value=isexist(result[8]), inline=True)
|
||||
embed.add_field(name="Profil sur le web : ", value="https://tuxbot.outout.tech/user-{}".format(result[9]), inline=True)
|
||||
embed.set_footer(text="Enregistré dans le bureau {} le {}.".format(result[5], cidate[0]))
|
||||
embed.add_field(name="Profil sur le web : ", value=f"https://tuxbot.outout.xyz/user-{result[9]}", inline=True)
|
||||
embed.set_footer(text=f"Enregistré dans le bureau {result[5]} le {formated_cidate}.")
|
||||
await ctx.send(embed=embed)
|
||||
except:
|
||||
await ctx.send(ctx.message.author.mention + "> :x: Désolé mais la carte d'identité de {0} est trop longue de ce fait je ne peux te l'envoyer, essaye de l'aléger, {0} :wink: !".format(args.mention))
|
||||
except Exception as e:
|
||||
await ctx.send(f"{ctx.message.author.mention}> :x: Désolé mais la carte d'identité de {user.mention} est trop longue de ce fait je ne peux te l'envoyer, essaye de l'aléger, {user.mention} :wink: !")
|
||||
await ctx.send(f':sob: Une erreur est survenue : \n {type(e).__name__}: {e}')
|
||||
else:
|
||||
return await ctx.send('Impossible de trouver l\'user.')
|
||||
|
||||
@_ci.command(pass_context=True, name="register")
|
||||
async def ci_register(self, ctx):
|
||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
||||
existansw = cursor.fetchone()
|
||||
if existansw != None:
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.message.author.id)))
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if result:
|
||||
await ctx.send("Mais tu as déja une carte d'identité ! u_u")
|
||||
else:
|
||||
date = datetime.datetime.now()
|
||||
now = datetime.datetime.now()
|
||||
|
||||
nd = str(date.day)
|
||||
nd += "-"
|
||||
nd += str(date.month)
|
||||
nd += "-"
|
||||
nd += str(date.year)
|
||||
|
||||
cursor.execute("""INSERT INTO users(userid, username, useravatar, userbirth, cidate, cibureau) VALUES(?, ?, ?, ?, ?, ?)""", (ctx.message.author.id, ctx.message.author.name, ctx.message.author.avatar_url, ctx.message.author.created_at, nd, str(ctx.message.guild.name)))
|
||||
conn.commit()
|
||||
await ctx.send(":clap: Bievenue à toi {} dans le communisme {} ! Fait ``.ci`` pour plus d'informations !".format(ctx.message.author.name, str(ctx.message.guild.name)))
|
||||
self.cursor.execute("""INSERT INTO users(userid, username, useravatar, userbirth, cidate, cibureau) VALUES(%s, %s, %s, %s, %s, %s)""", (str(ctx.message.author.id), str(ctx.message.author), str(ctx.message.author.avatar_url_as(format="jpg", size=512)), str(ctx.message.author.created_at), now, str(ctx.message.guild.name)))
|
||||
self.conn.commit()
|
||||
await ctx.send(f":clap: Bievenue à toi {ctx.message.author.name} dans le communisme {ctx.message.guild.name} ! Fait ``.ci`` pour plus d'informations !")
|
||||
|
||||
@_ci.command(pass_context=True, name="delete")
|
||||
async def ci_delete(self, ctx):
|
||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
||||
existansw = cursor.fetchone()
|
||||
if existansw != None:
|
||||
cursor.execute("""DELETE FROM users WHERE userid =?""", (ctx.message.author.id,))
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.message.author.id)))
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if result:
|
||||
self.cursor.execute("""DELETE FROM users WHERE userid =%s""", (str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
await ctx.send("Tu es maintenant sans papiers !")
|
||||
else:
|
||||
await ctx.send("Déja enregistre ta carte d'identité avant de la supprimer u_u (après c'est pas logique...)")
|
||||
|
||||
@_ci.command(pass_context=True, name="update")
|
||||
async def ci_image(self, ctx):
|
||||
try:
|
||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
||||
existansw = cursor.fetchone()
|
||||
async def ci_update(self, ctx):
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
if existansw != None:
|
||||
cursor.execute("""UPDATE users SET useravatar = ?, username = ?, cibureau = ? WHERE userid = ?""", (ctx.message.author.avatar_url, ctx.message.author.name, str(ctx.message.guild), ctx.message.author.id))
|
||||
conn.commit()
|
||||
await ctx.send(ctx.message.author.mention + "> Tu viens, en quelques sortes, de renaitre !")
|
||||
try:
|
||||
self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.message.author.id)))
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if result:
|
||||
self.cursor.execute("""SELECT cidate FROM users WHERE userid=%s""",(str(ctx.message.author.id)))
|
||||
old_ci_date = self.cursor.fetchone()
|
||||
|
||||
try:
|
||||
new_ci_date = datetime.datetime.fromisoformat(old_ci_date[0])
|
||||
except ValueError:
|
||||
old_ci_date = datetime.datetime.strptime(old_ci_date[0].replace('/', '-'), '%d-%m-%Y')
|
||||
|
||||
old_ci_date_day = check_date(str(old_ci_date.day))
|
||||
old_ci_date_month = check_date(str(old_ci_date.month))
|
||||
|
||||
new_ci_date = f"{str(old_ci_date.year)}-{str(old_ci_date_month)}-{str(old_ci_date_day)} 00:00:00.000000"
|
||||
|
||||
await ctx.send("succes update")
|
||||
|
||||
self.cursor.execute("""UPDATE users SET cidate = %s WHERE userid = %s""", (str(new_ci_date), str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
|
||||
self.cursor.execute("""UPDATE users SET useravatar = %s, username = %s, cibureau = %s WHERE userid = %s""", (str(ctx.message.author.avatar_url_as(format="jpg", size=512)), str(ctx.message.author), str(ctx.message.guild), str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
await ctx.send(f"{ctx.message.author.mention}> Tu viens, en quelques sortes, de renaitre !")
|
||||
else:
|
||||
await ctx.send(ctx.message.author.mention + "> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
|
||||
await ctx.send(f"{ctx.message.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
|
||||
|
||||
except Exception as e: #TODO : A virer dans l'event on_error
|
||||
await ctx.send(':( Erreur veuillez contacter votre administrateur :')
|
||||
await ctx.send('{}: {}'.format(type(e).__name__, e))
|
||||
await ctx.send(f'{type(e).__name__}: {e}')
|
||||
|
||||
@_ci.command(pass_context=True, name="setconfig")
|
||||
async def ci_setconfig(self, ctx, args_):
|
||||
try:
|
||||
args = ctx.message.content.split("setconfig ")
|
||||
args = args[1]
|
||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
||||
existansw = cursor.fetchone()
|
||||
async def ci_setconfig(self, ctx, *, conf: str = None):
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
if existansw != None:
|
||||
cursor.execute("""UPDATE users SET config = ? WHERE userid = ?""", (args, ctx.message.author.id))
|
||||
conn.commit()
|
||||
await ctx.send(ctx.message.author.mention + "> :ok_hand: Carte d'identité mise à jour !")
|
||||
if conf:
|
||||
self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.message.author.id)))
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if result:
|
||||
self.cursor.execute("""UPDATE users SET config = %s WHERE userid = %s""", (str(conf), str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
await ctx.send(f"{ctx.message.author.mention}> :ok_hand: Carte d'identité mise à jour !")
|
||||
else:
|
||||
await ctx.send(ctx.message.author.mention + "> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
|
||||
except:
|
||||
await ctx.send(ctx.message.author.mention + "> :x: Il manque un paramètre !")
|
||||
await ctx.send(f"{ctx.message.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
|
||||
else:
|
||||
await ctx.send(f"{ctx.message.author.mention}> :x: Il manque un paramètre !")
|
||||
|
||||
@_ci.command(pass_context=True, name="setos")
|
||||
async def ci_setos(self, ctx, args_):
|
||||
try:
|
||||
args = ctx.message.content.split("setos ")
|
||||
args = args[1]
|
||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
||||
existansw = cursor.fetchone()
|
||||
async def ci_setos(self, ctx, *, conf: str = None):
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
if existansw != None:
|
||||
cursor.execute("""UPDATE users SET os = ? WHERE userid = ?""", (args, ctx.message.author.id))
|
||||
conn.commit()
|
||||
await ctx.send(ctx.message.author.mention + "> :ok_hand: Carte d'identité mise à jour !")
|
||||
if conf:
|
||||
self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.message.author.id)))
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if result:
|
||||
self.cursor.execute("""UPDATE users SET os = %s WHERE userid = %s""", (str(conf), str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
await ctx.send(f"{ctx.message.author.mention}> :ok_hand: Carte d'identité mise à jour !")
|
||||
else:
|
||||
await ctx.send(ctx.message.author.mention + "> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
|
||||
except:
|
||||
await ctx.send(ctx.message.author.mention + "> :x: Il manque un paramètre !")
|
||||
await ctx.send(f"{ctx.message.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
|
||||
else:
|
||||
await ctx.send(f"{ctx.message.author.mention}> :x: Il manque un paramètre !")
|
||||
|
||||
@_ci.command(pass_context=True, name="setcountry")
|
||||
async def ci_setcountry(self, ctx, args):
|
||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
||||
existansw = cursor.fetchone()
|
||||
async def ci_setcountry(self, ctx, *, country: str = None):
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
if existansw != None:
|
||||
cursor.execute("""UPDATE users SET pays = ? WHERE userid = ?""", (args, ctx.message.author.id))
|
||||
conn.commit()
|
||||
await ctx.send(ctx.message.author.mention + "> :ok_hand: Carte d'identité mise à jour !")
|
||||
if country:
|
||||
self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.message.author.id)))
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if result:
|
||||
self.cursor.execute("""UPDATE users SET pays = %s WHERE userid = %s""", (str(country), str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
await ctx.send(f"{ctx.message.author.mention}> :ok_hand: Carte d'identité mise à jour !")
|
||||
else:
|
||||
await ctx.send(ctx.message.author.mention + "> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
|
||||
await ctx.send(f"{ctx.message.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
|
||||
else:
|
||||
await ctx.send(f"{ctx.message.author.mention}> :x: Il manque un paramètre !")
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@_ci.command(pass_context=True, name="list")
|
||||
async def ci_list(self, ctx):
|
||||
cursor.execute("""SELECT id, username FROM users""")
|
||||
rows = cursor.fetchall()
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
self.cursor.execute("""SELECT id, username FROM users""")
|
||||
rows = self.cursor.fetchall()
|
||||
msg = ""
|
||||
try:
|
||||
for row in rows:
|
||||
msg = msg + '{0} : {1} \n'.format(row[0], row[1])
|
||||
await ctx.send(msg)
|
||||
except:
|
||||
await ctx.send(":x: Pas d'entrés")
|
||||
row_id = row[0]
|
||||
row_name = row[1].encode('utf-8')
|
||||
msg += f"{str(row_id)} : {str(row_name)} \n"
|
||||
post = requests.post("https://hastebin.com/documents", data=msg)
|
||||
await ctx.send(f"{ctx.message.author.mention} liste posté avec succès sur :\nhttps://hastebin.com/{post.json()['key']}.txt")
|
||||
|
||||
with open('ci_list.txt', 'w', encoding='utf-8') as fp:
|
||||
for row in rows:
|
||||
row_id = row[0]
|
||||
row_name = row[1]
|
||||
|
||||
fp.write(f"{str(row_id)} : {str(row_name)} \n")
|
||||
|
||||
except Exception as e:
|
||||
await ctx.send(f':sob: Une erreur est survenue : \n {type(e).__name__}: {e}')
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Identity(bot))
|
||||
|
|
110
cogs/cog_manager.py
Executable file
|
@ -0,0 +1,110 @@
|
|||
from discord.ext import commands
|
||||
import discord
|
||||
from .utils import checks
|
||||
from .utils.paginator import HelpPaginator
|
||||
|
||||
|
||||
class CogManager:
|
||||
"""Gestionnaire des cogs"""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@checks.has_permissions(administrator=True)
|
||||
@commands.group(name="cogs", no_pm=True, pass_context=True, case_insensitive=True)
|
||||
async def _cogs(self, ctx):
|
||||
"""show help about 'cogs' command"""
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
text = "Tuxbot - Commandes cogs\n-> .cogs <load/unload/reload/info> *{cog}* : <load/unload/reload/info> *{cog}*\n-> .cogs <null/!(load/unload/reload)>: affiche cette aide"
|
||||
em = discord.Embed(title='Tuxbot - Commandes cogs', description=text, colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_cogs.command(name="load", pass_context=True)
|
||||
async def cogs_load(self, ctx, cog: str = ""):
|
||||
"""load a cog"""
|
||||
if cog != "":
|
||||
try:
|
||||
self.bot.load_extension(cog)
|
||||
|
||||
await ctx.send('\N{OK HAND SIGN}')
|
||||
print("cog : " + str(cog) + " chargé")
|
||||
except Exception as e:
|
||||
await ctx.send('\N{PISTOL}')
|
||||
await ctx.send(f'{type(e).__name__}: {e}')
|
||||
else:
|
||||
text = "Tuxbot - Commandes cogs\n-> .cogs <load/unload/reload/info> *{cog}* : <load/unload/reload/info> *{cog}*\n-> .cogs <null/!(load/unload/reload)>: affiche cette aide"
|
||||
em = discord.Embed(title='Tuxbot - Commandes cogs', description=text, colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_cogs.command(name="unload", pass_context=True)
|
||||
async def cogs_unload(self, ctx, cog: str = ""):
|
||||
"""unload a cog"""
|
||||
if cog != "":
|
||||
try:
|
||||
self.bot.unload_extension(cog)
|
||||
|
||||
await ctx.send('\N{OK HAND SIGN}')
|
||||
print("cog : " + str(cog) + " déchargé")
|
||||
except Exception as e:
|
||||
await ctx.send('\N{PISTOL}')
|
||||
await ctx.send(f'{type(e).__name__}: {e}')
|
||||
else:
|
||||
text = "Tuxbot - Commandes cogs\n-> .cogs <load/unload/reload/info> *{cog}* : <load/unload/reload/info> *{cog}*\n-> .cogs <null/!(load/unload/reload)>: affiche cette aide"
|
||||
em = discord.Embed(title='Tuxbot - Commandes cogs', description=text, colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_cogs.command(name="reload", pass_context=True)
|
||||
async def cogs_reload(self, ctx, cog: str = ""):
|
||||
"""reload a cog"""
|
||||
if cog != "":
|
||||
try:
|
||||
self.bot.unload_extension(cog)
|
||||
self.bot.load_extension(cog)
|
||||
|
||||
await ctx.send('\N{OK HAND SIGN}')
|
||||
print("cog : " + str(cog) + " rechargé")
|
||||
except Exception as e:
|
||||
await ctx.send('\N{PISTOL}')
|
||||
await ctx.send(f'{type(e).__name__}: {e}')
|
||||
else:
|
||||
text = "Tuxbot - Commandes cogs\n-> .cogs <load/unload/reload/info> *{cog}* : <load/unload/reload/info> *{cog}*\n-> .cogs <null/!(load/unload/reload)>: affiche cette aide"
|
||||
em = discord.Embed(title='Tuxbot - Commandes cogs', description=text, colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_cogs.command(name="info", pass_context=True)
|
||||
async def cogs_info(self, ctx, cog: str = ""):
|
||||
"""show info about a cog"""
|
||||
if cog != "":
|
||||
try:
|
||||
entity = self.bot.get_cog(cog)
|
||||
|
||||
if entity is None:
|
||||
clean = cog.replace('@', '@\u200b')
|
||||
await ctx.send(f'Command or category "{clean}" not found.')
|
||||
else:
|
||||
p = await HelpPaginator.from_cog(ctx, entity)
|
||||
await p.paginate()
|
||||
|
||||
|
||||
except Exception as e:
|
||||
await ctx.send('\N{PISTOL}')
|
||||
await ctx.send(f'{type(e).__name__}: {e}')
|
||||
else:
|
||||
text = "Tuxbot - Commandes cogs\n-> .cogs <load/unload/reload/info> *{cog}* : <load/unload/reload/info> *{cog}*\n-> .cogs <null/!(load/unload/reload)>: affiche cette aide"
|
||||
em = discord.Embed(title='Tuxbot - Commandes cogs', description=text, colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(CogManager(bot))
|
24
cogs/dev.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
from discord.ext import commands
|
||||
import discord
|
||||
|
||||
|
||||
class Dev:
|
||||
"""Gestionnaire des cogs"""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command(name="test", no_pm=True, pass_context=True, case_insensitive=True)
|
||||
async def _test(self, ctx):
|
||||
"""show help about 'cogs' command"""
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
text = "<:python:334346615366221825>"
|
||||
em = discord.Embed(title='Some test', description=text, colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Dev(bot))
|
52
cogs/filter_messages.py
Executable file
|
@ -0,0 +1,52 @@
|
|||
from discord.ext import commands
|
||||
import discord
|
||||
import asyncio
|
||||
import discord
|
||||
|
||||
import re
|
||||
|
||||
|
||||
class FilterMessages:
|
||||
"""Flitre des messages"""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
async def on_message(self, message):
|
||||
no_pub_guild = [280805240977227776, 303633056944881686, 274247231534792704]
|
||||
lien_channel = [280805783795662848, 508794201509593088]
|
||||
sondage_channel = [394146769107419146, 477147964393914388]
|
||||
|
||||
if message.author.bot \
|
||||
or str(message.author.id) in self.bot.config.authorized_id \
|
||||
or message.channel.permissions_for(message.author).administrator is True:
|
||||
return
|
||||
|
||||
discord_invite_regex = re.compile(r"(discord\.(gg|io|me|li)|discordapp\.com\/invite)\/[0-9A-Za-z]*", re.IGNORECASE)
|
||||
invalid_link_regex = re.compile(r"^(\[[^\]]+\]|<\:[a-z0-9]+\:[0-9]+>) .+ https?:\/\/\S*$", re.IGNORECASE)
|
||||
|
||||
try:
|
||||
if message.guild.id in no_pub_guild: ## discord invitation send by a non-admin and a non-authorized_id
|
||||
if isinstance(discord_invite_regex.search(message.content), re.Match):
|
||||
author = self.bot.get_user(message.author.id)
|
||||
await message.delete()
|
||||
await author.send("La pub pour les serveurs discord n'est pas autorisée ici")
|
||||
|
||||
if message.channel.id in lien_channel \
|
||||
and not isinstance(invalid_link_regex.search(message.content), re.Match): ## link send without pattern
|
||||
author = self.bot.get_user(message.author.id)
|
||||
await message.delete()
|
||||
await author.send("Votre message `" + content + "` a été supprimé du channel `liens` car il ne respecte pas la structure définie. Pour partager un lien veuillez suivre la structure suivante : ` [Sujet] Descirption http(s)://....`")
|
||||
await author.send("Si vous voulez commenter ou discuter à propos d'un lien, veuillez le faire dans le channel `#discussion-des-liens`.")
|
||||
|
||||
if message.channel.id in sondage_channel: ## a non-sondage send by a non-admin
|
||||
prefix_lenght = len(await self.bot.get_prefix(message))
|
||||
command = (message.content.split()[0])[prefix_lenght:]
|
||||
if command != "sondage":
|
||||
await message.delete()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(FilterMessages(bot))
|
121
cogs/funs.py
|
@ -1,57 +1,79 @@
|
|||
from discord.ext import commands
|
||||
from random import choice, shuffle
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import discord
|
||||
import urllib.request, json
|
||||
import urllib.request
|
||||
import json
|
||||
import random
|
||||
import requests
|
||||
|
||||
|
||||
class Funs:
|
||||
"""Commandes funs."""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command()
|
||||
async def avatar(self, ctx, user : discord.Member):
|
||||
async def avatar(self, ctx, user: discord.Member = None):
|
||||
"""Récuperer l'avatar de ..."""
|
||||
embed = discord.Embed(title="Avatar de : " + user.name, url=user.avatar_url, description="[Voir en plus grand]({})".format(user.avatar_url))
|
||||
embed.set_thumbnail(url=user.avatar_url)
|
||||
|
||||
if user == None:
|
||||
user = ctx.message.author
|
||||
|
||||
embed = discord.Embed(title="Avatar de : " + user.name,
|
||||
url=user.avatar_url_as(format="png"),
|
||||
description=f"[Voir en plus grand]({user.avatar_url_as(format='png')})")
|
||||
embed.set_thumbnail(url=user.user.avatar_url_as(format="png"))
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
async def poke(self, ctx, user: discord.Member):
|
||||
"""Poke quelqu'un"""
|
||||
await ctx.send(":clap: Hey {0} tu t'es fait poker par {1} !".format(user.mention, ctx.message.author.name))
|
||||
await ctx.send(":clap: Hey {0} tu t'es fait poker par {1} !".format(
|
||||
user.mention, ctx.message.author.name))
|
||||
await ctx.message.delete()
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command()
|
||||
async def btcprice(self, ctx):
|
||||
"""Le prix du BTC"""
|
||||
loading = await ctx.send("_réfléchis..._")
|
||||
try:
|
||||
with urllib.request.urlopen("http://api.coindesk.com/v1/bpi/currentprice/EUR.json") as url:
|
||||
data = json.loads(url.read().decode())
|
||||
btc = data['bpi']['EUR']['rate']
|
||||
btc = btc.split(".")
|
||||
except:
|
||||
url = urllib.request.urlopen("https://blockchain.info/fr/ticker")
|
||||
btc = json.loads(url.read().decode())
|
||||
except KeyError:
|
||||
btc = 1
|
||||
|
||||
if btc == 1:
|
||||
await ctx.send("Impossible d'accèder à l'API coindesk.com, veuillez réessayer ultérieurment !")
|
||||
await loading.edit(content="Impossible d'accèder à l'API blockchain.info, "
|
||||
"veuillez réessayer ultérieurment ! :c")
|
||||
else:
|
||||
await loading.edit(content="Un bitcoin est égal à : " + btc[0] + " €")
|
||||
frbtc = str(btc["EUR"]["last"]).replace(".", ",")
|
||||
usbtc = str(btc["USD"]["last"]).replace(".", ",")
|
||||
await loading.edit(content="Un bitcoin est égal à : {0}$US soit {1}€.".format(usbtc, frbtc))
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command()
|
||||
async def joke(self, ctx):
|
||||
async def joke(self, ctx, number:str = 0):
|
||||
"""Print a random joke in a json file"""
|
||||
with open('texts/jokes.json') as js:
|
||||
jk = json.load(js)
|
||||
|
||||
clef = str(random.randint(1,13))
|
||||
try:
|
||||
if int(number) <= 15 and int(number) > 0:
|
||||
clef = str(number)
|
||||
else:
|
||||
clef = str(random.randint(1,15))
|
||||
except:
|
||||
clef = str(random.randint(1,15))
|
||||
|
||||
|
||||
joke = jk["{}".format(clef)]
|
||||
|
||||
embed = discord.Embed(title="Blague _{}_ : ".format(clef), description=joke['content'], colour=0x03C9A9)
|
||||
|
@ -59,33 +81,60 @@ class Funs:
|
|||
embed.set_thumbnail(url='https://outout.tech/tuxbot/blobjoy.png')
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command()
|
||||
async def ethylotest(self, ctx):
|
||||
"""Ethylotest simulator 2018"""
|
||||
results_poulet = ["Désolé mais mon ethylotest est sous Windows Vista, merci de patienter...", "_(ethylotest)_ ``Une erreur est survenue. Windows cherche une solution à se problème...``", "Mais j'l'ai foutu où ce p*** d'ethylotest de m*** bordel fait ch*** tab***", "C'est pas possible z'avez cassé l'ethylotest !"]
|
||||
results_client = ["D'accord, il n'y a pas de problème à cela je suis complètement clean", "Bien sur si c'est votre devoir !", "Suce bi** !", "J'ai l'air d'être bourré ?", "_laissez moi prendre un bonbon à la menthe..._"]
|
||||
results_poulet = ["Désolé mais mon ethylotest est sous Windows Vista, "
|
||||
"merci de patienter...",
|
||||
"_(ethylotest)_ : Une erreur est survenue. Windows "
|
||||
"cherche une solution à se problème.",
|
||||
"Mais j'l'ai foutu où ce p\\*\\*\\* d'ethylotest de m\\*\\*\\* "
|
||||
"bordel fait ch\\*\\*\\*",
|
||||
"C'est pas possible z'avez cassé l'ethylotest !"]
|
||||
results_client = ["D'accord, il n'y a pas de problème à cela je suis "
|
||||
"complètement clean",
|
||||
"Bien sur si c'est votre devoir !", "Suce bi\\*e !",
|
||||
"J'ai l'air d'être bourré ?",
|
||||
"_laissez moi prendre un bonbon à la menthe..._"]
|
||||
|
||||
result_p = random.choice(results_poulet)
|
||||
result_c = random.choice(results_client)
|
||||
|
||||
await ctx.send(":oncoming_police_car: Bonjour bonjour, controle d'alcoolémie !")
|
||||
await ctx.send(":oncoming_police_car: Bonjour bonjour, contrôle "
|
||||
"d'alcoolémie !")
|
||||
await asyncio.sleep(0.5)
|
||||
await ctx.send(":man: " + result_c)
|
||||
await asyncio.sleep(1)
|
||||
await ctx.send(":police_car: " + result_p)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command()
|
||||
async def coin(self, ctx):
|
||||
"""Coin flip simulator 2025"""
|
||||
starts_msg = ["Je lance la pièce !", "C'est parti !", "C'est une pièce d'un cent faut pas la perdre", "C'est une pièce d'un euro faut pas la perdre", "Je lance !"]
|
||||
results_coin = ["{0} pile", "{0} face", "{1} Heu c'est quoi pile c'est quoi face enfaite ?", "{1} Oh shit, je crois que je l'ai perdue", "{1} Et bim je te vol ta pièce !", "{0} Oh une erreur d'impression il n'y a ni pile ni face !"]
|
||||
starts_msg = ["Je lance la pièce !", "C'est parti !", "C'est une pièce"
|
||||
" d'un cent faut"
|
||||
" pas la perdre",
|
||||
"C'est une pièce d'un euro faut pas la perdre",
|
||||
"Je lance !"]
|
||||
results_coin = ["{0} pile", "{0} face", "{1} Heu c'est quoi pile c'est"
|
||||
" quoi face enfaite ?",
|
||||
"{1} Oh shit, je crois que je l'ai perdue",
|
||||
"{1} Et bim je te vol ta pièce !",
|
||||
"{0} Oh une erreur d'impression il n'y a ni pile ni"
|
||||
" face !"]
|
||||
|
||||
start = random.choice(starts_msg)
|
||||
result = random.choice(results_coin)
|
||||
|
||||
await ctx.send(start)
|
||||
await asyncio.sleep(0.6)
|
||||
await ctx.send(result.format(":moneybag: Et la pièce retombe sur ...", ":robot:"))
|
||||
await ctx.send(result.format(":moneybag: Et la pièce retombe sur ...",
|
||||
":robot:"))
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command()
|
||||
async def pokemon(self, ctx):
|
||||
|
@ -101,33 +150,39 @@ class Funs:
|
|||
winer = poke1
|
||||
else:
|
||||
winer = poke2
|
||||
except:
|
||||
except KeyError:
|
||||
winer = poke1
|
||||
|
||||
await ctx.send(":flag_white: **Le combat commence !**")
|
||||
await asyncio.sleep(1)
|
||||
await ctx.send(":loudspeaker: Les concurants sont {} contre {} ! Bonne chance à eux !".format(poke1["Name"], poke2["Name"]))
|
||||
await ctx.send(":loudspeaker: Les concurants sont {} contre {} ! Bonne"
|
||||
" chance à eux !".format(poke1["Name"], poke2["Name"]))
|
||||
await asyncio.sleep(0.5)
|
||||
await ctx.send(":boom: {} commence et utilise {}".format(poke1["Name"], poke1["Fast Attack(s)"][0]["Name"]))
|
||||
await ctx.send(":boom: {} commence et utilise {}".format(
|
||||
poke1["Name"], poke1["Fast Attack(s)"][0]["Name"]))
|
||||
await asyncio.sleep(1)
|
||||
await ctx.send(":dash: {} réplique avec {}".format(poke2["Name"], poke2["Fast Attack(s)"][0]["Name"]))
|
||||
await ctx.send(":dash: {} réplique avec {}".format(
|
||||
poke2["Name"], poke2["Fast Attack(s)"][0]["Name"]))
|
||||
await asyncio.sleep(1.2)
|
||||
await ctx.send("_le combat continue de se dérouler..._")
|
||||
await asyncio.sleep(1.5)
|
||||
await ctx.send(":trophy: Le gagnant est **{}** !".format(winer["Name"]))
|
||||
await ctx.send(":trophy: Le gagnant est **{}** !".format(
|
||||
winer["Name"]))
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command()
|
||||
async def randomcat(self, ctx):
|
||||
"""Display a random cat"""
|
||||
|
||||
r = requests.get('http://random.cat/meow.php')
|
||||
r = requests.get('http://aws.random.cat/meow')
|
||||
cat = str(r.json()['file'])
|
||||
embed = discord.Embed(title="Meow", description="[Voir le chat plus grand]({})".format(cat), colour=0x03C9A9)
|
||||
embed = discord.Embed(title="Meow",
|
||||
description="[Voir le chat plus grand]({})".
|
||||
format(cat), colour=0x03C9A9)
|
||||
embed.set_thumbnail(url=cat)
|
||||
embed.set_author(name="Random.cat", url='https://random.cat/', icon_url='http://outout.tech/tuxbot/nyancat2.gif')
|
||||
embed.set_author(name="Random.cat", url='https://random.cat/')
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Funs(bot))
|
||||
|
|
222
cogs/passport.py
Executable file
|
@ -0,0 +1,222 @@
|
|||
from discord.ext import commands
|
||||
import discord
|
||||
|
||||
from PIL import Image
|
||||
from PIL import ImageOps
|
||||
|
||||
from .utils import checks
|
||||
from .utils import db
|
||||
from .utils.passport_generator import generate_passport
|
||||
from .utils.checks import get_user, check_date
|
||||
|
||||
import asyncio, aiohttp, io, time, imghdr, os, shutil, json, textwrap, re, math, datetime
|
||||
|
||||
class Passport:
|
||||
"""Commandes des passeports ."""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
self.cursor.execute("""SHOW TABLES LIKE 'passport'""")
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if not result:
|
||||
# Creation table Passport si premiere fois
|
||||
sql = "CREATE TABLE passport ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, userid TEXT null, os TEXT null, config TEXT null, languages TEXT null, pays TEXT null, passportdate TEXT null, theme CHAR(5) DEFAULT 'dark');"
|
||||
self.cursor.execute(sql)
|
||||
|
||||
@commands.group(pass_context=True)
|
||||
async def passeport(self, ctx):
|
||||
"""Passeport"""
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
text = open('texts/passport-info.md').read()
|
||||
em = discord.Embed(title='Commandes de carte de passeport de TuxBot', description=text, colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@passeport.command(pass_context=True)
|
||||
async def show(self, ctx, user: str = None):
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
if user == None:
|
||||
user = get_user(ctx.message, ctx.message.author.name)
|
||||
else:
|
||||
user = get_user(ctx.message, user)
|
||||
|
||||
wait_message = await ctx.send(f"Je vais chercher le passeport de {user.name} dans les archives, je vous prie de bien vouloir patienter...")
|
||||
|
||||
card = await generate_passport(self, user)
|
||||
s = 'data/users/cards/{0}.png'.format(user.id)
|
||||
|
||||
card.save(s, 'png')
|
||||
|
||||
with open('data/users/cards/{0}.png'.format(user.id), 'rb') as g:
|
||||
await ctx.message.channel.send(file=discord.File(g))
|
||||
await wait_message.delete()
|
||||
|
||||
@passeport.command(name="config", pass_context=True)
|
||||
async def passeport_config(self, ctx):
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
await ctx.send('Un message privé vous a été envoyé pour configurer votre passeport.')
|
||||
|
||||
questions = ["Système(s) d'exploitation :", "Configuration Système :", "Langages de programmation préférés :", "Pays :"]
|
||||
answers = {}
|
||||
|
||||
user_dm = await ctx.author.create_dm()
|
||||
|
||||
try:
|
||||
await user_dm.send("Salut ! Je vais vous posez quelques questions afin de configurer votre passeport, si vous ne voulez pas répondre à une question, envoyez `skip` pour passer à la question suivante.")
|
||||
except discord.HTTPException:
|
||||
await ctx.send(f"{str(ctx.message.author.mention)}> il m'est impossible de vous envoyer les messages nécessaire a la configuration de votre passeport :sob:")
|
||||
return
|
||||
|
||||
for x, question in enumerate(questions):
|
||||
await user_dm.send(question)
|
||||
|
||||
def check(m):
|
||||
return m.channel.id == user_dm.id and m.author.id == user_dm.recipient.id
|
||||
|
||||
answer = await self.bot.wait_for('message', check=check)
|
||||
if answer.content.lower() == 'skip':
|
||||
answers[x] = 'n/a'
|
||||
else:
|
||||
answers[x] = answer.content
|
||||
try:
|
||||
self.cursor.execute("""SELECT id, userid FROM passport WHERE userid = %s""", str(user_dm.recipient.id))
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if result:
|
||||
self.cursor.execute("""UPDATE passport SET os = %s, config = %s, languages = %s, pays = %s WHERE userid = %s""", (str(answers[0]), str(answers[1]), str(answers[2]), str(answers[3]), str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
else:
|
||||
now = datetime.datetime.now()
|
||||
|
||||
self.cursor.execute("""INSERT INTO passport(userid, os, config, languages, pays, passportdate, theme) VALUES(%s, %s, %s, %s, %s, %s, %s)""", (str(ctx.message.author.id), str(answers[0]), str(answers[1]), str(answers[2]), str(answers[3]), now, "dark"))
|
||||
self.conn.commit()
|
||||
await user_dm.send('Configuration de votre passeport terminée avec succès, vous pouvez désormais la voir en faisant `.passeport show`.')
|
||||
except Exception as e:
|
||||
await user_dm.send(f':sob: Une erreur est survenue : \n {type(e).__name__}: {e}')
|
||||
|
||||
@passeport.command(name="background", pass_context=True)
|
||||
async def passeport_background(self, ctx, *, url=""):
|
||||
try:
|
||||
background = ctx.message.attachments[0].url
|
||||
except:
|
||||
if url != "":
|
||||
background = url
|
||||
else:
|
||||
em = discord.Embed(title='Une erreur est survenue', description="Image ou URL introuvable.", colour=0xDC3546)
|
||||
await ctx.send(embed=em)
|
||||
return
|
||||
|
||||
user = ctx.message.author
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(background) as r:
|
||||
image = await r.content.read()
|
||||
except:
|
||||
em = discord.Embed(title='Une erreur est survenue', description="Image ou URL introuvable.", colour=0xDC3546)
|
||||
await ctx.send(embed=em)
|
||||
return
|
||||
|
||||
with open(f"data/users/backgrounds/{str(user.id)}.png",'wb') as f:
|
||||
f.write(image)
|
||||
|
||||
isImage = imghdr.what(f"data/users/backgrounds/{str(user.id)}.png")
|
||||
|
||||
if isImage == 'png' or isImage == 'jpeg' or isImage == 'jpg' or isImage == 'gif':
|
||||
f.close()
|
||||
em = discord.Embed(title='Configuration terminée', description="Fond d'écran enregistré et configuré avec succes", colour=0x28a745)
|
||||
await ctx.send(embed=em)
|
||||
else:
|
||||
f.close()
|
||||
os.remove(f"data/users/backgrounds/{str(user.id)}.png")
|
||||
em = discord.Embed(title='Une erreur est survenue', description="Est-ce bien une image que vous avez envoyé ? :thinking:", colour=0xDC3546)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@passeport.command(name="theme", aliases=["thème"], pass_context=True)
|
||||
async def passeport_theme(self, ctx, theme: str = ""):
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
possible_theme = ["dark", "light", "preview"]
|
||||
|
||||
if theme.lower() in possible_theme:
|
||||
if theme.lower() == "dark":
|
||||
self.cursor.execute("""UPDATE passport SET theme = %s WHERE userid = %s""", ("dark", str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
|
||||
em = discord.Embed(title='Configuration terminée', description="Thème enregistré avec succes", colour=0x28a745)
|
||||
await ctx.send(embed=em)
|
||||
elif theme.lower() == "light":
|
||||
self.cursor.execute("""UPDATE passport SET theme = %s WHERE userid = %s""", ("light", str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
|
||||
em = discord.Embed(title='Configuration terminée', description="Thème enregistré avec succes", colour=0x28a745)
|
||||
await ctx.send(embed=em)
|
||||
else:
|
||||
wait_message = await ctx.send(f"Laissez moi juste le temps de superposer les 2 passeports, je vous prie de bien vouloir patienter...")
|
||||
cardbg = Image.new('RGBA', (1600, 500), (0, 0, 0, 255))
|
||||
|
||||
card_dark = await generate_passport(self, ctx.author, "dark")
|
||||
card_dark.save(f'data/tmp/{ctx.author.id}_dark.png', 'png')
|
||||
|
||||
card_light = await generate_passport(self, ctx.author, "light")
|
||||
card_light.save(f'data/tmp/{ctx.author.id}_light.png', 'png')
|
||||
|
||||
saved_card_dark = Image.open(f'data/tmp/{ctx.author.id}_dark.png')
|
||||
saved_card_light = Image.open(f'data/tmp/{ctx.author.id}_light.png')
|
||||
|
||||
saved_card_dark = ImageOps.fit(saved_card_dark, (800, 500))
|
||||
saved_card_light = ImageOps.fit(saved_card_light, (800, 500))
|
||||
|
||||
cardbg.paste(saved_card_dark, (0, 0))
|
||||
cardbg.paste(saved_card_light, (800, 0))
|
||||
|
||||
cardbg.save(f'data/tmp/{ctx.author.id}.png', 'png')
|
||||
|
||||
with open(f'data/tmp/{ctx.author.id}.png', 'rb') as g:
|
||||
await ctx.send(file=discord.File(g))
|
||||
await wait_message.delete()
|
||||
await ctx.send(f"Et voila {ctx.author.mention} ! à gauche votre passeport avec le thème \"dark\" et à droite avec le thème \"light\" :wink:")
|
||||
|
||||
shutil.rmtree("data/tmp")
|
||||
os.mkdir("data/tmp")
|
||||
|
||||
else:
|
||||
em = discord.Embed(title='Une erreur est survenue', description="Les choix possible pour cette commande sont : `dark`, `light`, `preview`", colour=0xDC3546)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@passeport.command(name="delete", pass_context=True)
|
||||
async def passeport_delete(self, ctx):
|
||||
self.conn = db.connect_to_db(self)
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
self.cursor.execute("""SELECT id, userid FROM passport WHERE userid = %s""", str(ctx.author.id))
|
||||
result = self.cursor.fetchone()
|
||||
|
||||
if result:
|
||||
def check(m):
|
||||
return m.author.id == ctx.author.id and \
|
||||
m.channel.id == ctx.channel.id
|
||||
|
||||
await ctx.send(f"{str(ctx.message.author.mention)}> envoyez `CONFIRMER` afin de supprimer vos données conformément à l'article 17 du `règlement général sur la protection des données` sur le `Droit à l'effacement`")
|
||||
response = await self.bot.wait_for('message', check=check, timeout=10.0 * 60.0)
|
||||
if response.content == "CONFIRMER":
|
||||
os.remove(f"data/users/backgrounds/{str(ctx.author.id)}.png")
|
||||
self.cursor.execute("""DELETE FROM passport WHERE userid =%s""", (str(ctx.message.author.id)))
|
||||
self.conn.commit()
|
||||
|
||||
em = discord.Embed(title='Suppression confirmée', description="Vos données ont été supprimées avec succès", colour=0x28a745)
|
||||
await ctx.send(embed=em)
|
||||
else:
|
||||
await ctx.send("Déja configure ton passeport avant de la supprimer u_u (après c'est pas logique...)")
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Passport(bot))
|
127
cogs/role.py
Executable file
|
@ -0,0 +1,127 @@
|
|||
from discord.ext import commands
|
||||
import discord
|
||||
|
||||
class Role:
|
||||
"""Commandes role."""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
self.ARCH_ROLE = 393077257826205706
|
||||
self.DEBIAN_ROLE = 393077933209550859
|
||||
self.RHEL_ROLE = 393078333245751296
|
||||
self.ANDROID_ROLE = 393087862972612627
|
||||
self.BSD_ROLE = 401791543708745738
|
||||
|
||||
@commands.group(name="role", no_pm=True, pass_context=True, case_insensitive=True)
|
||||
async def _role(self, ctx):
|
||||
"""Affiche l'aide sur la commande role"""
|
||||
if ctx.message.guild.id != 280805240977227776:
|
||||
return
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
text = open('texts/roles.md').read()
|
||||
em = discord.Embed(title='Gestionnaires de rôles', description=text,colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_role.command(name="arch", aliases=["archlinux", "arch_linux"], pass_context=True)
|
||||
async def role_arch(self, ctx):
|
||||
"""Ajoute/retire le role 'Arch user'"""
|
||||
roles = ctx.message.author.roles
|
||||
role_id = []
|
||||
for role in roles:
|
||||
role_id.append(role.id)
|
||||
|
||||
user = ctx.message.author
|
||||
if self.ARCH_ROLE in role_id:
|
||||
await user.remove_roles(discord.Object(id=self.ARCH_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > Pourquoi tu viens de supprimer Arch Linux, c'était trop compliqué pour toi ? <:sad:343723037331292170>")
|
||||
else:
|
||||
await user.add_roles(discord.Object(id=self.ARCH_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > How un ArchLinuxien, c'est bon les ``yaourt`` ? <:hap:354275645574086656>")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_role.command(name="debian", pass_context=True)
|
||||
async def role_debian(self, ctx):
|
||||
"""Ajoute/retire le role 'debian user'"""
|
||||
roles = ctx.message.author.roles
|
||||
role_id = []
|
||||
for role in roles:
|
||||
role_id.append(role.id)
|
||||
|
||||
user = ctx.message.author
|
||||
if self.DEBIAN_ROLE in role_id:
|
||||
await user.remove_roles(discord.Object(id=self.DEBIAN_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > Adieu ! Tu verras, APT te manquera ! ")
|
||||
else:
|
||||
await user.add_roles(discord.Object(id=self.DEBIAN_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > Un utilisateur de Debian, encore et encore ! <:stuck_out_tongue:343723077412323339>")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_role.command(name="rhel", pass_context=True)
|
||||
async def role_rhel(self, ctx):
|
||||
"""Ajoute/retire le role 'rhel user'"""
|
||||
roles = ctx.message.author.roles
|
||||
role_id = []
|
||||
for role in roles:
|
||||
role_id.append(role.id)
|
||||
|
||||
user = ctx.message.author
|
||||
if self.RHEL_ROLE in role_id:
|
||||
await user.remove_roles(discord.Object(id=self.RHEL_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > Pourquoi tu t'en vas, il sont déjà assez seul là-bas <:sad:343723037331292170>")
|
||||
else:
|
||||
await user.add_roles(discord.Object(id=self.RHEL_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > Mais, voila quelqu'un qui porte des chapeaux ! <:hap:354275645574086656>")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_role.command(name="android", pass_context=True)
|
||||
async def role_android(self, ctx):
|
||||
"""Ajoute/retire le role 'android user'"""
|
||||
roles = ctx.message.author.roles
|
||||
role_id = []
|
||||
for role in roles:
|
||||
role_id.append(role.id)
|
||||
|
||||
user = ctx.message.author
|
||||
if self.ANDROID_ROLE in role_id:
|
||||
await user.remove_roles(discord.Object(id=self.ANDROID_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > How, me dit pas que tu as compris que les Android's allaient exterminer le monde ? <:trollface:375327667160875008>")
|
||||
else:
|
||||
await user.add_roles(discord.Object(id=self.ANDROID_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > Hey, un utilisateur d'Android, prêt à continuer l'extermination de WP et iOS ? <:stuck_out_tongue:343723077412323339>")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_role.command(name="bsd", pass_context=True)
|
||||
async def role_bsd(self, ctx):
|
||||
"""Ajoute/retire le role 'BSD user'"""
|
||||
roles = ctx.message.author.roles
|
||||
role_id = []
|
||||
for role in roles:
|
||||
role_id.append(role.id)
|
||||
|
||||
user = ctx.message.author
|
||||
if self.BSD_ROLE in role_id:
|
||||
await user.remove_roles(discord.Object(id=self.BSD_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > Ohhhh fait gaffe ou le démon va te piquer")
|
||||
else:
|
||||
await user.add_roles(discord.Object(id=self.BSD_ROLE))
|
||||
await ctx.send(ctx.message.author.mention + " > Quelqu'un sous BSD ! Au moins il a pas besoin de mettre GNU devant son OS à chaque fois :d")
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@_role.command(name="staff", pass_context=True, hidden=True)
|
||||
async def role_staff(self, ctx):
|
||||
"""Easter egg"""
|
||||
user = ctx.message.author
|
||||
await ctx.send(ctx.message.author.mention + " > Vous n'avez pas le rôle staff, tu crois quoi :joy:")
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Role(bot))
|
127
cogs/search.py
|
@ -1,12 +1,12 @@
|
|||
from discord.ext import commands
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import discord
|
||||
import urllib.request, json
|
||||
import wikipedia, bs4
|
||||
import asyncio
|
||||
import urllib.request
|
||||
import wikipedia
|
||||
|
||||
wikipedia.set_lang("fr")
|
||||
|
||||
|
||||
class Search:
|
||||
"""Commandes de WWW."""
|
||||
|
||||
|
@ -18,52 +18,62 @@ class Search:
|
|||
"""Rechercher sur le world wide web"""
|
||||
if ctx.invoked_subcommand is None:
|
||||
text = open('texts/search.md').read()
|
||||
em = discord.Embed(title='Commandes de search TuxBot', description=text, colour=0x89C4F9)
|
||||
em = discord.Embed(title='Commandes de search TuxBot',
|
||||
description=text,
|
||||
colour=0x89C4F9)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
|
||||
|
||||
|
||||
@_search.command(pass_context=True, name="docubuntu")
|
||||
async def search_docubuntu(self, ctx, args):
|
||||
attends = await ctx.send("_Je te cherche ça {} !_".format(ctx.message.author.mention))
|
||||
html = urllib.request.urlopen("https://doc.ubuntu-fr.org/" + args).read()
|
||||
attends = await ctx.send("_Je te cherche ça {} !_".format(
|
||||
ctx.message.author.mention))
|
||||
html = urllib.request.urlopen("https://doc.ubuntu-fr.org/" +
|
||||
args).read()
|
||||
if "avez suivi un lien" in str(html):
|
||||
await attends.edit(content=":sob: Nooooon ! Cette page n'existe pas, mais tu peux toujours la créer : https://doc.ubuntu-fr.org/"+ args)
|
||||
await attends.edit(content=":sob: Nooooon ! Cette page n'existe "
|
||||
"pas, mais tu peux toujours la créer : "
|
||||
"https://doc.ubuntu-fr.org/" + args)
|
||||
else:
|
||||
await attends.delete()
|
||||
embed = discord.Embed(description="Voila j'ai trouvé ! Voici la page ramenant à votre recherche, toujours aussi bien rédigée :wink: : https://doc.ubuntu-fr.org/" + args, url='http://doc.ubuntu-fr.org/')
|
||||
embed.set_author(name="DocUbuntu-Fr", url='http://doc.ubuntu-fr.org/', icon_url='http://outout.tech/tuxbot/ubuntu.png')
|
||||
embed.set_thumbnail(url='http://outout.tech/tuxbot/ubuntu.png')
|
||||
embed.set_footer(text="Merci à ceux qui ont pris le temps d'écrire cette documentation")
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@_search.command(pass_context=True, name="aur")
|
||||
async def search_aur(self, ctx, args):
|
||||
attends = await ctx.send("_Je te cherche ça {} !_".format(ctx.message.author.mention))
|
||||
erreur = 0
|
||||
try:
|
||||
html = urllib.request.urlopen("https://aur.archlinux.org/packages/" + args).read()
|
||||
except:
|
||||
erreur = 1
|
||||
|
||||
if erreur == 1:
|
||||
await attends.delete()
|
||||
embed = discord.Embed(description=":sob: Je n'ai pas trouvé le packet mais j'ai lancé une petite recherche, tu y trouveras peut être ton bonheur ? https://aur.archlinux.org/packages/?K=" + args,url='https://aur.archlinux.org/')
|
||||
embed.set_author(name="Aur.archlinux", url='https://aur.archlinux.org/', icon_url='http://outout.tech/tuxbot/arch.png')
|
||||
embed.set_thumbnail(url='http://outout.tech/tuxbot/arch.png')
|
||||
embed.set_footer(text="Pff même pas trouvé !")
|
||||
embed = discord.Embed(description="Voila j'ai trouvé ! Voici la "
|
||||
"page ramenant à votre recherche,"
|
||||
" toujours aussi bien rédigée "
|
||||
":wink: : https://doc.ubuntu-fr."
|
||||
"org/" + args,
|
||||
url='http://doc.ubuntu-fr.org/')
|
||||
embed.set_author(name="DocUbuntu-Fr",
|
||||
url='http://doc.ubuntu-fr.org/',
|
||||
icon_url='https://tuxbot.outout.xyz/data/ubuntu.png')
|
||||
embed.set_thumbnail(url='https://tuxbot.outout.xyz/data/ubuntu.png')
|
||||
embed.set_footer(text="Merci à ceux qui ont pris le temps d'écrire "
|
||||
"cette documentation")
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@_search.command(pass_context=True, name="docarch")
|
||||
async def search_docarch(self, ctx, args):
|
||||
attends = await ctx.send("_Je te cherche ça {} !_".format(
|
||||
ctx.message.author.mention))
|
||||
html = urllib.request.urlopen("https://wiki.archlinux.org/index.php/" +
|
||||
args).read()
|
||||
if "There is currently no text in this page" in str(html):
|
||||
await attends.edit(content=":sob: Nooooon ! Cette page n'existe "
|
||||
"pas.")
|
||||
else:
|
||||
await attends.delete()
|
||||
embed = discord.Embed(description="Et voila, j'ai trouvé la page sur le packet : https://aur.archlinux.org/packages/{0} ! \n Ca te dit un petit ``pacaur -S {0}`` ?".format(args), url='https://aur.archlinux.org/')
|
||||
embed.set_author(name="Aur.archlinux", url='https://aur.archlinux.org/', icon_url='http://outout.tech/tuxbot/arch.png')
|
||||
embed.set_thumbnail(url='http://outout.tech/tuxbot/arch.png')
|
||||
embed.set_footer(text="C'est vrai que pacman et pacaur sont mieux qu'APT ^^")
|
||||
embed = discord.Embed(description="Voila j'ai trouvé ! Voici la "
|
||||
"page ramenant à votre recherche,"
|
||||
" toujours aussi bien rédigée "
|
||||
":wink: : https://wiki.archlinux."
|
||||
"org/index.php/" + args,
|
||||
url='https://wiki.archlinux.org/index.php/')
|
||||
embed.set_author(name="Doc ArchLinux",
|
||||
url='https://wiki.archlinux.org/index.php/',
|
||||
icon_url='https://tuxbot.outout.xyz/data/arch.png')
|
||||
embed.set_thumbnail(url='https://tuxbot.outout.xyz/data/arch.png')
|
||||
embed.set_footer(text="Merci à ceux qui ont pris le temps d'écrire "
|
||||
"cette documentation")
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
||||
@_search.command(pass_context=True, name="wikipedia")
|
||||
async def search_wikipedia(self, ctx: commands.Context, args):
|
||||
"""Fait une recherche sur wikipd"""
|
||||
|
@ -77,17 +87,22 @@ class Search:
|
|||
nbmr = nbmr + 1
|
||||
mmssgg = mmssgg + "**{}**: {} \n".format(str(nbmr), value)
|
||||
|
||||
em = discord.Embed(title='Résultats de : ' + args, description = mmssgg, colour=0x4ECDC4)
|
||||
em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/commons/2/26/Paullusmagnus-logo_%28large%29.png")
|
||||
em = discord.Embed(title='Résultats de : ' + args,
|
||||
description = mmssgg,
|
||||
colour=0x4ECDC4)
|
||||
em.set_thumbnail(url="https://upload.wikimedia.org/wikipedia/commons/"
|
||||
"2/26/Paullusmagnus-logo_%28large%29.png")
|
||||
await wait.delete()
|
||||
|
||||
sending = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟"]
|
||||
|
||||
def check(reaction, user):
|
||||
return user == ctx.author and reaction.emoji in sending and reaction.message.id == msg.id
|
||||
return user == ctx.author and reaction.emoji in sending and \
|
||||
reaction.message.id == msg.id
|
||||
|
||||
async def waiter(future: asyncio.Future):
|
||||
reaction, user = await self.bot.wait_for('reaction_add', check=check)
|
||||
reaction, user = await self.bot.wait_for('reaction_add',
|
||||
check=check)
|
||||
future.set_result(reaction.emoji)
|
||||
|
||||
emoji = asyncio.Future()
|
||||
|
@ -109,19 +124,33 @@ class Search:
|
|||
try:
|
||||
await msg.delete()
|
||||
await ctx.trigger_typing()
|
||||
wait = await ctx.send(ctx.message.author.mention + " ah ok sympa cette recherche, je l'effectue de suite !")
|
||||
wait = await ctx.send(ctx.message.author.mention +
|
||||
" ah ok sympa cette recherche, je l'effectue de suite !")
|
||||
wp = wikipedia.page(args_)
|
||||
wp_contenu = wp.summary[:200] + "..."
|
||||
em = discord.Embed(title='Wikipedia : ' + wp.title, description = "{} \n_Lien_ : {} ".format(wp_contenu, wp.url), colour=0x9B59B6)
|
||||
em.set_author(name="Wikipedia", url='http://wikipedia.org', icon_url='https://upload.wikimedia.org/wikipedia/commons/2/26/Paullusmagnus-logo_%28large%29.png')
|
||||
em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/commons/2/26/Paullusmagnus-logo_%28large%29.png")
|
||||
em.set_footer(text="Merci à eux de nous fournir une encyclopédie libre !")
|
||||
em = discord.Embed(title='Wikipedia : ' + wp.title,
|
||||
description = "{} \n_Lien_ : {} ".format(
|
||||
wp_contenu, wp.url),
|
||||
colour=0x9B59B6)
|
||||
em.set_author(name="Wikipedia",
|
||||
url='http://wikipedia.org',
|
||||
icon_url='https://upload.wikimedia.org/wikipedia/'
|
||||
'commons/2/26/Paullusmagnus-logo_%28large'
|
||||
'%29.png')
|
||||
em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/"
|
||||
"commons/2/26/Paullusmagnus-logo_%28large"
|
||||
"%29.png")
|
||||
em.set_footer(text="Merci à eux de nous fournir une encyclopédie "
|
||||
"libre !")
|
||||
await wait.delete()
|
||||
await ctx.send(embed=em)
|
||||
|
||||
except wikipedia.exceptions.PageError: #TODO : A virer dans l'event on_error
|
||||
await ctx.send(":open_mouth: Une **erreur interne** est survenue, si cela ce reproduit contactez votre administrateur ou faites une Issue sur ``github`` !")
|
||||
|
||||
except wikipedia.exceptions.PageError:
|
||||
# TODO : A virer dans l'event on_error
|
||||
await ctx.send(":open_mouth: Une **erreur interne** est survenue,"
|
||||
" si cela ce reproduit contactez votre"
|
||||
" administrateur ou faites une Issue sur"
|
||||
" ``github`` !")
|
||||
|
||||
|
||||
def setup(bot):
|
||||
|
|
80
cogs/send_logs.py
Executable file
|
@ -0,0 +1,80 @@
|
|||
from discord.ext import commands
|
||||
import discord
|
||||
|
||||
import datetime, socket
|
||||
|
||||
class SendLogs:
|
||||
"""Send logs to a specific channel"""
|
||||
|
||||
def __init__(self, bot):
|
||||
|
||||
self.bot = bot
|
||||
self.log_channel = None
|
||||
self.main_server_id = int(self.bot.config.main_server_id)
|
||||
|
||||
async def on_resumed(self):
|
||||
em = discord.Embed(title="Et hop je me reconnecte à l'api 😃", colour=0x5cb85c)
|
||||
em.timestamp = datetime.datetime.utcnow()
|
||||
await self.log_channel.send(embed=em)
|
||||
|
||||
async def on_ready(self):
|
||||
self.log_channel = self.bot.get_channel(int(self.bot.config.log_channel_id))
|
||||
em = discord.Embed(title="Je suis opérationnel 😃", description=f"*Instance lancée sur {socket.gethostname()}*", colour=0x5cb85c)
|
||||
em.timestamp = datetime.datetime.utcnow()
|
||||
await self.log_channel.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
async def on_guild_join(self, guild: discord.Guild):
|
||||
em = discord.Embed(title=f"On m'a ajouté à : {str(guild.name)} 😃", colour=0x51A351)
|
||||
em.timestamp = datetime.datetime.utcnow()
|
||||
await self.log_channel.send(embed=em)
|
||||
|
||||
async def on_guild_remove(self, guild: discord.Guild):
|
||||
em = discord.Embed(title=f"On m'a viré de : {str(guild.name)} 😦", colour=0xBD362F)
|
||||
em.timestamp = datetime.datetime.utcnow()
|
||||
await self.log_channel.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
async def on_member_join(self, member):
|
||||
if member.guild.id == self.main_server_id:
|
||||
em = discord.Embed(title=f"{str(member)} *`({str(member.id)})`* nous a rejoint 😃", colour=0x51A351)
|
||||
em.set_footer(text="Compte crée le " + str(member.created_at), )
|
||||
em.timestamp = datetime.datetime.utcnow()
|
||||
await self.log_channel.send(embed=em)
|
||||
|
||||
async def on_member_remove(self, member):
|
||||
if member.guild.id == self.main_server_id:
|
||||
em = discord.Embed(title=f"{str(member)} *`({str(member.id)})`* nous a quitter 😦", colour=0xBD362F)
|
||||
em.timestamp = datetime.datetime.utcnow()
|
||||
await self.log_channel.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
async def on_message_delete(self, message):
|
||||
if message.guild.id == self.main_server_id and not message.author.bot:
|
||||
async def is_a_command(message):
|
||||
prefix_lenght = len(await self.bot.get_prefix(message))
|
||||
command = (message.content.split()[0])[prefix_lenght:]
|
||||
if command == '':
|
||||
command = "not_a_command"
|
||||
|
||||
return self.bot.get_command(str(command))
|
||||
|
||||
if await is_a_command(message) is None:
|
||||
em = discord.Embed(title=f"Message supprimé dans : {str(message.channel.name)}", colour=0xBD362F)
|
||||
em.add_field(name=f"{str(message.author)} *`({str(message.author.id)})`* a supprimé :", value=str(message.content))
|
||||
em.timestamp = datetime.datetime.utcnow()
|
||||
await self.log_channel.send(embed=em)
|
||||
|
||||
async def on_message_edit(self, before, after):
|
||||
if before.guild.id == self.main_server_id and not before.author.bot:
|
||||
em = discord.Embed(title="Message edité dans : " + str(before.channel.name), colour=0x0088CC)
|
||||
em.add_field(name=f"{str(before.author)} *`({str(before.author.id)})`* a edité :", value=str(before.content))
|
||||
em.add_field(name="Pour remplacer par :", value=str(after.content))
|
||||
em.timestamp = datetime.datetime.utcnow()
|
||||
await self.log_channel.send(embed=em)
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(SendLogs(bot))
|
109
cogs/sondage.py
Executable file
|
@ -0,0 +1,109 @@
|
|||
from discord.ext import commands
|
||||
import discord
|
||||
import random
|
||||
import asyncio
|
||||
import datetime
|
||||
|
||||
|
||||
class Sondage:
|
||||
"""Commandes sondage."""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
async def sondage(self, ctx, *, msg="help"):
|
||||
if msg != "help":
|
||||
await ctx.message.delete()
|
||||
options = msg.split(" | ")
|
||||
time = [x for x in options if x.startswith("time=")]
|
||||
if time:
|
||||
time = time[0]
|
||||
if time:
|
||||
options.remove(time)
|
||||
if len(options) <= 1:
|
||||
raise commands.errors.MissingRequiredArgument
|
||||
if len(options) >= 21:
|
||||
return await ctx.send(ctx.message.author.mention + "> :octagonal_sign: Vous ne pouvez pas mettre plus de 20 réponses !")
|
||||
if time:
|
||||
time = int(time.strip("time="))
|
||||
else:
|
||||
time = 0
|
||||
emoji = ['1⃣',
|
||||
'2⃣',
|
||||
'3⃣',
|
||||
'4⃣',
|
||||
'5⃣',
|
||||
'6⃣',
|
||||
'7⃣',
|
||||
'8⃣',
|
||||
'9⃣',
|
||||
'🔟',
|
||||
'0⃣',
|
||||
'🇦',
|
||||
'🇧',
|
||||
'🇨',
|
||||
'🇩',
|
||||
'🇪',
|
||||
'🇫',
|
||||
'🇬',
|
||||
'🇭',
|
||||
'🇮'
|
||||
]
|
||||
to_react = []
|
||||
confirmation_msg = "**{}?**:\n\n".format(options[0].rstrip("?"))
|
||||
for idx, option in enumerate(options[1:]):
|
||||
confirmation_msg += "{} - {}\n".format(emoji[idx], option)
|
||||
to_react.append(emoji[idx])
|
||||
confirmation_msg += "*Sondage proposé par* " + \
|
||||
str(ctx.message.author.mention)
|
||||
if time == 0:
|
||||
confirmation_msg += ""
|
||||
else:
|
||||
confirmation_msg += "\n\nVous avez {} secondes pour voter!".\
|
||||
format(time)
|
||||
poll_msg = await ctx.send(confirmation_msg)
|
||||
for emote in to_react:
|
||||
await poll_msg.add_reaction(emote)
|
||||
|
||||
if time != 0:
|
||||
await asyncio.sleep(time)
|
||||
|
||||
if time != 0:
|
||||
async for message in ctx.message.channel.history():
|
||||
if message.id == poll_msg.id:
|
||||
poll_msg = message
|
||||
results = {}
|
||||
for reaction in poll_msg.reactions:
|
||||
if reaction.emoji in to_react:
|
||||
results[reaction.emoji] = reaction.count - 1
|
||||
end_msg = "Le sondage est términé. Les résultats sont:\n\n"
|
||||
for result in results:
|
||||
end_msg += "{} {} - {} votes\n".\
|
||||
format(result,
|
||||
options[emoji.index(result)+1],
|
||||
results[result])
|
||||
top_result = max(results, key=lambda key: results[key])
|
||||
if len([x for x in results
|
||||
if results[x] == results[top_result]]) > 1:
|
||||
top_results = []
|
||||
for key, value in results.items():
|
||||
if value == results[top_result]:
|
||||
top_results.append(options[emoji.index(key)+1])
|
||||
end_msg += "\nLes gagnants sont : {}".\
|
||||
format(", ".join(top_results))
|
||||
else:
|
||||
top_result = options[emoji.index(top_result)+1]
|
||||
end_msg += "\n\"{}\" est le gagnant!".format(top_result)
|
||||
await ctx.send(end_msg)
|
||||
else:
|
||||
await ctx.message.delete()
|
||||
|
||||
text = open('texts/rpoll.md').read()
|
||||
em = discord.Embed(title='Aide sur le sondage',
|
||||
description=text,
|
||||
colour=0xEEEEEE)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Sondage(bot))
|
334
cogs/utility.py
|
@ -1,16 +1,12 @@
|
|||
from discord.ext import commands
|
||||
from random import choice, shuffle
|
||||
import random
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import time
|
||||
import discord
|
||||
import urllib.request, json
|
||||
import random
|
||||
import json
|
||||
import datetime, pytz
|
||||
|
||||
from datetime import date
|
||||
import calendar
|
||||
|
||||
import requests
|
||||
import urllib
|
||||
|
||||
|
||||
class Utility:
|
||||
|
@ -19,82 +15,168 @@ class Utility:
|
|||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command()
|
||||
async def clock(self, ctx, args):
|
||||
@commands.group(name="clock", pass_context=True, case_insensitive=True)
|
||||
async def clock(self, ctx):
|
||||
"""Display hour in a country"""
|
||||
args = args.upper()
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
text = open('texts/clocks.md').read()
|
||||
em = discord.Embed(title='Liste des Horloges', description=text, colour=0xEEEEEE)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@clock.command(name="montréal", aliases=["mtl", "montreal"], pass_context=True)
|
||||
async def clock_montreal(self, ctx):
|
||||
then = datetime.datetime.now(pytz.utc)
|
||||
form = '%H heures %M'
|
||||
try:
|
||||
argument = args[1]
|
||||
if args == "MONTREAL":
|
||||
|
||||
utc = then.astimezone(pytz.timezone('America/Montreal'))
|
||||
site = "http://ville.montreal.qc.ca/"
|
||||
img = "https://upload.wikimedia.org/wikipedia/commons/e/e0/Rentier_fws_1.jpg"
|
||||
country = "au Canada, Québec"
|
||||
description = "Montréal est la deuxième ville la plus peuplée du Canada. Elle se situe dans la région du Québec"
|
||||
elif args == "VANCOUVER":
|
||||
|
||||
form = '%H heures %M'
|
||||
tt = utc.strftime(form)
|
||||
|
||||
em = discord.Embed(title='Heure à Montréal', description=f"A [Montréal]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
|
||||
em.set_thumbnail(url = img)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@clock.command(name="vancouver", pass_context=True)
|
||||
async def clock_vancouver(self, ctx):
|
||||
then = datetime.datetime.now(pytz.utc)
|
||||
|
||||
utc = then.astimezone(pytz.timezone('America/Vancouver'))
|
||||
site = "http://vancouver.ca/"
|
||||
img = "https://upload.wikimedia.org/wikipedia/commons/f/fe/Dock_Vancouver.JPG"
|
||||
country = "au Canada"
|
||||
description = "Vancouver, officiellement City of Vancouver, est une cité portuaire au Canada"
|
||||
elif args == "NEW-YORK" or args == "N-Y":
|
||||
|
||||
form = '%H heures %M'
|
||||
tt = utc.strftime(form)
|
||||
|
||||
em = discord.Embed(title='Heure à Vancouver', description=f"A [Vancouver]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
|
||||
em.set_thumbnail(url = img)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@clock.command(name="new-york",aliases=["ny", "n-y", "new york"], pass_context=True)
|
||||
async def clock_new_york(self, ctx):
|
||||
then = datetime.datetime.now(pytz.utc)
|
||||
|
||||
utc = then.astimezone(pytz.timezone('America/New_York'))
|
||||
site = "http://www1.nyc.gov/"
|
||||
img = "https://upload.wikimedia.org/wikipedia/commons/e/e3/NewYork_LibertyStatue.jpg"
|
||||
country = "aux U.S.A."
|
||||
description = "New York, est la plus grande ville des États-Unis en termes d'habitants et l'une des plus importantes du continent américain. "
|
||||
elif args == "LOSANGELES" or args == "L-A" or args == "LA" or args == "LACITY":
|
||||
|
||||
form = '%H heures %M'
|
||||
tt = utc.strftime(form)
|
||||
|
||||
em = discord.Embed(title='Heure à New York', description=f"A [str(New York]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
|
||||
em.set_thumbnail(url = img)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@clock.command(name="la", aliases=["los-angeles", "losangeles", "l-a", "los angeles"], pass_context=True)
|
||||
async def clock_la(self, ctx):
|
||||
then = datetime.datetime.now(pytz.utc)
|
||||
|
||||
utc = then.astimezone(pytz.timezone('America/Los_Angeles'))
|
||||
site = "https://www.lacity.org/"
|
||||
img = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/LA_Skyline_Mountains2.jpg/800px-LA_Skyline_Mountains2.jpg"
|
||||
country = "aux U.S.A."
|
||||
description = "Los Angeles est la deuxième ville la plus peuplée des États-Unis après New York. Elle est située dans le sud de l'État de Californie, sur la côte pacifique."
|
||||
elif args == "PARIS":
|
||||
|
||||
form = '%H heures %M'
|
||||
tt = utc.strftime(form)
|
||||
|
||||
em = discord.Embed(title='Heure à Los Angeles', description=f"A [Los Angeles]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
|
||||
em.set_thumbnail(url = img)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@clock.command(name="paris", aliases=["baguette"],pass_context=True)
|
||||
async def clock_paris(self, ctx):
|
||||
then = datetime.datetime.now(pytz.utc)
|
||||
|
||||
utc = then.astimezone(pytz.timezone('Europe/Paris'))
|
||||
site = "http://www.paris.fr/"
|
||||
img = "https://upload.wikimedia.org/wikipedia/commons/a/af/Tour_eiffel_at_sunrise_from_the_trocadero.jpg"
|
||||
country = "en France"
|
||||
description = "Paris est la capitale de la France. Elle se situe au cœur d'un vaste bassin sédimentaire aux sols fertiles et au climat tempéré, le bassin parisien."
|
||||
elif args == "BERLIN":
|
||||
|
||||
form = '%H heures %M'
|
||||
tt = utc.strftime(form)
|
||||
|
||||
em = discord.Embed(title='Heure à Paris', description=f"A [Paris]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
|
||||
em.set_thumbnail(url = img)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@clock.command(name="berlin", pass_context=True)
|
||||
async def clock_berlin(self, ctx):
|
||||
then = datetime.datetime.now(pytz.utc)
|
||||
|
||||
utc = then.astimezone(pytz.timezone('Europe/Berlin'))
|
||||
site = "http://www.berlin.de/"
|
||||
img = "https://upload.wikimedia.org/wikipedia/commons/9/91/Eduard_Gaertner_Schlossfreiheit.jpg"
|
||||
country = "en Allemagne"
|
||||
description = "Berlin est la capitale et la plus grande ville d'Allemagne. Située dans le nord-est du pays, elle compte environ 3,5 millions d'habitants. "
|
||||
elif args == "BERN" or args == "ZURICH" or args == "BERNE":
|
||||
|
||||
form = '%H heures %M'
|
||||
tt = utc.strftime(form)
|
||||
|
||||
em = discord.Embed(title='Heure à Berlin', description=f"A [Berlin]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
|
||||
em.set_thumbnail(url = img)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@clock.command(name="berne", aliases=["zurich", "bern"], pass_context=True)
|
||||
async def clock_berne(self, ctx):
|
||||
then = datetime.datetime.now(pytz.utc)
|
||||
|
||||
utc = then.astimezone(pytz.timezone('Europe/Zurich'))
|
||||
site = "http://www.berne.ch/"
|
||||
img = "https://upload.wikimedia.org/wikipedia/commons/d/db/Justitia_Statue_02.jpg"
|
||||
country = "en Suisse"
|
||||
description = "Berne est la cinquième plus grande ville de Suisse et la capitale du canton homonyme. Depuis 1848, Berne est la « ville fédérale »."
|
||||
elif args == "TOKYO":
|
||||
|
||||
form = '%H heures %M'
|
||||
tt = utc.strftime(form)
|
||||
|
||||
em = discord.Embed(title='Heure à Berne', description=f"A [Berne]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
|
||||
em.set_thumbnail(url = img)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@clock.command(name="tokyo", pass_context=True)
|
||||
async def clock_tokyo(self, ctx):
|
||||
then = datetime.datetime.now(pytz.utc)
|
||||
|
||||
utc = then.astimezone(pytz.timezone('Asia/Tokyo'))
|
||||
site = "http://www.gotokyo.org/"
|
||||
img = "https://upload.wikimedia.org/wikipedia/commons/3/37/TaroTokyo20110213-TokyoTower-01.jpg"
|
||||
country = "au Japon"
|
||||
description = "Tokyo, anciennement Edo, officiellement la préfecture métropolitaine de Tokyo, est la capitale du Japon."
|
||||
elif args == "MOSCOU":
|
||||
|
||||
form = '%H heures %M'
|
||||
tt = utc.strftime(form)
|
||||
|
||||
em = discord.Embed(title='Heure à Tokyo', description=f"A [Tokyo]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
|
||||
em.set_thumbnail(url = img)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
@clock.command(name="moscou", aliases=["moscow", "moskova"], pass_context=True)
|
||||
async def clock_moscou(self, ctx):
|
||||
then = datetime.datetime.now(pytz.utc)
|
||||
|
||||
utc = then.astimezone(pytz.timezone('Europe/Moscow'))
|
||||
site = "https://www.mos.ru/"
|
||||
img = "https://upload.wikimedia.org/wikipedia/commons/f/f7/Andreyevsky_Zal.jpg"
|
||||
country = "en Russie"
|
||||
description = "Moscou est la capitale de la Fédération de Russie et la plus grande ville d'Europe. Moscou est situé sur la rivière Moskova. "
|
||||
try:
|
||||
if args == "LIST":
|
||||
text = open('texts/clocks.md').read()
|
||||
em = discord.Embed(title='Liste des Horloges', description=text, colour=0xEEEEEE)
|
||||
await ctx.send(embed=em)
|
||||
else:
|
||||
|
||||
form = '%H heures %M'
|
||||
tt = utc.strftime(form)
|
||||
em = discord.Embed(title='Heure à ' + args.title(), description="A [{}]({}) {}, Il est **{}** ! \n {} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_".format(str(args), site, str(country), str(tt), str(description)), colour=0xEEEEEE)
|
||||
|
||||
em = discord.Embed(title='Heure à Moscou', description=f"A [Moscou]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
|
||||
em.set_thumbnail(url = img)
|
||||
await ctx.send(embed=em)
|
||||
except UnboundLocalError:
|
||||
await ctx.send("[**Erreur**] Ville inconnue, faites ``.clock list`` pour obtenir la liste des villes")
|
||||
except IndexError:
|
||||
await ctx.send("[**Erreur**] Ville inconnue, faites ``.clock list`` pour obtenir la liste des villes")
|
||||
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
|
@ -107,112 +189,14 @@ class Utility:
|
|||
clef = str(random.randint(0,12))
|
||||
chaine = ytb["{}".format(clef)]
|
||||
|
||||
embed = discord.Embed(title=chaine['name'], url=chaine['url'],
|
||||
description="**{}**, {} \n[Je veux voir ça]({})".format(chaine['name'], chaine['desc'], chaine['url']))
|
||||
embed = discord.Embed(title=chaine['name'],
|
||||
url=chaine['url'],
|
||||
description=f"**{chaine['name']}**, {chaine['desc']} \n[Je veux voir ça]({chaine['url']})")
|
||||
embed.set_thumbnail(url='https://outout.tech/tuxbot/yt.png')
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
async def afk(self, ctx):
|
||||
"""Away from keyboard"""
|
||||
msgs = ["s'absente de discord quelques instants", "se casse de son pc", "va sortir son chien", "reviens bientôt", "va nourrir son cochon", "va manger des cookies", "va manger de la poutine", "va faire caca", "va faire pipi"]
|
||||
msg = random.choice(msgs)
|
||||
|
||||
await ctx.send("**{}** {}...".format(ctx.message.author.mention, msg))
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
async def back(self, ctx):
|
||||
"""I'm back !"""
|
||||
msgs = ["a réssuscité", "est de nouveau parmi nous", "a fini de faire caca", "a fini d'urine", "n'est plus mort", "est de nouveau sur son PC", "a fini de manger sa poutine", "a fini de danser", "s'est réveillé", "est de retour dans ce monde cruel"]
|
||||
msg = random.choice(msgs)
|
||||
|
||||
await ctx.send("**{}** {} !".format(ctx.message.author.mention, msg))
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
async def sondage(self, ctx, *, msg):
|
||||
"""Create a poll using reactions. >help rpoll for more information.
|
||||
>rpoll <question> | <answer> | <answer> - Create a poll. You may use as many answers as you want, placing a pipe | symbol in between them.
|
||||
Example:
|
||||
>rpoll What is your favorite anime? | Steins;Gate | Naruto | Attack on Titan | Shrek
|
||||
You can also use the "time" flag to set the amount of time in seconds the poll will last for.
|
||||
Example:
|
||||
>rpoll What time is it? | HAMMER TIME! | SHOWTIME! | time=10
|
||||
"""
|
||||
await ctx.message.delete()
|
||||
options = msg.split(" | ")
|
||||
time = [x for x in options if x.startswith("time=")]
|
||||
if time:
|
||||
time = time[0]
|
||||
if time:
|
||||
options.remove(time)
|
||||
if len(options) <= 1:
|
||||
raise commands.errors.MissingRequiredArgument
|
||||
if len(options) >= 11:
|
||||
return await ctx.send("Vous ne pouvez mettre que 9 options de réponse ou moins.")
|
||||
if time:
|
||||
time = int(time.strip("time="))
|
||||
else:
|
||||
time = 0
|
||||
emoji = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣']
|
||||
to_react = []
|
||||
confirmation_msg = "**{}?**:\n\n".format(options[0].rstrip("?"))
|
||||
for idx, option in enumerate(options[1:]):
|
||||
confirmation_msg += "{} - {}\n".format(emoji[idx], option)
|
||||
to_react.append(emoji[idx])
|
||||
confirmation_msg += "*Sondage proposé par* "+str(ctx.message.author.mention)
|
||||
if time == 0:
|
||||
confirmation_msg += ""
|
||||
else:
|
||||
confirmation_msg += "\n\nVous avez {} secondes pour voter!".format(time)
|
||||
poll_msg = await ctx.send(confirmation_msg)
|
||||
for emote in to_react:
|
||||
await poll_msg.add_reaction(emote)
|
||||
|
||||
if time != 0:
|
||||
await asyncio.sleep(time)
|
||||
|
||||
if time != 0:
|
||||
async for message in ctx.message.channel.history():
|
||||
if message.id == poll_msg.id:
|
||||
poll_msg = message
|
||||
results = {}
|
||||
for reaction in poll_msg.reactions:
|
||||
if reaction.emoji in to_react:
|
||||
results[reaction.emoji] = reaction.count - 1
|
||||
end_msg = "Le sondage est términé. Les résultats sont:\n\n"
|
||||
for result in results:
|
||||
end_msg += "{} {} - {} votes\n".format(result, options[emoji.index(result)+1], results[result])
|
||||
top_result = max(results, key=lambda key: results[key])
|
||||
if len([x for x in results if results[x] == results[top_result]]) > 1:
|
||||
top_results = []
|
||||
for key, value in results.items():
|
||||
if value == results[top_result]:
|
||||
top_results.append(options[emoji.index(key)+1])
|
||||
end_msg += "\nLes gagnants sont : {}".format(", ".join(top_results))
|
||||
else:
|
||||
top_result = options[emoji.index(top_result)+1]
|
||||
end_msg += "\n\"{}\" est le gagnant!".format(top_result)
|
||||
await ctx.send(end_msg)
|
||||
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
async def sondage_aide(self, ctx):
|
||||
await ctx.message.delete()
|
||||
|
||||
text = open('texts/rpoll.md').read()
|
||||
em = discord.Embed(title='Aide sur le sondage', description=text, colour=0xEEEEEE)
|
||||
await ctx.send(embed=em)
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command(name='hastebin', pass_context=True)
|
||||
async def _hastebin(self, ctx, *, data):
|
||||
"""Poster sur Hastebin."""
|
||||
|
@ -221,22 +205,80 @@ class Utility:
|
|||
post = requests.post("https://hastebin.com/documents", data=data)
|
||||
|
||||
try:
|
||||
await ctx.send(str(ctx.message.author.mention)+" message posté avec succes sur :\nhttps://hastebin.com/{}.txt".format(post.json()["key"]))
|
||||
await ctx.send(f"{ctx.message.author.mention} message posté avec succès sur :\nhttps://hastebin.com/{post.json()['key']}.txt")
|
||||
except json.JSONDecodeError:
|
||||
await ctx.send("Impossible de poster ce message. L'API doit etre HS.")
|
||||
await ctx.send("Impossible de poster ce message. L'API doit être HS.")
|
||||
|
||||
@commands.command(name='test', pass_context=True)
|
||||
async def test(self, ctx):
|
||||
"""---------------------------------------------------------------------"""
|
||||
|
||||
date = datetime.datetime.now()
|
||||
@commands.command(name='iplocalise', pass_context=True)
|
||||
async def _iplocalise(self, ctx, ipaddress):
|
||||
"""Recup headers."""
|
||||
if ipaddress.startswith("http://"):
|
||||
ipaddress = ipaddress.split("http://")[1]
|
||||
if ipaddress.startswith("https://"):
|
||||
ipaddress = ipaddress.split("https://")[1]
|
||||
iploading = await ctx.send("_réfléchis..._")
|
||||
ipapi = urllib.request.urlopen("http://ip-api.com/json/" + ipaddress)
|
||||
ipinfo = json.loads(ipapi.read().decode())
|
||||
|
||||
nd = str(date.day)
|
||||
nd += "-"
|
||||
nd += str(date.month)
|
||||
nd += "-"
|
||||
nd += str(date.year)
|
||||
if ipinfo["status"] != "fail":
|
||||
await iploading.edit(content="L'adresse IP ``{query}`` appartient à ``{org}`` et se situe à ``{city}``, dans ``{regionName}``, ``{country}``.".format(**ipinfo))
|
||||
else:
|
||||
await iploading.edit(content=f"Erreur, impossible d'avoir des informations sur l'adresse IP {ipinfo['query']}")
|
||||
|
||||
await ctx.send(nd)
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
@commands.command(name='getheaders', pass_context=True)
|
||||
async def _getheaders(self, ctx, *, adresse):
|
||||
"""Recuperer les HEADERS :d"""
|
||||
print("Loaded")
|
||||
if adresse.startswith("http://") != True and adresse.startswith("https://") != True:
|
||||
adresse = "http://" + adresse
|
||||
if len(adresse) > 200:
|
||||
await ctx.send("{0} Essaye d'entrer une adresse de moins de 200 caractères plutôt.".format(ctx.author.mention))
|
||||
elif adresse.startswith("http://") or adresse.startswith("https://") or adresse.startswith("ftp://"):
|
||||
try:
|
||||
get = urllib.request.urlopen(adresse, timeout = 1)
|
||||
embed = discord.Embed(title="Entêtes de {0}".format(adresse), color=0xd75858)
|
||||
embed.add_field(name="Code Réponse", value=get.getcode(), inline = True)
|
||||
embed.set_thumbnail(url="https://http.cat/{}".format(str(get.getcode())))
|
||||
if get.getheader('location'):
|
||||
embed.add_field(name="Redirection vers", value=get.getheader('location'), inline=True)
|
||||
if get.getheader('server'):
|
||||
embed.add_field(name="Serveur", value=get.getheader('server'), inline=True)
|
||||
if get.getheader('content-type'):
|
||||
embed.add_field(name="Type de contenu", value = get.getheader('content-type'), inline = True)
|
||||
if get.getheader('x-content-type-options'):
|
||||
embed.add_field(name="x-content-type", value= get.getheader('x-content-type-options'), inline=True)
|
||||
if get.getheader('x-frame-options'):
|
||||
embed.add_field(name="x-frame-options", value= get.getheader('x-frame-options'), inline=True)
|
||||
if get.getheader('cache-control'):
|
||||
embed.add_field(name="Controle du cache", value = get.getheader('cache-control'), inline = True)
|
||||
await ctx.send(embed=embed)
|
||||
except urllib.error.HTTPError as e:
|
||||
embed = discord.Embed(title="Entêtes de {0}".format(adresse), color=0xd75858)
|
||||
embed.add_field(name="Code Réponse", value=e.getcode(), inline = True)
|
||||
embed.set_thumbnail(url="https://http.cat/{}".format(str(e.getcode())))
|
||||
await ctx.send(embed=embed)
|
||||
print('''An error occurred: {} The response code was {}'''.format(e, e.getcode()))
|
||||
except urllib.error.URLError as e:
|
||||
print("ERROR @ getheaders @ urlerror : {} - adress {}".format(e, adresse))
|
||||
await ctx.send('[CONTACTER ADMIN] URLError: {}'.format(e.reason))
|
||||
except Exception as e:
|
||||
print("ERROR @ getheaders @ Exception : {} - adress {}".format(e, adresse))
|
||||
await ctx.send("{0} Impossible d'accèder à {1}, es-tu sur que l'adresse {1} est correcte et que le serveur est allumé ?".format(ctx.author.mention, adresse))
|
||||
else:
|
||||
await ctx.send("{0} Merci de faire commencer {1} par ``https://``, ``http://`` ou ``ftp://``.".format(ctx.message.author.mention, adresse))
|
||||
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
@commands.command(name='github', pass_context=True)
|
||||
async def _github(ctx):
|
||||
"""Pour voir mon code"""
|
||||
text = "How tu veux voir mon repos Github pour me disséquer ? Pas de soucis ! Je suis un Bot, je ne ressens pas la douleur !\n https://github.com/outout14/tuxbot-bot"
|
||||
em = discord.Embed(title='Repos TuxBot-Bot', description=text, colour=0xE9D460)
|
||||
em.set_author(name='Outout', icon_url="https://avatars0.githubusercontent.com/u/14958554?v=3&s=400")
|
||||
await ctx.send(embed=em)
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Utility(bot))
|
||||
|
|
|
@ -1,75 +1,101 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import discord.utils
|
||||
from discord.ext import commands
|
||||
|
||||
|
||||
def is_owner_check(message): # OUTOUT id RICK id L4P1N id GIGA id FLAYOR id ROMAIN id
|
||||
owner = str(message.author.id) in ['171685542553976832', '163697401935298560', '88644904112128000', '92619860521005056', '273757386127441920', '269156684155453451'] ###ID's modo & admin
|
||||
rights = str(message.author.top_role.name).upper() in ['ADMIN', 'ADMINISTRATEURS', 'ADMINISTRATEUR', 'MODO', 'MODÉRATEUR', 'MODÉRATEURS', 'MODERATEUR', 'MODERATEURS']
|
||||
if rights == True or owner == True:
|
||||
return True # Owner of the bot
|
||||
else:
|
||||
return False
|
||||
def is_owner_check(message):
|
||||
return str(message.author.id) in ['171685542553976832', '269156684155453451']
|
||||
|
||||
def is_owner(warn=True):
|
||||
def check(ctx, warn):
|
||||
owner = is_owner_check(ctx.message)
|
||||
if not owner and warn:
|
||||
print(ctx.message.author.name + " à essayer d'executer " + ctx.message.content)
|
||||
print(ctx.message.author.name + " à essayer d'executer " + ctx.message.content + " sur le serveur " + ctx.message.guild.name)
|
||||
return owner
|
||||
|
||||
owner = commands.check(lambda ctx: check(ctx, warn))
|
||||
return owner
|
||||
|
||||
def check_permissions(ctx, perms):
|
||||
msg = ctx.message
|
||||
if is_owner_check(msg):
|
||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
async def check_permissions(ctx, perms, *, check=all):
|
||||
is_owner = await ctx.bot.is_owner(ctx.author)
|
||||
if is_owner or is_owner_check(ctx.message) == True:
|
||||
return True
|
||||
|
||||
ch = msg.channel
|
||||
author = msg.author
|
||||
resolved = ch.permissions_for(author)
|
||||
return all(getattr(resolved, name, None) == value for name, value in perms.items())
|
||||
resolved = ctx.channel.permissions_for(ctx.author)
|
||||
return check(getattr(resolved, name, None) == value for name, value in perms.items())
|
||||
|
||||
def has_permissions(*, check=all, **perms):
|
||||
async def pred(ctx):
|
||||
return await check_permissions(ctx, perms, check=check)
|
||||
return commands.check(pred)
|
||||
|
||||
def role_or_permissions(ctx, check, **perms):
|
||||
if check_permissions(ctx, perms):
|
||||
async def check_guild_permissions(ctx, perms, *, check=all):
|
||||
is_owner = await ctx.bot.is_owner(ctx.author)
|
||||
if is_owner:
|
||||
return True
|
||||
|
||||
ch = ctx.message.channel
|
||||
author = ctx.message.author
|
||||
if ch.is_private:
|
||||
return False # can't have roles in PMs
|
||||
|
||||
role = discord.utils.find(check, author.roles)
|
||||
return role is not None
|
||||
|
||||
|
||||
def admin_or_permissions(**perms):
|
||||
def predicate(ctx):
|
||||
return role_or_permissions(ctx, lambda r: r.name == 'Bot Admin', **perms)
|
||||
|
||||
return commands.check(predicate)
|
||||
|
||||
|
||||
def is_in_servers(*server_ids):
|
||||
def predicate(ctx):
|
||||
server = ctx.message.server
|
||||
if server is None:
|
||||
if ctx.guild is None:
|
||||
return False
|
||||
return server.id in server_ids
|
||||
|
||||
return commands.check(predicate)
|
||||
resolved = ctx.author.guild_permissions
|
||||
return check(getattr(resolved, name, None) == value for name, value in perms.items())
|
||||
|
||||
def embed_perms(message):
|
||||
try:
|
||||
check = message.author.permissions_in(message.channel).embed_links
|
||||
except:
|
||||
check = True
|
||||
def has_guild_permissions(*, check=all, **perms):
|
||||
async def pred(ctx):
|
||||
return await check_guild_permissions(ctx, perms, check=check)
|
||||
return commands.check(pred)
|
||||
|
||||
return check
|
||||
# These do not take channel overrides into account
|
||||
|
||||
def is_mod():
|
||||
async def pred(ctx):
|
||||
return await check_guild_permissions(ctx, {'manage_guild': True})
|
||||
return commands.check(pred)
|
||||
|
||||
def is_admin():
|
||||
async def pred(ctx):
|
||||
return await check_guild_permissions(ctx, {'administrator': True})
|
||||
return commands.check(pred)
|
||||
|
||||
def mod_or_permissions(**perms):
|
||||
perms['manage_guild'] = True
|
||||
async def predicate(ctx):
|
||||
return await check_guild_permissions(ctx, perms, check=any)
|
||||
return commands.check(predicate)
|
||||
|
||||
def admin_or_permissions(**perms):
|
||||
perms['administrator'] = True
|
||||
async def predicate(ctx):
|
||||
return await check_guild_permissions(ctx, perms, check=any)
|
||||
return commands.check(predicate)
|
||||
|
||||
def is_in_guilds(*guild_ids):
|
||||
def predicate(ctx):
|
||||
guild = ctx.guild
|
||||
if guild is None:
|
||||
return False
|
||||
return guild.id in guild_ids
|
||||
return commands.check(predicate)
|
||||
|
||||
def is_lounge_cpp():
|
||||
return is_in_guilds(145079846832308224)
|
||||
|
||||
def get_user(message, user):
|
||||
try:
|
||||
member = message.mentions[0]
|
||||
except:
|
||||
member = message.guild.get_member_named(user)
|
||||
if not member:
|
||||
try:
|
||||
member = message.guild.get_member(int(user))
|
||||
except ValueError:
|
||||
pass
|
||||
if not member:
|
||||
return None
|
||||
return member
|
||||
|
||||
def check_date(date: str):
|
||||
if len(date) == 1:
|
||||
return f"0{date}"
|
||||
else:
|
||||
return date
|
43
cogs/utils/cli_colors.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
class text_colors:
|
||||
BLACK = '\033[30m'
|
||||
RED = '\033[31m'
|
||||
GREEN = '\033[32m'
|
||||
YELLOW = '\033[33m'
|
||||
BLUE = '\033[34m'
|
||||
MAGENTA = '\033[35m'
|
||||
CYAN = '\033[36m'
|
||||
LIGHT_GRAY = '\033[37m'
|
||||
DARK_GRAY = '\033[90m'
|
||||
LIGHT_RED = '\033[91m'
|
||||
LIGHT_GREEN = '\033[92m'
|
||||
LIGHT_YELLOW = '\033[93m'
|
||||
LIGHT_BLUE = '\033[94m'
|
||||
LIGHT_MAGENTA = '\033[95m'
|
||||
LIGHT_CYAN = '\033[96m'
|
||||
WHITE = '\033[97m'
|
||||
|
||||
class bg_colors:
|
||||
BLACK = '\033[40m'
|
||||
RED = '\033[41m'
|
||||
GREEN = '\033[42m'
|
||||
YELLOW = '\033[43m'
|
||||
BLUE = '\033[44m'
|
||||
MAGENTA = '\033[45m'
|
||||
CYAN = '\033[46m'
|
||||
LIGHT_GRAY = '\033[47m'
|
||||
DARK_GRAY = '\033[100m'
|
||||
LIGHT_RED = '\033[101m'
|
||||
LIGHT_GREEN = '\033[102m'
|
||||
LIGHT_YELLOW = '\033[103m'
|
||||
LIGHT_BLUE = '\033[104m'
|
||||
LIGHT_MAGENTA = '\033[105m'
|
||||
LIGHT_CYAN = '\033[106m'
|
||||
WHITE = '\033[107m'
|
||||
|
||||
class text_style:
|
||||
BOLD = '\033[1m'
|
||||
DIM = '\033[2m'
|
||||
UNDERLINE = '\033[4m'
|
||||
BLINK = '\033[5m'
|
||||
|
||||
ENDC = '\033[0m'
|
24
cogs/utils/db.py
Executable file
|
@ -0,0 +1,24 @@
|
|||
import pymysql
|
||||
|
||||
def connect_to_db(self):
|
||||
mysqlHost = self.bot.config.mysql["host"]
|
||||
mysqlUser = self.bot.config.mysql["username"]
|
||||
mysqlPass = self.bot.config.mysql["password"]
|
||||
mysqlDB = self.bot.config.mysql["dbname"]
|
||||
|
||||
try:
|
||||
return pymysql.connect(host=mysqlHost, user=mysqlUser, passwd=mysqlPass, db=mysqlDB, charset='utf8')
|
||||
except KeyError:
|
||||
print("Rest in peperoni, Impossible de se connecter a la base de données.")
|
||||
print(str(KeyError))
|
||||
return
|
||||
|
||||
def reconnect_to_db(self):
|
||||
if not self.conn:
|
||||
mysqlHost = self.bot.config.mysql["host"]
|
||||
mysqlUser = self.bot.config.mysql["username"]
|
||||
mysqlPass = self.bot.config.mysql["password"]
|
||||
mysqlDB = self.bot.config.mysql["dbname"]
|
||||
|
||||
return pymysql.connect(host=mysqlHost, user=mysqlUser, passwd=mysqlPass, db=mysqlDB, charset='utf8')
|
||||
return self.conn
|
245
cogs/utils/passport_generator.py
Normal file
|
@ -0,0 +1,245 @@
|
|||
from PIL import Image
|
||||
from PIL import ImageOps
|
||||
from PIL import ImageDraw
|
||||
from PIL import ImageFont
|
||||
|
||||
from .checks import check_date
|
||||
import aiohttp, imghdr, textwrap, math, datetime
|
||||
|
||||
async def generate_passport(self, user, theme: str = None):
|
||||
name = user.name
|
||||
userid = user.id
|
||||
avatar = user.avatar_url
|
||||
def_avatar = user.default_avatar_url
|
||||
created = datetime.datetime.fromisoformat(str(user.created_at))
|
||||
nick = user.display_name
|
||||
discr = user.discriminator
|
||||
roles = user.roles
|
||||
|
||||
top_role_color = str(user.top_role.color)[1:]
|
||||
user_color = tuple(int(top_role_color[i:i+2], 16) for i in (0, 2 ,4))
|
||||
user_color += (255,)
|
||||
|
||||
color = {
|
||||
"dark": {
|
||||
"background": 39,
|
||||
"question": 220,
|
||||
"answer": 150
|
||||
},
|
||||
"light": {
|
||||
"background": 216,
|
||||
"question": 35,
|
||||
"answer": 61
|
||||
}
|
||||
}
|
||||
|
||||
user_birth_day = check_date(str(created.day))
|
||||
user_birth_month = check_date(str(created.month))
|
||||
|
||||
formated_user_birth = str(user_birth_day) + "/" + str(user_birth_month) + "/" + str(created.year)
|
||||
formated_passportdate = "n/a"
|
||||
|
||||
roleImages = {}
|
||||
|
||||
def draw_underlined_text(draw, pos, text, font, **options):
|
||||
twidth, theight = draw.textsize(text, font=font)
|
||||
lx, ly = pos[0], pos[1] + theight
|
||||
draw.text(pos, text, font=font, **options)
|
||||
draw.line((lx, ly, lx + twidth, ly), **options)
|
||||
|
||||
def break_line(draw, pos, text, font, **options):
|
||||
lines = text.split("\n")
|
||||
current_y = pos[1]
|
||||
for line in lines:
|
||||
twidth, theight = draw.textsize(line, font=font)
|
||||
lx, ly = pos[0], current_y
|
||||
if textwrap.fill(line, 60) == line:
|
||||
draw.text((lx, ly), textwrap.fill(line, 60), font=font, **options)
|
||||
current_y += math.floor(theight)
|
||||
else:
|
||||
draw.text((lx, ly), textwrap.fill(line, 60), font=font, **options)
|
||||
current_y += math.floor(theight*2)
|
||||
|
||||
for x, role in enumerate(roles):
|
||||
try:
|
||||
roleImages[role.name] = Image.open(f"data/images/roles/small/{role.name.lower().replace(' user', '')}.png")
|
||||
except Exception as e:
|
||||
next
|
||||
|
||||
if avatar == '':
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(def_avatar) as r:
|
||||
image = await r.content.read()
|
||||
else:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(avatar) as r:
|
||||
image = await r.content.read()
|
||||
with open('data/users/avatars/{}.png'.format(user.id), 'wb') as f:
|
||||
f.write(image)
|
||||
|
||||
checked = False
|
||||
|
||||
while checked == False:
|
||||
checks = 0
|
||||
isImage = imghdr.what('data/users/avatars/{}.png'.format(user.id))
|
||||
|
||||
if checks > 4:
|
||||
checked = True
|
||||
|
||||
if isImage != 'None':
|
||||
checked = True
|
||||
else:
|
||||
checks += 1
|
||||
|
||||
av = Image.open('data/users/avatars/{}.png'.format(user.id))
|
||||
userAvatar = av.resize((128, 128), resample=Image.BILINEAR).convert('RGBA')
|
||||
maxsize = ( 800, 500)
|
||||
try:
|
||||
bg = Image.open('data/users/backgrounds/{0}.png'.format(user.id))
|
||||
bg_width, bg_height = bg.size
|
||||
|
||||
bg = ImageOps.fit(bg,maxsize)
|
||||
|
||||
except:
|
||||
bg = Image.open('data/images/background_default.png')
|
||||
|
||||
fontFace = 'data/fonts/{}'.format(self.bot.config.fonts['normal'])
|
||||
fontFace_bold = 'data/fonts/{}'.format(self.bot.config.fonts['bold'])
|
||||
|
||||
fontSize = 18
|
||||
fontSizeVeryTiny = 16
|
||||
|
||||
descSizeQuestion = 10
|
||||
descSizeAnswer = 10
|
||||
|
||||
headerSize = 32
|
||||
headerSizeTiny = 24
|
||||
headerSizeVeryTiny = 16
|
||||
|
||||
header_font = ImageFont.truetype(fontFace_bold, headerSize)
|
||||
header_font_tiny = ImageFont.truetype(fontFace_bold, headerSizeTiny)
|
||||
header_font_very_tiny = ImageFont.truetype(fontFace_bold, headerSizeVeryTiny)
|
||||
|
||||
font = ImageFont.truetype(fontFace, fontSize)
|
||||
font_very_tiny = ImageFont.truetype(fontFace, fontSizeVeryTiny)
|
||||
|
||||
desc_font_question = ImageFont.truetype(fontFace_bold, descSizeQuestion)
|
||||
desc_font_answer = ImageFont.truetype(fontFace, descSizeAnswer)
|
||||
font_bold = font = ImageFont.truetype(fontFace_bold, fontSize)
|
||||
|
||||
answers = None
|
||||
|
||||
self.cursor.execute("SELECT os, config, languages, pays, passportdate, theme FROM passport WHERE userid=%s", str(user.id))
|
||||
answers = self.cursor.fetchone()
|
||||
|
||||
if not theme:
|
||||
if answers:
|
||||
theme = str(answers[5])
|
||||
else:
|
||||
theme = "dark"
|
||||
|
||||
cardbg = Image.new('RGBA', (800, 500), (0, 0, 0, 255))
|
||||
d = ImageDraw.Draw(cardbg)
|
||||
|
||||
d.rectangle([(0, 0), 800, 500], fill=(255, 255, 255, 255))
|
||||
cardbg.paste(bg, (0, 0))
|
||||
|
||||
cardfg = Image.new('RGBA', (800, 500), (255, 255, 255, 0))
|
||||
dd = ImageDraw.Draw(cardfg)
|
||||
|
||||
# Info Box Top
|
||||
dd.rectangle([(60, 60), (600, 191)], fill=(color[theme]["background"], color[theme]["background"], color[theme]["background"], 200))
|
||||
dd.rectangle([(60, 60), (600, 134)], fill=(color[theme]["background"], color[theme]["background"], color[theme]["background"], 255))
|
||||
|
||||
# Avatar box
|
||||
if user_color == (0, 0, 0, 255):
|
||||
user_color = (color[theme]["background"], color[theme]["background"], color[theme]["background"], 255)
|
||||
dd.rectangle([(609, 60), (740, 191)], fill=user_color)
|
||||
cardfg.paste(userAvatar, (611, 62))
|
||||
|
||||
# Profile Information
|
||||
if textwrap.fill(nick, 25) != nick:
|
||||
dd.text((70, 70), nick, fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 220), font=header_font_very_tiny)
|
||||
dd.text((70, 106), '@' + name + '#' + discr, fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 225), font=font_very_tiny)
|
||||
elif textwrap.fill(nick, 15) != nick:
|
||||
dd.text((70, 70), nick, fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 220), font=header_font_tiny)
|
||||
dd.text((70, 106), '@' + name + '#' + discr, fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 225), font=font)
|
||||
else:
|
||||
dd.text((70, 64), nick, fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 220), font=header_font)
|
||||
dd.text((70, 106), '@' + name + '#' + discr, fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 225), font=font)
|
||||
|
||||
draw_underlined_text(dd, (380, 75), "Date de parution sur discord :", fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 220), font=desc_font_question)
|
||||
dd.text((542, 75), formated_user_birth, fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 225), font=desc_font_answer)
|
||||
|
||||
# Roles
|
||||
for idy, ii in enumerate(roleImages):
|
||||
|
||||
startx = int((270 - (30 * len(roleImages))) / 2)
|
||||
|
||||
cardfg.paste(roleImages[ii], (197 + startx + (30 * idy),152), roleImages[ii])
|
||||
|
||||
|
||||
#Info Box Bottom
|
||||
dd.rectangle([(60, 200), (740, 450)], fill=(color[theme]["background"], color[theme]["background"], color[theme]["background"], 200))
|
||||
|
||||
if answers:
|
||||
passportdate = datetime.datetime.fromisoformat(answers[4])
|
||||
passportdate_day = check_date(str(passportdate.day))
|
||||
passportdate_month = check_date(str(passportdate.month))
|
||||
|
||||
formated_passportdate = str(passportdate_day) + "/" + str(passportdate_month) + "/" + str(passportdate.year)
|
||||
|
||||
draw_underlined_text(dd, (80, 220), "Système(s) d'exploitation :", desc_font_question, fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 255))
|
||||
break_line(
|
||||
dd,
|
||||
(80, 240),
|
||||
answers[0],
|
||||
fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 255),
|
||||
font=desc_font_answer
|
||||
)
|
||||
|
||||
draw_underlined_text(dd, (80, 300), "Langages de programmation préférés :", desc_font_question, fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 255))
|
||||
break_line(
|
||||
dd,
|
||||
(80, 320),
|
||||
answers[2],
|
||||
fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 255),
|
||||
font=desc_font_answer
|
||||
)
|
||||
|
||||
draw_underlined_text(dd, (80, 380), "Pays :", desc_font_question, fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 255))
|
||||
break_line(
|
||||
dd,
|
||||
(80, 400),
|
||||
answers[3],
|
||||
fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 255),
|
||||
font=desc_font_answer
|
||||
)
|
||||
|
||||
dd.line((400, 220, 400, 430), fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 255))
|
||||
|
||||
draw_underlined_text(dd, (410, 220), "Configuration Système :", desc_font_question, fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 255))
|
||||
break_line(
|
||||
dd,
|
||||
(410, 240),
|
||||
answers[1],
|
||||
fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 255),
|
||||
font=desc_font_answer
|
||||
)
|
||||
|
||||
else:
|
||||
dd.text(
|
||||
(370, 300),
|
||||
"Non renseigné.",
|
||||
fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 255),
|
||||
font=desc_font_question
|
||||
)
|
||||
|
||||
draw_underlined_text(dd, (380, 100), "Date de création du passeport :", fill=(color[theme]["question"], color[theme]["question"], color[theme]["question"], 220), font=desc_font_question)
|
||||
dd.text((542, 100), formated_passportdate, fill=(color[theme]["answer"], color[theme]["answer"], color[theme]["answer"], 225), font=desc_font_answer)
|
||||
|
||||
card = Image.new('RGBA', (800, 500), (255, 255, 255, 255))
|
||||
card = Image.alpha_composite(card, cardbg)
|
||||
card = Image.alpha_composite(card, cardfg)
|
||||
|
||||
return card
|
26
config.py.example
Executable file
|
@ -0,0 +1,26 @@
|
|||
token = "INSERT TOKEN HERE"
|
||||
client_id = "INSERT_CLIENT_ID_HERE"
|
||||
log_channel_id = "INSERT_LOG_CHANNEL_HERE"
|
||||
main_server_id = "INSERT_MAIN_CHANNEL_ID_HERE"
|
||||
|
||||
game = "PLAYING_GAME_HERE"
|
||||
prefix = ["."]
|
||||
description = """
|
||||
Je suis TuxBot, le bot qui vit de l'OpenSource ! ;)
|
||||
"""
|
||||
|
||||
mysql = {
|
||||
"host": "localhost",
|
||||
"username": "msqlusername",
|
||||
"password": "msqlpasswd",
|
||||
"dbname": "mysqldb"
|
||||
}
|
||||
|
||||
authorized_id = ['admin ids here']
|
||||
|
||||
## Passport settings
|
||||
|
||||
fonts = {
|
||||
"normal": "NotoSansCJK-Regular.ttc",
|
||||
"bold": "NotoSansCJK-Bold.ttc"
|
||||
}
|
BIN
data/.DS_Store
vendored
Normal file
BIN
data/fonts/NotoSansCJK-Bold.ttc
Executable file
BIN
data/fonts/NotoSansCJK-Regular.ttc
Executable file
BIN
data/images/.DS_Store
vendored
Normal file
BIN
data/images/background_default.light.png
Executable file
After Width: | Height: | Size: 627 KiB |
BIN
data/images/background_default.png
Executable file
After Width: | Height: | Size: 1.3 MiB |
BIN
data/images/roles/android.png
Normal file
After Width: | Height: | Size: 1,012 B |
BIN
data/images/roles/antergos.png
Executable file
After Width: | Height: | Size: 1.6 KiB |
BIN
data/images/roles/arch.png
Executable file
After Width: | Height: | Size: 763 B |
BIN
data/images/roles/bsd.png
Executable file
After Width: | Height: | Size: 845 B |
BIN
data/images/roles/debian.png
Executable file
After Width: | Height: | Size: 1 KiB |
BIN
data/images/roles/elementary.png
Executable file
After Width: | Height: | Size: 2 KiB |
BIN
data/images/roles/fedora.png
Executable file
After Width: | Height: | Size: 962 B |
BIN
data/images/roles/gentoo.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
data/images/roles/linuxmint.png
Executable file
After Width: | Height: | Size: 1.2 KiB |
BIN
data/images/roles/manjaro.png
Executable file
After Width: | Height: | Size: 239 B |
BIN
data/images/roles/opensuse.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
data/images/roles/rhel.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
data/images/roles/small/android.png
Normal file
After Width: | Height: | Size: 518 B |
BIN
data/images/roles/small/antergos.png
Executable file
After Width: | Height: | Size: 2.4 KiB |
BIN
data/images/roles/small/arch.png
Executable file
After Width: | Height: | Size: 1.7 KiB |
BIN
data/images/roles/small/bsd.png
Executable file
After Width: | Height: | Size: 1.6 KiB |
BIN
data/images/roles/small/debian.png
Executable file
After Width: | Height: | Size: 2 KiB |
BIN
data/images/roles/small/elementaryOS.png
Executable file
After Width: | Height: | Size: 478 B |
BIN
data/images/roles/small/fedora.png
Executable file
After Width: | Height: | Size: 2 KiB |
BIN
data/images/roles/small/gentoo.png
Executable file
After Width: | Height: | Size: 2.2 KiB |
BIN
data/images/roles/small/macos.png
Executable file
After Width: | Height: | Size: 610 B |
BIN
data/images/roles/small/manjaro.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
data/images/roles/small/mint.png
Executable file
After Width: | Height: | Size: 2 KiB |
BIN
data/images/roles/small/opensuse.png
Executable file
After Width: | Height: | Size: 2.5 KiB |
BIN
data/images/roles/small/other.png
Executable file
After Width: | Height: | Size: 917 B |
BIN
data/images/roles/small/rhel.png
Executable file
After Width: | Height: | Size: 1.6 KiB |
BIN
data/images/roles/small/ubuntu.png
Executable file
After Width: | Height: | Size: 2.3 KiB |
BIN
data/images/roles/small/void.png
Executable file
After Width: | Height: | Size: 2.2 KiB |
BIN
data/images/roles/small/windows.png
Executable file
After Width: | Height: | Size: 261 B |
BIN
data/images/roles/ubuntu.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
data/images/roles/void.png
Executable file
After Width: | Height: | Size: 911 B |
43
launch.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import locale
|
||||
from dialog import Dialog
|
||||
from subprocess import call
|
||||
import os
|
||||
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
d = Dialog(dialog="dialog")
|
||||
d.set_background_title("Tuxbot Manager v0.5a")
|
||||
|
||||
while True:
|
||||
|
||||
mmenu, rmenu = d.menu("Que souhaitez vous faire ?", choices = [("(1)", "Lancer Tuxbot"), ("(2)", "Eteindre Tuxbot"), ("(3)", "Mettre à jour Tuxbot"), ("(4)", "Quitter")])
|
||||
|
||||
if rmenu == "(1)":
|
||||
d.gauge_start("Lancement")
|
||||
d.gauge_update(10)
|
||||
# try:
|
||||
# call(["screen", "-S", "tuxbot", "-X","quit"])
|
||||
# except:
|
||||
# d.gauge_update(35)
|
||||
d.gauge_update(40)
|
||||
call(["screen","-S","tuxbot", "-d", "-m", "python3", "bot.py"])
|
||||
d.gauge_update(100)
|
||||
d.gauge_stop()
|
||||
d.msgbox("Tuxbot est correctement lancé ! Merci de faire .ping sur discord pour vérifier.")
|
||||
|
||||
if rmenu == "(2)":
|
||||
d.gauge_start("Arrêt")
|
||||
d.gauge_update(10)
|
||||
call(["screen", "-S", "tuxbot", "-X","quit"])
|
||||
d.gauge_update(100)
|
||||
d.gauge_stop()
|
||||
d.msgbox("Tuxbot s'est correctement arrêté. Faites vite ;-) !")
|
||||
|
||||
if rmenu == "(4)":
|
||||
d.pause("A bientôt !\n(C) 2018 Gnous.EU Dev Team.", seconds=2)
|
||||
call(["clear"])
|
||||
exit()
|
||||
|
||||
if rmenu == "(3)":
|
||||
d.msgbox("Fonctionnalité indisponible pour le moment du fait que le serveur GIT de tuxbot est hors service.")
|
33
readme.md
|
@ -1,26 +1,9 @@
|
|||
# Tuxbot
|
||||
|
||||
[![forthebadge](http://forthebadge.com/images/badges/contains-cat-gifs.svg)](http://forthebadge.com)
|
||||
[![forthebadge](https://forthebadge.com/images/badges/made-with-python.svg)](http://forthebadge.com)
|
||||
|
||||
TuxBot, un bot discord écrit en Python.
|
||||
TuxBot, un bot discord écrit en Python. Il dispose d'une multitude de fonctionnalités.
|
||||
Ici ce trouve le code source du bot provenant du serveur Discord [Aide GNU/Linux-Fr"](https://discord.gg/79943dJ "Rejoindre le serveur"), il à été créé spécialement pour ce discord, si vous souhaitez l'utiliser il vous faudra modifier ``params.json`` et ``cogs/utils/checks.py`` ;)
|
||||
|
||||
### Pré-requis
|
||||
|
||||
Il vous faut :
|
||||
|
||||
- Un ordinateur sous **GNU/Linux** avec une connexion à internet;
|
||||
- Python3.5 ou + ;
|
||||
- Installer ``requirements.txt`` (avec ``pip install -r requirements.txt`` par ex)
|
||||
|
||||
### Installation
|
||||
|
||||
Une fois les pré-requis installés et ``params.json`` édité, placez vous dans le repertoire de tuxbot et lancez ``bot.py`` avec python3 (ex: ``python3 bot.py``)
|
||||
|
||||
## Démarrage
|
||||
|
||||
Placez vous dans le repertoire de tuxbot et exécutez ``bot.py`` avec python3 (ex: ``python3 bot.py``)
|
||||
## Installation
|
||||
[Voir le guide d'installation](https://wiki.gnous.eu/wiki/Tuxbot/Install)
|
||||
|
||||
## Fabriqué avec
|
||||
* [PyCharm](https://www.jetbrains.com/pycharm/) - Editeur de texte payant :3
|
||||
|
@ -31,15 +14,7 @@ Liste des versions : [Cliquer pour afficher](https://github.com/outout14/tuxbot-
|
|||
|
||||
## Auteurs
|
||||
* **Maël** _alias_ [@outout14](https://github.com/outout14)
|
||||
* **Romain** _alias_ [Romain le malchanceux](https://github.com/Rom194)
|
||||
* **Romain** _alias_ [Romain](https://github.com/Rom194)
|
||||
|
||||
## License
|
||||
|
||||
Ce projet est sous licence ``Creative Commons BY-NC-SA 4.0`` - voir le fichier [LICENSE.md](LICENSE.md) pour plus d'informations
|
||||
|
||||
|
||||
|
||||
## Support on Beerpay
|
||||
Hey dude! Help me out for a couple of :beers:!
|
||||
|
||||
[![Beerpay](https://beerpay.io/outout14/tuxbot-bot/badge.svg?style=beer-square)](https://beerpay.io/outout14/tuxbot-bot) [![Beerpay](https://beerpay.io/outout14/tuxbot-bot/make-wish.svg?style=flat-square)](https://beerpay.io/outout14/tuxbot-bot?focus=wish)
|
|
@ -5,3 +5,5 @@ bs4
|
|||
pytz
|
||||
requests
|
||||
wikipedia
|
||||
pymysql
|
||||
pillow
|
|
@ -7,5 +7,5 @@ La carte d'identité est un petit système dans tuxbot permetant de vous démarq
|
|||
-> .ci setos _nom de l'os_ : Défini votre système d'exploitation
|
||||
-> .ci setconfig _votre configuration pc_ : Défini la configuration de votre ordinateur
|
||||
-> .ci setcountry : Défini votre pays
|
||||
-> .ci update : Met à jour votre image si vous l'avez changé :wink:
|
||||
-> .ci delete : Supprime votre carte d'identité :sob:
|
||||
-> .ci update : Met à jour votre image si vous l'avez changé
|
||||
-> .ci delete : Supprime votre carte d'identité
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
**Commandes utilitaires**
|
||||
-> .afk : Signaler son absence
|
||||
-> .back : Signaler son retour
|
||||
-> .afk : Signaler son absence *(commande désactivée)*
|
||||
-> .back : Signaler son retour *(commande désactivée)*
|
||||
-> .clock _ville_: Affiche l'heure et quelques infos sur la ville en question
|
||||
-> .ytdiscover : Découvrir des chaines youtube
|
||||
-> .search _site_ _contenu_ : Fait une recherche sur un site (.search pour plus d'infos)
|
||||
|
@ -8,7 +8,11 @@
|
|||
-> .poke _@pseudo_ : Poke _@pseudo_
|
||||
-> .hastebin _code_ : Poste du code sur hastebin
|
||||
-> .sondage _question_ | _reponse_ | _reponse_ | _option_ : Créer un sondage avec des réactions
|
||||
-> .sondage_aide : Affiche l'aide pour la commande sondage
|
||||
-> .sondage : Affiche l'aide pour la commande sondage
|
||||
-> .role _nomdurole_ : Ajoute/Retire le rôle en question
|
||||
-> .iplocalise _IP ou NDD_ : affiche la localisation et le propriétaire de l'ip (ou de l'IP lié a un nom de domaine)
|
||||
-> .getheaders _IP ou NDD_ : affiche les en-têtes (headers) d'une IP/Nom de domaine via HTTP/HTTPS/FTP
|
||||
-> .btcprice : Affiche le prix du bitcoin
|
||||
|
||||
**Commandes Funs**
|
||||
-> .joke : Affiche une blague aléatoire
|
||||
|
@ -30,6 +34,6 @@
|
|||
**Commandes diverses** :
|
||||
-> .info : Affiche des informations sur le bot
|
||||
-> .help : Affiche ce message
|
||||
-> .clock list: Affiche la liste des horloges des villes
|
||||
-> .clock : Affiche la liste des horloges des villes
|
||||
-> .ping : Ping le bot
|
||||
-> .github : Affiche le repos Github du Bot :heart:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
<:stafftools:314348604095594498> **Développement** :
|
||||
└> Outout : [outout.tech](https://outout.tech/)
|
||||
└> Romain : [son github](https://github.com/Rom194)
|
||||
└> Outout : [outout.xyz](https://outout.xyz/)
|
||||
└> Romain : [son github](http://git.dyjix.eu/Romain)
|
||||
└> Langage : [Python3](http://www.python.org/)
|
||||
└> Api : [discord.py {3}](https://github.com/Rapptz/discord.py)
|
||||
└> En se basant sur : [RobotDanny](https://github.com/Rapptz/RoboDanny)
|
||||
|
@ -12,12 +12,13 @@
|
|||
|
||||
<:contact:334347787200233483> **Contact** :
|
||||
└> <:discord:314003252830011395> : Outout#8406
|
||||
└> <:twitter:314349922877046786> : [@outout14_](https://twitter.com/outout14_)
|
||||
└> <:mail:334345653419245571> : [outout@linuxmail.org](mailto:outout@linuxmail.org)
|
||||
└> <:twitter:314349922877046786> : [@outoutxyz](https://twitter.com/outouxyz)
|
||||
└> <:mail:334345653419245571> : [mael@gnous.eu](mailto:mael@gnous.eu)
|
||||
└> <:discord:314003252830011395> : Romain#5117
|
||||
|
||||
|
||||
<:discord:314003252830011395> **Serveurs** :
|
||||
└> <:tux:282212977627758593> Serveur de TuxBot : [rejoindre](https://discord.gg/5UZy8Pn)
|
||||
└> <:tux:282212977627758593> Serveur GNU/Linux-Fr : [rejoindre](https://discord.gg/B5TzW7x)
|
||||
└> :tux: Serveur de TuxBot : [rejoindre](https://discord.gg/5UZy8Pn)
|
||||
└> <:tux:514930485751971866> Serveur GNU/Linux-Fr : [rejoindre](https://discord.gg/B5TzW7x)
|
||||
|
||||
|
||||
|
|
9
texts/passport-info.md
Executable file
|
@ -0,0 +1,9 @@
|
|||
Le passeport est un petit système dans tuxbot permetant de vous démarquer de vos amis en ayant la possibilité d'y renseigner plusieurs informations !
|
||||
|
||||
**Liste des commandes : **
|
||||
-> .passeport : Affiche l'aide sur les cartes d'identité
|
||||
-> .passeport show _pseudo_ : Affiche le passeport de _pseudo_
|
||||
-> .passeport config : Vous envois un message privé afin de configurer votre passeport
|
||||
-> .passeport background _url_ : Défini _url_ comme étant le fond d'écran de votre passeport
|
||||
-> .passeport thème <dark/light/preview>: Definie le theme de votre passeport (`.passeport preview` envoi une image avec les 2 thèmes pour comparer)
|
||||
-> .passeport delete : Supprime les informations de votre carte passeport
|
13
texts/roles.md
Executable file
|
@ -0,0 +1,13 @@
|
|||
|
||||
Pour améliorer l'expérience utilisateur de tout le monde, vous pouvez spécifier la·les distribution·s que vous utilisez via les rôles Discord.
|
||||
|
||||
**Liste des rôles**
|
||||
└> Arch : pour <:archlinux:282214818486812673>
|
||||
└> Debian : pour Debian <:debian:375326392482791424> et ses dérivés (Ubuntu, Kali, etc.)
|
||||
└> Rhel : pour Red Hat Entreprise Linux et ses dérivés (Fedora, CentOS, etc.)
|
||||
└> Android : pour Android <:android:282214818486812673>
|
||||
└> BSD : pour BSD <:bsd:401797313657569280>
|
||||
|
||||
**Commandes**
|
||||
└> Pour ajouter un rôle : ``.role Nomdurole``
|
||||
└> Pour retirer un rôle : ``.role Nomdurole``
|
|
@ -3,4 +3,4 @@ _Attention ! entrez vos termes de recherche sans espaces !_
|
|||
Pour effectuer une recherche utilisez la commande ``.search {site_de_recherche} {termes_recherche}``
|
||||
-> [**docubuntu**](https://doc.ubuntu-fr.org) : Effectuer une recherche sur un paquet dans la Documentation du site ubuntu-fr.org.
|
||||
-> [**wikipedia**](https://fr.wikipedia.org) : Effectuer une recherche sur l'encyclopédie libre Wikipedia en Français !
|
||||
-> [**aur**](https://aur.archlinux.org) : Effectuer une recherche sur Archlinux Aur !
|
||||
-> [**docaur**](https://doc.archlinux.org) : Effectuer une recherche sur la doc ArchLinux !
|
||||
|
|