Made Pylint happy.

This commit is contained in:
Vegard Berg 2022-07-21 21:27:47 +02:00
parent 6e6af4b508
commit 2357c835a6
6 changed files with 279 additions and 89 deletions

View File

@ -1,27 +1,21 @@
import re
from os import getenv
from naff import (
Client,
Intents,
listen,
slash_command,
InteractionContext,
slash_option,
OptionTypes,
)
from naff.api.events.discord import MessageCreate
from naff.models.discord.enums import ButtonStyles, Permissions
from naff.models.discord.embed import (
Embed,
EmbedAttachment,
EmbedAuthor,
EmbedField,
EmbedFooter,
EmbedProvider,
)
from naff.models.discord.components import ActionRow, Button, Select, SelectOption
from dotenv import load_dotenv
from os import getenv
bot = Client(intents=Intents.ALL, debug_scope=387153131378835456)
@ -42,6 +36,7 @@ async def ping_command(ctx: InteractionContext):
ctx.ephemeral = True
await ctx.send("Pong!")
@slash_command(name="bot-info", description="Get info about the bot")
async def bot_info_command(ctx: InteractionContext):
await ctx.send(
@ -49,7 +44,7 @@ async def bot_info_command(ctx: InteractionContext):
embed=Embed(
title=f"{bot.user.username}",
description=f"This bot is owned by {bot.owner}",
color=0x00ff00,
color=0x00FF00,
timestamp=bot.user.created_at,
url=bot.user.avatar.as_url(),
author=EmbedAuthor(
@ -65,7 +60,7 @@ async def bot_info_command(ctx: InteractionContext):
name="**Extensions**",
value=f"{len(bot.extensions)}",
)
]
],
),
)
@ -75,4 +70,3 @@ if __name__ == "__main__":
bot.load_extension("commands.quote")
bot.load_extension("commands.infractions")
bot.start(getenv("DISCORD_TOKEN"))

View File

