This commit is contained in:
Romain J 2021-04-20 17:12:38 +02:00
parent 7f9c202cc6
commit 64fba7fec6
19 changed files with 101 additions and 84 deletions

View file

@ -5,6 +5,7 @@
<excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/dist" /> <excludeFolder url="file://$MODULE_DIR$/dist" />
<excludeFolder url="file://$MODULE_DIR$/venv" /> <excludeFolder url="file://$MODULE_DIR$/venv" />
<excludeFolder url="file://$MODULE_DIR$/data" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.10 (tuxbot_bot)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.10 (tuxbot_bot)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />

14
.idea/webResources.xml Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebResourcesPaths">
<contentEntries>
<entry url="file://$PROJECT_DIR$">
<entryData>
<resourceRoots>
<path value="file://$PROJECT_DIR$" />
</resourceRoots>
</entryData>
</entry>
</contentEntries>
</component>
</project>

View file

@ -34,7 +34,7 @@ update-all:
$(VIRTUAL_ENV)/bin/pip install --upgrade --force-reinstall . $(VIRTUAL_ENV)/bin/pip install --upgrade --force-reinstall .
.PHONY: dev .PHONY: dev
dev: black update dev: black type update
tuxbot tuxbot
# Docker # Docker

View file

@ -23,7 +23,7 @@ log = logging.getLogger("tuxbot.cogs.Admin")
_ = Translator("Admin", __file__) _ = Translator("Admin", __file__)
class Admin(commands.Cog, name="Admin"): class Admin(commands.Cog):
def __init__(self, bot: Tux): def __init__(self, bot: Tux):
self.bot = bot self.bot = bot

View file

@ -16,7 +16,7 @@ log = logging.getLogger("tuxbot.cogs.Crypto")
_ = Translator("Crypto", __file__) _ = Translator("Crypto", __file__)
class Crypto(commands.Cog, name="Crypto"): class Crypto(commands.Cog):
def __init__(self, bot: Tux): def __init__(self, bot: Tux):
self.bot = bot self.bot = bot

View file

@ -5,8 +5,8 @@ from tuxbot.cogs.Crypto.functions.parser import data_parser
async def extract( async def extract(
attachments: list[Optional[Attachment]], data: str, max_size: int attachments: list[Optional[Attachment]], data: Optional[str], max_size: int
) -> Union[dict, NoReturn]: ) -> dict:
if not data and len(attachments) == 0: if not data and len(attachments) == 0:
raise ValueError raise ValueError

View file

@ -1,7 +1,8 @@
import re import re
from typing import Optional
def data_parser(data: str) -> dict: def data_parser(data: Optional[str]) -> dict:
output = { output = {
"message": "", "message": "",
"compressed": False, "compressed": False,

View file

@ -22,7 +22,7 @@ log = logging.getLogger("tuxbot.cogs.Custom")
_ = Translator("Custom", __file__) _ = Translator("Custom", __file__)
class Custom(commands.Cog, name="Custom"): class Custom(commands.Cog):
def __init__(self, bot: Tux): def __init__(self, bot: Tux):
self.bot = bot self.bot = bot
@ -76,10 +76,10 @@ class Custom(commands.Cog, name="Custom"):
@_custom.command(name="alias", aliases=["aliases"]) @_custom.command(name="alias", aliases=["aliases"])
async def _custom_alias(self, ctx: ContextPlus, *, alias: AliasConvertor): async def _custom_alias(self, ctx: ContextPlus, *, alias: AliasConvertor):
args = str(alias).split(" | ") args: list[str] = str(alias).split(" | ")
command = args[0] command = args[0]
alias = args[1] custom = args[1]
user_aliases = await self._get_aliases(ctx) user_aliases = await self._get_aliases(ctx)
@ -87,17 +87,17 @@ class Custom(commands.Cog, name="Custom"):
set_if_none(self.bot.config.Users, ctx.author.id, Config.User) set_if_none(self.bot.config.Users, ctx.author.id, Config.User)
user_aliases = await self._get_aliases(ctx) user_aliases = await self._get_aliases(ctx)
if alias in user_aliases.keys(): if custom in user_aliases.keys():
return await ctx.send( return await ctx.send(
_( _(
"The alias `{alias}` is already defined " "The alias `{alias}` is already defined "
"for the command `{command}`", "for the command `{command}`",
ctx, ctx,
self.bot.config, self.bot.config,
).format(alias=alias, command=user_aliases.get(alias)) ).format(alias=custom, command=user_aliases.get(custom))
) )
user_aliases[alias] = command user_aliases[custom] = command
await self._save_alias(ctx, user_aliases) await self._save_alias(ctx, user_aliases)
@ -107,5 +107,5 @@ class Custom(commands.Cog, name="Custom"):
"was successfully created", "was successfully created",
ctx, ctx,
self.bot.config, self.bot.config,
).format(alias=alias, command=command) ).format(alias=custom, command=command)
) )

