tuxbot-bot/cogs/utility.py

604 lines
26 KiB
Python
Raw Normal View History

2020-04-27 15:21:56 +00:00
import datetime
import json
import pytz
import random
import urllib
2020-08-18 19:50:23 +00:00
import aiohttp
2020-04-27 15:21:56 +00:00
import ipinfo as ipinfoio
2020-08-19 15:07:50 +00:00
import pydig
2020-08-18 20:01:34 +00:00
2020-08-19 14:33:48 +00:00
import telnetlib
from graphviz import Digraph
2020-04-27 15:21:56 +00:00
from ipwhois.net import Net
from ipwhois.asn import IPASN
2020-08-18 19:39:23 +00:00
import ipwhois
2020-04-27 15:21:56 +00:00
import discord
2020-08-19 14:33:48 +00:00
import requests, re
2020-04-27 15:21:56 +00:00
from discord.ext import commands
import socket
class Utility(commands.Cog):
"""Commandes utilitaires."""
def __init__(self, bot):
self.bot = bot
@commands.group(name="clock", pass_context=True, case_insensitive=True)
async def clock(self, ctx):
"""Display hour in a country"""
if ctx.invoked_subcommand is None:
text = open('texts/clocks.md').read()
em = discord.Embed(title='Liste des Horloges', description=text, colour=0xEEEEEE)
await ctx.send(embed=em)
@clock.command(name="montréal", aliases=["mtl", "montreal"], pass_context=True)
async def clock_montreal(self, ctx):
then = datetime.datetime.now(pytz.utc)
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"
form = '%H heures %M'
tt = utc.strftime(form)
em = discord.Embed(title='Heure à Montréal', description=f"A [Montréal]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
em.set_thumbnail(url = img)
await ctx.send(embed=em)
@clock.command(name="vancouver", pass_context=True)
async def clock_vancouver(self, ctx):
then = datetime.datetime.now(pytz.utc)
utc = then.astimezone(pytz.timezone('America/Vancouver'))
site = "http://vancouver.ca/"
img = "https://upload.wikimedia.org/wikipedia/commons/f/fe/Dock_Vancouver.JPG"
country = "au Canada"
description = "Vancouver, officiellement City of Vancouver, est une cité portuaire au Canada"
form = '%H heures %M'
tt = utc.strftime(form)
em = discord.Embed(title='Heure à Vancouver', description=f"A [Vancouver]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
em.set_thumbnail(url = img)
await ctx.send(embed=em)
@clock.command(name="new-york",aliases=["ny", "n-y", "new york"], pass_context=True)
async def clock_new_york(self, ctx):
then = datetime.datetime.now(pytz.utc)
utc = then.astimezone(pytz.timezone('America/New_York'))
site = "http://www1.nyc.gov/"
img = "https://upload.wikimedia.org/wikipedia/commons/e/e3/NewYork_LibertyStatue.jpg"
country = "aux U.S.A."
description = "New York, est la plus grande ville des États-Unis en termes d'habitants et l'une des plus importantes du continent américain. "
form = '%H heures %M'
tt = utc.strftime(form)
em = discord.Embed(title='Heure à New York', description=f"A [str(New York]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
em.set_thumbnail(url = img)
await ctx.send(embed=em)
@clock.command(name="la", aliases=["los-angeles", "losangeles", "l-a", "los angeles"], pass_context=True)
async def clock_la(self, ctx):
then = datetime.datetime.now(pytz.utc)
utc = then.astimezone(pytz.timezone('America/Los_Angeles'))
site = "https://www.lacity.org/"
img = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/LA_Skyline_Mountains2.jpg/800px-LA_Skyline_Mountains2.jpg"
country = "aux U.S.A."
description = "Los Angeles est la deuxième ville la plus peuplée des États-Unis après New York. Elle est située dans le sud de l'État de Californie, sur la côte pacifique."
form = '%H heures %M'
tt = utc.strftime(form)
em = discord.Embed(title='Heure à Los Angeles', description=f"A [Los Angeles]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
em.set_thumbnail(url = img)
await ctx.send(embed=em)
@clock.command(name="paris", aliases=["baguette"],pass_context=True)
async def clock_paris(self, ctx):
then = datetime.datetime.now(pytz.utc)
utc = then.astimezone(pytz.timezone('Europe/Paris'))
site = "http://www.paris.fr/"
img = "https://upload.wikimedia.org/wikipedia/commons/a/af/Tour_eiffel_at_sunrise_from_the_trocadero.jpg"
country = "en France"
description = "Paris est la capitale de la France. Elle se situe au cœur d'un vaste bassin sédimentaire aux sols fertiles et au climat tempéré, le bassin parisien."
form = '%H heures %M'
tt = utc.strftime(form)
em = discord.Embed(title='Heure à Paris', description=f"A [Paris]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
em.set_thumbnail(url = img)
await ctx.send(embed=em)
@clock.command(name="berlin", pass_context=True)
async def clock_berlin(self, ctx):
then = datetime.datetime.now(pytz.utc)
utc = then.astimezone(pytz.timezone('Europe/Berlin'))
site = "http://www.berlin.de/"
img = "https://upload.wikimedia.org/wikipedia/commons/9/91/Eduard_Gaertner_Schlossfreiheit.jpg"
country = "en Allemagne"
description = "Berlin est la capitale et la plus grande ville d'Allemagne. Située dans le nord-est du pays, elle compte environ 3,5 millions d'habitants. "
form = '%H heures %M'
tt = utc.strftime(form)
em = discord.Embed(title='Heure à Berlin', description=f"A [Berlin]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
em.set_thumbnail(url = img)
await ctx.send(embed=em)
@clock.command(name="berne", aliases=["zurich", "bern"], pass_context=True)
async def clock_berne(self, ctx):
then = datetime.datetime.now(pytz.utc)
utc = then.astimezone(pytz.timezone('Europe/Zurich'))
site = "http://www.berne.ch/"
img = "https://upload.wikimedia.org/wikipedia/commons/d/db/Justitia_Statue_02.jpg"
country = "en Suisse"
description = "Berne est la cinquième plus grande ville de Suisse et la capitale du canton homonyme. Depuis 1848, Berne est la « ville fédérale »."
form = '%H heures %M'
tt = utc.strftime(form)
em = discord.Embed(title='Heure à Berne', description=f"A [Berne]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE)
em.set_thumbnail(url = img)
await ctx.send(embed=em)
@clock.command(name="tokyo", pass_context=True)
async def clock_tokyo(self, ctx):
then = datetime.datetime.now(pytz.utc)
utc = then.astimezone(pytz.timezone('Asia/Tokyo'))
site = "http://www.gotokyo.org/"
img = "https://upload.wikimedia.org/wikipedia/commons/3/37/TaroTokyo20110213-TokyoTower-01.jpg"
country = "au Japon"
description = "Tokyo, anciennement Edo, officiellement la préfecture métropolitaine de Tokyo, est la capitale du Japon."
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='iplocalise', pass_context=True)
async def _iplocalise(self, ctx, ipaddress, iptype=""):
realipaddress = ipaddress
"""Getting headers."""
if ipaddress.startswith("http://"):
if ipaddress[-1:] == '/':
ipaddress = ipaddress[:-1]
ipaddress = ipaddress.split("http://")[1]
if ipaddress.startswith("https://"):
if ipaddress[-1:] == '/':
ipaddress = ipaddress[:-1]
ipaddress = ipaddress.split("https://")[1]
if(iptype=="ipv6" or iptype=="v6" or iptype=="-6"):
try:
ipaddress = socket.getaddrinfo(ipaddress, None, socket.AF_INET6)[1][4][0]
except Exception as e:
await ctx.send("Erreur, cette adresse n'est pas disponible en IPv6.")
return
elif(iptype=="ipv4" or iptype=="v4" or iptype=="-4"):
try:
ipaddress = socket.getaddrinfo(ipaddress, None, socket.AF_INET)[1][4][0]
except Exception as e:
await ctx.send("Erreur, cette adresse n'est pas disponible en IPv4.")
return
else:
try:
ipaddress = socket.getaddrinfo(ipaddress, None)[1][4][0]
except Exception as e:
await ctx.send("Erreur, cette adresse n'est pas disponible.")
return
iploading = await ctx.send("_Récupération des informations..._")
2020-08-18 19:39:23 +00:00
try:
net = Net(ipaddress)
obj = IPASN(net)
ipinfo = obj.lookup()
except ipwhois.exceptions.IPDefinedError:
await ctx.send("Cette IP est reservée à un usage local selon la RFC 1918. Impossible d'avoir des informations supplémentaires à son propos.")
await iploading.delete()
return
2020-04-27 15:21:56 +00:00
try:
iphostname = socket.gethostbyaddr(ipaddress)[0]
except:
iphostname = "N/A"
# IPINFO api
api_result = True
try:
2020-08-18 19:50:23 +00:00
with open('ipinfoio.key') as k:
access_token = k.read().replace("\n", "")
2020-04-27 15:21:56 +00:00
handler = ipinfoio.getHandler(access_token)
details = handler.getDetails(ipaddress)
2020-08-18 19:50:23 +00:00
except Exception as e:
2020-04-27 15:21:56 +00:00
api_result = False
try:
embed = discord.Embed(title=f"Informations pour ``{realipaddress} ({ipaddress})``", color=0x5858d7)
if(api_result):
2020-08-18 19:39:23 +00:00
asn = details.org.split(" ")[0]
embed.add_field(name="Appartient à :", value=f"[{details.org}](https://bgp.he.net/{asn})")
2020-04-27 15:21:56 +00:00
else:
2020-08-18 19:39:23 +00:00
embed.add_field(name="Appartient à :", value=f"{ipinfo['asn_description']} ([AS{ipinfo['asn']}](https://bgp.he.net/{ipinfo['asn']}))", inline = False)
2020-04-27 15:21:56 +00:00
embed.add_field(name="RIR :", value=f"{ipinfo['asn_registry']}", inline = True)
if(api_result):
embed.add_field(name="Région :", value=f"{details.city} - {details.region} ({details.country})")
else:
embed.add_field(name="Région :", value=f"{ipinfo['asn_country_code']}")
embed.add_field(name="Nom de l'hôte :", value=f"{iphostname}")
# Adding country flag
if(api_result):
embed.set_thumbnail(url=f"https://www.countryflags.io/{details.country}/shiny/64.png")
else:
embed.set_thumbnail(url=f"https://www.countryflags.io/{ipinfo['asn_country_code']}/shiny/64.png")
await ctx.send(embed=embed)
except:
await ctx.send(content=f"Erreur, impossible d'avoir des informations sur l'adresse IP ``{realipaddress}``")
await iploading.delete()
2020-08-18 20:01:34 +00:00
"""---------------------------------------------------------------------"""
@commands.command(name='dig', pass_context=True)
async def _dig(self, ctx, domain, querytype="abc", dnssec="no"):
if not querytype in ['A', 'AAAA', 'CNAME', 'NS', 'DS', 'DNSKEY', 'SOA', 'TXT', 'PTR', 'MX']:
await ctx.send("Requêtes supportées : A, AAAA, CNAME, NS, DS, DNSKEY, SOA, TXT, PTR, MX")
return
2020-08-19 15:07:50 +00:00
2020-08-18 20:01:34 +00:00
if(dnssec == "no"):
resolver = pydig.Resolver(
nameservers=[
'80.67.169.40',
'80.67.169.12',
]
)
else:
resolver = pydig.Resolver(
nameservers=[
'80.67.169.40',
'80.67.169.12',
],
additional_args=[
'+dnssec',
]
)
resquery = resolver.query(domain, querytype)
embed = discord.Embed(title=f"Requête DIG sur {domain} pour une entrée {querytype}", color=0x5858d7)
champ_id = 1
for champ in resquery:
embed.add_field(name=f"Champ {champ_id} :", value=champ)
champ_id = champ_id + 1
if champ_id == 1:
embed.add_field(name="Ooops", value="Pas de résultat")
await ctx.send(embed=embed)
2020-08-19 14:33:48 +00:00
2020-04-27 15:21:56 +00:00
"""---------------------------------------------------------------------"""
2020-08-18 19:50:23 +00:00
@commands.command(name='getheaders')
async def _getheaders(self, ctx: commands.Context, addr: str):
if (addr.startswith('http') or addr.startswith('ftp')) is not True:
addr = f"http://{addr}"
await ctx.trigger_typing()
try:
async with self.bot.session.get(addr) as s:
e = discord.Embed(
title=f"Headers : {addr}",
color=0xd75858
)
e.add_field(name="Status", value=s.status, inline=True)
e.set_thumbnail(url=f"https://http.cat/{s.status}")
headers = dict(s.headers.items())
headers.pop('Set-Cookie', headers)
for key, value in headers.items():
e.add_field(name=key, value=value, inline=True)
await ctx.send(embed=e)
except aiohttp.ClientError:
await ctx.send(
f"Cannot connect to host {addr}"
)
2020-04-27 15:21:56 +00:00
"""---------------------------------------------------------------------"""
@commands.command(name='peeringdb', pass_context=True)
async def _peeringdb(self, ctx, *, asn):
def notEmptyField(embed, name, value):
if(value != ""):
embed.add_field(name=name, value=value)
if asn.startswith("AS"):
asn = asn[2:]
loadingmsg = await ctx.send("_Récupération des informations..._")
"""Getting the ASN id in the peeringdb database"""
try:
asnid = urllib.request.urlopen("https://www.peeringdb.com/api/as_set/" + asn)
asnid = json.loads(asnid.read().decode())
pdbid = asnid["data"][0][asn]
asinfo = urllib.request.urlopen("https://www.peeringdb.com/api/net?irr_as_set=" + pdbid)
asinfo = json.loads(asinfo.read().decode())["data"]
for asndata in asinfo:
if(asndata['asn'] == int(asn)):
asinfo = asndata
asproto = ""
if(asinfo["info_ipv6"]):
asproto = asproto + "IPv6 "
if(asinfo["info_unicast"]):
asproto = asproto + "Unicast "
if(asinfo["info_multicast"]):
asproto = asproto + "Multicast "
if(asinfo["info_never_via_route_servers"]):
asproto = asproto + "Never via Route servers"
embed = discord.Embed(title=f"Informations pour {asinfo['name']} ``AS{asn}``", color=0x5858d7)
notEmptyField(embed, name="Nom :", value=asinfo['name'])
notEmptyField(embed, name="Aka :", value=asinfo['aka'])
notEmptyField(embed, name="Site :", value=asinfo['website'])
notEmptyField(embed, name="Looking Glass :", value=asinfo['looking_glass'])
notEmptyField(embed, name="Traffic :", value=asinfo['info_traffic'])
notEmptyField(embed, name="Ratio du traffic :", value=asinfo['info_ratio'])
notEmptyField(embed, name="Prefixes IPv4 :", value=asinfo['info_prefixes4'])
notEmptyField(embed, name="Prefixes IPv6 :", value=asinfo['info_prefixes6'])
notEmptyField(embed, name="Politique de Peering :", value=f"[{asinfo['policy_general']}]({asinfo['policy_url']})")
notEmptyField(embed, name="Protocoles supportés :", value=asproto)
embed.set_footer(text=f"https://www.peeringdb.com/")
await ctx.send(embed=embed)
await loadingmsg.delete()
except IndexError:
await ctx.send(f"Impossible d'avoir des informations sur l'AS AS{asn}")
await loadingmsg.delete()
except urllib.error.HTTPError:
await ctx.send(f"L'AS{asn} est introuvable dans la base de données de PeeringDB.")
await loadingmsg.delete()
2020-08-19 14:33:48 +00:00
"""---------------------------------------------------------------------"""
@commands.command(name='shroute', pass_context=True)
2020-08-24 15:52:45 +00:00
async def _shroute(self, ctx, srv, ipaddress):
"""Show as path graph to an IP via data from a Route Server using graphviz"""
2020-08-19 14:33:48 +00:00
if not srv in ["opentransit", 'he', 'att', "oregonuniv", "warian", 'csaholdigs', 'iamageeknz']:
await ctx.send("Requêtes supportées : opentransit (Orange), he (Huricanne Electric), att (AT&T), oregonuniv, warian, csaholdigs, iamageeknz")
return
2020-08-24 15:52:45 +00:00
#List of RS
2020-08-19 14:33:48 +00:00
if srv == "opentransit":
host = "route-server.opentransit.net"
user = "rviews"
password = "Rviews"
lg_asn = "5511"
cmd = "show bgp {}"
elif srv == "oregonuniv":
host = "route-views.routeviews.org"
user = "rviews"
password = "none"
lg_asn = "3582"
cmd = "show bgp {}"
elif srv == "warian":
host = "route-server.warian.net"
user = "none"
password = "rviews"
lg_asn = "56911"
cmd = "show bgp ipv4 unicast {}"
2020-08-24 15:52:45 +00:00
elif srv == "csaholdigs": #Blacklist sometime
2020-08-19 14:33:48 +00:00
host = "route-views.sg.routeviews.org"
user = "none"
password = "none"
lg_asn = "45494"
cmd = "show bgp ipv4 unicast {}"
2020-08-24 15:52:45 +00:00
elif srv == "he": #Blacklist sometime
2020-08-19 14:33:48 +00:00
host = "route-server.he.net"
user = "none"
password = "none"
lg_asn = "6939"
cmd = "show bgp ipv4 unicast {}"
2020-08-24 15:52:45 +00:00
elif srv == "iamageeknz": #Blacklist sometime
2020-08-19 14:33:48 +00:00
host = "rs.as45186.net"
user = "none"
password = "none"
lg_asn = "45186"
cmd = "show bgp ipv4 unicast {}"
elif srv == "att":
host = "route-server.ip.att.net"
user = "rviews"
password = "rviews"
lg_asn = "7018"
cmd = "show route {}"
ip = ipaddress
await ctx.send("Connexion en cours au route server...")
tn = telnetlib.Telnet(host)
2020-08-24 15:52:45 +00:00
#Login to the RS via Telnet
2020-08-19 14:33:48 +00:00
if user != "none":
if(srv == "att"):
tn.read_until("login: ".encode())
tn.write((user + "\n").encode())
else:
tn.read_until("Username: ".encode())
tn.write((user + "\n").encode())
if password != "none":
if(srv == "att"):
tn.read_until("Password:".encode())
tn.write((password + "\n").encode())
else:
tn.read_until("Password: ".encode())
tn.write((password + "\n").encode())
await ctx.send("Connecté ! Récupération des données...")
2020-08-24 15:52:45 +00:00
#Sending show route via telnet to the RS
2020-08-19 14:33:48 +00:00
tn.write((cmd + "\n").format(ip).encode())
tn.write(chr(25).encode())
tn.write(chr(25).encode())
tn.write(chr(25).encode())
tn.write("q\n".encode())
tn.write("exit\n".encode())
await ctx.send("Données récupérées ! Traitement en cours")
2020-08-24 15:52:45 +00:00
#Parsing data
2020-08-19 14:33:48 +00:00
data = tn.read_all().decode("utf-8")
paths = {}
2020-08-24 15:52:45 +00:00
#Parsing as paths
2020-08-19 14:33:48 +00:00
paths["as_list"] = re.findall(r" ([0-9][0-9 ]+),", data)
if(paths["as_list"] == []):
paths["as_list"] = re.findall(r" ([0-9][0-9 ]+)[^0-9.]", data)
2020-08-24 15:52:45 +00:00
#Custom parsing for AT&T
2020-08-19 14:33:48 +00:00
if(srv == "att"):
paths["as_list"] = re.findall(r"(?<=AS path: 7018 )[0-9][0-9 ]+[^ I]", data)
2020-08-24 15:52:45 +00:00
#Graphviz diagram
g = Digraph('G', filename='bgpgraph', format='png', graph_attr={'rankdir':'LR', 'concentrate': 'true'})
2020-08-19 14:33:48 +00:00
2020-08-24 15:52:45 +00:00
#Diagram paths generation
as_path_count = 0
for as_path in paths['as_list']:
2020-08-19 14:33:48 +00:00
as_path = as_path.split(" ")
as_path.reverse()
original_asn = as_path[0]
border_asn = as_path[-1]
precedent_asn = original_asn
for asn in as_path:
2020-08-24 15:52:45 +00:00
if asn != "2001": #Cause HE got a default or something weird to this asn
if asn != original_asn:
g.edge("AS" + asn, "AS" + precedent_asn)
precedent_asn = asn
if asn == border_asn:
g.edge("AS" + lg_asn, "AS" + asn)
as_path_count += 1
#If empty as_path
if as_path_count == 0:
await ctx.send("Pas de route trouvée vers l'IP demandée depuis le route server choisi.")
return
2020-08-19 14:33:48 +00:00
2020-08-24 15:52:45 +00:00
#Render the graph
2020-08-19 14:33:48 +00:00
g.render()
2020-08-24 15:52:45 +00:00
#Send it
with open('bgpgraph.png', 'rb') as fp:
await ctx.send(file=discord.File(fp, 'bgpgraph.png'))
2020-08-19 14:33:48 +00:00
2020-04-27 15:21:56 +00:00
"""---------------------------------------------------------------------"""
@commands.command(name='git', pass_context=True)
async def _git(self, ctx):
"""Pour voir mon code"""
text = "How tu veux voir mon repos Gitea pour me disséquer ? " \
"Pas de soucis ! Je suis un Bot, je ne ressens pas la " \
"douleur !\n https://git.gnous.eu/gnouseu/tuxbot-bot"
em = discord.Embed(title='Repos TuxBot-Bot', description=text, colour=0xE9D460)
em.set_author(name='Gnous', icon_url="https://cdn.discordapp.com/"
"icons/280805240977227776/"
"9ba1f756c9d9bfcf27989d0d0abb3862"
".png")
await ctx.send(embed=em)
"""---------------------------------------------------------------------"""
@commands.command(name='quote', pass_context=True)
async def _quote(self, ctx, quote_id):
global quoted_message
async def get_message(message_id: int):
for channel in ctx.message.guild.channels:
if isinstance(channel, discord.TextChannel):
test_chan = await self.bot.fetch_channel(channel.id)
try:
return await test_chan.fetch_message(message_id)
except (discord.NotFound, discord.Forbidden):
pass
return None
quoted_message = await get_message(int(quote_id))
if quoted_message is not None:
embed = discord.Embed(colour=quoted_message.author.colour,
description=quoted_message.clean_content,
timestamp=quoted_message.created_at)
embed.set_author(name=quoted_message.author.display_name,
icon_url=quoted_message.author.avatar_url_as(
format="jpg"))
if len(quoted_message.attachments) >= 1:
embed.set_image(url=quoted_message.attachments[0].url)
embed.add_field(name="**Original**",
value=f"[Go!]({quoted_message.jump_url})")
embed.set_footer(text="#" + quoted_message.channel.name)
await ctx.send(embed=embed)
else:
await ctx.send("Impossible de trouver le message.")
def setup(bot):
bot.add_cog(Utility(bot))