@ -7,8 +7,6 @@ from naff import (
OptionTypes,
InteractionContext,
Embed,
EmbedAttachment,
EmbedAuthor,
EmbedField,
Permissions,
Member,
@ -17,7 +15,9 @@ from naff import (
Button,
ButtonStyles,
)
from database import Infractions as InfractionsModel, GuildSettings as GuildSettingsModel
from database import (
Infractions as InfractionsModel,
)
class Infractions(Extension):
@ -39,7 +39,7 @@ class Infractions(Extension):
return
embeds: List[Embed] = []
for infraction in infractions:
for infraction in infractions: # pylint: disable=not-an-iterable
embed = Embed(
title="Infraction",
description=f"{infraction.reason}",
@ -53,12 +53,21 @@ class Infractions(Extension):
],
)
embeds.append(embed)
await ctx.send(embed=embeds, ephemeral=True)
@slash_command(name="user-infractions", description="View a user's infractions", dm_permission=False, default_member_permissions=Permissions.KICK_MEMBERS)
@slash_option(name="user", description="User to view", required=True, opt_type=OptionTypes.USER)
await ctx.send(embed=embeds, ephemeral=True)
@slash_command(
name="user-infractions",
description="View a user's infractions",
dm_permission=False,
default_member_permissions=Permissions.KICK_MEMBERS,
)
@slash_option(
name="user",
description="User to view",
required=True,
opt_type=OptionTypes.USER,
)
async def user_infractions(self, ctx: InteractionContext, user: Member):
await ctx.defer(ephemeral=False)
infractions: List[InfractionsModel] = InfractionsModel.select().where(
@ -71,16 +80,16 @@ class Infractions(Extension):
return
embeds: List[Embed] = []
for infraction in infractions:
issuer = await self.client.fetch_member(guild_id=ctx.guild, user_id=infraction.given_by)
for infraction in infractions: # pylint: disable=not-an-iterable
issuer = await self.client.fetch_member(
guild_id=ctx.guild, user_id=infraction.given_by
)
embed = Embed(
title=f"Infraction for user {user.display_name} ({user.username}#{user.discriminator}, {user.id})",
title=f"Infraction for user {user.display_name} ({user.username}#{user.discriminator}, {user.id})", # pylint: disable=line-too-long
description=f"{infraction.reason}",
color=infraction_colour(infraction.weight),
fields=[
EmbedField(
name="**ID**", value=f"{infraction.id}"
),
EmbedField(name="**ID**", value=f"{infraction.id}"),
EmbedField(
name="**Received**",
value=f"<t:{int(infraction.at_time.timestamp())}:F>",
@ -90,15 +99,49 @@ class Infractions(Extension):
],
)
embeds.append(embed)
await ctx.send(embed=embeds, ephemeral=False)
@slash_command(name="warn", description="Warn a user", dm_permission=False, default_member_permissions=Permissions.KICK_MEMBERS)
@slash_option(name="user", description="User to warn", required=True, opt_type=OptionTypes.USER)
@slash_option(name="reason", description="Reason for warning", required=False, opt_type=OptionTypes.STRING)
@slash_option(name="weight", description="Severity of warning", required=False, opt_type=OptionTypes.NUMBER, min_value=0.0, max_value=10.0)
@slash_option(name="silent", description="Silent warning (will not notify user)", required=False, opt_type=OptionTypes.BOOLEAN)
async def warn_user(self, ctx: InteractionContext, user: Member, reason: str = None, weight: float = None, silent: bool = None):
@slash_command(
name="warn",
description="Warn a user",
dm_permission=False,
default_member_permissions=Permissions.KICK_MEMBERS,
)
@slash_option(
name="user",
description="User to warn",
required=True,
opt_type=OptionTypes.USER,
)
@slash_option(
name="reason",
description="Reason for warning",
required=False,
opt_type=OptionTypes.STRING,
)
@slash_option(
name="weight",
description="Severity of warning",
required=False,
opt_type=OptionTypes.NUMBER,
min_value=0.0,
max_value=10.0,
)
@slash_option(
name="silent",
description="Silent warning (will not notify user)",
required=False,
opt_type=OptionTypes.BOOLEAN,
)
async def warn_user(
self,
ctx: InteractionContext,
user: Member,
reason: str = None,
weight: float = None,
silent: bool = None,
):
await ctx.defer(ephemeral=False)
if weight is None:
weight = 1.0
@ -124,55 +167,75 @@ class Infractions(Extension):
color=infraction_colour(weight),
fields=[
EmbedField(name="**Severity**", value=f"{weight}"),
EmbedField(name="**Issued at**", value=f"<t:{int(infraction.at_time.timestamp())}:F>"),
EmbedField(
name="**Issued at**",
value=f"<t:{int(infraction.at_time.timestamp())}:F>", # pylint: disable=no-member
),
],
)
)
except Exception:
except Exception: # pylint: disable=broad-except
warning_msg = None
await ctx.send(f"Warned {user.display_name} ({user.username}#{user.discriminator}, {user.id}) for \"{reason}\" with severity {weight}", ephemeral=True)
await ctx.send(
f'Warned {user.display_name} ({user.username}#{user.discriminator}, {user.id}) for "{reason}" with severity {weight}', # pylint: disable=line-too-long
ephemeral=True,
)
if not silent and warning_msg is None:
await ctx.send(f"{user.mention} has been warned, but I couldn't DM them.", ephemeral=True)
await ctx.send(
f"{user.mention} has been warned, but I couldn't DM them.",
ephemeral=True,
)
@slash_command(name="remove-infraction", description="Remove an infraction", dm_permission=False, default_member_permissions=Permissions.KICK_MEMBERS)
@slash_option(name="infraction-id", description="ID of infraction to remove", required=True, opt_type=OptionTypes.INTEGER)
@slash_command(
name="remove-infraction",
description="Remove an infraction",
dm_permission=False,
default_member_permissions=Permissions.KICK_MEMBERS,
)
@slash_option(
name="infraction-id",
description="ID of infraction to remove",
required=True,
opt_type=OptionTypes.INTEGER,
)
async def remove_infraction(self, ctx: InteractionContext, infraction_id: int):
await ctx.defer(ephemeral=True)
infraction: InfractionsModel = InfractionsModel.get_or_none(InfractionsModel.id == infraction_id)
infraction: InfractionsModel = InfractionsModel.get_or_none(
InfractionsModel.id == infraction_id
)
if infraction is None:
await ctx.send("That infraction doesn't exist.", ephemeral=True)
return
elif infraction.guild_id != int(ctx.guild_id):
if infraction.guild_id != int(ctx.guild_id):
await ctx.send("That infraction doesn't exist.", ephemeral=True)
return
components = [ActionRow(
# pylint: disable=unexpected-keyword-arg
components = [
ActionRow(
Button(
custom_id=f"remove-infraction:remove:{infraction.id}",
style= ButtonStyles.DANGER,
style=ButtonStyles.DANGER,
label="Remove infraction",
),
Button(
custom_id=f"remove-infraction:cancel:{infraction.id}",
style= ButtonStyles.SECONDARY,
style=ButtonStyles.SECONDARY,
label="Cancel",
),
)]
)
]
msg = await ctx.send(
await ctx.send(
content="Remove this infraction? (times out in 60 seconds)",
embed=Embed(
title="Infraction",
description=f"{infraction.reason}",
color=infraction_colour(infraction.weight),
fields=[
EmbedField(
name="**ID**", value=f"{infraction.id}"
),
EmbedField(name="**ID**", value=f"{infraction.id}"),
EmbedField(
name="**Received**",
value=f"<t:{int(infraction.at_time.timestamp())}:F>",
@ -182,11 +245,13 @@ class Infractions(Extension):
],
),
ephemeral=True,
components=components
components=components,
)
try:
used_comp = await self.client.wait_for_component(components=components, timeout=60)
used_comp = await self.client.wait_for_component(
components=components, timeout=60
)
except TimeoutError:
await ctx.send("Timed out.", ephemeral=True)
return
@ -195,28 +260,23 @@ class Infractions(Extension):
if group != "remove-infraction" or action == "cancel":
await used_comp.context.send("Cancelled.", ephemeral=True)
return
if action == "remove" and inf_id == str(infraction.id):
infraction.delete_instance()
await used_comp.context.send("Removed.", ephemeral=True)
return
def infraction_colour(w: float) -> int:
if w < 0.5:
return 0xBCBCBC
elif w < 1.0:
if w < 1.0:
return 0xFF7711
else:
return 0xFF2211
return 0xFF2211
def setup(client):
InfractionsModel.create_table()
Infractions(client)
logging.info("Infractions extension loaded.")

View File

@ -1,27 +1,42 @@
from naff import Extension, listen, slash_command, slash_option, context_menu, CommandTypes, events, InteractionContext, OptionTypes, Client
from naff.models.discord.enums import ButtonStyles, Permissions
from naff.models.discord.embed import Embed, EmbedAuthor, EmbedField, EmbedFooter
from naff.models.discord.components import ActionRow, Button
import re
import logging
from naff import (
Extension,
slash_command,
slash_option,
InteractionContext,
OptionTypes,
Client,
)
from naff.models.discord.enums import ButtonStyles, Permissions
from naff.models.discord.embed import Embed, EmbedAuthor, EmbedField
from naff.models.discord.components import ActionRow, Button
class QuoteExtension(Extension):
def __init__(self, client: Client):
self.client = client
@slash_command(name="quote", description="Quote a message", dm_permission=False)
@slash_option(name="url", description="Message URL", required=True, opt_type=OptionTypes.STRING)
@slash_option(
name="url",
description="Message URL",
required=True,
opt_type=OptionTypes.STRING,
)
async def quote_command(self, ctx: InteractionContext, url: str):
url_match = re.match(r"https?://discord(?:app)?\.com/channels/(\d+)/(\d+)/(\d+)", url)
url_match = re.match(
r"https?://discord(?:app)?\.com/channels/(\d+)/(\d+)/(\d+)", url
)
if url_match is None:
ctx.ephemeral = True
await ctx.send("Invalid URL")
return
guild_id, channel_id, message_id = url_match.groups()
_, channel_id, message_id = url_match.groups()
chan = await self.client.fetch_channel(channel_id)
msg = await chan.fetch_message(message_id)
@ -31,27 +46,40 @@ class QuoteExtension(Extension):
print(msg)
return
if not (ctx.author.channel_permissions(chan) & (Permissions.VIEW_CHANNEL | Permissions.READ_MESSAGE_HISTORY)) \
== (Permissions.VIEW_CHANNEL | Permissions.READ_MESSAGE_HISTORY):
if not (
ctx.author.channel_permissions(chan)
& (Permissions.VIEW_CHANNEL | Permissions.READ_MESSAGE_HISTORY)
) == (Permissions.VIEW_CHANNEL | Permissions.READ_MESSAGE_HISTORY):
ctx.ephemeral = True
await ctx.send("You don't have permission to view this message", ephemeral=True)
await ctx.send(
"You don't have permission to view this message", ephemeral=True
)
return
author_embed = EmbedAuthor(name=msg.author.display_name, icon_url=msg.author.display_avatar.as_url())
author_embed = EmbedAuthor(
name=msg.author.display_name, icon_url=msg.author.display_avatar.as_url()
)
embed = Embed(
#title=msg.author.display_name,
# title=msg.author.display_name,
author=author_embed,
description=msg.content,
color=0x00ff00,
timestamp=msg.created_at,
url=url)
description=msg.content,
color=0x00FF00,
timestamp=msg.created_at,
url=url,
)
if len(msg.attachments) == 1 and msg.attachments[0].width is not None:
embed.set_image(url=msg.attachments[0].url)
elif len(msg.attachments) > 1:
field = EmbedField(name="**Attachments**", value="\n".join([f"• [{a.filename}]({a.url})" for a in msg.attachments]))
embed.fields.append(field)
field = EmbedField(
name="**Attachments**",
value="\n".join(
[f"• [{a.filename}]({a.url})" for a in msg.attachments]
),
)
embed.fields.append(field) # pylint: disable=E1101
# pylint: disable=E1123
components: list[ActionRow] = [
ActionRow(
Button(
@ -68,5 +96,3 @@ class QuoteExtension(Extension):
def setup(bot):
QuoteExtension(bot)
logging.info("Quote extension loaded")

View File

@ -1,9 +1,9 @@
from typing import Text
import datetime
from peewee import (
SqliteDatabase,
Model,
BigIntegerField,
IntegerField,
CharField,
TextField,
DateTimeField,
@ -13,7 +13,6 @@ from peewee import (
CompositeKey,
ForeignKeyField,
)
import datetime
db = SqliteDatabase("heimdallr.db")

101
poetry.lock generated
View File

@ -29,6 +29,18 @@ python-versions = ">=3.6"
[package.dependencies]
frozenlist = ">=1.1.0"
[[package]]
name = "astroid"
version = "2.11.7"
description = "An abstract syntax tree for Python with inference support."
category = "dev"
optional = false
python-versions = ">=3.6.2"
[package.dependencies]
lazy-object-proxy = ">=1.4.0"
wrapt = ">=1.11,<2"
[[package]]
name = "async-timeout"
version = "4.0.2"
@ -102,6 +114,17 @@ category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "dill"
version = "0.3.5.1"
description = "serialize all of python"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*"
[package.extras]
graph = ["objgraph (>=1.7.2)"]
[[package]]
name = "discord-typings"
version = "0.5.1"
@ -129,6 +152,36 @@ category = "main"
optional = false
python-versions = ">=3.5"
[[package]]
name = "isort"
version = "5.10.1"
description = "A Python utility / library to sort Python imports."
category = "dev"
optional = false
python-versions = ">=3.6.1,<4.0"
[package.extras]
pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
requirements_deprecated_finder = ["pipreqs", "pip-api"]
colors = ["colorama (>=0.4.3,<0.5.0)"]
plugins = ["setuptools"]
[[package]]
name = "lazy-object-proxy"
version = "1.7.1"
description = "A fast and thorough lazy object proxy."
category = "dev"
optional = false
python-versions = ">=3.6"
[[package]]
name = "mccabe"
version = "0.7.0"
description = "McCabe checker, plugin for flake8"
category = "dev"
optional = false
python-versions = ">=3.6"
[[package]]
name = "multidict"
version = "6.0.2"
@ -201,6 +254,28 @@ python-versions = ">=3.7"
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"]
test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"]
[[package]]
name = "pylint"
version = "2.14.5"
description = "python code static checker"
category = "dev"
optional = false
python-versions = ">=3.7.2"
[package.dependencies]
astroid = ">=2.11.6,<=2.12.0-dev0"
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
dill = ">=0.2"
isort = ">=4.2.5,<6"
mccabe = ">=0.6,<0.8"
platformdirs = ">=2.2.0"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
tomlkit = ">=0.10.1"
[package.extras]
spelling = ["pyenchant (>=3.2,<4.0)"]
testutils = ["gitpython (>3)"]
[[package]]
name = "python-dotenv"
version = "0.20.0"
@ -220,6 +295,14 @@ category = "main"
optional = false
python-versions = ">=3.7"
[[package]]
name = "tomlkit"
version = "0.11.1"
description = "Style preserving TOML library"
category = "dev"
optional = false
python-versions = ">=3.6,<4.0"
[[package]]
name = "typing-extensions"
version = "4.3.0"
@ -228,6 +311,14 @@ category = "main"
optional = false
python-versions = ">=3.7"
[[package]]
name = "wrapt"
version = "1.14.1"
description = "Module for decorators, wrappers and monkey patching."
category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
[[package]]
name = "yarl"
version = "1.7.2"
@ -243,11 +334,12 @@ multidict = ">=4.0"
[metadata]
lock-version = "1.1"
python-versions = "^3.10"
content-hash = "e627f4aee5fb3f13166070bf9a9744284a6b3e5e004838e99ff592c4cd35eda5"
content-hash = "3917de69112df241cadc7031034f6654e92f81df42f7bf627192ab88325e7e92"
[metadata.files]
aiohttp = []
aiosignal = []
astroid = []
async-timeout = []
attrs = [
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
@ -260,12 +352,16 @@ colorama = [
{file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
{file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
]
dill = []
discord-typings = []
frozenlist = []
idna = [
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
{file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
]
isort = []
lazy-object-proxy = []
mccabe = []
multidict = [
{file = "multidict-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2"},
{file = "multidict-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3"},
@ -333,9 +429,12 @@ orjson = []
pathspec = []
peewee = []
platformdirs = []
pylint = []
python-dotenv = []
tomli = []
tomlkit = []
typing-extensions = []
wrapt = []
yarl = [
{file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"},
{file = "yarl-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b"},

View File

@ -13,6 +13,18 @@ python-dotenv = "^0.20.0"
[tool.poetry.dev-dependencies]
black = "^22.6.0"
pylint = "^2.14.5"
[tool.pylint.main]
fail-under = 8
py-version = "3.10"
[tool.pylint.basic]
argument-naming-style = "snake_case"
attr-naming-style = "snake_case"
[tool.pylint."messages control"]
disable = ["C0103", "C0114", "C0115", "C0116", "R0903", "R0913"]
[build-system]
requires = ["poetry-core>=1.0.0"]