View file

@ -12,7 +12,7 @@ log = logging.getLogger("tuxbot.cogs.Dev")
_ = Translator("Dev", __file__) _ = Translator("Dev", __file__)
class Dev(commands.Cog, name="Dev"): class Dev(commands.Cog):
def __init__(self, bot: Tux): def __init__(self, bot: Tux):
self.bot = bot self.bot = bot
@ -26,6 +26,6 @@ class Dev(commands.Cog, name="Dev"):
await ctx.send(str(5 / 0)) await ctx.send(str(5 / 0))
elif crash_type == "TypeError": elif crash_type == "TypeError":
# noinspection PyTypeChecker # noinspection PyTypeChecker
await ctx.send(str(int([]))) await ctx.send(str(int([]))) # type: ignore
elif crash_type == "IndexError": elif crash_type == "IndexError":
await ctx.send(str([0][5])) await ctx.send(str([0][5]))

View file

@ -6,6 +6,7 @@ import textwrap
import traceback import traceback
from collections import defaultdict from collections import defaultdict
from logging import LogRecord from logging import LogRecord
from typing import Any, Dict
import discord import discord
import humanize import humanize
@ -47,13 +48,13 @@ class GatewayHandler(logging.Handler):
self.cog.add_record(record) self.cog.add_record(record)
class Logs(commands.Cog, name="Logs"): class Logs(commands.Cog):
def __init__(self, bot: Tux): def __init__(self, bot: Tux):
self.bot = bot self.bot = bot
self.process = psutil.Process() self.process = psutil.Process()
self._batch_lock = asyncio.Lock() self._batch_lock = asyncio.Lock()
self._data_batch = [] self._data_batch: list[Dict[str, Any]] = []
self._gateway_queue = asyncio.Queue() self._gateway_queue: asyncio.Queue = asyncio.Queue()
self.gateway_worker.start() # pylint: disable=no-member self.gateway_worker.start() # pylint: disable=no-member
self.__config: LogsConfig = ConfigFile( self.__config: LogsConfig = ConfigFile(
@ -61,8 +62,8 @@ class Logs(commands.Cog, name="Logs"):
LogsConfig, LogsConfig,
).config ).config
self._resumes = [] self._resumes: list[datetime.datetime] = []
self._identifies = defaultdict(list) self._identifies: defaultdict[Any, list] = defaultdict(list)
self.old_on_error = bot.on_error self.old_on_error = bot.on_error
bot.on_error = self.on_error bot.on_error = self.on_error
@ -215,7 +216,7 @@ class Logs(commands.Cog, name="Logs"):
e = discord.Embed(colour=0x0A97F5, title="New DM") # blue colour e = discord.Embed(colour=0x0A97F5, title="New DM") # blue colour
e.set_author( e.set_author(
name=message.author, name=message.author,
icon_url=message.author.avatar_url_as(format="png"), icon_url=message.author.avatar.url,
) )
e.description = message.content e.description = message.content
if len(message.attachments) > 0: if len(message.attachments) > 0:

View file

