mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 22:23:13 +00:00
commit
bc0af82592
14 changed files with 135 additions and 189 deletions
|
@ -109,8 +109,6 @@
|
||||||
"error_no_case_found_description": "no case found with that ID.",
|
"error_no_case_found_description": "no case found with that ID.",
|
||||||
"error_no_private_message_author": "Guild Only",
|
"error_no_private_message_author": "Guild Only",
|
||||||
"error_no_private_message_description": "this command can only be used in servers.",
|
"error_no_private_message_description": "this command can only be used in servers.",
|
||||||
"error_not_allowed_in_channel_author": "Not Allowed In Channel",
|
|
||||||
"error_not_allowed_in_channel_description": "you can only use that command in {0}.",
|
|
||||||
"error_not_owner_author": "Owner Only",
|
"error_not_owner_author": "Owner Only",
|
||||||
"error_not_owner_description": "this command requires Lumi ownership permissions.",
|
"error_not_owner_description": "this command requires Lumi ownership permissions.",
|
||||||
"error_private_message_only_author": "Private Message Only",
|
"error_private_message_only_author": "Private Message Only",
|
||||||
|
@ -168,6 +166,9 @@
|
||||||
"mod_warn_dm": "**{0}** you have been warned in `{1}`.\n\n**Reason:** `{2}`",
|
"mod_warn_dm": "**{0}** you have been warned in `{1}`.\n\n**Reason:** `{2}`",
|
||||||
"mod_warned_author": "User Warned",
|
"mod_warned_author": "User Warned",
|
||||||
"mod_warned_user": "user `{0}` has been warned.",
|
"mod_warned_user": "user `{0}` has been warned.",
|
||||||
|
"mod_kicked_author": "User Kicked",
|
||||||
|
"mod_kicked_user": "user `{0}` has been kicked.",
|
||||||
|
"mod_kick_dm": "**{0}** you have been kicked from `{1}`.\n\n**Reason:** `{2}`",
|
||||||
"ping_author": "I'm online!",
|
"ping_author": "I'm online!",
|
||||||
"ping_footer": "Latency: {0}ms",
|
"ping_footer": "Latency: {0}ms",
|
||||||
"ping_pong": "Pong!",
|
"ping_pong": "Pong!",
|
||||||
|
@ -189,5 +190,6 @@
|
||||||
"xp_lb_field_value": "level: **{0}**\nxp: `{1}/{2}`",
|
"xp_lb_field_value": "level: **{0}**\nxp: `{1}/{2}`",
|
||||||
"xp_level": "Level {0}",
|
"xp_level": "Level {0}",
|
||||||
"xp_progress": "Progress to next level",
|
"xp_progress": "Progress to next level",
|
||||||
"xp_server_rank": "Server Rank: #{0}"
|
"xp_server_rank": "Server Rank: #{0}",
|
||||||
|
"error_command_not_found": "No command called \"{0}\" found."
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,13 +66,6 @@ async def on_command_error(ctx, error):
|
||||||
str(error),
|
str(error),
|
||||||
)
|
)
|
||||||
|
|
||||||
elif isinstance(error, LumiExceptions.NotAllowedInChannel):
|
|
||||||
author_text = CONST.STRINGS["error_not_allowed_in_channel_author"]
|
|
||||||
description = CONST.STRINGS["error_not_allowed_in_channel_description"].format(
|
|
||||||
error.command_channel.mention,
|
|
||||||
)
|
|
||||||
ephemeral = True
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
author_text = CONST.STRINGS["error_unknown_error_author"]
|
author_text = CONST.STRINGS["error_unknown_error_author"]
|
||||||
description = CONST.STRINGS["error_unknown_error_description"]
|
description = CONST.STRINGS["error_unknown_error_description"]
|
||||||
|
@ -111,8 +104,6 @@ class ErrorListener(Cog):
|
||||||
|
|
||||||
@Cog.listener()
|
@Cog.listener()
|
||||||
async def on_command_error(self, ctx, error) -> None:
|
async def on_command_error(self, ctx, error) -> None:
|
||||||
if isinstance(error, LumiExceptions.NotAllowedInChannel):
|
|
||||||
return
|
|
||||||
await on_command_error(ctx, error)
|
await on_command_error(ctx, error)
|
||||||
await self.log_command_error(ctx, error, ".")
|
await self.log_command_error(ctx, error, ".")
|
||||||
|
|
||||||
|
|
|
@ -17,25 +17,3 @@ def birthdays_enabled():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return commands.check(predicate)
|
return commands.check(predicate)
|
||||||
|
|
||||||
|
|
||||||
def allowed_in_channel():
|
|
||||||
async def predicate(ctx):
|
|
||||||
if ctx.guild is None:
|
|
||||||
return True
|
|
||||||
|
|
||||||
guild_config = GuildConfig(ctx.guild.id)
|
|
||||||
command_channel_id = guild_config.command_channel_id
|
|
||||||
|
|
||||||
if command_channel_id:
|
|
||||||
command_channel = await ctx.bot.get_or_fetch_channel(
|
|
||||||
ctx.guild,
|
|
||||||
command_channel_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
if ctx.channel.id != command_channel_id and command_channel:
|
|
||||||
raise LumiExceptions.NotAllowedInChannel(command_channel)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
return commands.check(predicate)
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ class Constants:
|
||||||
TITLE = "Luminara"
|
TITLE = "Luminara"
|
||||||
AUTHOR = "wlinator"
|
AUTHOR = "wlinator"
|
||||||
LICENSE = "GNU General Public License v3.0"
|
LICENSE = "GNU General Public License v3.0"
|
||||||
VERSION = "2.8.4" # "Moderation: Config" update
|
VERSION = "2.8.5" # "Moderation: Kicks" update
|
||||||
|
|
||||||
# bot credentials
|
# bot credentials
|
||||||
TOKEN: Optional[str] = os.environ.get("TOKEN", None)
|
TOKEN: Optional[str] = os.environ.get("TOKEN", None)
|
||||||
|
|
|
@ -21,14 +21,18 @@ class EmbedBuilder:
|
||||||
image_url=None,
|
image_url=None,
|
||||||
thumbnail_url=None,
|
thumbnail_url=None,
|
||||||
timestamp=None,
|
timestamp=None,
|
||||||
|
hide_author=False,
|
||||||
|
hide_author_icon=False,
|
||||||
):
|
):
|
||||||
|
if not hide_author:
|
||||||
if not author_text:
|
if not author_text:
|
||||||
author_text = ctx.author.name
|
author_text = ctx.author.name
|
||||||
elif show_name:
|
elif show_name:
|
||||||
description = f"**{ctx.author.name}** {description}"
|
description = f"**{ctx.author.name}** {description}"
|
||||||
|
|
||||||
if not author_icon_url:
|
if not hide_author_icon and not author_icon_url:
|
||||||
author_icon_url = ctx.author.display_avatar.url
|
author_icon_url = ctx.author.display_avatar.url
|
||||||
|
|
||||||
if not footer_text:
|
if not footer_text:
|
||||||
footer_text = "Luminara"
|
footer_text = "Luminara"
|
||||||
if not footer_icon_url:
|
if not footer_icon_url:
|
||||||
|
@ -39,7 +43,12 @@ class EmbedBuilder:
|
||||||
description=description,
|
description=description,
|
||||||
color=color or CONST.COLOR_DEFAULT,
|
color=color or CONST.COLOR_DEFAULT,
|
||||||
)
|
)
|
||||||
embed.set_author(name=author_text, icon_url=author_icon_url, url=author_url)
|
if not hide_author:
|
||||||
|
embed.set_author(
|
||||||
|
name=author_text,
|
||||||
|
icon_url=None if hide_author_icon else author_icon_url,
|
||||||
|
url=author_url,
|
||||||
|
)
|
||||||
embed.set_footer(text=footer_text, icon_url=footer_icon_url)
|
embed.set_footer(text=footer_text, icon_url=footer_icon_url)
|
||||||
embed.timestamp = timestamp or datetime.datetime.now()
|
embed.timestamp = timestamp or datetime.datetime.now()
|
||||||
|
|
||||||
|
@ -63,6 +72,8 @@ class EmbedBuilder:
|
||||||
image_url=None,
|
image_url=None,
|
||||||
thumbnail_url=None,
|
thumbnail_url=None,
|
||||||
timestamp=None,
|
timestamp=None,
|
||||||
|
hide_author=False,
|
||||||
|
hide_author_icon=False,
|
||||||
):
|
):
|
||||||
return EmbedBuilder.create_embed(
|
return EmbedBuilder.create_embed(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -78,6 +89,8 @@ class EmbedBuilder:
|
||||||
image_url=image_url,
|
image_url=image_url,
|
||||||
thumbnail_url=thumbnail_url,
|
thumbnail_url=thumbnail_url,
|
||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
|
hide_author=hide_author,
|
||||||
|
hide_author_icon=hide_author_icon,
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -93,6 +106,8 @@ class EmbedBuilder:
|
||||||
image_url=None,
|
image_url=None,
|
||||||
thumbnail_url=None,
|
thumbnail_url=None,
|
||||||
timestamp=None,
|
timestamp=None,
|
||||||
|
hide_author=False,
|
||||||
|
hide_author_icon=False,
|
||||||
):
|
):
|
||||||
return EmbedBuilder.create_embed(
|
return EmbedBuilder.create_embed(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -108,6 +123,8 @@ class EmbedBuilder:
|
||||||
image_url=image_url,
|
image_url=image_url,
|
||||||
thumbnail_url=thumbnail_url,
|
thumbnail_url=thumbnail_url,
|
||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
|
hide_author=hide_author,
|
||||||
|
hide_author_icon=hide_author_icon,
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -123,6 +140,8 @@ class EmbedBuilder:
|
||||||
image_url=None,
|
image_url=None,
|
||||||
thumbnail_url=None,
|
thumbnail_url=None,
|
||||||
timestamp=None,
|
timestamp=None,
|
||||||
|
hide_author=False,
|
||||||
|
hide_author_icon=False,
|
||||||
):
|
):
|
||||||
return EmbedBuilder.create_embed(
|
return EmbedBuilder.create_embed(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -138,6 +157,8 @@ class EmbedBuilder:
|
||||||
image_url=image_url,
|
image_url=image_url,
|
||||||
thumbnail_url=thumbnail_url,
|
thumbnail_url=thumbnail_url,
|
||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
|
hide_author=hide_author,
|
||||||
|
hide_author_icon=hide_author_icon,
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -153,6 +174,8 @@ class EmbedBuilder:
|
||||||
image_url=None,
|
image_url=None,
|
||||||
thumbnail_url=None,
|
thumbnail_url=None,
|
||||||
timestamp=None,
|
timestamp=None,
|
||||||
|
hide_author=False,
|
||||||
|
hide_author_icon=False,
|
||||||
):
|
):
|
||||||
return EmbedBuilder.create_embed(
|
return EmbedBuilder.create_embed(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -168,4 +191,6 @@ class EmbedBuilder:
|
||||||
image_url=image_url,
|
image_url=image_url,
|
||||||
thumbnail_url=thumbnail_url,
|
thumbnail_url=thumbnail_url,
|
||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
|
hide_author=hide_author,
|
||||||
|
hide_author_icon=hide_author_icon,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
from lib import formatter
|
|
||||||
from lib.constants import CONST
|
from lib.constants import CONST
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,64 +10,6 @@ def clean_error_embed(ctx):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class GenericErrors:
|
|
||||||
@staticmethod
|
|
||||||
def bad_arg(ctx, error):
|
|
||||||
embed = clean_error_embed(ctx)
|
|
||||||
if embed.description is None:
|
|
||||||
embed.description = formatter.shorten(str(error), 100)
|
|
||||||
else:
|
|
||||||
embed.description += formatter.shorten(str(error), 100)
|
|
||||||
embed.set_footer(
|
|
||||||
text=f"For more info do {formatter.get_prefix(ctx)}help {formatter.get_invoked_name(ctx)}",
|
|
||||||
icon_url=CONST.QUESTION_ICON,
|
|
||||||
)
|
|
||||||
|
|
||||||
return embed
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def private_message_only(ctx):
|
|
||||||
embed = clean_error_embed(ctx)
|
|
||||||
if embed.description is None:
|
|
||||||
embed.description = "this command can only be used in private messages."
|
|
||||||
else:
|
|
||||||
embed.description += "this command can only be used in private messages."
|
|
||||||
embed.set_footer(
|
|
||||||
text=f"For more info do '{formatter.get_prefix(ctx)}help {formatter.get_invoked_name(ctx)}'",
|
|
||||||
icon_url=CONST.QUESTION_ICON,
|
|
||||||
)
|
|
||||||
|
|
||||||
return embed
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def guild_only(ctx):
|
|
||||||
embed = clean_error_embed(ctx)
|
|
||||||
if embed.description is None:
|
|
||||||
embed.description = "this command can only be used in a server."
|
|
||||||
else:
|
|
||||||
embed.description += "this command can only be used in a server."
|
|
||||||
embed.set_footer(
|
|
||||||
text=f"For more info do '{formatter.get_prefix(ctx)}help {formatter.get_invoked_name(ctx)}'",
|
|
||||||
icon_url=CONST.QUESTION_ICON,
|
|
||||||
)
|
|
||||||
|
|
||||||
return embed
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def channel_not_allowed(ctx, channel):
|
|
||||||
embed = clean_error_embed(ctx)
|
|
||||||
if embed.description is None:
|
|
||||||
embed.description = f"you can only do that command in {channel.mention}."
|
|
||||||
else:
|
|
||||||
embed.description += f"you can only do that command in {channel.mention}."
|
|
||||||
embed.set_footer(
|
|
||||||
text="This message will delete itself after 5s",
|
|
||||||
icon_url=CONST.EXCLAIM_ICON,
|
|
||||||
)
|
|
||||||
|
|
||||||
return embed
|
|
||||||
|
|
||||||
|
|
||||||
class EconErrors:
|
class EconErrors:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def out_of_time(ctx):
|
def out_of_time(ctx):
|
||||||
|
@ -98,35 +39,3 @@ class EconErrors:
|
||||||
)
|
)
|
||||||
|
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
|
|
||||||
class MiscErrors:
|
|
||||||
@staticmethod
|
|
||||||
def prefix_too_long(ctx):
|
|
||||||
embed = clean_error_embed(ctx)
|
|
||||||
if embed.description is None:
|
|
||||||
embed.description = "this prefix is too long."
|
|
||||||
else:
|
|
||||||
embed.description += "this prefix is too long."
|
|
||||||
embed.set_footer(
|
|
||||||
text=f"For more info do '{formatter.get_prefix(ctx)}help {formatter.get_invoked_name(ctx)}'",
|
|
||||||
icon_url=CONST.QUESTION_ICON,
|
|
||||||
)
|
|
||||||
|
|
||||||
return embed
|
|
||||||
|
|
||||||
|
|
||||||
class HelpErrors:
|
|
||||||
@staticmethod
|
|
||||||
def error_message(ctx, error):
|
|
||||||
"""
|
|
||||||
See discord.ext.commands.HelpCommand.send_error_message
|
|
||||||
"""
|
|
||||||
embed = clean_error_embed(ctx)
|
|
||||||
embed.description += error
|
|
||||||
embed.set_footer(
|
|
||||||
text=f"See '{formatter.get_prefix(ctx)}help'",
|
|
||||||
icon_url=CONST.EXCLAIM_ICON,
|
|
||||||
)
|
|
||||||
|
|
||||||
return embed
|
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
|
||||||
class NotAllowedInChannel(commands.CheckFailure):
|
|
||||||
"""
|
|
||||||
Raised when checks.allowed_in_channel() fails.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, commands_channel):
|
|
||||||
self.command_channel = commands_channel
|
|
||||||
|
|
||||||
|
|
||||||
class BirthdaysDisabled(commands.CheckFailure):
|
class BirthdaysDisabled(commands.CheckFailure):
|
||||||
"""
|
"""
|
||||||
Raised when the birthdays module is disabled in ctx.guild.
|
Raised when the birthdays module is disabled in ctx.guild.
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import bridge, commands
|
from discord.ext import bridge, commands
|
||||||
|
|
||||||
from lib import checks
|
|
||||||
from modules.economy import balance, blackjack, daily, give, slots
|
from modules.economy import balance, blackjack, daily, give, slots
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +16,6 @@ class Economy(commands.Cog):
|
||||||
guild_only=True,
|
guild_only=True,
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
@commands.cooldown(1, 10, commands.BucketType.user)
|
@commands.cooldown(1, 10, commands.BucketType.user)
|
||||||
async def balance_command(self, ctx):
|
async def balance_command(self, ctx):
|
||||||
return await balance.cmd(ctx)
|
return await balance.cmd(ctx)
|
||||||
|
@ -31,7 +28,6 @@ class Economy(commands.Cog):
|
||||||
guild_only=True,
|
guild_only=True,
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def blackjack_command(self, ctx, *, bet: int):
|
async def blackjack_command(self, ctx, *, bet: int):
|
||||||
return await blackjack.cmd(ctx, bet)
|
return await blackjack.cmd(ctx, bet)
|
||||||
|
|
||||||
|
@ -43,7 +39,6 @@ class Economy(commands.Cog):
|
||||||
guild_only=True,
|
guild_only=True,
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def daily_command(self, ctx):
|
async def daily_command(self, ctx):
|
||||||
return await daily.cmd(ctx)
|
return await daily.cmd(ctx)
|
||||||
|
|
||||||
|
@ -53,7 +48,6 @@ class Economy(commands.Cog):
|
||||||
guild_only=True,
|
guild_only=True,
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def give_command(self, ctx, *, user: discord.Member, amount: int):
|
async def give_command(self, ctx, *, user: discord.Member, amount: int):
|
||||||
return await give.cmd(ctx, user, amount)
|
return await give.cmd(ctx, user, amount)
|
||||||
|
|
||||||
|
@ -62,7 +56,6 @@ class Economy(commands.Cog):
|
||||||
help="Give a server member some cash. You can use ID or mention them.",
|
help="Give a server member some cash. You can use ID or mention them.",
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def give_command_prefixed(self, ctx, user: discord.User, *, amount: int):
|
async def give_command_prefixed(self, ctx, user: discord.User, *, amount: int):
|
||||||
try:
|
try:
|
||||||
member = await ctx.guild.fetch_member(user.id)
|
member = await ctx.guild.fetch_member(user.id)
|
||||||
|
@ -79,7 +72,6 @@ class Economy(commands.Cog):
|
||||||
guild_only=True,
|
guild_only=True,
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
@commands.cooldown(1, 5, commands.BucketType.user)
|
@commands.cooldown(1, 5, commands.BucketType.user)
|
||||||
async def slots_command(self, ctx, *, bet: int):
|
async def slots_command(self, ctx, *, bet: int):
|
||||||
return await slots.cmd(self, ctx, bet)
|
return await slots.cmd(self, ctx, bet)
|
||||||
|
|
|
@ -8,7 +8,7 @@ from loguru import logger
|
||||||
|
|
||||||
from config.parser import JsonCache
|
from config.parser import JsonCache
|
||||||
from lib import interaction
|
from lib import interaction
|
||||||
from lib.embeds.error import EconErrors, GenericErrors
|
from lib.embeds.error import EconErrors
|
||||||
from services.currency_service import Currency
|
from services.currency_service import Currency
|
||||||
from services.stats_service import BlackJackStats
|
from services.stats_service import BlackJackStats
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ async def cmd(ctx, bet: int):
|
||||||
stats.push()
|
stats.push()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await ctx.respond(embed=GenericErrors.default_exception(ctx))
|
# await ctx.respond(embed=GenericErrors.default_exception(ctx))
|
||||||
logger.error("Something went wrong in the blackjack command: ", e)
|
logger.error("Something went wrong in the blackjack command: ", e)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from discord.ext import bridge, commands
|
from discord.ext import bridge, commands
|
||||||
|
|
||||||
from lib import checks
|
|
||||||
from modules.levels import leaderboard, level
|
from modules.levels import leaderboard, level
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +15,6 @@ class Levels(commands.Cog):
|
||||||
guild_only=True,
|
guild_only=True,
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
@commands.cooldown(1, 30, commands.BucketType.user)
|
@commands.cooldown(1, 30, commands.BucketType.user)
|
||||||
async def level_command(self, ctx) -> None:
|
async def level_command(self, ctx) -> None:
|
||||||
await level.rank(ctx)
|
await level.rank(ctx)
|
||||||
|
@ -29,7 +27,6 @@ class Levels(commands.Cog):
|
||||||
guild_only=True,
|
guild_only=True,
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
@commands.cooldown(1, 180, commands.BucketType.user)
|
@commands.cooldown(1, 180, commands.BucketType.user)
|
||||||
async def leaderboard_command(self, ctx) -> None:
|
async def leaderboard_command(self, ctx) -> None:
|
||||||
await leaderboard.cmd(ctx)
|
await leaderboard.cmd(ctx)
|
||||||
|
|
|
@ -5,7 +5,6 @@ from discord.commands import SlashCommandGroup
|
||||||
from discord.ext import bridge, commands, tasks
|
from discord.ext import bridge, commands, tasks
|
||||||
|
|
||||||
from Client import LumiBot
|
from Client import LumiBot
|
||||||
from lib import checks
|
|
||||||
from modules.config import c_prefix
|
from modules.config import c_prefix
|
||||||
from modules.misc import avatar, backup, info, introduction, invite, ping, xkcd
|
from modules.misc import avatar, backup, info, introduction, invite, ping, xkcd
|
||||||
|
|
||||||
|
@ -28,7 +27,6 @@ class Misc(commands.Cog):
|
||||||
guild_only=True,
|
guild_only=True,
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def avatar(self, ctx, user: discord.Member) -> None:
|
async def avatar(self, ctx, user: discord.Member) -> None:
|
||||||
return await avatar.get_avatar(ctx, user)
|
return await avatar.get_avatar(ctx, user)
|
||||||
|
|
||||||
|
@ -38,7 +36,6 @@ class Misc(commands.Cog):
|
||||||
description="Simple status check.",
|
description="Simple status check.",
|
||||||
help="Simple status check.",
|
help="Simple status check.",
|
||||||
)
|
)
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def ping(self, ctx) -> None:
|
async def ping(self, ctx) -> None:
|
||||||
await ping.ping(self, ctx)
|
await ping.ping(self, ctx)
|
||||||
|
|
||||||
|
@ -47,7 +44,6 @@ class Misc(commands.Cog):
|
||||||
description="See Lumi's uptime since the last update.",
|
description="See Lumi's uptime since the last update.",
|
||||||
help="See how long Lumi has been online since his last update.",
|
help="See how long Lumi has been online since his last update.",
|
||||||
)
|
)
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def uptime(self, ctx) -> None:
|
async def uptime(self, ctx) -> None:
|
||||||
await ping.uptime(self, ctx, self.start_time)
|
await ping.uptime(self, ctx, self.start_time)
|
||||||
|
|
||||||
|
@ -56,7 +52,6 @@ class Misc(commands.Cog):
|
||||||
description="Generate an invite link.",
|
description="Generate an invite link.",
|
||||||
help="Generate a link to invite Lumi to your own server!",
|
help="Generate a link to invite Lumi to your own server!",
|
||||||
)
|
)
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def invite_command(self, ctx) -> None:
|
async def invite_command(self, ctx) -> None:
|
||||||
await invite.cmd(ctx)
|
await invite.cmd(ctx)
|
||||||
|
|
||||||
|
@ -67,7 +62,6 @@ class Misc(commands.Cog):
|
||||||
guild_only=True,
|
guild_only=True,
|
||||||
)
|
)
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def prefix_command(self, ctx) -> None:
|
async def prefix_command(self, ctx) -> None:
|
||||||
await c_prefix.get_prefix(ctx)
|
await c_prefix.get_prefix(ctx)
|
||||||
|
|
||||||
|
@ -77,7 +71,6 @@ class Misc(commands.Cog):
|
||||||
description="Shows basic Lumi stats.",
|
description="Shows basic Lumi stats.",
|
||||||
help="Shows basic Lumi stats.",
|
help="Shows basic Lumi stats.",
|
||||||
)
|
)
|
||||||
@checks.allowed_in_channel()
|
|
||||||
async def info_command(self, ctx) -> None:
|
async def info_command(self, ctx) -> None:
|
||||||
unix_timestamp: int = int(round(self.start_time.timestamp()))
|
unix_timestamp: int = int(round(self.start_time.timestamp()))
|
||||||
await info.cmd(self, ctx, unix_timestamp)
|
await info.cmd(self, ctx, unix_timestamp)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import bridge, commands
|
from discord.ext import bridge, commands
|
||||||
|
|
||||||
from modules.moderation import ban, cases, warn, timeout
|
from modules.moderation import ban, cases, warn, timeout, kick
|
||||||
|
|
||||||
|
|
||||||
class Moderation(commands.Cog):
|
class Moderation(commands.Cog):
|
||||||
|
@ -163,6 +163,25 @@ class Moderation(commands.Cog):
|
||||||
):
|
):
|
||||||
await timeout.untimeout_user(ctx, target, reason)
|
await timeout.untimeout_user(ctx, target, reason)
|
||||||
|
|
||||||
|
@bridge.bridge_command(
|
||||||
|
name="kick",
|
||||||
|
aliases=["k"],
|
||||||
|
description="Kick a user from the server.",
|
||||||
|
help="Kicks a user from the server.",
|
||||||
|
guild_only=True,
|
||||||
|
)
|
||||||
|
@bridge.has_permissions(kick_members=True)
|
||||||
|
@commands.bot_has_permissions(kick_members=True)
|
||||||
|
@commands.guild_only()
|
||||||
|
async def kick_command(
|
||||||
|
self,
|
||||||
|
ctx,
|
||||||
|
target: discord.Member,
|
||||||
|
*,
|
||||||
|
reason: str | None = None,
|
||||||
|
):
|
||||||
|
await kick.kick_user(self, ctx, target, reason)
|
||||||
|
|
||||||
|
|
||||||
def setup(client):
|
def setup(client):
|
||||||
client.add_cog(Moderation(client))
|
client.add_cog(Moderation(client))
|
||||||
|
|
57
modules/moderation/kick.py
Normal file
57
modules/moderation/kick.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import asyncio
|
||||||
|
import discord
|
||||||
|
|
||||||
|
from lib import formatter
|
||||||
|
from lib.constants import CONST
|
||||||
|
from lib.embed_builder import EmbedBuilder
|
||||||
|
from modules.moderation.utils.actionable import async_actionable
|
||||||
|
from modules.moderation.utils.case_handler import create_case
|
||||||
|
from typing import Optional
|
||||||
|
from discord.ext.commands import UserConverter
|
||||||
|
|
||||||
|
|
||||||
|
async def kick_user(cog, ctx, target: discord.Member, reason: Optional[str] = None):
|
||||||
|
bot_member = await cog.client.get_or_fetch_member(ctx.guild, ctx.bot.user.id)
|
||||||
|
await async_actionable(target, ctx.author, bot_member)
|
||||||
|
|
||||||
|
output_reason = reason or CONST.STRINGS["mod_no_reason"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
await target.send(
|
||||||
|
embed=EmbedBuilder.create_warning_embed(
|
||||||
|
ctx,
|
||||||
|
author_text=CONST.STRINGS["mod_kicked_author"],
|
||||||
|
description=CONST.STRINGS["mod_kick_dm"].format(
|
||||||
|
target.name,
|
||||||
|
ctx.guild.name,
|
||||||
|
output_reason,
|
||||||
|
),
|
||||||
|
show_name=False,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
dm_sent = True
|
||||||
|
|
||||||
|
except (discord.HTTPException, discord.Forbidden):
|
||||||
|
dm_sent = False
|
||||||
|
|
||||||
|
await target.kick(
|
||||||
|
reason=CONST.STRINGS["mod_reason"].format(
|
||||||
|
ctx.author.name,
|
||||||
|
formatter.shorten(output_reason, 200),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
respond_task = ctx.respond(
|
||||||
|
embed=EmbedBuilder.create_success_embed(
|
||||||
|
ctx,
|
||||||
|
author_text=CONST.STRINGS["mod_kicked_author"],
|
||||||
|
description=CONST.STRINGS["mod_kicked_user"].format(target.name),
|
||||||
|
footer_text=CONST.STRINGS["mod_dm_sent"]
|
||||||
|
if dm_sent
|
||||||
|
else CONST.STRINGS["mod_dm_not_sent"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
target_user = await UserConverter().convert(ctx, str(target.id))
|
||||||
|
create_case_task = create_case(ctx, target_user, "KICK", reason)
|
||||||
|
await asyncio.gather(respond_task, create_case_task, return_exceptions=True)
|
|
@ -1,10 +1,9 @@
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from config.parser import JsonCache
|
from lib.embed_builder import EmbedBuilder
|
||||||
from lib.embeds.error import HelpErrors
|
from lib.constants import CONST
|
||||||
|
from lib.exceptions.LumiExceptions import LumiException
|
||||||
art = JsonCache.read_json("art")
|
|
||||||
|
|
||||||
|
|
||||||
class LumiHelp(commands.HelpCommand):
|
class LumiHelp(commands.HelpCommand):
|
||||||
|
@ -22,10 +21,11 @@ class LumiHelp(commands.HelpCommand):
|
||||||
return "`{}{}`".format(self.context.clean_prefix, command.qualified_name)
|
return "`{}{}`".format(self.context.clean_prefix, command.qualified_name)
|
||||||
|
|
||||||
async def send_bot_help(self, mapping):
|
async def send_bot_help(self, mapping):
|
||||||
embed = discord.Embed(color=discord.Color.blurple())
|
embed = EmbedBuilder.create_info_embed(
|
||||||
|
ctx=self.context,
|
||||||
embed.set_author(name="Help Command", icon_url=art["logo"]["transparent"])
|
author_text="Help Command",
|
||||||
embed.description = "Full list of commands: https://wiki.wlinator.org/cmdlist"
|
show_name=False,
|
||||||
|
)
|
||||||
|
|
||||||
for cog, lumi_commands in mapping.items():
|
for cog, lumi_commands in mapping.items():
|
||||||
filtered = await self.filter_commands(lumi_commands, sort=True)
|
filtered = await self.filter_commands(lumi_commands, sort=True)
|
||||||
|
@ -46,10 +46,11 @@ class LumiHelp(commands.HelpCommand):
|
||||||
await channel.send(embed=embed)
|
await channel.send(embed=embed)
|
||||||
|
|
||||||
async def send_command_help(self, command):
|
async def send_command_help(self, command):
|
||||||
embed = discord.Embed(
|
embed = EmbedBuilder.create_success_embed(
|
||||||
title=f"{self.context.clean_prefix}{command.qualified_name}",
|
ctx=self.context,
|
||||||
color=discord.Color.blurple(),
|
author_text=f"{self.context.clean_prefix}{command.qualified_name}",
|
||||||
description=command.help,
|
description=command.help,
|
||||||
|
show_name=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
usage_value = "`{}{} {}`".format(
|
usage_value = "`{}{} {}`".format(
|
||||||
|
@ -69,25 +70,16 @@ class LumiHelp(commands.HelpCommand):
|
||||||
await channel.send(embed=embed)
|
await channel.send(embed=embed)
|
||||||
|
|
||||||
async def send_error_message(self, error):
|
async def send_error_message(self, error):
|
||||||
channel = self.get_destination()
|
raise LumiException(error)
|
||||||
await channel.send(embed=HelpErrors.error_message(self.context, error))
|
|
||||||
|
|
||||||
async def send_group_help(self, group):
|
async def send_group_help(self, group):
|
||||||
channel = self.get_destination()
|
raise LumiException(
|
||||||
await channel.send(
|
CONST.STRINGS["error_command_not_found"].format(group.qualified_name),
|
||||||
embed=HelpErrors.error_message(
|
|
||||||
self.context,
|
|
||||||
f'No command called "{group.qualified_name}" found.',
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_cog_help(self, cog):
|
async def send_cog_help(self, cog):
|
||||||
channel = self.get_destination()
|
raise LumiException(
|
||||||
await channel.send(
|
CONST.STRINGS["error_command_not_found"].format(cog.qualified_name),
|
||||||
embed=HelpErrors.error_message(
|
|
||||||
self.context,
|
|
||||||
f'No command called "{cog.qualified_name}" found.',
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def command_callback(self, ctx, *, command=None):
|
async def command_callback(self, ctx, *, command=None):
|
||||||
|
@ -103,7 +95,7 @@ class LumiHelp(commands.HelpCommand):
|
||||||
if cog is not None:
|
if cog is not None:
|
||||||
return await self.send_cog_help(cog)
|
return await self.send_cog_help(cog)
|
||||||
|
|
||||||
maybe_coro = discord.utils.maybe_coroutine
|
maybe_coro = discord.utils.maybe_coroutine # type: ignore
|
||||||
|
|
||||||
# If it's not a cog then it's a command.
|
# If it's not a cog then it's a command.
|
||||||
# Since we want to have detailed errors when someone
|
# Since we want to have detailed errors when someone
|
||||||
|
|
Loading…
Reference in a new issue