mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 18:03:12 +00:00
commit
1fa72bda6f
15 changed files with 249 additions and 335 deletions
|
@ -1,6 +1,4 @@
|
|||
{
|
||||
"lumi_exception_generic": "An error occurred.",
|
||||
"lumi_exception_blacklisted": "User is blacklisted",
|
||||
"admin_award_description": "awarded **${0}** to {1}.",
|
||||
"admin_award_title": "Awarded Currency",
|
||||
"admin_blacklist_author": "User Blacklisted",
|
||||
|
@ -19,21 +17,23 @@
|
|||
"admin_sync_error_title": "Sync Error",
|
||||
"admin_sync_title": "Sync Successful",
|
||||
"bet_limit": "❌ | **{0}** you cannot place any bets above **${1}**.",
|
||||
"birthday_check_started": "Daily birthday check started.",
|
||||
"birthday_check_skipped": "Birthday announcements in guild with ID {0} skipped: no birthday channel.",
|
||||
"birthday_check_success": "Birthday announcement Success! user/guild/chan ID: {0}/{1}/{2}",
|
||||
"birthday_check_error": "Birthday announcement skipped processing user/guild {0}/{1} | {2}",
|
||||
"birthday_check_finished": "Daily birthday check finished. {0} birthdays processed. {1} birthdays failed.",
|
||||
"birthday_add_invalid_date": "The date you entered is invalid.",
|
||||
"birthday_add_success_author": "Birthday Set",
|
||||
"birthday_add_success_description": "your birthday has been set to **{0} {1}**.",
|
||||
"birthday_check_error": "Birthday announcement skipped processing user/guild {0}/{1} | {2}",
|
||||
"birthday_check_finished": "Daily birthday check finished. {0} birthdays processed. {1} birthdays failed.",
|
||||
"birthday_check_skipped": "Birthday announcements in guild with ID {0} skipped: no birthday channel.",
|
||||
"birthday_check_started": "Daily birthday check started.",
|
||||
"birthday_check_success": "Birthday announcement Success! user/guild/chan ID: {0}/{1}/{2}",
|
||||
"birthday_delete_success_author": "Birthday Deleted",
|
||||
"birthday_delete_success_description": "your birthday has been deleted from this server.",
|
||||
"birthday_leap_year": "February 29",
|
||||
"birthday_upcoming_author": "Upcoming Birthdays!",
|
||||
"birthday_upcoming_description_line": "🎂 {0} - {1}",
|
||||
"birthday_upcoming_no_birthdays_author": "No Upcoming Birthdays",
|
||||
"birthday_upcoming_no_birthdays": "there are no upcoming birthdays in this server.",
|
||||
"birthday_leap_year": "February 29",
|
||||
"birthday_upcoming_no_birthdays_author": "No Upcoming Birthdays",
|
||||
"boost_default_description": "Thanks for boosting, **{0}**!!",
|
||||
"boost_default_title": "New Booster",
|
||||
"case_case_field": "Case:",
|
||||
"case_case_field_value": "`{0}`",
|
||||
"case_duration_field": "Duration:",
|
||||
|
@ -121,6 +121,7 @@
|
|||
"error_actionable_hierarchy_bot": "I don't have permission to perform this action on this user due to role hierarchy.",
|
||||
"error_actionable_hierarchy_user": "you don't have permission to perform this action on this user due to role hierarchy.",
|
||||
"error_actionable_self": "you can't perform this action on yourself.",
|
||||
"error_already_playing_blackjack": "you already have a game of blackjack running.",
|
||||
"error_bad_argument_author": "Bad Argument",
|
||||
"error_bad_argument_description": "{0}",
|
||||
"error_birthdays_disabled_author": "Birthdays Disabled",
|
||||
|
@ -146,10 +147,14 @@
|
|||
"error_no_private_message_description": "this command can only be used in servers.",
|
||||
"error_not_owner_author": "Owner Only",
|
||||
"error_not_owner_description": "this command requires Lumi ownership permissions.",
|
||||
"error_out_of_time": "you ran out of time.",
|
||||
"error_out_of_time_economy": "you ran out of time. Your bet was forfeited.",
|
||||
"error_private_message_only_author": "Private Message Only",
|
||||
"error_private_message_only_description": "this command can only be used in private messages.",
|
||||
"error_unknown_error_author": "Unknown Error",
|
||||
"error_unknown_error_description": "an unknown error occurred. Please try again later.",
|
||||
"greet_default_description": "_ _\n**Welcome** to **{0}**",
|
||||
"greet_template_description": "↓↓↓\n{0}",
|
||||
"help_use_prefix": "Please use Lumi's prefix to get help. Type `{0}help`",
|
||||
"info_api_version": "**API:** v{0}\n",
|
||||
"info_database_records": "**Database:** {0} records",
|
||||
|
@ -180,6 +185,8 @@
|
|||
"invite_description": "Thanks for inviting me to your server!",
|
||||
"level_up": "📈 | **{0}** you have reached **Level {1}**.",
|
||||
"level_up_prefix": "📈 | **{0}** ",
|
||||
"lumi_exception_blacklisted": "User is blacklisted",
|
||||
"lumi_exception_generic": "An error occurred.",
|
||||
"mod_ban_dm": "**{0}** you have been banned from `{1}`.\n\n**Reason:** `{2}`",
|
||||
"mod_banned_author": "User Banned",
|
||||
"mod_banned_user": "user with ID `{0}` has been banned.",
|
||||
|
@ -214,6 +221,31 @@
|
|||
"ping_uptime": "I've been online since <t:{0}:R>.",
|
||||
"stats_blackjack": "🃏 | You've played **{0}** games of BlackJack, betting a total of **${1}**. You won **{2}** of those games with a total payout of **${3}**.",
|
||||
"stats_slots": "🎰 | You've played **{0}** games of Slots, betting a total of **${1}**. Your total payout was **${2}**.",
|
||||
"trigger_already_exists": "Failed to add custom reaction. This text already contains another trigger. To avoid unexpected behavior, please delete it before adding a new one.",
|
||||
"trigger_limit_reached": "Failed to add custom reaction. You have reached the limit of 100 custom reactions for this server.",
|
||||
"triggers_add_author": "Custom Reaction Created",
|
||||
"triggers_add_description": "**Trigger Text:** `{0}`\n**Reaction Type:** {1}\n**Full Match:** `{2}`\n",
|
||||
"triggers_add_emoji_details": "**Emoji ID:** `{0}`",
|
||||
"triggers_add_text_details": "**Response:** `{0}`",
|
||||
"triggers_delete_author": "Custom Reaction Deleted",
|
||||
"triggers_delete_description": "custom reaction has been successfully deleted.",
|
||||
"triggers_delete_not_found_author": "Custom Reaction Not Found",
|
||||
"triggers_list_custom_reaction_id": "**ID:** {0}",
|
||||
"triggers_list_custom_reactions_title": "Custom Reactions",
|
||||
"triggers_list_emoji_id": "**Emoji ID:** `{0}`",
|
||||
"triggers_list_full_match": "**Full Match:** `{0}`",
|
||||
"triggers_list_reaction_type": "**Reaction Type:** {0}",
|
||||
"triggers_list_response": "**Response:** `{0}`",
|
||||
"triggers_list_trigger_text": "**Trigger Text:** `{0}`",
|
||||
"triggers_list_usage_count": "**Usage Count:** `{0}`",
|
||||
"triggers_no_reactions_description": "There are no custom reactions set up yet.\n\nTo create a new custom reaction, use the following commands:\n`/trigger add emoji` - Add a new custom emoji reaction.\n`/trigger add response` - Add a new custom text reaction.\n\n**Emoji Reaction:**\nAn emoji reaction will react with a specific emoji when the trigger text is detected.\n\n**Text Reaction:**\nA text reaction will respond with a specific text message when the trigger text is detected.",
|
||||
"triggers_no_reactions_title": "No Custom Reactions Found",
|
||||
"triggers_not_added": "failed to add custom reaction. Please try again.",
|
||||
"triggers_not_deleted": "something went wrong while trying to delete this trigger.",
|
||||
"triggers_not_found": "no custom reaction found with the provided ID.",
|
||||
"triggers_reaction_service_footer": "Reaction Service",
|
||||
"triggers_type_emoji": "Emoji",
|
||||
"triggers_type_text": "Text",
|
||||
"xkcd_description": "[Explainxkcd]({0}) | [Webpage]({1})",
|
||||
"xkcd_footer": "Xkcd Service",
|
||||
"xkcd_not_found": "failed to fetch this comic.",
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
from discord.ext.commands import Cog
|
||||
from loguru import logger
|
||||
|
||||
import lib.embeds.boost
|
||||
from lib.embeds.greet import Greet
|
||||
from modules.config import c_boost, c_greet
|
||||
from services.blacklist_service import BlacklistUserService
|
||||
from services.config_service import GuildConfig
|
||||
|
||||
|
@ -21,7 +20,7 @@ class EventHandler(Cog):
|
|||
if not config.welcome_channel_id:
|
||||
return
|
||||
|
||||
embed = Greet.message(member, config.welcome_message)
|
||||
embed = c_greet.create_greet_embed(member, config.welcome_message)
|
||||
|
||||
try:
|
||||
await member.guild.get_channel(config.welcome_channel_id).send(
|
||||
|
@ -48,7 +47,7 @@ class EventHandler(Cog):
|
|||
if not config.boost_channel_id:
|
||||
return
|
||||
|
||||
embed = lib.embeds.boost.Boost.message(
|
||||
embed = c_boost.create_boost_embed(
|
||||
member,
|
||||
config.boost_message,
|
||||
config.boost_image_url,
|
||||
|
|
|
@ -14,7 +14,7 @@ class Constants:
|
|||
TITLE = "Luminara"
|
||||
AUTHOR = "wlinator"
|
||||
LICENSE = "GNU General Public License v3.0"
|
||||
VERSION = "2.8.10" # "Refactor JSON Handling" update
|
||||
VERSION = "2.8.11" # "Embed Refactor" update
|
||||
|
||||
# bot credentials
|
||||
TOKEN: Optional[str] = os.environ.get("TOKEN", None)
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import discord
|
||||
|
||||
import lib.formatter
|
||||
from lib.constants import CONST
|
||||
|
||||
|
||||
class Boost:
|
||||
@staticmethod
|
||||
def message(member, template=None, image_url=None):
|
||||
embed = discord.Embed(
|
||||
color=discord.Color.nitro_pink(),
|
||||
title="New Booster",
|
||||
description=f"Thanks for boosting, **{member.name}**!!",
|
||||
)
|
||||
|
||||
if template:
|
||||
# REPLACE
|
||||
embed.description = lib.formatter.template(template, member.name)
|
||||
|
||||
embed.set_author(name=member.name, icon_url=member.display_avatar)
|
||||
embed.set_image(url=image_url if image_url else CONST.BOOST_ICON)
|
||||
embed.set_footer(
|
||||
text=f"Total server boosts: {member.guild.premium_subscription_count}",
|
||||
icon_url=CONST.EXCLAIM_ICON,
|
||||
)
|
||||
|
||||
return embed
|
|
@ -1,41 +0,0 @@
|
|||
import discord
|
||||
|
||||
from lib.constants import CONST
|
||||
|
||||
|
||||
def clean_error_embed(ctx):
|
||||
return discord.Embed(
|
||||
color=discord.Color.red(),
|
||||
description=f"**{ctx.author.name}** ",
|
||||
)
|
||||
|
||||
|
||||
class EconErrors:
|
||||
@staticmethod
|
||||
def out_of_time(ctx):
|
||||
embed = clean_error_embed(ctx)
|
||||
if embed.description is None:
|
||||
embed.description = "you ran out of time."
|
||||
else:
|
||||
embed.description += "you ran out of time."
|
||||
embed.set_footer(text="Your bet was forfeited", icon_url=CONST.EXCLAIM_ICON)
|
||||
|
||||
return embed
|
||||
|
||||
@staticmethod
|
||||
def already_playing(ctx):
|
||||
embed = clean_error_embed(ctx)
|
||||
if embed.description is None:
|
||||
embed.description = (
|
||||
f"you already have a game of {ctx.command.name} running."
|
||||
)
|
||||
else:
|
||||
embed.description += (
|
||||
f"you already have a game of {ctx.command.name} running."
|
||||
)
|
||||
embed.set_footer(
|
||||
text="Please finish this game first",
|
||||
icon_url=CONST.EXCLAIM_ICON,
|
||||
)
|
||||
|
||||
return embed
|
|
@ -1,19 +0,0 @@
|
|||
import discord
|
||||
from lib import formatter
|
||||
|
||||
|
||||
class Greet:
|
||||
@staticmethod
|
||||
def message(member, template=None):
|
||||
embed = discord.Embed(
|
||||
color=discord.Color.embed_background(),
|
||||
description=f"_ _\n**Welcome** to **{member.guild.name}**",
|
||||
)
|
||||
if template:
|
||||
embed.description = (
|
||||
f"{embed.description}\n↓↓↓\n{formatter.template(template, member.name)}"
|
||||
)
|
||||
|
||||
embed.set_thumbnail(url=member.display_avatar.url)
|
||||
|
||||
return embed
|
|
@ -1,118 +0,0 @@
|
|||
import datetime
|
||||
from typing import Optional
|
||||
from lib.constants import CONST
|
||||
|
||||
import discord
|
||||
from lib import formatter
|
||||
|
||||
|
||||
def create_embed(
|
||||
title: str,
|
||||
description: str,
|
||||
color: int,
|
||||
icon_url: str,
|
||||
) -> discord.Embed:
|
||||
embed = discord.Embed(
|
||||
color=color,
|
||||
description=description,
|
||||
)
|
||||
embed.set_author(name=title, icon_url=icon_url)
|
||||
embed.set_footer(text="Reaction Service", icon_url=CONST.LUMI_LOGO_TRANSPARENT)
|
||||
embed.timestamp = datetime.datetime.now(datetime.timezone.utc)
|
||||
return embed
|
||||
|
||||
|
||||
def create_creation_embed(
|
||||
trigger_text: str,
|
||||
response: Optional[str],
|
||||
emoji_id: Optional[int],
|
||||
is_emoji: bool,
|
||||
is_full_match: bool,
|
||||
) -> discord.Embed:
|
||||
trigger_text = formatter.shorten(trigger_text, 50)
|
||||
if response:
|
||||
response = formatter.shorten(response, 50)
|
||||
|
||||
description = (
|
||||
f"**Trigger Text:** `{trigger_text}`\n"
|
||||
f"**Reaction Type:** {'Emoji' if is_emoji else 'Text'}\n"
|
||||
f"{f'**Emoji ID:** `{str(emoji_id)}`' if is_emoji else f'**Response:** `{response}`'}\n"
|
||||
f"**Full Match:** `{is_full_match}`"
|
||||
)
|
||||
return create_embed(
|
||||
"Custom Reaction Created",
|
||||
description,
|
||||
0xFF8C00,
|
||||
CONST.CHECK_ICON,
|
||||
)
|
||||
|
||||
|
||||
def create_failure_embed(
|
||||
trigger_text: str,
|
||||
is_emoji: bool,
|
||||
limit_reached: bool = False,
|
||||
trigger_already_exists: bool = False,
|
||||
) -> discord.Embed:
|
||||
trigger_text = formatter.shorten(trigger_text, 50)
|
||||
|
||||
description = f"**Trigger Text:** `{trigger_text}`\n"
|
||||
|
||||
if limit_reached:
|
||||
description += "Failed to add custom reaction. You have reached the limit of 100 custom reactions for this server."
|
||||
elif trigger_already_exists:
|
||||
description += "Failed to add custom reaction. This text already contains another trigger. To avoid unexpected behavior, please delete it before adding a new one."
|
||||
else:
|
||||
description += "Failed to add custom reaction."
|
||||
|
||||
return create_embed(
|
||||
"Custom Reaction Creation Failed",
|
||||
description,
|
||||
0xFF4500,
|
||||
CONST.CROSS_ICON,
|
||||
)
|
||||
|
||||
|
||||
def create_deletion_embed(trigger_text: str, is_emoji: bool) -> discord.Embed:
|
||||
trigger_text = formatter.shorten(trigger_text, 50)
|
||||
|
||||
description = f"**Trigger Text:** `{trigger_text}`\n"
|
||||
description += "Custom reaction has been successfully deleted."
|
||||
|
||||
return create_embed(
|
||||
"Custom Reaction Deleted",
|
||||
description,
|
||||
0xFF8C00,
|
||||
CONST.CHECK_ICON,
|
||||
)
|
||||
|
||||
|
||||
def create_not_found_embed(reaction_id: int) -> discord.Embed:
|
||||
description = f"**Reaction ID:** `{reaction_id}`\n"
|
||||
description += "No custom reaction found with the provided ID."
|
||||
|
||||
return create_embed(
|
||||
"Custom Reaction Not Found",
|
||||
description,
|
||||
0xFF4500,
|
||||
CONST.CROSS_ICON,
|
||||
)
|
||||
|
||||
|
||||
def create_no_triggers_embed() -> discord.Embed:
|
||||
description = (
|
||||
"There are no custom reactions set up yet.\n\n"
|
||||
"To create a new custom reaction, use the following commands:\n"
|
||||
"`/trigger add emoji` - Add a new custom emoji reaction.\n"
|
||||
"`/trigger add response` - Add a new custom text reaction.\n\n"
|
||||
"**Emoji Reaction:**\n"
|
||||
"An emoji reaction will react with a specific emoji when the trigger text is detected.\n\n"
|
||||
"**Text Reaction:**\n"
|
||||
"A text reaction will respond with a specific text message when the trigger text is detected."
|
||||
)
|
||||
|
||||
return create_embed(
|
||||
"No Custom Reactions Found",
|
||||
description,
|
||||
0xFF8C00,
|
||||
CONST.EXCLAIM_ICON,
|
||||
)
|
|
@ -69,11 +69,10 @@ class IntroductionFinishButtons(View):
|
|||
self.stop()
|
||||
|
||||
async def interaction_check(self, interaction: discord.Interaction) -> bool:
|
||||
if interaction.user != self.ctx.author:
|
||||
await interaction.response.send_message(
|
||||
"You can't use these buttons.",
|
||||
ephemeral=True,
|
||||
)
|
||||
return False
|
||||
else:
|
||||
if interaction.user == self.ctx.author:
|
||||
return True
|
||||
await interaction.response.send_message(
|
||||
"You can't use these buttons.",
|
||||
ephemeral=True,
|
||||
)
|
||||
return False
|
||||
|
|
|
@ -10,7 +10,6 @@ from services.birthday_service import Birthday
|
|||
|
||||
|
||||
async def add(ctx, month, month_index, day):
|
||||
"""Set a user's birthday in a specific guild."""
|
||||
leap_year = 2020
|
||||
max_days = calendar.monthrange(leap_year, month_index)[1]
|
||||
|
||||
|
@ -35,7 +34,6 @@ async def add(ctx, month, month_index, day):
|
|||
|
||||
|
||||
async def delete(ctx):
|
||||
"""Delete a user's birthday in a specific server."""
|
||||
Birthday(ctx.author.id, ctx.guild.id).delete()
|
||||
|
||||
embed = EmbedBuilder.create_success_embed(
|
||||
|
@ -48,7 +46,6 @@ async def delete(ctx):
|
|||
|
||||
|
||||
async def upcoming(ctx):
|
||||
"""Get the upcoming birthdays for a specific server."""
|
||||
upcoming_birthdays = Birthday.get_upcoming_birthdays(ctx.guild.id)
|
||||
|
||||
if not upcoming_birthdays:
|
||||
|
|
|
@ -3,7 +3,7 @@ from lib.embed_builder import EmbedBuilder
|
|||
from lib.constants import CONST
|
||||
from services.config_service import GuildConfig
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from lib.embeds.boost import Boost
|
||||
import lib.formatter
|
||||
|
||||
|
||||
async def set_boost_channel(ctx, channel: discord.TextChannel):
|
||||
|
@ -61,7 +61,7 @@ async def set_boost_template(ctx, text: str):
|
|||
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
example_embed = Boost.message(ctx.author, text, guild_config.boost_image_url)
|
||||
example_embed = create_boost_embed(ctx.author, text, guild_config.boost_image_url)
|
||||
return await ctx.send(embed=example_embed, content=ctx.author.mention)
|
||||
|
||||
|
||||
|
@ -94,5 +94,31 @@ async def set_boost_image(ctx, image_url: str | None):
|
|||
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
example_embed = Boost.message(ctx.author, guild_config.boost_message, image_url)
|
||||
example_embed = create_boost_embed(
|
||||
ctx.author,
|
||||
guild_config.boost_message,
|
||||
image_url,
|
||||
)
|
||||
return await ctx.send(embed=example_embed, content=ctx.author.mention)
|
||||
|
||||
|
||||
async def create_boost_embed(
|
||||
member: discord.Member,
|
||||
template: str | None = None,
|
||||
image_url: str | None = None,
|
||||
):
|
||||
embed = discord.Embed(
|
||||
color=discord.Color.nitro_pink(),
|
||||
title=CONST.STRINGS["boost_default_title"],
|
||||
description=CONST.STRINGS["boost_default_description"].format(member.name),
|
||||
)
|
||||
|
||||
if template:
|
||||
embed.description = lib.formatter.template(template, member.name)
|
||||
|
||||
embed.set_author(name=member.name, icon_url=member.display_avatar)
|
||||
embed.set_image(url=image_url or CONST.BOOST_ICON)
|
||||
embed.set_footer(
|
||||
text=f"Total server boosts: {member.guild.premium_subscription_count}",
|
||||
icon_url=CONST.EXCLAIM_ICON,
|
||||
)
|
||||
|
|
|
@ -1,29 +1,37 @@
|
|||
from typing import Optional
|
||||
|
||||
import discord
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from discord.ext.commands import MemberConverter
|
||||
|
||||
from lib import formatter
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from services.config_service import GuildConfig
|
||||
from lib.embeds.greet import Greet
|
||||
|
||||
|
||||
async def set_welcome_channel(ctx, channel: discord.TextChannel):
|
||||
guild_config = GuildConfig(ctx.guild.id)
|
||||
async def set_welcome_channel(ctx, channel: discord.TextChannel) -> None:
|
||||
if not ctx.guild:
|
||||
raise LumiException()
|
||||
|
||||
guild_config: GuildConfig = GuildConfig(ctx.guild.id)
|
||||
guild_config.welcome_channel_id = channel.id
|
||||
guild_config.push()
|
||||
|
||||
embed = EmbedBuilder().create_success_embed(
|
||||
embed: discord.Embed = EmbedBuilder().create_success_embed(
|
||||
ctx=ctx,
|
||||
author_text=CONST.STRINGS["config_author"],
|
||||
description=CONST.STRINGS["config_welcome_channel_set"].format(channel.mention),
|
||||
)
|
||||
|
||||
return await ctx.respond(embed=embed)
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
|
||||
async def disable_welcome_module(ctx):
|
||||
guild_config = GuildConfig(ctx.guild.id)
|
||||
async def disable_welcome_module(ctx) -> None:
|
||||
guild_config: GuildConfig = GuildConfig(ctx.guild.id)
|
||||
|
||||
if not guild_config.welcome_channel_id:
|
||||
embed = EmbedBuilder().create_warning_embed(
|
||||
embed: discord.Embed = EmbedBuilder().create_warning_embed(
|
||||
ctx=ctx,
|
||||
author_text=CONST.STRINGS["config_author"],
|
||||
description=CONST.STRINGS["config_welcome_module_already_disabled"],
|
||||
|
@ -32,21 +40,24 @@ async def disable_welcome_module(ctx):
|
|||
guild_config.welcome_channel_id = None
|
||||
guild_config.welcome_message = None
|
||||
guild_config.push()
|
||||
embed = EmbedBuilder().create_success_embed(
|
||||
embed: discord.Embed = EmbedBuilder().create_success_embed(
|
||||
ctx=ctx,
|
||||
author_text=CONST.STRINGS["config_author"],
|
||||
description=CONST.STRINGS["config_welcome_module_disabled"],
|
||||
)
|
||||
|
||||
return await ctx.respond(embed=embed)
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
|
||||
async def set_welcome_template(ctx, text: str):
|
||||
guild_config = GuildConfig(ctx.guild.id)
|
||||
async def set_welcome_template(ctx, text: str) -> None:
|
||||
if not ctx.guild:
|
||||
raise LumiException()
|
||||
|
||||
guild_config: GuildConfig = GuildConfig(ctx.guild.id)
|
||||
guild_config.welcome_message = text
|
||||
guild_config.push()
|
||||
|
||||
embed = EmbedBuilder().create_success_embed(
|
||||
embed: discord.Embed = EmbedBuilder().create_success_embed(
|
||||
ctx=ctx,
|
||||
author_text=CONST.STRINGS["config_author"],
|
||||
description=CONST.STRINGS["config_welcome_template_updated"],
|
||||
|
@ -60,5 +71,26 @@ async def set_welcome_template(ctx, text: str):
|
|||
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
example_embed = Greet.message(ctx.author, text)
|
||||
return await ctx.send(embed=example_embed, content=ctx.author.mention)
|
||||
greet_member: discord.Member = await MemberConverter().convert(ctx, str(ctx.author))
|
||||
example_embed: discord.Embed = create_greet_embed(greet_member, text)
|
||||
await ctx.send(embed=example_embed, content=ctx.author.mention)
|
||||
|
||||
|
||||
def create_greet_embed(
|
||||
member: discord.Member,
|
||||
template: Optional[str] = None,
|
||||
) -> discord.Embed:
|
||||
embed: discord.Embed = discord.Embed(
|
||||
color=discord.Color.embed_background(),
|
||||
description=CONST.STRINGS["greet_default_description"].format(
|
||||
member.guild.name,
|
||||
),
|
||||
)
|
||||
if template and embed.description is not None:
|
||||
embed.description += CONST.STRINGS["greet_template_description"].format(
|
||||
formatter.template(template, member.name),
|
||||
)
|
||||
|
||||
embed.set_thumbnail(url=member.display_avatar.url)
|
||||
|
||||
return embed
|
||||
|
|
|
@ -7,9 +7,9 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from lib import interaction
|
||||
from lib.embeds.error import EconErrors
|
||||
from services.currency_service import Currency
|
||||
from services.stats_service import BlackJackStats
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from lib.constants import CONST
|
||||
|
||||
est = pytz.timezone("US/Eastern")
|
||||
|
@ -25,13 +25,11 @@ async def cmd(ctx, bet: int):
|
|||
3 = dealer busted
|
||||
4 = dealer won
|
||||
5 = player won with 21 (blackjack)
|
||||
6 = timed out
|
||||
"""
|
||||
|
||||
# check if the player already has an active blackjack going
|
||||
if ctx.author.id in active_blackjack_games:
|
||||
await ctx.respond(embed=EconErrors.already_playing(ctx))
|
||||
return
|
||||
raise LumiException(CONST.STRINGS["error_already_playing_blackjack"])
|
||||
|
||||
# Currency handler
|
||||
ctx_currency = Currency(ctx.author.id)
|
||||
|
@ -99,8 +97,10 @@ async def cmd(ctx, bet: int):
|
|||
status = 3 if dealer_hand_value > 21 else 4
|
||||
break
|
||||
else:
|
||||
status = 6
|
||||
break
|
||||
# timed out
|
||||
ctx_currency.take_balance(bet)
|
||||
ctx_currency.push()
|
||||
raise LumiException(CONST.STRINGS["error_out_of_time_economy"])
|
||||
|
||||
# refresh
|
||||
view = interaction.BlackJackButtons(ctx)
|
||||
|
@ -118,7 +118,8 @@ async def cmd(ctx, bet: int):
|
|||
"""
|
||||
At this point the game has concluded, generate a final output & backend
|
||||
"""
|
||||
payout = bet * 2 if status == 5 else bet * multiplier
|
||||
|
||||
payout = bet * multiplier if status != 5 else bet * 2
|
||||
is_won = status not in [1, 4]
|
||||
|
||||
embed = blackjack_finished(
|
||||
|
@ -150,15 +151,6 @@ async def cmd(ctx, bet: int):
|
|||
hand_player=player_hand,
|
||||
hand_dealer=dealer_hand,
|
||||
)
|
||||
stats.push()
|
||||
|
||||
elif status == 6:
|
||||
await ctx.send(
|
||||
embed=EconErrors.out_of_time(ctx),
|
||||
content=ctx.author.mention,
|
||||
)
|
||||
ctx_currency.take_balance(bet)
|
||||
ctx_currency.push()
|
||||
|
||||
else:
|
||||
ctx_currency.add_balance(payout)
|
||||
|
@ -173,7 +165,8 @@ async def cmd(ctx, bet: int):
|
|||
hand_player=player_hand,
|
||||
hand_dealer=dealer_hand,
|
||||
)
|
||||
stats.push()
|
||||
|
||||
stats.push()
|
||||
|
||||
except Exception as e:
|
||||
# await ctx.respond(embed=GenericErrors.default_exception(ctx))
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
from typing import Optional
|
||||
|
||||
from discord.ext import bridge
|
||||
|
||||
from lib.embeds.triggers import create_creation_embed, create_failure_embed
|
||||
from services.reactions_service import CustomReactionsService
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib import formatter
|
||||
|
||||
|
||||
async def add_reaction(
|
||||
|
@ -22,20 +24,15 @@ async def add_reaction(
|
|||
creator_id: int = ctx.author.id
|
||||
|
||||
if not await check_reaction_limit(
|
||||
ctx,
|
||||
reaction_service,
|
||||
guild_id,
|
||||
trigger_text,
|
||||
is_emoji,
|
||||
):
|
||||
return
|
||||
|
||||
if not await check_existing_trigger(
|
||||
ctx,
|
||||
reaction_service,
|
||||
guild_id,
|
||||
trigger_text,
|
||||
is_emoji,
|
||||
):
|
||||
return
|
||||
|
||||
|
@ -47,51 +44,63 @@ async def add_reaction(
|
|||
emoji_id=emoji_id,
|
||||
is_emoji=is_emoji,
|
||||
is_full_match=is_full_match,
|
||||
is_global=False, # only bot admins can create global custom reactions
|
||||
is_global=False,
|
||||
)
|
||||
|
||||
if success:
|
||||
embed = create_creation_embed(
|
||||
trigger_text,
|
||||
response,
|
||||
if not success:
|
||||
raise LumiException(CONST.STRINGS["triggers_not_added"])
|
||||
|
||||
trigger_text = formatter.shorten(trigger_text, 50)
|
||||
|
||||
if response:
|
||||
response = formatter.shorten(response, 50)
|
||||
|
||||
embed = EmbedBuilder.create_success_embed(
|
||||
ctx,
|
||||
author_text=CONST.STRINGS["triggers_add_author"],
|
||||
description="",
|
||||
footer_text=CONST.STRINGS["triggers_reaction_service_footer"],
|
||||
show_name=False,
|
||||
)
|
||||
|
||||
embed.description += CONST.STRINGS["triggers_add_description"].format(
|
||||
trigger_text,
|
||||
CONST.STRINGS["triggers_type_emoji"]
|
||||
if is_emoji
|
||||
else CONST.STRINGS["triggers_type_text"],
|
||||
is_full_match,
|
||||
)
|
||||
|
||||
if is_emoji:
|
||||
embed.description += CONST.STRINGS["triggers_add_emoji_details"].format(
|
||||
emoji_id,
|
||||
is_emoji,
|
||||
is_full_match,
|
||||
)
|
||||
else:
|
||||
embed = create_failure_embed(trigger_text, is_emoji)
|
||||
embed.description += CONST.STRINGS["triggers_add_text_details"].format(response)
|
||||
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
|
||||
async def check_reaction_limit(
|
||||
ctx: bridge.Context,
|
||||
reaction_service: CustomReactionsService,
|
||||
guild_id: int,
|
||||
trigger_text: str,
|
||||
is_emoji: bool,
|
||||
) -> bool:
|
||||
if await reaction_service.count_custom_reactions(guild_id) >= 100:
|
||||
embed = create_failure_embed(trigger_text, is_emoji, limit_reached=True)
|
||||
await ctx.respond(embed=embed)
|
||||
return False
|
||||
limit_reached = await reaction_service.count_custom_reactions(guild_id) >= 100
|
||||
|
||||
if limit_reached:
|
||||
raise LumiException(CONST.STRINGS["trigger_limit_reached"])
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def check_existing_trigger(
|
||||
ctx: bridge.Context,
|
||||
reaction_service: CustomReactionsService,
|
||||
guild_id: int,
|
||||
trigger_text: str,
|
||||
is_emoji: bool,
|
||||
) -> bool:
|
||||
existing_trigger = await reaction_service.find_trigger(guild_id, trigger_text)
|
||||
|
||||
if existing_trigger:
|
||||
embed = create_failure_embed(
|
||||
trigger_text,
|
||||
is_emoji,
|
||||
trigger_already_exists=True,
|
||||
)
|
||||
await ctx.respond(embed=embed)
|
||||
return False
|
||||
raise LumiException(CONST.STRINGS["trigger_already_exists"])
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
from discord.ext import bridge
|
||||
|
||||
from lib.embeds.triggers import (
|
||||
create_deletion_embed,
|
||||
create_failure_embed,
|
||||
create_not_found_embed,
|
||||
)
|
||||
from services.reactions_service import CustomReactionsService
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.constants import CONST
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
|
||||
|
||||
async def delete_reaction(ctx: bridge.Context, reaction_id: int) -> None:
|
||||
|
@ -14,23 +11,18 @@ async def delete_reaction(ctx: bridge.Context, reaction_id: int) -> None:
|
|||
|
||||
reaction_service = CustomReactionsService()
|
||||
guild_id: int = ctx.guild.id
|
||||
|
||||
# Check if the reaction exists and belongs to the guild
|
||||
reaction = await reaction_service.find_id(reaction_id)
|
||||
|
||||
if reaction is None or reaction["guild_id"] != guild_id or reaction["is_global"]:
|
||||
embed = create_not_found_embed(reaction_id)
|
||||
await ctx.respond(embed=embed)
|
||||
return
|
||||
raise LumiException(CONST.STRINGS["triggers_not_found"])
|
||||
|
||||
trigger_text = reaction["trigger_text"]
|
||||
is_emoji = reaction["is_emoji"]
|
||||
await reaction_service.delete_custom_reaction(reaction_id)
|
||||
|
||||
# Attempt to delete the reaction
|
||||
success: bool = await reaction_service.delete_custom_reaction(reaction_id)
|
||||
embed = EmbedBuilder.create_success_embed(
|
||||
ctx,
|
||||
author_text=CONST.STRINGS["triggers_delete_author"],
|
||||
description=CONST.STRINGS["triggers_delete_description"],
|
||||
footer_text=CONST.STRINGS["triggers_reaction_service_footer"],
|
||||
)
|
||||
|
||||
if success:
|
||||
embed = create_deletion_embed(trigger_text, is_emoji)
|
||||
await ctx.respond(embed=embed)
|
||||
else:
|
||||
embed = create_failure_embed(trigger_text, is_emoji)
|
||||
await ctx.respond(embed=embed)
|
||||
await ctx.respond(embed=embed)
|
||||
|
|
|
@ -1,39 +1,79 @@
|
|||
import datetime
|
||||
|
||||
import discord
|
||||
from discord.ext import bridge, pages
|
||||
from lib.constants import CONST
|
||||
from lib.embeds.triggers import create_no_triggers_embed
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.reactions_service import CustomReactionsService
|
||||
from typing import Any, Dict, List
|
||||
from lib import formatter
|
||||
|
||||
import discord
|
||||
|
||||
|
||||
async def list_reactions(ctx: bridge.Context) -> None:
|
||||
if ctx.guild is None:
|
||||
return
|
||||
|
||||
reaction_service = CustomReactionsService()
|
||||
reaction_service: CustomReactionsService = CustomReactionsService()
|
||||
guild_id: int = ctx.guild.id
|
||||
|
||||
# Fetch all reactions for the guild
|
||||
reactions = await reaction_service.find_all_by_guild(guild_id)
|
||||
reactions: List[Dict[str, Any]] = await reaction_service.find_all_by_guild(guild_id)
|
||||
if not reactions:
|
||||
embed = create_no_triggers_embed()
|
||||
embed: discord.Embed = EmbedBuilder.create_warning_embed(
|
||||
ctx,
|
||||
author_text=CONST.STRINGS["triggers_no_reactions_title"],
|
||||
description=CONST.STRINGS["triggers_no_reactions_description"],
|
||||
footer_text=CONST.STRINGS["triggers_reaction_service_footer"],
|
||||
show_name=False,
|
||||
)
|
||||
await ctx.respond(embed=embed)
|
||||
return
|
||||
|
||||
# Create pages for pagination
|
||||
pages_list = []
|
||||
for reaction in reactions:
|
||||
description = f"""**Trigger Text:** `{reaction['trigger_text']}`\n**Reaction Type:** {'Emoji' if reaction['is_emoji'] else 'Text'}\n{f"**Emoji ID:** `{str(reaction['emoji_id'])}`" if reaction['is_emoji'] else f"**Response:** `{reaction['response']}`"}\n**Full Match:** `{'True' if reaction['is_full_match'] else 'False'}`\n**Usage Count:** `{reaction['usage_count']}`"""
|
||||
embed = discord.Embed(
|
||||
title=f"ID: {reaction['id']}",
|
||||
description=description,
|
||||
color=0xFF8C00,
|
||||
embed = EmbedBuilder.create_success_embed(
|
||||
ctx,
|
||||
title=CONST.STRINGS["triggers_list_custom_reaction_id"].format(
|
||||
reaction["id"],
|
||||
),
|
||||
author_text=CONST.STRINGS["triggers_list_custom_reactions_title"],
|
||||
footer_text=CONST.STRINGS["triggers_reaction_service_footer"],
|
||||
show_name=False,
|
||||
)
|
||||
embed.set_author(name="Custom Reactions", icon_url=CONST.CHECK_ICON)
|
||||
embed.set_footer(text="Reaction Service", icon_url=CONST.LUMI_LOGO_TRANSPARENT)
|
||||
embed.timestamp = datetime.datetime.now(datetime.timezone.utc)
|
||||
|
||||
description_lines = [
|
||||
CONST.STRINGS["triggers_list_trigger_text"].format(
|
||||
formatter.shorten(reaction["trigger_text"], 50),
|
||||
),
|
||||
CONST.STRINGS["triggers_list_reaction_type"].format(
|
||||
CONST.STRINGS["triggers_type_emoji"]
|
||||
if reaction["is_emoji"]
|
||||
else CONST.STRINGS["triggers_type_text"],
|
||||
),
|
||||
]
|
||||
|
||||
if reaction["is_emoji"]:
|
||||
description_lines.append(
|
||||
CONST.STRINGS["triggers_list_emoji_id"].format(reaction["emoji_id"]),
|
||||
)
|
||||
else:
|
||||
description_lines.append(
|
||||
CONST.STRINGS["triggers_list_response"].format(
|
||||
formatter.shorten(reaction["response"], 50),
|
||||
),
|
||||
)
|
||||
|
||||
description_lines.extend(
|
||||
[
|
||||
CONST.STRINGS["triggers_list_full_match"].format(
|
||||
"True" if reaction["is_full_match"] else "False",
|
||||
),
|
||||
CONST.STRINGS["triggers_list_usage_count"].format(
|
||||
reaction["usage_count"],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
embed.description = "\n".join(description_lines)
|
||||
pages_list.append(embed)
|
||||
|
||||
paginator = pages.Paginator(pages=pages_list, timeout=180.0)
|
||||
paginator: pages.Paginator = pages.Paginator(pages=pages_list, timeout=180.0)
|
||||
await paginator.respond(ctx, ephemeral=False)
|
||||
|
|
Loading…
Reference in a new issue