@ -134,7 +134,7 @@ async def get_pydig_result(
def check_ip_version_or_raise(version: str) -> Union[bool, NoReturn]: def check_ip_version_or_raise(version: str) -> Union[bool, NoReturn]:
if version in ["4", "6", ""]: if version in ["4", "6", "None"]:
return True return True
raise InvalidIp(_("Invalid ip version")) raise InvalidIp(_("Invalid ip version"))

View file

@ -1,7 +1,7 @@
import asyncio import asyncio
import logging import logging
import time import time
from typing import Union from typing import Union, Optional
import aiohttp import aiohttp
import discord import discord
@ -48,7 +48,7 @@ log = logging.getLogger("tuxbot.cogs.Network")
_ = Translator("Network", __file__) _ = Translator("Network", __file__)
class Network(commands.Cog, name="Network"): class Network(commands.Cog):
def __init__(self, bot: Tux): def __init__(self, bot: Tux):
self.bot = bot self.bot = bot
self.__config: NetworkConfig = ConfigFile( self.__config: NetworkConfig = ConfigFile(
@ -78,7 +78,7 @@ class Network(commands.Cog, name="Network"):
self, self,
ctx: ContextPlus, ctx: ContextPlus,
ip: IPConverter, ip: IPConverter,
version: IPVersionConverter = "", version: Optional[IPVersionConverter] = None,
): ):
check_ip_version_or_raise(str(version)) check_ip_version_or_raise(str(version))

View file

@ -2,7 +2,6 @@ import json
from os.path import dirname from os.path import dirname
import discord import discord
from tuxbot.cogs import Polls
from tuxbot.core.i18n import Translator from tuxbot.core.i18n import Translator
from tuxbot.core.utils.functions.utils import upper_first from tuxbot.core.utils.functions.utils import upper_first
@ -14,7 +13,7 @@ _ = Translator("Polls", dirname(__file__))
async def _poll_reaction_add( async def _poll_reaction_add(
self: Polls, pld: discord.RawReactionActionEvent, poll: Poll self, pld: discord.RawReactionActionEvent, poll: Poll
): ):
if poll.is_anonymous: if poll.is_anonymous:
try: try:
@ -40,7 +39,7 @@ async def _poll_reaction_add(
async def _suggest_reaction_add( async def _suggest_reaction_add(
self: Polls, pld: discord.RawReactionActionEvent, suggest: Suggest self, pld: discord.RawReactionActionEvent, suggest: Suggest
): ):
poll = await suggest.poll poll = await suggest.poll
@ -48,10 +47,10 @@ async def _suggest_reaction_add(
poll.author_id == pld.user_id poll.author_id == pld.user_id
or (await self.bot.is_owner(discord.Object(pld.user_id))) or (await self.bot.is_owner(discord.Object(pld.user_id)))
or ( or (
(channel := await self.bot.fetch_channel(pld.channel_id)) (_channel := await self.bot.fetch_channel(pld.channel_id))
# pylint: disable=used-before-assignment # pylint: disable=used-before-assignment
.permissions_for( .permissions_for(
await channel.guild.fetch_member(pld.user_id) await _channel.guild.fetch_member(pld.user_id)
).administrator ).administrator
) )
): ):
@ -77,19 +76,19 @@ async def _suggest_reaction_add(
await poll.save() await poll.save()
channel: discord.TextChannel = await self.bot.fetch_channel( poll_channel: discord.TextChannel = await self.bot.fetch_channel(
poll.channel_id poll.channel_id
) )
message = await channel.fetch_message(poll.message_id) message = await poll_channel.fetch_message(poll.message_id)
await message.add_reaction(emote) await message.add_reaction(emote)
await self.update_poll(poll) await self.update_poll(poll)
channel: discord.TextChannel = await self.bot.fetch_channel( suggest_channel: discord.TextChannel = await self.bot.fetch_channel(
suggest.channel_id suggest.channel_id
) )
message = await channel.fetch_message(suggest.message_id) message = await suggest_channel.fetch_message(suggest.message_id)
await message.delete() await message.delete()
@ -102,20 +101,18 @@ async def _suggest_reaction_add(
pass pass
async def cog_command_error(self: Polls, ctx, error): async def cog_command_error(self, ctx, error):
if isinstance(error, (InvalidChannel, BadPoll, TooLongProposition)): if isinstance(error, (InvalidChannel, BadPoll, TooLongProposition)):
await ctx.send(_(str(error), ctx, self.bot.config)) await ctx.send(_(str(error), ctx, self.bot.config))
async def on_raw_reaction_add( async def on_raw_reaction_add(self, pld: discord.RawReactionActionEvent):
self: Polls, pld: discord.RawReactionActionEvent
):
poll = await self.get_poll(pld) poll = await self.get_poll(pld)
if poll: if isinstance(poll, Poll):
await _poll_reaction_add(self, pld, poll) await _poll_reaction_add(self, pld, poll)
elif suggest := await self.get_suggest(pld): elif isinstance(suggest := await self.get_suggest(pld), Suggest):
await _suggest_reaction_add(self, pld, suggest) await _suggest_reaction_add(self, pld, suggest)

View file

@ -1,6 +1,6 @@
import json import json
import logging import logging
from typing import Union from typing import Union, Dict, Iterable, Any
import discord import discord
from discord.ext import commands from discord.ext import commands
@ -21,7 +21,7 @@ log = logging.getLogger("tuxbot.cogs.Polls")
_ = Translator("Polls", __file__) _ = Translator("Polls", __file__)
class Polls(commands.Cog, name="Polls"): class Polls(commands.Cog):
def __init__(self, bot: Tux): def __init__(self, bot: Tux):
self.bot = bot self.bot = bot
@ -63,9 +63,9 @@ class Polls(commands.Cog, name="Polls"):
poll_row.channel_id = stmt.channel.id poll_row.channel_id = stmt.channel.id
poll_row.message_id = stmt.id poll_row.message_id = stmt.id
poll_row.author_id = ctx.author.id poll_row.author_id = ctx.author.id
poll_row.content = {} poll_row.content = {} # type: ignore
poll_row.is_anonymous = anonymous poll_row.is_anonymous = anonymous
poll_row.available_choices = len(answers) poll_row.available_choices = len(answers) # type: ignore
await poll_row.save() await poll_row.save()
@ -113,12 +113,12 @@ class Polls(commands.Cog, name="Polls"):
} }
content = ( content = (
json.loads(poll.content) json.loads(poll.content) # type: ignore
if isinstance(poll.content, str) if isinstance(poll.content, str)
else poll.content else poll.content
) )
responses = {} responses: Dict[int, int] = {}
async for response in poll.choices: async for response in poll.choices:
if responses.get(response.choice): if responses.get(response.choice):
@ -126,14 +126,14 @@ class Polls(commands.Cog, name="Polls"):
else: else:
responses[response.choice] = 1 responses[response.choice] = 1
for i, field in enumerate(content.get("fields")): for i, field in enumerate(content.get("fields")): # type: ignore
responders = responses.get(i, 0) responders = responses.get(i, 0)
chart_options["data"]["labels"].append( chart_options["data"]["labels"].append( # type: ignore
field["name"][6:].replace("__", "") field["name"][6:].replace("__", "")
) )
chart_options["data"]["datasets"][0]["data"].append(responders) chart_options["data"]["datasets"][0]["data"].append(responders) # type: ignore
if responders <= 1: if responders <= 1:
field["value"] = f"**{responders}** vote" field["value"] = f"**{responders}** vote"
@ -142,22 +142,22 @@ class Polls(commands.Cog, name="Polls"):
e = discord.Embed(description=content.get("description")) e = discord.Embed(description=content.get("description"))
e.set_author( e.set_author(
name=content.get("author").get("name"), name=content.get("author").get("name"), # type: ignore
icon_url=content.get("author").get("icon_url"), icon_url=content.get("author").get("icon_url"), # type: ignore
) )
chart_url = URL(chart_base_url + json.dumps(chart_options)) chart_url = URL(chart_base_url + json.dumps(chart_options))
e.set_thumbnail(url=str(chart_url)) e.set_thumbnail(url=str(chart_url))
for field in content.get("fields"): for field in content.get("fields"): # type: ignore
e.add_field( e.add_field(
name=field.get("name"), value=field.get("value"), inline=True name=field.get("name"), value=field.get("value"), inline=True
) )
e.set_footer(text=content.get("footer").get("text")) e.set_footer(text=content.get("footer").get("text")) # type: ignore
await message.edit(embed=e) await message.edit(embed=e)
poll.content = json.dumps(content) poll.content = json.dumps(content) # type: ignore
await poll.save() await poll.save()
@ -190,7 +190,7 @@ class Polls(commands.Cog, name="Polls"):
"""Just to change type for PyCharm""" """Just to change type for PyCharm"""
suggest_row.poll = poll suggest_row.poll = poll
suggest_row.proposition = new suggest_row.proposition = new # type: ignore
await suggest_row.save() await suggest_row.save()
@ -215,7 +215,7 @@ class Polls(commands.Cog, name="Polls"):
text=_("Requested by {author}", ctx, self.bot.config).format( text=_("Requested by {author}", ctx, self.bot.config).format(
author=ctx.author.name author=ctx.author.name
), ),
icon_url=ctx.author.avatar_url_as(format="png"), icon_url=ctx.author.avatar.url,
) )
await stmt.edit(content="", embed=e) await stmt.edit(content="", embed=e)

