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:!
|
||||||
|
|
205
bot.py
|
@ -1,149 +1,120 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
__author__ = "Maël / Outout"
|
__author__ = ["Romain", "Maël / Outout"]
|
||||||
__licence__ = "WTFPL Licence 2.0"
|
__licence__ = "WTFPL Licence 2.0"
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import discord
|
import discord
|
||||||
from cogs.utils import checks
|
from cogs.utils import checks
|
||||||
import datetime, re
|
|
||||||
import json, asyncio
|
import datetime
|
||||||
|
import json
|
||||||
import copy
|
import copy
|
||||||
import logging
|
|
||||||
from logging.handlers import RotatingFileHandler
|
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
from collections import Counter
|
import os
|
||||||
|
import aiohttp
|
||||||
|
|
||||||
description = """
|
import config
|
||||||
Je suis TuxBot, le bot qui vit de l'OpenSource ! ;)
|
import cogs.utils.cli_colors as colors
|
||||||
"""
|
|
||||||
|
|
||||||
l_extensions = [
|
l_extensions = [
|
||||||
|
|
||||||
'cogs.basics',
|
'cogs.admin',
|
||||||
#'cogs.test',
|
# 'cogs.afk',
|
||||||
'cogs.admin',
|
'cogs.basics',
|
||||||
'cogs.funs',
|
'cogs.ci',
|
||||||
'cogs.utility',
|
'cogs.cog_manager',
|
||||||
'cogs.search',
|
'cogs.filter_messages',
|
||||||
'cogs.ci'
|
'cogs.funs',
|
||||||
|
'cogs.passport',
|
||||||
|
'cogs.role',
|
||||||
|
'cogs.search',
|
||||||
|
'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")
|
help_attrs = dict(hidden=True, in_help=True, name="DONOTUSE")
|
||||||
|
|
||||||
|
|
||||||
# CREDENTIALS #
|
class TuxBot(commands.Bot):
|
||||||
try:
|
def __init__ (self):
|
||||||
def load_credentials():
|
self.config = config
|
||||||
with open('params.json') as f:
|
super().__init__(command_prefix=self.config.prefix[0],
|
||||||
return json.load(f)
|
description=self.config.description,
|
||||||
except:
|
pm_help=None,
|
||||||
print("Le fichier de paramètre est introuvable, veuillez le créer et le configurer.")
|
help_attrs=help_attrs)
|
||||||
|
|
||||||
credentials = load_credentials()
|
self.client_id = self.config.client_id
|
||||||
prefix = credentials.get("prefix", ["."])
|
self.session = aiohttp.ClientSession(loop=self.loop)
|
||||||
bot = commands.Bot(command_prefix=prefix, description=description, pm_help=None, help_attrs=help_attrs)
|
self._events = []
|
||||||
|
|
||||||
@bot.event
|
|
||||||
async def on_command_error(error, ctx):
|
|
||||||
if isinstance(error, commands.NoPrivateMessage):
|
|
||||||
await bot.send_message(ctx.message.author, 'Cette commande ne peut pas être utilisée en message privée.')
|
|
||||||
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.')
|
|
||||||
elif isinstance(error, commands.CommandInvokeError):
|
|
||||||
print('In {0.command.qualified_name}:'.format(ctx), file=sys.stderr)
|
|
||||||
traceback.print_tb(error.original.__traceback__)
|
|
||||||
print('{0.__class__.__name__}: {0}'.format(error.original), file=sys.stderr)
|
|
||||||
|
|
||||||
@bot.event
|
self.add_command(self.do)
|
||||||
async def on_ready():
|
|
||||||
print('---------------------')
|
|
||||||
print('CONNECTÉ :')
|
|
||||||
print(""" Nom d\'utilisateur : {0.name}#{0.discriminator}
|
|
||||||
ID : {0.id}""".format(bot.user))
|
|
||||||
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()
|
|
||||||
|
|
||||||
@bot.event
|
for extension in l_extensions:
|
||||||
async def on_resumed():
|
try:
|
||||||
print('resumed...')
|
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)
|
||||||
|
|
||||||
@bot.event
|
async def on_command_error(self, ctx, error):
|
||||||
async def on_message(message):
|
if isinstance(error, commands.NoPrivateMessage):
|
||||||
if message.author.bot:
|
await ctx.author.send('Cette commande ne peut pas être utilisee en message privee.')
|
||||||
return
|
elif isinstance(error, commands.DisabledCommand):
|
||||||
|
await ctx.author.send('Desoler mais cette commande est desactive, 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)
|
||||||
|
|
||||||
try:
|
async def on_ready(self):
|
||||||
await bot.process_commands(message)
|
if not hasattr(self, 'uptime'):
|
||||||
except Exception as e:
|
self.uptime = datetime.datetime.utcnow()
|
||||||
print('Erreur rencontré : \n {}: {} \n \n'.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
@bot.command(pass_context=True, hidden=True)
|
log_channel_id = self.get_channel(int(self.config.log_channel_id))
|
||||||
@checks.is_owner()
|
|
||||||
async def do(ctx, times : int, *, command):
|
|
||||||
"""Repeats a command a specified number of times."""
|
|
||||||
msg = copy.copy(ctx.message)
|
|
||||||
msg.content = command
|
|
||||||
for i in range(times):
|
|
||||||
await bot.process_commands(msg)
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
print('\n\n---------------------')
|
||||||
async def github(ctx):
|
print('CONNECTÉ :')
|
||||||
"""Pour voir mon code"""
|
print(f'Nom d\'utilisateur: {self.user} {colors.text_style.DIM}(ID: {self.user.id}){colors.ENDC}')
|
||||||
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"
|
print(f'Channel de log: {log_channel_id} {colors.text_style.DIM}(ID: {log_channel_id.id}){colors.ENDC}')
|
||||||
em = discord.Embed(title='Repos TuxBot-Bot', description=text, colour=0xE9D460)
|
print(f'Prefix: {self.config.prefix[0]}')
|
||||||
em.set_author(name='Outout', icon_url="https://avatars0.githubusercontent.com/u/14958554?v=3&s=400")
|
print('Merci d\'utiliser TuxBot')
|
||||||
await ctx.send(embed=em)
|
print('---------------------\n\n')
|
||||||
|
|
||||||
async def on_command_error(self, ctx, error):
|
await self.change_presence(status=discord.Status.dnd, activity=discord.Game(name=self.config.game))
|
||||||
if isinstance(error, commands.NoPrivateMessage):
|
|
||||||
await ctx.author.send('Cette commande ne peut pas être utilisée en message privée.')
|
async def on_resumed():
|
||||||
elif isinstance(error, commands.DisabledCommand):
|
print('resumed...')
|
||||||
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):
|
async def on_message(self, message):
|
||||||
print(f'In {ctx.command.qualified_name}:', file=sys.stderr)
|
if message.author.bot:
|
||||||
traceback.print_tb(error.original.__traceback__)
|
return
|
||||||
print(f'{error.original.__class__.__name__}: {error.original}', file=sys.stderr)
|
|
||||||
|
try:
|
||||||
|
await self.process_commands(message)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{colors.text_colors.RED}Erreur rencontré : \n {type(e).__name__}: {e}{colors.ENDC} \n \n')
|
||||||
|
|
||||||
|
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)
|
||||||
|
msg.content = command
|
||||||
|
for i in range(times):
|
||||||
|
await bot.process_commands(msg)
|
||||||
|
|
||||||
## LOAD ##
|
## LOAD ##
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
if os.path.exists('config.py') is not True:
|
||||||
credentials = load_credentials()
|
print(f"{colors.text_colors.RED}Veuillez créer le fichier config.py{colors.ENDC}"); exit()
|
||||||
token = credentials.get('token')
|
|
||||||
if token is None:
|
tuxbot = TuxBot()
|
||||||
print("/!\ Le token est manquant dans le fichier params.json...")
|
tuxbot.run()
|
||||||
bot.client_id = credentials.get('client_id', None)
|
|
||||||
except:
|
|
||||||
print("Impossible de démarer TuxBot dû à une erreur inconnue.")
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
BIN
cogs/.DS_Store
vendored
Normal file
387
cogs/admin.py
|
@ -1,105 +1,336 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
import discord
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import time
|
import time
|
||||||
import discord
|
|
||||||
from .utils import checks
|
from .utils import checks
|
||||||
|
|
||||||
|
from .utils.checks import get_user
|
||||||
|
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
class Admin:
|
class Admin:
|
||||||
"""Commandes secrètes d'administration."""
|
"""Commandes secrètes d'administration."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
|
||||||
self.bot = bot
|
|
||||||
|
|
||||||
@checks.is_owner()
|
def __init__(self, bot):
|
||||||
@commands.command(name='unload_cog', hidden=True)
|
self.bot = bot
|
||||||
async def _unload(self, ctx, module: str):
|
|
||||||
"""Unloads a module."""
|
|
||||||
try:
|
|
||||||
self.bot.unload_extension("cogs."+module)
|
|
||||||
except Exception as e:
|
|
||||||
await ctx.send('\N{PISTOL}')
|
|
||||||
await ctx.send('{}: {}'.format(type(e).__name__, e))
|
|
||||||
else:
|
|
||||||
await ctx.send('\N{OK HAND SIGN}')
|
|
||||||
print("cog : " + str(module) + " activé")
|
|
||||||
|
|
||||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
|
||||||
@checks.is_owner()
|
@checks.has_permissions(administrator=True)
|
||||||
@commands.command(name='load_cog', hidden=True)
|
@commands.command(pass_context=True)
|
||||||
async def _load(self, ctx, module: str):
|
async def ban(self, ctx, user, *, reason=""):
|
||||||
"""Unloads a module."""
|
"""Ban user"""
|
||||||
try:
|
user = get_user(ctx.message, user)
|
||||||
self.bot.load_extension("cogs."+module)
|
if user:
|
||||||
except Exception as e:
|
try:
|
||||||
await ctx.send('\N{PISTOL}')
|
await user.ban(reason=reason)
|
||||||
await ctx.send('{}: {}'.format(type(e).__name__, e))
|
return_msg = "`{}` a été banni\n".format(user.mention)
|
||||||
else:
|
if reason:
|
||||||
await ctx.send('\N{OK HAND SIGN}')
|
return_msg += "raison : `{}`".format(reason)
|
||||||
print("cog : " + str(module) + " desactivé")
|
return_msg += "."
|
||||||
|
await ctx.send(return_msg)
|
||||||
|
except discord.Forbidden:
|
||||||
|
await ctx.send('Impossible de bannir cet user, probleme de permission.')
|
||||||
|
else:
|
||||||
|
return await ctx.send('Impossible de trouver l\'user.')
|
||||||
|
|
||||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
|
||||||
@checks.is_owner()
|
@checks.has_permissions(administrator=True)
|
||||||
@commands.command(name='reload_cog', hidden=True)
|
@commands.command(pass_context=True)
|
||||||
async def _reload(self, ctx, *, module: str):
|
async def kick(self, ctx, user, *, reason=""):
|
||||||
"""Reloads a module."""
|
"""Kick a user"""
|
||||||
try:
|
user = get_user(ctx.message, user)
|
||||||
self.bot.unload_extension("cogs."+module)
|
if user:
|
||||||
self.bot.load_extension("cogs."+module)
|
try:
|
||||||
await ctx.send("Je te reload ca")
|
await user.kick(reason=reason)
|
||||||
except Exception as e: #TODO : A virer dans l'event on_error
|
return_msg = "`{}` a été kické\n".format(user.mention)
|
||||||
await ctx.send(':( Erreur :')
|
if reason:
|
||||||
await ctx.send('{}: {}'.format(type(e).__name__, e))
|
return_msg += "raison : `{}`".format(reason)
|
||||||
else:
|
return_msg += "."
|
||||||
await ctx.send('\N{OK HAND SIGN}')
|
await ctx.send(return_msg)
|
||||||
print("cog : " + str(module) + " relancé")
|
except discord.Forbidden:
|
||||||
|
await ctx.send('Impossible de kicker cet user, probleme de permission.')
|
||||||
|
else:
|
||||||
|
return await ctx.send('Impossible de trouver l\'user.')
|
||||||
|
|
||||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
|
||||||
@checks.is_owner()
|
@checks.has_permissions(administrator=True)
|
||||||
@commands.command(name='clear', pass_context=True, hidden=True)
|
@commands.command(name='clear', pass_context=True)
|
||||||
async def _clear(self, ctx, number: int):
|
async def _clear(self, ctx, number: int, silent: str = True):
|
||||||
|
"""Clear <number> of message(s)"""
|
||||||
|
try:
|
||||||
|
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:
|
||||||
|
await ctx.send('Trop de messages, entre un nombre < 1000')
|
||||||
|
|
||||||
await ctx.message.delete()
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
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
|
|
||||||
await ctx.send(':sob: Une erreur est survenue : \n {}: {}'.format(type(e).__name__, e))
|
|
||||||
await ctx.send("Hop voila j'ai viré des messages! Hello World")
|
|
||||||
print(str(number)+" messages ont été supprimés")
|
|
||||||
else:
|
|
||||||
await ctx.send('Trop de messages, entre un nombre < 1000')
|
|
||||||
|
|
||||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
@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:
|
||||||
|
await ctx.message.delete()
|
||||||
|
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(name='say', pass_context=True, hidden=True)
|
|
||||||
async def _say(self, ctx, *direuh:str):
|
|
||||||
try:
|
|
||||||
dire = ctx.message.content.split("say ")
|
|
||||||
await ctx.message.delete()
|
|
||||||
await ctx.send(dire[1])
|
|
||||||
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', 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.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_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):
|
def setup(bot):
|
||||||
bot.add_cog(Admin(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))
|
109
cogs/basics.py
|
@ -1,56 +1,67 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from random import choice, shuffle
|
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
|
||||||
import time
|
|
||||||
import discord
|
import discord
|
||||||
import platform, socket
|
import platform
|
||||||
import os
|
import socket
|
||||||
|
|
||||||
import wikipedia, bs4
|
import subprocess
|
||||||
|
|
||||||
class General:
|
|
||||||
"""Commandes générales."""
|
|
||||||
|
|
||||||
def __init__(self, bot):
|
|
||||||
self.bot = bot
|
|
||||||
|
|
||||||
@commands.command()
|
|
||||||
async def ping(self, ctx):
|
|
||||||
t1 = time.perf_counter()
|
|
||||||
await ctx.trigger_typing()
|
|
||||||
t2 = time.perf_counter()
|
|
||||||
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
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")
|
|
||||||
await ctx.send(embed=em)
|
|
||||||
|
|
||||||
|
|
||||||
## HELP PLZ ##
|
class Basics:
|
||||||
@commands.command()
|
"""Commandes générales."""
|
||||||
async def help(self, ctx):
|
|
||||||
"""Affiches l'aide du bot"""
|
def __init__(self, bot):
|
||||||
text = open('texts/help.md').read()
|
self.bot = bot
|
||||||
em = discord.Embed(title='Commandes de TuxBot', description=text, colour=0x89C4F9)
|
|
||||||
await ctx.send(embed=em)
|
@commands.command()
|
||||||
|
async def ping(self, ctx):
|
||||||
|
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:]
|
||||||
|
|
||||||
|
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 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)
|
||||||
|
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)
|
||||||
|
|
||||||
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@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="/home/****/bot.py")
|
||||||
|
await ctx.send(embed=em)
|
||||||
|
|
||||||
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@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)
|
||||||
|
await ctx.send(embed=em)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(General(bot))
|
bot.add_cog(Basics(bot))
|
||||||
|
|
375
cogs/ci.py
|
@ -1,188 +1,249 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from random import choice, shuffle
|
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
|
||||||
import discord
|
import discord
|
||||||
import platform, socket
|
|
||||||
import os
|
|
||||||
import sqlite3
|
|
||||||
|
|
||||||
import time
|
from .utils import checks
|
||||||
import datetime, pytz
|
from .utils import db
|
||||||
|
from .utils.checks import get_user, check_date
|
||||||
|
|
||||||
from datetime import date
|
import datetime
|
||||||
import calendar
|
|
||||||
|
|
||||||
#### SQL #####
|
import pymysql
|
||||||
conn = sqlite3.connect('tuxbot.db') #Connexion SQL
|
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:
|
class Identity:
|
||||||
"""Commandes des cartes d'identité ."""
|
"""Commandes des cartes d'identité ."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@commands.group(name="ci", no_pm=True, pass_context=True)
|
self.conn = db.connect_to_db(self)
|
||||||
async def _ci(self, ctx):
|
self.cursor = self.conn.cursor()
|
||||||
"""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")
|
self.cursor.execute("""SHOW TABLES LIKE 'users'""")
|
||||||
async def ci_test(self, ctx, args : discord.Member):
|
result = self.cursor.fetchone()
|
||||||
|
|
||||||
def isexist(var):
|
if not result:
|
||||||
if not var:
|
# Creation table Utilisateur si premiere fois
|
||||||
return "Non renseigné."
|
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);"
|
||||||
else:
|
self.cursor.execute(sql)
|
||||||
return var
|
|
||||||
|
|
||||||
cursor.execute("""SELECT userid, username, useravatar, userbirth, cidate, cibureau, os, config, pays, id FROM users WHERE userid=?""",(args.id,))
|
@commands.group(name="ci", no_pm=True, pass_context=True)
|
||||||
result = cursor.fetchone()
|
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)
|
||||||
|
|
||||||
if not result:
|
@_ci.command(pass_context=True, name="show")
|
||||||
await ctx.send(ctx.message.author.mention + "> :x: Désolé mais {} est sans papier !".format(args.mention))
|
async def ci_show(self, ctx, args: str = None):
|
||||||
|
self.conn = db.connect_to_db(self)
|
||||||
|
self.cursor = self.conn.cursor()
|
||||||
|
|
||||||
else:
|
if args == None:
|
||||||
try:
|
user = get_user(ctx.message, ctx.message.author.name)
|
||||||
userbirth = result[3].split(" ")
|
else:
|
||||||
cidate = result[4].split(" ")
|
user = get_user(ctx.message, args)
|
||||||
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="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]))
|
|
||||||
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))
|
|
||||||
|
|
||||||
@_ci.command(pass_context=True, name="register")
|
if user:
|
||||||
async def ci_register(self, ctx):
|
self.cursor.execute("""SELECT userid, username, useravatar, userbirth, cidate, cibureau, os, config, pays, id FROM users WHERE userid=%s""",(str(user.id)))
|
||||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
result = self.cursor.fetchone()
|
||||||
existansw = cursor.fetchone()
|
|
||||||
if existansw != None:
|
|
||||||
await ctx.send("Mais tu as déja une carte d'identité ! u_u")
|
|
||||||
else:
|
|
||||||
date = datetime.datetime.now()
|
|
||||||
|
|
||||||
nd = str(date.day)
|
def isexist(var):
|
||||||
nd += "-"
|
if not var:
|
||||||
nd += str(date.month)
|
return "Non renseigné."
|
||||||
nd += "-"
|
else:
|
||||||
nd += str(date.year)
|
return var
|
||||||
|
|
||||||
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)))
|
if not result:
|
||||||
conn.commit()
|
await ctx.send(f"{ctx.message.author.mention}> :x: Désolé mais {user.mention} est sans papier !")
|
||||||
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)))
|
else:
|
||||||
|
try:
|
||||||
|
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))
|
||||||
|
|
||||||
@_ci.command(pass_context=True, name="delete")
|
formated_user_birth = str(user_birth_day) + "/" + str(user_birth_month) + "/" + str(user_birth.year)
|
||||||
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,))
|
|
||||||
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")
|
try: ## a virer une fois le patch appliqué pour tout le monde
|
||||||
async def ci_image(self, ctx):
|
cidate = datetime.datetime.fromisoformat(result[4])
|
||||||
try:
|
cidate_day = check_date(str(cidate.day)) ## a garder
|
||||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
cidate_month = check_date(str(cidate.month)) ## a garder
|
||||||
existansw = cursor.fetchone()
|
|
||||||
|
|
||||||
if existansw != None:
|
formated_cidate = str(cidate_day) + "/" + str(cidate_month) + "/" + str(cidate.year) ## a garder
|
||||||
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))
|
except ValueError: ## a virer une fois le patch appliqué pour tout le monde
|
||||||
conn.commit()
|
formated_cidate = str(result[4]).replace('-', '/') ## a virer une fois le patch appliqué pour tout le monde
|
||||||
await ctx.send(ctx.message.author.mention + "> Tu viens, en quelques sortes, de renaitre !")
|
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
|
||||||
else:
|
|
||||||
await ctx.send(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
|
embed=discord.Embed(title="Carte d'identité | Communisme Linuxien")
|
||||||
await ctx.send(':( Erreur veuillez contacter votre administrateur :')
|
embed.set_author(name=result[1], icon_url=result[2])
|
||||||
await ctx.send('{}: {}'.format(type(e).__name__, e))
|
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 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=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 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="setconfig")
|
@_ci.command(pass_context=True, name="register")
|
||||||
async def ci_setconfig(self, ctx, args_):
|
async def ci_register(self, ctx):
|
||||||
try:
|
self.conn = db.connect_to_db(self)
|
||||||
args = ctx.message.content.split("setconfig ")
|
self.cursor = self.conn.cursor()
|
||||||
args = args[1]
|
|
||||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
|
||||||
existansw = cursor.fetchone()
|
|
||||||
|
|
||||||
if existansw != None:
|
self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.message.author.id)))
|
||||||
cursor.execute("""UPDATE users SET config = ? WHERE userid = ?""", (args, ctx.message.author.id))
|
result = self.cursor.fetchone()
|
||||||
conn.commit()
|
|
||||||
await ctx.send(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 !")
|
|
||||||
|
|
||||||
@_ci.command(pass_context=True, name="setos")
|
if result:
|
||||||
async def ci_setos(self, ctx, args_):
|
await ctx.send("Mais tu as déja une carte d'identité ! u_u")
|
||||||
try:
|
else:
|
||||||
args = ctx.message.content.split("setos ")
|
now = datetime.datetime.now()
|
||||||
args = args[1]
|
|
||||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
|
||||||
existansw = cursor.fetchone()
|
|
||||||
|
|
||||||
if existansw != None:
|
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)))
|
||||||
cursor.execute("""UPDATE users SET os = ? WHERE userid = ?""", (args, ctx.message.author.id))
|
self.conn.commit()
|
||||||
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 !")
|
||||||
await ctx.send(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 !")
|
|
||||||
|
|
||||||
@_ci.command(pass_context=True, name="setcountry")
|
@_ci.command(pass_context=True, name="delete")
|
||||||
async def ci_setcountry(self, ctx, args):
|
async def ci_delete(self, ctx):
|
||||||
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
|
self.conn = db.connect_to_db(self)
|
||||||
existansw = cursor.fetchone()
|
self.cursor = self.conn.cursor()
|
||||||
|
|
||||||
if existansw != None:
|
self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.message.author.id)))
|
||||||
cursor.execute("""UPDATE users SET pays = ? WHERE userid = ?""", (args, ctx.message.author.id))
|
result = self.cursor.fetchone()
|
||||||
conn.commit()
|
|
||||||
await ctx.send(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 !")
|
|
||||||
|
|
||||||
@_ci.command(pass_context=True, name="list")
|
if result:
|
||||||
async def ci_list(self, ctx):
|
self.cursor.execute("""DELETE FROM users WHERE userid =%s""", (str(ctx.message.author.id)))
|
||||||
cursor.execute("""SELECT id, username FROM users""")
|
self.conn.commit()
|
||||||
rows = cursor.fetchall()
|
await ctx.send("Tu es maintenant sans papiers !")
|
||||||
msg = ""
|
else:
|
||||||
try:
|
await ctx.send("Déja enregistre ta carte d'identité avant de la supprimer u_u (après c'est pas logique...)")
|
||||||
for row in rows:
|
|
||||||
msg = msg + '{0} : {1} \n'.format(row[0], row[1])
|
@_ci.command(pass_context=True, name="update")
|
||||||
await ctx.send(msg)
|
async def ci_update(self, ctx):
|
||||||
except:
|
self.conn = db.connect_to_db(self)
|
||||||
await ctx.send(":x: Pas d'entrés")
|
self.cursor = self.conn.cursor()
|
||||||
|
|
||||||
|
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(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(f'{type(e).__name__}: {e}')
|
||||||
|
|
||||||
|
@_ci.command(pass_context=True, name="setconfig")
|
||||||
|
async def ci_setconfig(self, ctx, *, conf: str = None):
|
||||||
|
self.conn = db.connect_to_db(self)
|
||||||
|
self.cursor = self.conn.cursor()
|
||||||
|
|
||||||
|
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(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, *, conf: str = None):
|
||||||
|
self.conn = db.connect_to_db(self)
|
||||||
|
self.cursor = self.conn.cursor()
|
||||||
|
|
||||||
|
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(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, *, country: str = None):
|
||||||
|
self.conn = db.connect_to_db(self)
|
||||||
|
self.cursor = self.conn.cursor()
|
||||||
|
|
||||||
|
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(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):
|
||||||
|
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:
|
||||||
|
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):
|
def setup(bot):
|
||||||
bot.add_cog(Identity(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))
|
263
cogs/funs.py
|
@ -1,133 +1,188 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from random import choice, shuffle
|
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import discord
|
import discord
|
||||||
import urllib.request, json
|
import urllib.request
|
||||||
|
import json
|
||||||
import random
|
import random
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
class Funs:
|
class Funs:
|
||||||
"""Commandes funs."""
|
"""Commandes funs."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def avatar(self, ctx, user: discord.Member = None):
|
||||||
|
"""Récuperer l'avatar de ..."""
|
||||||
|
|
||||||
|
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.message.delete()
|
||||||
|
|
||||||
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def btcprice(self, ctx):
|
||||||
|
"""Le prix du BTC"""
|
||||||
|
loading = await ctx.send("_réfléchis..._")
|
||||||
|
try:
|
||||||
|
url = urllib.request.urlopen("https://blockchain.info/fr/ticker")
|
||||||
|
btc = json.loads(url.read().decode())
|
||||||
|
except KeyError:
|
||||||
|
btc = 1
|
||||||
|
|
||||||
|
if btc == 1:
|
||||||
|
await loading.edit(content="Impossible d'accèder à l'API blockchain.info, "
|
||||||
|
"veuillez réessayer ultérieurment ! :c")
|
||||||
|
else:
|
||||||
|
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, number:str = 0):
|
||||||
|
"""Print a random joke in a json file"""
|
||||||
|
with open('texts/jokes.json') as js:
|
||||||
|
jk = json.load(js)
|
||||||
|
|
||||||
|
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)]
|
||||||
|
|
||||||
@commands.command()
|
embed = discord.Embed(title="Blague _{}_ : ".format(clef), description=joke['content'], colour=0x03C9A9)
|
||||||
async def avatar(self, ctx, user : discord.Member):
|
embed.set_footer(text="Par " + joke['author'])
|
||||||
"""Récuperer l'avatar de ..."""
|
embed.set_thumbnail(url='https://outout.tech/tuxbot/blobjoy.png')
|
||||||
embed = discord.Embed(title="Avatar de : " + user.name, url=user.avatar_url, description="[Voir en plus grand]({})".format(user.avatar_url))
|
await ctx.send(embed=embed)
|
||||||
embed.set_thumbnail(url=user.avatar_url)
|
|
||||||
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.message.delete()
|
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def btcprice(self, ctx):
|
async def ethylotest(self, ctx):
|
||||||
"""Le prix du BTC"""
|
"""Ethylotest simulator 2018"""
|
||||||
loading = await ctx.send("_réfléchis..._")
|
results_poulet = ["Désolé mais mon ethylotest est sous Windows Vista, "
|
||||||
try:
|
"merci de patienter...",
|
||||||
with urllib.request.urlopen("http://api.coindesk.com/v1/bpi/currentprice/EUR.json") as url:
|
"_(ethylotest)_ : Une erreur est survenue. Windows "
|
||||||
data = json.loads(url.read().decode())
|
"cherche une solution à se problème.",
|
||||||
btc = data['bpi']['EUR']['rate']
|
"Mais j'l'ai foutu où ce p\\*\\*\\* d'ethylotest de m\\*\\*\\* "
|
||||||
btc = btc.split(".")
|
"bordel fait ch\\*\\*\\*",
|
||||||
except:
|
"C'est pas possible z'avez cassé l'ethylotest !"]
|
||||||
btc = 1
|
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..._"]
|
||||||
|
|
||||||
if btc == 1:
|
result_p = random.choice(results_poulet)
|
||||||
await ctx.send("Impossible d'accèder à l'API coindesk.com, veuillez réessayer ultérieurment !")
|
result_c = random.choice(results_client)
|
||||||
else:
|
|
||||||
await loading.edit(content="Un bitcoin est égal à : " + btc[0] + " €")
|
|
||||||
|
|
||||||
@commands.command()
|
await ctx.send(":oncoming_police_car: Bonjour bonjour, contrôle "
|
||||||
async def joke(self, ctx):
|
"d'alcoolémie !")
|
||||||
"""Print a random joke in a json file"""
|
await asyncio.sleep(0.5)
|
||||||
with open('texts/jokes.json') as js:
|
await ctx.send(":man: " + result_c)
|
||||||
jk = json.load(js)
|
await asyncio.sleep(1)
|
||||||
|
await ctx.send(":police_car: " + result_p)
|
||||||
|
|
||||||
clef = str(random.randint(1,13))
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
joke = jk["{}".format(clef)]
|
|
||||||
|
|
||||||
embed = discord.Embed(title="Blague _{}_ : ".format(clef), description=joke['content'], colour=0x03C9A9)
|
@commands.command()
|
||||||
embed.set_footer(text="Par " + joke['author'])
|
async def coin(self, ctx):
|
||||||
embed.set_thumbnail(url='https://outout.tech/tuxbot/blobjoy.png')
|
"""Coin flip simulator 2025"""
|
||||||
await ctx.send(embed=embed)
|
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 !"]
|
||||||
|
|
||||||
@commands.command()
|
start = random.choice(starts_msg)
|
||||||
async def ethylotest(self, ctx):
|
result = random.choice(results_coin)
|
||||||
"""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..._"]
|
|
||||||
|
|
||||||
result_p = random.choice(results_poulet)
|
await ctx.send(start)
|
||||||
result_c = random.choice(results_client)
|
await asyncio.sleep(0.6)
|
||||||
|
await ctx.send(result.format(":moneybag: Et la pièce retombe sur ...",
|
||||||
|
":robot:"))
|
||||||
|
|
||||||
await ctx.send(":oncoming_police_car: Bonjour bonjour, controle 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()
|
@commands.command()
|
||||||
async def coin(self, ctx):
|
async def pokemon(self, ctx):
|
||||||
"""Coin flip simulator 2025"""
|
"""Random pokemon fight"""
|
||||||
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 !"]
|
with open('texts/pokemons.json') as js:
|
||||||
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 !"]
|
jk = json.load(js)
|
||||||
|
|
||||||
start = random.choice(starts_msg)
|
poke1 = jk[random.randint(1, 150)]
|
||||||
result = random.choice(results_coin)
|
poke2 = jk[random.randint(1, 150)]
|
||||||
|
|
||||||
await ctx.send(start)
|
try:
|
||||||
await asyncio.sleep(0.6)
|
if poke1['MaxHP'] > poke2['MaxHP']:
|
||||||
await ctx.send(result.format(":moneybag: Et la pièce retombe sur ...", ":robot:"))
|
winer = poke1
|
||||||
|
else:
|
||||||
|
winer = poke2
|
||||||
|
except KeyError:
|
||||||
|
winer = poke1
|
||||||
|
|
||||||
@commands.command()
|
await ctx.send(":flag_white: **Le combat commence !**")
|
||||||
async def pokemon(self, ctx):
|
await asyncio.sleep(1)
|
||||||
"""Random pokemon fight"""
|
await ctx.send(":loudspeaker: Les concurants sont {} contre {} ! Bonne"
|
||||||
with open('texts/pokemons.json') as js:
|
" chance à eux !".format(poke1["Name"], poke2["Name"]))
|
||||||
jk = json.load(js)
|
await asyncio.sleep(0.5)
|
||||||
|
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 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"]))
|
||||||
|
|
||||||
poke1 = jk[random.randint(1, 150)]
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
poke2 = jk[random.randint(1, 150)]
|
|
||||||
|
|
||||||
try:
|
|
||||||
if poke1['MaxHP'] > poke2['MaxHP']:
|
|
||||||
winer = poke1
|
|
||||||
else:
|
|
||||||
winer = poke2
|
|
||||||
except:
|
|
||||||
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 asyncio.sleep(0.5)
|
|
||||||
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 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"]))
|
|
||||||
|
|
||||||
@commands.command()
|
|
||||||
async def randomcat(self, ctx):
|
|
||||||
"""Display a random cat"""
|
|
||||||
|
|
||||||
r = requests.get('http://random.cat/meow.php')
|
|
||||||
cat = str(r.json()['file'])
|
|
||||||
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')
|
|
||||||
await ctx.send(embed=embed)
|
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def randomcat(self, ctx):
|
||||||
|
"""Display a random cat"""
|
||||||
|
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.set_thumbnail(url=cat)
|
||||||
|
embed.set_author(name="Random.cat", url='https://random.cat/')
|
||||||
|
await ctx.send(embed=embed)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Funs(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))
|
231
cogs/search.py
|
@ -1,128 +1,157 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
|
||||||
import discord
|
import discord
|
||||||
import urllib.request, json
|
import asyncio
|
||||||
import wikipedia, bs4
|
import urllib.request
|
||||||
|
import wikipedia
|
||||||
|
|
||||||
wikipedia.set_lang("fr")
|
wikipedia.set_lang("fr")
|
||||||
|
|
||||||
|
|
||||||
class Search:
|
class Search:
|
||||||
"""Commandes de WWW."""
|
"""Commandes de WWW."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@commands.group(name="search", no_pm=True, pass_context=True)
|
@commands.group(name="search", no_pm=True, pass_context=True)
|
||||||
async def _search(self, ctx):
|
async def _search(self, ctx):
|
||||||
"""Rechercher sur le world wide web"""
|
"""Rechercher sur le world wide web"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
text = open('texts/search.md').read()
|
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',
|
||||||
await ctx.send(embed=em)
|
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()
|
||||||
|
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)
|
||||||
|
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='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="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"""
|
||||||
|
|
||||||
@_search.command(pass_context=True, name="docubuntu")
|
wait = await ctx.send("_Je cherche..._")
|
||||||
async def search_docubuntu(self, ctx, args):
|
results = wikipedia.search(args)
|
||||||
attends = await ctx.send("_Je te cherche ça {} !_".format(ctx.message.author.mention))
|
nbmr = 0
|
||||||
html = urllib.request.urlopen("https://doc.ubuntu-fr.org/" + args).read()
|
mmssgg = ""
|
||||||
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)
|
|
||||||
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")
|
for value in results:
|
||||||
async def search_aur(self, ctx, args):
|
nbmr = nbmr + 1
|
||||||
attends = await ctx.send("_Je te cherche ça {} !_".format(ctx.message.author.mention))
|
mmssgg = mmssgg + "**{}**: {} \n".format(str(nbmr), value)
|
||||||
erreur = 0
|
|
||||||
try:
|
|
||||||
html = urllib.request.urlopen("https://aur.archlinux.org/packages/" + args).read()
|
|
||||||
except:
|
|
||||||
erreur = 1
|
|
||||||
|
|
||||||
if erreur == 1:
|
em = discord.Embed(title='Résultats de : ' + args,
|
||||||
await attends.delete()
|
description = mmssgg,
|
||||||
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/')
|
colour=0x4ECDC4)
|
||||||
embed.set_author(name="Aur.archlinux", url='https://aur.archlinux.org/', icon_url='http://outout.tech/tuxbot/arch.png')
|
em.set_thumbnail(url="https://upload.wikimedia.org/wikipedia/commons/"
|
||||||
embed.set_thumbnail(url='http://outout.tech/tuxbot/arch.png')
|
"2/26/Paullusmagnus-logo_%28large%29.png")
|
||||||
embed.set_footer(text="Pff même pas trouvé !")
|
await wait.delete()
|
||||||
await ctx.send(embed=embed)
|
|
||||||
|
|
||||||
else:
|
sending = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟"]
|
||||||
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 ^^")
|
|
||||||
await ctx.send(embed=embed)
|
|
||||||
|
|
||||||
|
def check(reaction, user):
|
||||||
|
return user == ctx.author and reaction.emoji in sending and \
|
||||||
|
reaction.message.id == msg.id
|
||||||
|
|
||||||
@_search.command(pass_context=True, name="wikipedia")
|
async def waiter(future: asyncio.Future):
|
||||||
async def search_wikipedia(self, ctx: commands.Context, args):
|
reaction, user = await self.bot.wait_for('reaction_add',
|
||||||
"""Fait une recherche sur wikipd"""
|
check=check)
|
||||||
|
future.set_result(reaction.emoji)
|
||||||
|
|
||||||
wait = await ctx.send("_Je cherche..._")
|
emoji = asyncio.Future()
|
||||||
results = wikipedia.search(args)
|
self.bot.loop.create_task(waiter(emoji))
|
||||||
nbmr = 0
|
|
||||||
mmssgg = ""
|
|
||||||
|
|
||||||
for value in results:
|
msg = await ctx.send(embed=em)
|
||||||
nbmr = nbmr + 1
|
for e in sending:
|
||||||
mmssgg = mmssgg + "**{}**: {} \n".format(str(nbmr), value)
|
await msg.add_reaction(e)
|
||||||
|
if emoji.done():
|
||||||
|
break
|
||||||
|
|
||||||
em = discord.Embed(title='Résultats de : ' + args, description = mmssgg, colour=0x4ECDC4)
|
while not emoji.done():
|
||||||
em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/commons/2/26/Paullusmagnus-logo_%28large%29.png")
|
await asyncio.sleep(0.1)
|
||||||
await wait.delete()
|
|
||||||
|
|
||||||
sending = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟"]
|
sPage = int(sending.index(emoji.result()))
|
||||||
|
|
||||||
def check(reaction, user):
|
args_ = results[sPage]
|
||||||
return user == ctx.author and reaction.emoji in sending and reaction.message.id == msg.id
|
|
||||||
|
|
||||||
async def waiter(future: asyncio.Future):
|
try:
|
||||||
reaction, user = await self.bot.wait_for('reaction_add', check=check)
|
await msg.delete()
|
||||||
future.set_result(reaction.emoji)
|
await ctx.trigger_typing()
|
||||||
|
wait = await ctx.send(ctx.message.author.mention +
|
||||||
emoji = asyncio.Future()
|
" ah ok sympa cette recherche, je l'effectue de suite !")
|
||||||
self.bot.loop.create_task(waiter(emoji))
|
wp = wikipedia.page(args_)
|
||||||
|
wp_contenu = wp.summary[:200] + "..."
|
||||||
msg = await ctx.send(embed=em)
|
em = discord.Embed(title='Wikipedia : ' + wp.title,
|
||||||
for e in sending:
|
description = "{} \n_Lien_ : {} ".format(
|
||||||
await msg.add_reaction(e)
|
wp_contenu, wp.url),
|
||||||
if emoji.done():
|
colour=0x9B59B6)
|
||||||
break
|
em.set_author(name="Wikipedia",
|
||||||
|
url='http://wikipedia.org',
|
||||||
while not emoji.done():
|
icon_url='https://upload.wikimedia.org/wikipedia/'
|
||||||
await asyncio.sleep(0.1)
|
'commons/2/26/Paullusmagnus-logo_%28large'
|
||||||
|
'%29.png')
|
||||||
sPage = int(sending.index(emoji.result()))
|
em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/"
|
||||||
|
"commons/2/26/Paullusmagnus-logo_%28large"
|
||||||
args_ = results[sPage]
|
"%29.png")
|
||||||
|
em.set_footer(text="Merci à eux de nous fournir une encyclopédie "
|
||||||
try:
|
"libre !")
|
||||||
await msg.delete()
|
await wait.delete()
|
||||||
await ctx.trigger_typing()
|
await ctx.send(embed=em)
|
||||||
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 !")
|
|
||||||
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):
|
def setup(bot):
|
||||||
bot.add_cog(Search(bot))
|
bot.add_cog(Search(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))
|
452
cogs/utility.py
|
@ -1,242 +1,284 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from random import choice, shuffle
|
|
||||||
import random
|
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
|
||||||
import time
|
|
||||||
import discord
|
import discord
|
||||||
import urllib.request, json
|
import random
|
||||||
|
import json
|
||||||
import datetime, pytz
|
import datetime, pytz
|
||||||
|
|
||||||
from datetime import date
|
|
||||||
import calendar
|
import calendar
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
|
||||||
class Utility:
|
class Utility:
|
||||||
"""Commandes utilitaires."""
|
"""Commandes utilitaires."""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@commands.command()
|
@commands.group(name="clock", pass_context=True, case_insensitive=True)
|
||||||
async def clock(self, ctx, args):
|
async def clock(self, ctx):
|
||||||
"""Display hour in a country"""
|
"""Display hour in a country"""
|
||||||
args = args.upper()
|
|
||||||
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":
|
|
||||||
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":
|
|
||||||
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":
|
|
||||||
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":
|
|
||||||
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":
|
|
||||||
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":
|
|
||||||
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":
|
|
||||||
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":
|
|
||||||
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:
|
|
||||||
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.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")
|
|
||||||
|
|
||||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
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)
|
||||||
|
|
||||||
@commands.command()
|
@clock.command(name="montréal", aliases=["mtl", "montreal"], pass_context=True)
|
||||||
async def ytdiscover(self, ctx):
|
async def clock_montreal(self, ctx):
|
||||||
"""Random youtube channel"""
|
then = datetime.datetime.now(pytz.utc)
|
||||||
with open('texts/ytb.json') as js:
|
|
||||||
ytb = json.load(js)
|
|
||||||
|
|
||||||
clef = str(random.randint(0,12))
|
utc = then.astimezone(pytz.timezone('America/Montreal'))
|
||||||
chaine = ytb["{}".format(clef)]
|
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"
|
||||||
|
|
||||||
embed = discord.Embed(title=chaine['name'], url=chaine['url'],
|
form = '%H heures %M'
|
||||||
description="**{}**, {} \n[Je veux voir ça]({})".format(chaine['name'], chaine['desc'], chaine['url']))
|
tt = utc.strftime(form)
|
||||||
embed.set_thumbnail(url='https://outout.tech/tuxbot/yt.png')
|
|
||||||
await ctx.send(embed=embed)
|
|
||||||
|
|
||||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
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)
|
||||||
|
|
||||||
@commands.command(pass_context=True)
|
@clock.command(name="vancouver", pass_context=True)
|
||||||
async def afk(self, ctx):
|
async def clock_vancouver(self, ctx):
|
||||||
"""Away from keyboard"""
|
then = datetime.datetime.now(pytz.utc)
|
||||||
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))
|
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"
|
||||||
|
|
||||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
form = '%H heures %M'
|
||||||
|
tt = utc.strftime(form)
|
||||||
|
|
||||||
@commands.command(pass_context=True)
|
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)
|
||||||
async def back(self, ctx):
|
em.set_thumbnail(url = img)
|
||||||
"""I'm back !"""
|
await ctx.send(embed=em)
|
||||||
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))
|
@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. "
|
||||||
|
|
||||||
@commands.command(pass_context=True)
|
form = '%H heures %M'
|
||||||
async def sondage(self, ctx, *, msg):
|
tt = utc.strftime(form)
|
||||||
"""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:
|
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)
|
||||||
await asyncio.sleep(time)
|
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)
|
||||||
|
|
||||||
if time != 0:
|
utc = then.astimezone(pytz.timezone('America/Los_Angeles'))
|
||||||
async for message in ctx.message.channel.history():
|
site = "https://www.lacity.org/"
|
||||||
if message.id == poll_msg.id:
|
img = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/LA_Skyline_Mountains2.jpg/800px-LA_Skyline_Mountains2.jpg"
|
||||||
poll_msg = message
|
country = "aux U.S.A."
|
||||||
results = {}
|
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."
|
||||||
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)
|
|
||||||
|
|
||||||
|
form = '%H heures %M'
|
||||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
tt = utc.strftime(form)
|
||||||
|
|
||||||
@commands.command(pass_context=True)
|
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)
|
||||||
async def sondage_aide(self, ctx):
|
em.set_thumbnail(url = img)
|
||||||
await ctx.message.delete()
|
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)
|
||||||
|
|
||||||
text = open('texts/rpoll.md').read()
|
utc = then.astimezone(pytz.timezone('Europe/Paris'))
|
||||||
em = discord.Embed(title='Aide sur le sondage', description=text, colour=0xEEEEEE)
|
site = "http://www.paris.fr/"
|
||||||
await ctx.send(embed=em)
|
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."
|
||||||
|
|
||||||
"""--------------------------------------------------------------------------------------------------------------------------"""
|
form = '%H heures %M'
|
||||||
|
tt = utc.strftime(form)
|
||||||
|
|
||||||
@commands.command(name='hastebin', pass_context=True)
|
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)
|
||||||
async def _hastebin(self, ctx, *, data):
|
em.set_thumbnail(url = img)
|
||||||
"""Poster sur Hastebin."""
|
await ctx.send(embed=em)
|
||||||
await ctx.message.delete()
|
|
||||||
|
@clock.command(name="berlin", pass_context=True)
|
||||||
|
async def clock_berlin(self, ctx):
|
||||||
|
then = datetime.datetime.now(pytz.utc)
|
||||||
|
|
||||||
post = requests.post("https://hastebin.com/documents", data=data)
|
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. "
|
||||||
|
|
||||||
try:
|
form = '%H heures %M'
|
||||||
await ctx.send(str(ctx.message.author.mention)+" message posté avec succes sur :\nhttps://hastebin.com/{}.txt".format(post.json()["key"]))
|
tt = utc.strftime(form)
|
||||||
except json.JSONDecodeError:
|
|
||||||
await ctx.send("Impossible de poster ce message. L'API doit etre HS.")
|
|
||||||
|
|
||||||
@commands.command(name='test', pass_context=True)
|
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)
|
||||||
async def test(self, ctx):
|
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)
|
||||||
|
|
||||||
date = datetime.datetime.now()
|
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 »."
|
||||||
|
|
||||||
nd = str(date.day)
|
form = '%H heures %M'
|
||||||
nd += "-"
|
tt = utc.strftime(form)
|
||||||
nd += str(date.month)
|
|
||||||
nd += "-"
|
|
||||||
nd += str(date.year)
|
|
||||||
|
|
||||||
await ctx.send(nd)
|
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."
|
||||||
|
|
||||||
|
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. "
|
||||||
|
|
||||||
|
form = '%H heures %M'
|
||||||
|
tt = utc.strftime(form)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def ytdiscover(self, ctx):
|
||||||
|
"""Random youtube channel"""
|
||||||
|
with open('texts/ytb.json') as js:
|
||||||
|
ytb = json.load(js)
|
||||||
|
|
||||||
|
clef = str(random.randint(0,12))
|
||||||
|
chaine = ytb["{}".format(clef)]
|
||||||
|
|
||||||
|
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(name='hastebin', pass_context=True)
|
||||||
|
async def _hastebin(self, ctx, *, data):
|
||||||
|
"""Poster sur Hastebin."""
|
||||||
|
await ctx.message.delete()
|
||||||
|
|
||||||
|
post = requests.post("https://hastebin.com/documents", data=data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
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 être HS.")
|
||||||
|
|
||||||
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@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())
|
||||||
|
|
||||||
|
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']}")
|
||||||
|
|
||||||
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
@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):
|
def setup(bot):
|
||||||
bot.add_cog(Utility(bot))
|
bot.add_cog(Utility(bot))
|
||||||
|
|
|
@ -1,75 +1,101 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import discord.utils
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
|
||||||
def is_owner_check(message): # OUTOUT id RICK id L4P1N id GIGA id FLAYOR id ROMAIN id
|
def is_owner_check(message):
|
||||||
owner = str(message.author.id) in ['171685542553976832', '163697401935298560', '88644904112128000', '92619860521005056', '273757386127441920', '269156684155453451'] ###ID's modo & admin
|
return str(message.author.id) in ['171685542553976832', '269156684155453451']
|
||||||
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(warn=True):
|
def is_owner(warn=True):
|
||||||
def check(ctx, warn):
|
def check(ctx, warn):
|
||||||
owner = is_owner_check(ctx.message)
|
owner = is_owner_check(ctx.message)
|
||||||
if not owner and warn:
|
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
|
return owner
|
||||||
|
|
||||||
owner = commands.check(lambda ctx: check(ctx, warn))
|
owner = commands.check(lambda ctx: check(ctx, warn))
|
||||||
return owner
|
return owner
|
||||||
|
|
||||||
def check_permissions(ctx, perms):
|
"""--------------------------------------------------------------------------------------------------------------------------"""
|
||||||
msg = ctx.message
|
|
||||||
if is_owner_check(msg):
|
|
||||||
return True
|
|
||||||
|
|
||||||
ch = msg.channel
|
async def check_permissions(ctx, perms, *, check=all):
|
||||||
author = msg.author
|
is_owner = await ctx.bot.is_owner(ctx.author)
|
||||||
resolved = ch.permissions_for(author)
|
if is_owner or is_owner_check(ctx.message) == True:
|
||||||
return all(getattr(resolved, name, None) == value for name, value in perms.items())
|
return True
|
||||||
|
|
||||||
|
resolved = ctx.channel.permissions_for(ctx.author)
|
||||||
|
return check(getattr(resolved, name, None) == value for name, value in perms.items())
|
||||||
|
|
||||||
def role_or_permissions(ctx, check, **perms):
|
def has_permissions(*, check=all, **perms):
|
||||||
if check_permissions(ctx, perms):
|
async def pred(ctx):
|
||||||
return True
|
return await check_permissions(ctx, perms, check=check)
|
||||||
|
return commands.check(pred)
|
||||||
|
|
||||||
ch = ctx.message.channel
|
async def check_guild_permissions(ctx, perms, *, check=all):
|
||||||
author = ctx.message.author
|
is_owner = await ctx.bot.is_owner(ctx.author)
|
||||||
if ch.is_private:
|
if is_owner:
|
||||||
return False # can't have roles in PMs
|
return True
|
||||||
|
|
||||||
role = discord.utils.find(check, author.roles)
|
if ctx.guild is None:
|
||||||
return role is not None
|
return False
|
||||||
|
|
||||||
|
resolved = ctx.author.guild_permissions
|
||||||
|
return check(getattr(resolved, name, None) == value for name, value in perms.items())
|
||||||
|
|
||||||
def admin_or_permissions(**perms):
|
def has_guild_permissions(*, check=all, **perms):
|
||||||
def predicate(ctx):
|
async def pred(ctx):
|
||||||
return role_or_permissions(ctx, lambda r: r.name == 'Bot Admin', **perms)
|
return await check_guild_permissions(ctx, perms, check=check)
|
||||||
|
return commands.check(pred)
|
||||||
|
|
||||||
return commands.check(predicate)
|
# These do not take channel overrides into account
|
||||||
|
|
||||||
|
|
||||||
def is_in_servers(*server_ids):
|
|
||||||
def predicate(ctx):
|
|
||||||
server = ctx.message.server
|
|
||||||
if server is None:
|
|
||||||
return False
|
|
||||||
return server.id in server_ids
|
|
||||||
|
|
||||||
return commands.check(predicate)
|
|
||||||
|
|
||||||
def embed_perms(message):
|
|
||||||
try:
|
|
||||||
check = message.author.permissions_in(message.channel).embed_links
|
|
||||||
except:
|
|
||||||
check = True
|
|
||||||
|
|
||||||
return check
|
|
||||||
|
|
||||||
def is_mod():
|
def is_mod():
|
||||||
async def pred(ctx):
|
async def pred(ctx):
|
||||||
return await check_guild_permissions(ctx, {'manage_guild': True})
|
return await check_guild_permissions(ctx, {'manage_guild': True})
|
||||||
return commands.check(pred)
|
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.")
|
35
readme.md
|
@ -1,26 +1,9 @@
|
||||||
# Tuxbot
|
# Tuxbot
|
||||||
|
TuxBot, un bot discord écrit en Python. Il dispose d'une multitude de fonctionnalités.
|
||||||
[![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.
|
|
||||||
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`` ;)
|
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
|
## Installation
|
||||||
|
[Voir le guide d'installation](https://wiki.gnous.eu/wiki/Tuxbot/Install)
|
||||||
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
|
## Fabriqué avec
|
||||||
* [PyCharm](https://www.jetbrains.com/pycharm/) - Editeur de texte payant :3
|
* [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
|
## Auteurs
|
||||||
* **Maël** _alias_ [@outout14](https://github.com/outout14)
|
* **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
|
## License
|
||||||
|
Ce projet est sous licence ``Creative Commons BY-NC-SA 4.0`` - voir le fichier [LICENSE.md](LICENSE.md) pour plus d'informations
|
||||||
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
|
pytz
|
||||||
requests
|
requests
|
||||||
wikipedia
|
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 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 setconfig _votre configuration pc_ : Défini la configuration de votre ordinateur
|
||||||
-> .ci setcountry : Défini votre pays
|
-> .ci setcountry : Défini votre pays
|
||||||
-> .ci update : Met à jour votre image si vous l'avez changé :wink:
|
-> .ci update : Met à jour votre image si vous l'avez changé
|
||||||
-> .ci delete : Supprime votre carte d'identité :sob:
|
-> .ci delete : Supprime votre carte d'identité
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
**Commandes utilitaires**
|
**Commandes utilitaires**
|
||||||
-> .afk : Signaler son absence
|
-> .afk : Signaler son absence *(commande désactivée)*
|
||||||
-> .back : Signaler son retour
|
-> .back : Signaler son retour *(commande désactivée)*
|
||||||
-> .clock _ville_: Affiche l'heure et quelques infos sur la ville en question
|
-> .clock _ville_: Affiche l'heure et quelques infos sur la ville en question
|
||||||
-> .ytdiscover : Découvrir des chaines youtube
|
-> .ytdiscover : Découvrir des chaines youtube
|
||||||
-> .search _site_ _contenu_ : Fait une recherche sur un site (.search pour plus d'infos)
|
-> .search _site_ _contenu_ : Fait une recherche sur un site (.search pour plus d'infos)
|
||||||
|
@ -8,7 +8,11 @@
|
||||||
-> .poke _@pseudo_ : Poke _@pseudo_
|
-> .poke _@pseudo_ : Poke _@pseudo_
|
||||||
-> .hastebin _code_ : Poste du code sur hastebin
|
-> .hastebin _code_ : Poste du code sur hastebin
|
||||||
-> .sondage _question_ | _reponse_ | _reponse_ | _option_ : Créer un sondage avec des réactions
|
-> .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**
|
**Commandes Funs**
|
||||||
-> .joke : Affiche une blague aléatoire
|
-> .joke : Affiche une blague aléatoire
|
||||||
|
@ -30,6 +34,6 @@
|
||||||
**Commandes diverses** :
|
**Commandes diverses** :
|
||||||
-> .info : Affiche des informations sur le bot
|
-> .info : Affiche des informations sur le bot
|
||||||
-> .help : Affiche ce message
|
-> .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
|
-> .ping : Ping le bot
|
||||||
-> .github : Affiche le repos Github du Bot :heart:
|
-> .github : Affiche le repos Github du Bot :heart:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
<:stafftools:314348604095594498> **Développement** :
|
<:stafftools:314348604095594498> **Développement** :
|
||||||
└> Outout : [outout.tech](https://outout.tech/)
|
└> Outout : [outout.xyz](https://outout.xyz/)
|
||||||
└> Romain : [son github](https://github.com/Rom194)
|
└> Romain : [son github](http://git.dyjix.eu/Romain)
|
||||||
└> Langage : [Python3](http://www.python.org/)
|
└> Langage : [Python3](http://www.python.org/)
|
||||||
└> Api : [discord.py {3}](https://github.com/Rapptz/discord.py)
|
└> Api : [discord.py {3}](https://github.com/Rapptz/discord.py)
|
||||||
└> En se basant sur : [RobotDanny](https://github.com/Rapptz/RoboDanny)
|
└> En se basant sur : [RobotDanny](https://github.com/Rapptz/RoboDanny)
|
||||||
|
@ -12,12 +12,13 @@
|
||||||
|
|
||||||
<:contact:334347787200233483> **Contact** :
|
<:contact:334347787200233483> **Contact** :
|
||||||
└> <:discord:314003252830011395> : Outout#8406
|
└> <:discord:314003252830011395> : Outout#8406
|
||||||
└> <:twitter:314349922877046786> : [@outout14_](https://twitter.com/outout14_)
|
└> <:twitter:314349922877046786> : [@outoutxyz](https://twitter.com/outouxyz)
|
||||||
└> <:mail:334345653419245571> : [outout@linuxmail.org](mailto:outout@linuxmail.org)
|
└> <:mail:334345653419245571> : [mael@gnous.eu](mailto:mael@gnous.eu)
|
||||||
|
└> <:discord:314003252830011395> : Romain#5117
|
||||||
|
|
||||||
|
|
||||||
<:discord:314003252830011395> **Serveurs** :
|
<:discord:314003252830011395> **Serveurs** :
|
||||||
└> <:tux:282212977627758593> Serveur de TuxBot : [rejoindre](https://discord.gg/5UZy8Pn)
|
└> :tux: Serveur de TuxBot : [rejoindre](https://discord.gg/5UZy8Pn)
|
||||||
└> <:tux:282212977627758593> Serveur GNU/Linux-Fr : [rejoindre](https://discord.gg/B5TzW7x)
|
└> <: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}``
|
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.
|
-> [**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 !
|
-> [**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 !
|
||||||
|
|