feat(commands|Network>iplocalise): feat iplocalise command
todo: - fix l'INET6 qui s'affiche comme 10 plutot que 6 - suppr le message Retrieving info si la commande n'a pas pu etre faite - this shit https://canary.discord.com/channels/767804368233037886/768097484655689758/803299217279811634
This commit is contained in:
parent
fa3069244d
commit
7962205d16
17 changed files with 504 additions and 7 deletions
|
@ -17,6 +17,7 @@
|
|||
<w>gnous</w>
|
||||
<w>ipinfo</w>
|
||||
<w>iplocalise</w>
|
||||
<w>ipwhois</w>
|
||||
<w>jishaku</w>
|
||||
<w>langue</w>
|
||||
<w>levelname</w>
|
||||
|
|
|
@ -21,6 +21,7 @@ install_requires =
|
|||
discord.py @ git+https://github.com/Rapptz/discord.py
|
||||
discord_flags>=2.1.1
|
||||
humanize>=2.6.0
|
||||
ipwhois>=1.2.0
|
||||
jishaku>=1.19.1.200
|
||||
psutil>=5.7.2
|
||||
requests>=2.25.1
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Tuxbot-bot\n"
|
||||
"Report-Msgid-Bugs-To: rick@gnous.eu\n"
|
||||
"POT-Creation-Date: 2021-01-25 14:36+0100\n"
|
||||
"POT-Creation-Date: 2021-01-25 16:09+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Tuxbot-bot\n"
|
||||
"Report-Msgid-Bugs-To: rick@gnous.eu\n"
|
||||
"POT-Creation-Date: 2021-01-25 14:36+0100\n"
|
||||
"POT-Creation-Date: 2021-01-25 16:09+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
19
tuxbot/cogs/Network/__init__.py
Normal file
19
tuxbot/cogs/Network/__init__.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
from collections import namedtuple
|
||||
|
||||
from tuxbot.core.bot import Tux
|
||||
from .network import Network
|
||||
from .config import NetworkConfig, HAS_MODELS
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro release_level")
|
||||
version_info = VersionInfo(major=1, minor=0, micro=0, release_level="alpha")
|
||||
|
||||
__version__ = "v{}.{}.{}-{}".format(
|
||||
version_info.major,
|
||||
version_info.minor,
|
||||
version_info.micro,
|
||||
version_info.release_level,
|
||||
).replace("\n", "")
|
||||
|
||||
|
||||
def setup(bot: Tux):
|
||||
bot.add_cog(Network(bot))
|
15
tuxbot/cogs/Network/config.py
Normal file
15
tuxbot/cogs/Network/config.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
from structured_config import Structure, StrField
|
||||
|
||||
HAS_MODELS = False
|
||||
|
||||
|
||||
class NetworkConfig(Structure):
|
||||
ipinfoKey: str = StrField("")
|
||||
|
||||
|
||||
extra = {
|
||||
"ipinfoKey": {
|
||||
"type": str,
|
||||
"description": "API Key for ipinfo.io (.iplocalise command)",
|
||||
},
|
||||
}
|
39
tuxbot/cogs/Network/functions/converters.py
Normal file
39
tuxbot/cogs/Network/functions/converters.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
import re
|
||||
|
||||
from discord.ext import commands
|
||||
|
||||
from tuxbot.cogs.Network.functions.exceptions import InvalidIp
|
||||
|
||||
|
||||
def _(x):
|
||||
return x
|
||||
|
||||
|
||||
DOMAIN_PATTERN = "^([A-Za-z0-9]\.|[A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9]\.){1,3}[A-Za-z]{2,6}$"
|
||||
IP_PATTERN = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
|
||||
|
||||
|
||||
class IPConverter(commands.Converter):
|
||||
async def convert(self, ctx, argument):
|
||||
argument = argument.replace("http://", "").replace("https://", "")
|
||||
|
||||
check_domain = re.match(DOMAIN_PATTERN, argument)
|
||||
check_ip = re.match(IP_PATTERN, argument)
|
||||
|
||||
if check_domain or check_ip:
|
||||
return argument
|
||||
|
||||
raise InvalidIp(_("Invalid ip or domain"))
|
||||
|
||||
|
||||
class IPVersionConverter(commands.Converter):
|
||||
async def convert(self, ctx, argument):
|
||||
if not argument:
|
||||
return argument
|
||||
|
||||
argument = argument.replace("-", "").replace("p", "").replace("v", "")
|
||||
|
||||
if argument not in ["4", "6"]:
|
||||
raise InvalidIp(_("Invalid ip version"))
|
||||
|
||||
return argument
|
9
tuxbot/cogs/Network/functions/exceptions.py
Normal file
9
tuxbot/cogs/Network/functions/exceptions.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from discord.ext import commands
|
||||
|
||||
|
||||
class RFC18(commands.UserNotFound):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidIp(commands.BadArgument):
|
||||
pass
|
64
tuxbot/cogs/Network/locales/en-US.po
Normal file
64
tuxbot/cogs/Network/locales/en-US.po
Normal file
|
@ -0,0 +1,64 @@
|
|||
# French translations for Tuxbot-bot package
|
||||
# Traductions françaises du paquet Tuxbot-bot.
|
||||
# Copyright (C) 2020 THE Tuxbot-bot'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the Tuxbot-bot package.
|
||||
# Automatically generated, 2020.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Tuxbot-bot\n"
|
||||
"Report-Msgid-Bugs-To: rick@gnous.eu\n"
|
||||
"POT-Creation-Date: 2021-01-19 14:39+0100\n"
|
||||
"PO-Revision-Date: 2021-01-19 14:39+0100\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: tuxbot/cogs/Network/functions/converters.py:22
|
||||
msgid "Invalid ip or domain"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/functions/converters.py:35
|
||||
msgid "Invalid ip version"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:49 tuxbot/cogs/Network/network.py:52
|
||||
#, python-brace-format
|
||||
msgid "in v{v}"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:61
|
||||
#, python-brace-format
|
||||
msgid "Impossible to collect information on this ip {version}"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:89
|
||||
#, python-brace-format
|
||||
msgid "IP address {ip_address} is already defined as Private-Use Networks via RFC 1918."
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:109
|
||||
msgid "*Retrieving information...*"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:123
|
||||
#, python-brace-format
|
||||
msgid "Information for ``{ip} ({ip_address})``"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:135 tuxbot/cogs/Network/network.py:156
|
||||
msgid "Belongs to:"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:140 tuxbot/cogs/Network/network.py:161
|
||||
msgid "Region:"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:174
|
||||
#, python-brace-format
|
||||
msgid "Hostname: {hostname}"
|
||||
msgstr ""
|
64
tuxbot/cogs/Network/locales/fr-FR.po
Normal file
64
tuxbot/cogs/Network/locales/fr-FR.po
Normal file
|
@ -0,0 +1,64 @@
|
|||
# French translations for Tuxbot-bot package
|
||||
# Traductions françaises du paquet Tuxbot-bot.
|
||||
# Copyright (C) 2020 THE Tuxbot-bot'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the Tuxbot-bot package.
|
||||
# Automatically generated, 2020.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Tuxbot-bot\n"
|
||||
"Report-Msgid-Bugs-To: rick@gnous.eu\n"
|
||||
"POT-Creation-Date: 2021-01-19 14:39+0100\n"
|
||||
"PO-Revision-Date: 2021-01-19 14:39+0100\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: tuxbot/cogs/Network/functions/converters.py:22
|
||||
msgid "Invalid ip or domain"
|
||||
msgstr "Nome de domaine ou adresse IP invalide"
|
||||
|
||||
#: tuxbot/cogs/Network/functions/converters.py:35
|
||||
msgid "Invalid ip version"
|
||||
msgstr "Version d'adresse IP invalide"
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:49 tuxbot/cogs/Network/network.py:52
|
||||
#, python-brace-format
|
||||
msgid "in v{v}"
|
||||
msgstr "en v{v}"
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:61
|
||||
#, python-brace-format
|
||||
msgid "Impossible to collect information on this ip {version}"
|
||||
msgstr "Impossible de collecter des informations pour cette IP {version}"
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:89
|
||||
#, python-brace-format
|
||||
msgid "IP address {ip_address} is already defined as Private-Use Networks via RFC 1918."
|
||||
msgstr "L'adresse ip {ip_address} est est reservée à un usage local selon la RFC 1918"
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:109
|
||||
msgid "*Retrieving information...*"
|
||||
msgstr "*Récupération des informations...*"
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:123
|
||||
#, python-brace-format
|
||||
msgid "Information for ``{ip} ({ip_address})``"
|
||||
msgstr "Informations pour ``{ip} ({ip_address})``"
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:135 tuxbot/cogs/Network/network.py:156
|
||||
msgid "Belongs to:"
|
||||
msgstr "Appartient à :"
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:140 tuxbot/cogs/Network/network.py:161
|
||||
msgid "Region:"
|
||||
msgstr "Région :"
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:174
|
||||
#, python-brace-format
|
||||
msgid "Hostname: {hostname}"
|
||||
msgstr "Nom d'hôte : {hostname}"
|
63
tuxbot/cogs/Network/locales/messages.pot
Normal file
63
tuxbot/cogs/Network/locales/messages.pot
Normal file
|
@ -0,0 +1,63 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the Tuxbot-bot package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Tuxbot-bot\n"
|
||||
"Report-Msgid-Bugs-To: rick@gnous.eu\n"
|
||||
"POT-Creation-Date: 2021-01-25 16:09+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: tuxbot/cogs/Network/functions/converters.py:22
|
||||
msgid "Invalid ip or domain"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/functions/converters.py:35
|
||||
msgid "Invalid ip version"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:49 tuxbot/cogs/Network/network.py:52
|
||||
#, python-brace-format
|
||||
msgid "in v{v}"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:61
|
||||
#, python-brace-format
|
||||
msgid "Impossible to collect information on this ip {version}"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:89
|
||||
#, python-brace-format
|
||||
msgid "IP address {ip_address} is already defined as Private-Use Networks via RFC 1918."
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:109
|
||||
msgid "*Retrieving information...*"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:123
|
||||
#, python-brace-format
|
||||
msgid "Information for ``{ip} ({ip_address})``"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:135 tuxbot/cogs/Network/network.py:156
|
||||
msgid "Belongs to:"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:140 tuxbot/cogs/Network/network.py:161
|
||||
msgid "Region:"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Network/network.py:174
|
||||
#, python-brace-format
|
||||
msgid "Hostname: {hostname}"
|
||||
msgstr ""
|
0
tuxbot/cogs/Network/models/__init__.py
Normal file
0
tuxbot/cogs/Network/models/__init__.py
Normal file
199
tuxbot/cogs/Network/network.py
Normal file
199
tuxbot/cogs/Network/network.py
Normal file
|
@ -0,0 +1,199 @@
|
|||
import functools
|
||||
import logging
|
||||
import socket
|
||||
from typing import Union, NoReturn
|
||||
|
||||
import discord
|
||||
import ipinfo
|
||||
import ipwhois
|
||||
from discord.ext import commands
|
||||
from ipinfo.exceptions import RequestQuotaExceededError
|
||||
from ipwhois import Net
|
||||
from ipwhois.asn import IPASN
|
||||
from structured_config import ConfigFile
|
||||
|
||||
from tuxbot.cogs.Network.functions.converters import (
|
||||
IPConverter,
|
||||
IPVersionConverter,
|
||||
)
|
||||
from tuxbot.cogs.Network.functions.exceptions import RFC18, InvalidIp
|
||||
from tuxbot.core.bot import Tux
|
||||
from tuxbot.core.i18n import (
|
||||
Translator,
|
||||
)
|
||||
from tuxbot.core.utils.data_manager import cogs_data_path
|
||||
from tuxbot.core.utils.functions.extra import (
|
||||
ContextPlus,
|
||||
command_extra,
|
||||
)
|
||||
from .config import NetworkConfig
|
||||
|
||||
log = logging.getLogger("tuxbot.cogs.Network")
|
||||
_ = Translator("Network", __file__)
|
||||
|
||||
|
||||
class Network(commands.Cog, name="Network"):
|
||||
def __init__(self, bot: Tux):
|
||||
self.bot = bot
|
||||
self.config: NetworkConfig = ConfigFile(
|
||||
str(
|
||||
cogs_data_path(self.bot.instance_name, "Network")
|
||||
/ "config.yaml"
|
||||
),
|
||||
NetworkConfig,
|
||||
).config
|
||||
|
||||
async def cog_command_error(self, ctx, error):
|
||||
if isinstance(error, (RequestQuotaExceededError, RFC18, InvalidIp)):
|
||||
await ctx.send(_(str(error), ctx, self.bot.config))
|
||||
|
||||
# =========================================================================
|
||||
# =========================================================================
|
||||
|
||||
async def _get_ip(self, ctx: ContextPlus, ip: str, inet: str = "") -> str:
|
||||
inet_text = ""
|
||||
|
||||
if inet == "6":
|
||||
inet = socket.AF_INET6
|
||||
inet_text = _("in v{v}", ctx, self.bot.config).format(v=inet)
|
||||
elif inet == "4":
|
||||
inet = socket.AF_INET
|
||||
inet_text = _("in v{v}", ctx, self.bot.config).format(v=inet)
|
||||
else:
|
||||
inet = 0
|
||||
|
||||
try:
|
||||
return socket.getaddrinfo(str(ip), None, inet)[1][4][0]
|
||||
except socket.gaierror:
|
||||
return await ctx.send(
|
||||
_(
|
||||
"Impossible to collect information on this ip {version}".format(
|
||||
version=inet_text
|
||||
),
|
||||
ctx,
|
||||
self.bot.config,
|
||||
)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _get_hostname(ip: str) -> str:
|
||||
try:
|
||||
return socket.gethostbyaddr(ip)[0]
|
||||
except socket.herror:
|
||||
return "N/A"
|
||||
|
||||
@staticmethod
|
||||
def get_ipwhois_result(ip_address: str) -> Union[NoReturn, dict]:
|
||||
try:
|
||||
net = Net(ip_address)
|
||||
obj = IPASN(net)
|
||||
return obj.lookup()
|
||||
except ipwhois.exceptions.ASNRegistryError:
|
||||
return {}
|
||||
except ipwhois.exceptions.IPDefinedError as e:
|
||||
|
||||
def _(x):
|
||||
return x
|
||||
|
||||
raise RFC18(
|
||||
_(
|
||||
"IP address {ip_address} is already defined as Private-Use"
|
||||
" Networks via RFC 1918."
|
||||
)
|
||||
) from e
|
||||
|
||||
async def get_ipinfo_result(
|
||||
self, ip_address: str
|
||||
) -> Union[NoReturn, dict]:
|
||||
try:
|
||||
handler = ipinfo.getHandlerAsync(self.config.ipinfoKey)
|
||||
return (await handler.getDetails(ip_address)).all
|
||||
except RequestQuotaExceededError:
|
||||
return {}
|
||||
|
||||
# =========================================================================
|
||||
# =========================================================================
|
||||
|
||||
@command_extra(name="iplocalise", aliases=["localiseip"], deletable=True)
|
||||
async def _iplocalise(
|
||||
self,
|
||||
ctx: ContextPlus,
|
||||
ip: IPConverter,
|
||||
version: IPVersionConverter = "",
|
||||
):
|
||||
tmp = await ctx.send(
|
||||
_("*Retrieving information...*", ctx, self.bot.config),
|
||||
deletable=False,
|
||||
)
|
||||
|
||||
ip_address = await self._get_ip(ctx, str(ip), str(version))
|
||||
ip_hostname = self._get_hostname(ip_address)
|
||||
|
||||
ipinfo_result = await self.get_ipinfo_result(ip_address)
|
||||
ipwhois_result = await self.bot.loop.run_in_executor(
|
||||
None, functools.partial(self.get_ipwhois_result, ip_address)
|
||||
)
|
||||
|
||||
e = discord.Embed(
|
||||
title=_(
|
||||
"Information for ``{ip} ({ip_address})``", ctx, self.bot.config
|
||||
).format(ip=ip, ip_address=ip_address),
|
||||
color=0x5858D7,
|
||||
)
|
||||
|
||||
if ipinfo_result:
|
||||
org = ipinfo_result.get("org", "")
|
||||
asn = org.split()[0]
|
||||
|
||||
e.add_field(
|
||||
name=_("Belongs to:", ctx, self.bot.config),
|
||||
value=f"[{org}](https://bgp.he.net/{asn})",
|
||||
inline=True,
|
||||
)
|
||||
|
||||
e.add_field(
|
||||
name=_("Region:", ctx, self.bot.config),
|
||||
value=f"{ipinfo_result.get('city', 'N/A')} - "
|
||||
f"{ipinfo_result.get('region', 'N/A')} "
|
||||
f"({ipinfo_result.get('country', 'N/A')})",
|
||||
inline=False,
|
||||
)
|
||||
|
||||
e.set_thumbnail(
|
||||
url=f"https://www.countryflags.io/{ipinfo_result['country']}"
|
||||
f"/shiny/64.png"
|
||||
)
|
||||
elif ipwhois_result:
|
||||
org = ipwhois_result.get("asn_description", "N/A")
|
||||
asn = ipwhois_result.get("asn", "N/A")
|
||||
asn_country = ipwhois_result.get("asn_country_code", "N/A")
|
||||
|
||||
e.add_field(
|
||||
name=_("Belongs to:", ctx, self.bot.config),
|
||||
value=f"{org} ([AS{asn}](https://bgp.he.net/{asn}))",
|
||||
inline=True,
|
||||
)
|
||||
|
||||
e.add_field(
|
||||
name=_("Region:", ctx, self.bot.config),
|
||||
value=asn_country,
|
||||
inline=False,
|
||||
)
|
||||
|
||||
e.set_thumbnail(
|
||||
url=f"https://www.countryflags.io/{asn_country}/shiny/64.png"
|
||||
)
|
||||
|
||||
if ipwhois_result:
|
||||
e.add_field(
|
||||
name="RIR :", value=ipwhois_result["asn_registry"], inline=True
|
||||
)
|
||||
|
||||
e.set_footer(
|
||||
text=_("Hostname: {hostname}", ctx, self.bot.config).format(
|
||||
hostname=ip_hostname
|
||||
),
|
||||
)
|
||||
|
||||
await tmp.delete()
|
||||
await ctx.send(embed=e)
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Tuxbot-bot\n"
|
||||
"Report-Msgid-Bugs-To: rick@gnous.eu\n"
|
||||
"POT-Creation-Date: 2021-01-25 14:36+0100\n"
|
||||
"POT-Creation-Date: 2021-01-25 16:09+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Tuxbot-bot\n"
|
||||
"Report-Msgid-Bugs-To: rick@gnous.eu\n"
|
||||
"POT-Creation-Date: 2021-01-25 14:36+0100\n"
|
||||
"POT-Creation-Date: 2021-01-25 16:09+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -29,7 +29,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"**{}** physical memory\n"
|
||||
"**{}** virtual memory\n"
|
||||
"**{}**% CPU"
|
||||
"**{:.2f}**% CPU"
|
||||
msgstr ""
|
||||
|
||||
#: tuxbot/cogs/Utils/utils.py:77
|
||||
|
|
|
@ -25,8 +25,9 @@ class ContextPlus(commands.Context):
|
|||
delete_after=None,
|
||||
nonce=None,
|
||||
allowed_mentions=None,
|
||||
deletable=False
|
||||
deletable=True
|
||||
): # i know *args and **kwargs but, i prefer work with same values
|
||||
|
||||
if content:
|
||||
content = content.replace(
|
||||
self.bot.config.Core.token, TOKEN_REPLACEMENT
|
||||
|
@ -47,7 +48,7 @@ class ContextPlus(commands.Context):
|
|||
|
||||
if (
|
||||
hasattr(self.command, "deletable") and self.command.deletable
|
||||
) or deletable:
|
||||
) and deletable:
|
||||
message = await super().send(
|
||||
content=content,
|
||||
tts=tts,
|
||||
|
|
|
@ -1,2 +1,24 @@
|
|||
import functools
|
||||
|
||||
from discord.ext import commands
|
||||
|
||||
from tuxbot.core.utils.functions.extra import ContextPlus
|
||||
|
||||
|
||||
def upper_first(string: str) -> str:
|
||||
return "".join(string[0].upper() + string[1:])
|
||||
|
||||
|
||||
def typing(func):
|
||||
@functools.wraps(func)
|
||||
async def wrapped(*args, **kwargs):
|
||||
context = (
|
||||
args[0]
|
||||
if isinstance(args[0], (commands.Context, ContextPlus))
|
||||
else args[1]
|
||||
)
|
||||
|
||||
async with context.typing():
|
||||
await func(*args, **kwargs)
|
||||
|
||||
return wrapped
|
||||
|
|
Loading…
Reference in a new issue