discordbot/cogs/safebooru_cog.py
2025-05-11 17:16:06 -06:00

121 lines
6.8 KiB
Python

import discord
from discord.ext import commands, tasks
from discord import app_commands
import typing # Need this for Optional
import logging
from .gelbooru_watcher_base_cog import GelbooruWatcherBaseCog
# Setup logger for this cog
log = logging.getLogger(__name__)
class SafebooruCog(GelbooruWatcherBaseCog): # Removed name="Safebooru"
# Define the command group specific to this cog
safebooruwatch = app_commands.Group(name="safebooruwatch", description="Manage Safebooru tag watchers for new posts.")
def __init__(self, bot: commands.Bot):
super().__init__(
bot=bot,
cog_name="Safebooru",
api_base_url="https://safebooru.org/index.php", # Corrected base URL
default_tags="hatsune_miku 1girl", # Example default
is_nsfw_site=False, # Safebooru is generally SFW
command_group_name="safebooruwatch",
main_command_name="safebooru"
)
# --- Prefix Command ---
@commands.command(name="safebooru")
async def safebooru_prefix(self, ctx: commands.Context, *, tags: typing.Optional[str] = None):
"""Search for images on Safebooru with the provided tags."""
actual_tags = tags or self.default_tags
loading_msg = await ctx.reply(f"Fetching data from {self.cog_name}, please wait...")
response = await self._fetch_posts_logic("prefix_internal", actual_tags, hidden=False)
if isinstance(response, tuple):
content, all_results = response
view = self.GelbooruButtons(self, actual_tags, all_results, hidden=False)
await loading_msg.edit(content=content, view=view)
elif isinstance(response, str): # Error
await loading_msg.edit(content=response, view=None)
# --- Slash Command ---
@app_commands.command(name="safebooru", description="Get random image from Safebooru with specified tags")
@app_commands.describe(
tags="The tags to search for (e.g., '1girl cat_ears')",
hidden="Set to True to make the response visible only to you (default: False)"
)
async def safebooru_slash(self, interaction: discord.Interaction, tags: typing.Optional[str] = None, hidden: bool = False):
"""Slash command version of safebooru."""
actual_tags = tags or self.default_tags
await self._slash_command_logic(interaction, actual_tags, hidden)
# --- New Browse Command ---
@app_commands.command(name="safeboorubrowse", description="Browse Safebooru results with navigation buttons")
@app_commands.describe(
tags="The tags to search for (e.g., '1girl dog_ears')",
hidden="Set to True to make the response visible only to you (default: False)"
)
async def safebooru_browse_slash(self, interaction: discord.Interaction, tags: typing.Optional[str] = None, hidden: bool = False):
"""Browse Safebooru results with navigation buttons."""
actual_tags = tags or self.default_tags
await self._browse_slash_command_logic(interaction, actual_tags, hidden)
# --- safebooruwatch slash command group ---
@safebooruwatch.command(name="add", description="Watch for new Safebooru posts with specific tags in a channel or thread.")
@app_commands.describe(
tags="The tags to search for (e.g., '1girl cat_ears').",
channel="The parent channel for the subscription. Must be a Forum Channel if using forum mode.",
thread_target="Optional: Name or ID of a thread within the channel (for TextChannels only).",
post_title="Optional: Title for a new forum post if 'channel' is a Forum Channel."
)
@app_commands.checks.has_permissions(manage_guild=True)
async def safebooruwatch_add(self, interaction: discord.Interaction, tags: str, channel: typing.Union[discord.TextChannel, discord.ForumChannel], thread_target: typing.Optional[str] = None, post_title: typing.Optional[str] = None):
await interaction.response.defer(ephemeral=True)
await self._watch_add_logic(interaction, tags, channel, thread_target, post_title)
@safebooruwatch.command(name="request", description="Request a new Safebooru tag watch (requires moderator approval).")
@app_commands.describe(
tags="The tags you want to watch.",
forum_channel="The Forum Channel where a new post for this watch should be created.",
post_title="Optional: A title for the new forum post (defaults to tags)."
)
async def safebooruwatch_request(self, interaction: discord.Interaction, tags: str, forum_channel: discord.ForumChannel, post_title: typing.Optional[str] = None):
await interaction.response.defer(ephemeral=True)
await self._watch_request_logic(interaction, tags, forum_channel, post_title)
@safebooruwatch.command(name="pending_list", description="Lists all pending Safebooru watch requests.")
@app_commands.checks.has_permissions(manage_guild=True)
async def safebooruwatch_pending_list(self, interaction: discord.Interaction):
await self._watch_pending_list_logic(interaction)
@safebooruwatch.command(name="approve_request", description="Approves a pending Safebooru watch request.")
@app_commands.describe(request_id="The ID of the request to approve.")
@app_commands.checks.has_permissions(manage_guild=True)
async def safebooruwatch_approve_request(self, interaction: discord.Interaction, request_id: str):
await interaction.response.defer(ephemeral=True)
await self._watch_approve_request_logic(interaction, request_id)
@safebooruwatch.command(name="reject_request", description="Rejects a pending Safebooru watch request.")
@app_commands.describe(request_id="The ID of the request to reject.", reason="Optional reason for rejection.")
@app_commands.checks.has_permissions(manage_guild=True)
async def safebooruwatch_reject_request(self, interaction: discord.Interaction, request_id: str, reason: typing.Optional[str] = None):
await interaction.response.defer(ephemeral=True)
await self._watch_reject_request_logic(interaction, request_id, reason)
@safebooruwatch.command(name="list", description="List active Safebooru tag watches for this server.")
@app_commands.checks.has_permissions(manage_guild=True)
async def safebooruwatch_list(self, interaction: discord.Interaction):
await self._watch_list_logic(interaction)
@safebooruwatch.command(name="remove", description="Stop watching for new Safebooru posts using a subscription ID.")
@app_commands.describe(subscription_id="The ID of the subscription to remove (get from 'list' command).")
@app_commands.checks.has_permissions(manage_guild=True)
async def safebooruwatch_remove(self, interaction: discord.Interaction, subscription_id: str):
await self._watch_remove_logic(interaction, subscription_id)
async def setup(bot: commands.Bot):
await bot.add_cog(SafebooruCog(bot))
log.info("SafebooruCog (refactored) added to bot.")