diff --git a/handlers/error.py b/handlers/error.py index 704d25e..97bd33c 100644 --- a/handlers/error.py +++ b/handlers/error.py @@ -17,6 +17,7 @@ error_map: dict[type[Exception], str] = { commands.NoPrivateMessage: CONST.STRINGS["error_no_private_message_description"], commands.NotOwner: CONST.STRINGS["error_not_owner_unknown"], commands.PrivateMessageOnly: CONST.STRINGS["error_private_message_only_description"], + commands.NSFWChannelRequired: CONST.STRINGS["error_nsfw_channel_required_description"], exceptions.BirthdaysDisabled: CONST.STRINGS["error_birthdays_disabled_description"], } diff --git a/locales/strings.en-US.json b/locales/strings.en-US.json index 9a192c3..377d5a7 100644 --- a/locales/strings.en-US.json +++ b/locales/strings.en-US.json @@ -191,6 +191,7 @@ "error_not_enough_cash": "you don't have enough cash.", "error_not_owner": "{0} tried to use a bot admin command ({1})", "error_not_owner_unknown": "Unknown", + "error_nsfw_channel_required_description": "this command can only be used in Age-Restricted (NSFW) channels.", "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", @@ -213,6 +214,7 @@ "info_service_footer": "Info Service", "info_system": "**System:** {0} ({1})\n", "info_uptime": "**Uptime:** \n", + "inspirobot_author": "InspiroBot (AI Generated)", "intro_content": "Introduction by {0}", "intro_content_footer": "Type .intro in my DMs to start", "intro_no_channel": "the introduction channel is not set, please contact a moderator.", diff --git a/modules/misc/inspirotbot.py b/modules/misc/inspirotbot.py new file mode 100644 index 0000000..d1c98a1 --- /dev/null +++ b/modules/misc/inspirotbot.py @@ -0,0 +1,46 @@ +from discord.ext import commands + +import lib.format +from lib.client import Luminara +from lib.const import CONST +from lib.exceptions import LumiException +from ui.embeds import Builder +from wrappers.inspirobot import InspiroBot + + +class Inspirobot(commands.Cog): + def __init__(self, bot: Luminara) -> None: + self.bot: Luminara = bot + self.inspirobot.usage = lib.format.generate_usage(self.inspirobot) + + @commands.hybrid_command( + name="inspirobot", + aliases=["inspiro", "ib"], + ) + @commands.is_nsfw() + async def inspirobot(self, ctx: commands.Context[Luminara]) -> None: + """ + Get a random AI-generated motivational image from Inspirobot. + + Parameters + ---------- + ctx : commands.Context[Luminara] + The context of the command. + """ + async with ctx.typing(): + try: + image_url = await InspiroBot().get_image() + except Exception as e: + msg = f"Failed to get image URL from Inspirobot: {e}" + raise LumiException(msg) from e + + embed = Builder.create_embed( + Builder.SUCCESS, + author_text=CONST.STRINGS["inspirobot_author"], + image_url=image_url, + ) + await ctx.send(embed=embed) + + +async def setup(bot: Luminara) -> None: + await bot.add_cog(Inspirobot(bot)) diff --git a/settings.yaml b/settings.yaml index 199a017..c53846f 100644 --- a/settings.yaml +++ b/settings.yaml @@ -88,7 +88,7 @@ info: title: Luminara author: wlinator license: GNU General Public License v3.0 - version: "3.1.0" + version: "3.2.0" repository_url: https://git.wlinator.org/Luminara/Lumi invite_url: https://discord.com/oauth2/authorize?client_id=1038050427272429588&permissions=8&scope=bot diff --git a/wrappers/inspirobot.py b/wrappers/inspirobot.py new file mode 100644 index 0000000..fb21c31 --- /dev/null +++ b/wrappers/inspirobot.py @@ -0,0 +1,20 @@ +import httpx + + +class InspiroBot: + def __init__(self): + self.base_url = "https://inspirobot.me/api?generate=true" + + async def get_image(self) -> str: + """ + Get a random motivational image from Inspirobot. + + Returns + ------- + str + The URL of the image. + """ + async with httpx.AsyncClient(timeout=10.0) as client: + response = await client.get(self.base_url) + response.raise_for_status() + return response.text