View file

@ -20,7 +20,7 @@ log = logging.getLogger("tuxbot.cogs.Utils")
_ = Translator("Utils", __file__) _ = Translator("Utils", __file__)
class Utils(commands.Cog, name="Utils"): class Utils(commands.Cog):
def __init__(self, bot: Tux): def __init__(self, bot: Tux):
self.bot = bot self.bot = bot

View file

@ -205,7 +205,7 @@ class Tux(commands.AutoShardedBot):
self.console.print() self.console.print()
async def is_owner( async def is_owner(
self, user: Union[discord.User, discord.Member] self, user: Union[discord.User, discord.Member, discord.Object]
) -> bool: ) -> bool:
"""Determines if the user is a bot owner. """Determines if the user is a bot owner.

View file

@ -46,14 +46,16 @@ def get_locale_name(locale: str) -> str:
class Translator: class Translator:
"""Class to load texts at init.""" """Class to load texts at init."""
def __init__(self, name: str, file_location: Union[Path, os.PathLike]): def __init__(
self, name: str, file_location: Union[Path, os.PathLike, str]
):
"""Initializes the Translator object. """Initializes the Translator object.
Parameters Parameters
---------- ----------
name : str name : str
The cog name. The cog name.
file_location:Path|os.PathLike file_location:Path|os.PathLike|str
File path for the required extension. File path for the required extension.
""" """

View file

@ -13,27 +13,6 @@ formatter = logging.Formatter(
) )
def _setup_logging(level: int, location: pathlib.Path, name: str) -> None:
logger = logging.getLogger(name)
logger.setLevel(level)
logger_file = location / f"{name}.log"
handler = logging.handlers.RotatingFileHandler(
str(logger_file.resolve()),
maxBytes=MAX_BYTES,
backupCount=MAX_OLD_LOGS,
)
base_handler = logging.handlers.RotatingFileHandler(
str(logger_file.resolve()),
maxBytes=MAX_BYTES,
backupCount=MAX_OLD_LOGS,
)
handler.setFormatter(formatter)
base_handler.setFormatter(formatter)
def init_logging(level: int, location: pathlib.Path) -> None: def init_logging(level: int, location: pathlib.Path) -> None:
"""Initialize loggers. """Initialize loggers.
@ -45,8 +24,30 @@ def init_logging(level: int, location: pathlib.Path) -> None:
Where to store Logs. Where to store Logs.
""" """
_setup_logging(level, location, "discord") # dpy_logger = logging.getLogger("discord")
_setup_logging(level, location, "tuxbot") # dpy_logger.setLevel(logging.WARN)
# dpy_logger_file = location / "discord.log"
base_logger = logging.getLogger("tuxbot")
base_logger.setLevel(level)
base_logger_file = location / "tuxbot.log"
# dpy_handler = logging.handlers.RotatingFileHandler(
# str(dpy_logger_file.resolve()),
# maxBytes=MAX_BYTES,
# backupCount=MAX_OLD_LOGS,
# )
base_handler = logging.handlers.RotatingFileHandler(
str(base_logger_file.resolve()),
maxBytes=MAX_BYTES,
backupCount=MAX_OLD_LOGS,
)
stdout_handler = logging.StreamHandler(sys.stdout) stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(formatter) stdout_handler.setFormatter(formatter)
# dpy_handler.setFormatter(formatter)
base_handler.setFormatter(formatter)
# dpy_logger.addHandler(dpy_handler)
base_logger.addHandler(base_handler)

View file

@ -199,7 +199,7 @@ def additional_config(cogs: Union[str, list] = "**"):
console.print(Rule(f"\nConfiguration for `{cog_name}` module")) console.print(Rule(f"\nConfiguration for `{cog_name}` module"))
mod = importlib.import_module(str(path).replace("/", ".")[:-3]) mod = importlib.import_module(str(path).replace("/", ".")[:-3])
mod_config_type = getattr(mod, cog_name.capitalize() + "Config") mod_config_type = getattr(mod, cog_name.capitalize() + "Config")
mod_extra = mod.extra mod_extra = mod.extra # type: ignore
mod_config = config.ConfigFile( mod_config = config.ConfigFile(
str(cogs_data_path(cog_name) / "config.yaml"), str(cogs_data_path(cog_name) / "config.yaml"),