discordbot/cogs/rule34_cog.py
2025-05-11 17:06:25 -06:00

130 lines
7.4 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 Rule34Cog(GelbooruWatcherBaseCog): # Removed name="Rule34"
# Define the command group specific to this cog
r34watch = app_commands.Group(name="r34watch", description="Manage Rule34 tag watchers for new posts.")
def __init__(self, bot: commands.Bot):
super().__init__(
bot=bot,
cog_name="Rule34",
api_base_url="https://api.rule34.xxx/index.php",
default_tags="kasane_teto", # Example default
is_nsfw_site=True,
command_group_name="r34watch", # For potential use in base class messages
main_command_name="rule34" # For potential use in base class messages
)
# The __init__ in base class handles session creation and task starting.
# --- Prefix Command ---
@commands.command(name="rule34")
async def rule34_prefix(self, ctx: commands.Context, *, tags: typing.Optional[str] = None):
"""Search for images on Rule34 with the provided tags."""
actual_tags = tags or self.default_tags
# The base class _prefix_command_logic needs to be adjusted or called differently.
# For now, let's replicate the simple call structure.
# We need to ensure the loading message is handled correctly.
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="rule34", description="Get random image from Rule34 with specified tags")
@app_commands.describe(
tags="The tags to search for (e.g., 'kasane_teto rating:safe')",
hidden="Set to True to make the response visible only to you (default: False)"
)
async def rule34_slash(self, interaction: discord.Interaction, tags: typing.Optional[str] = None, hidden: bool = False):
"""Slash command version of rule34."""
actual_tags = tags or self.default_tags
await self._slash_command_logic(interaction, actual_tags, hidden)
# --- New Browse Command ---
@app_commands.command(name="rule34browse", description="Browse Rule34 results with navigation buttons")
@app_commands.describe(
tags="The tags to search for (e.g., 'kasane_teto rating:safe')",
hidden="Set to True to make the response visible only to you (default: False)"
)
async def rule34_browse_slash(self, interaction: discord.Interaction, tags: typing.Optional[str] = None, hidden: bool = False):
"""Browse Rule34 results with navigation buttons."""
actual_tags = tags or self.default_tags
await self._browse_slash_command_logic(interaction, actual_tags, hidden)
# --- r34watch slash command group ---
# All subcommands will call the corresponding _watch_..._logic methods from the base class.
@r34watch.command(name="add", description="Watch for new Rule34 posts with specific tags in a channel or thread.")
@app_commands.describe(
tags="The tags to search for (e.g., 'kasane_teto rating:safe').",
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 r34watch_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) # Defer here before calling base logic
await self._watch_add_logic(interaction, tags, channel, thread_target, post_title)
@r34watch.command(name="request", description="Request a new Rule34 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 r34watch_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)
@r34watch.command(name="pending_list", description="Lists all pending Rule34 watch requests.")
@app_commands.checks.has_permissions(manage_guild=True)
async def r34watch_pending_list(self, interaction: discord.Interaction):
# No defer needed if _watch_pending_list_logic handles it or is quick
await self._watch_pending_list_logic(interaction)
@r34watch.command(name="approve_request", description="Approves a pending Rule34 watch request.")
@app_commands.describe(request_id="The ID of the request to approve.")
@app_commands.checks.has_permissions(manage_guild=True)
async def r34watch_approve_request(self, interaction: discord.Interaction, request_id: str):
await interaction.response.defer(ephemeral=True)
await self._watch_approve_request_logic(interaction, request_id)
@r34watch.command(name="reject_request", description="Rejects a pending Rule34 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 r34watch_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)
@r34watch.command(name="list", description="List active Rule34 tag watches for this server.")
@app_commands.checks.has_permissions(manage_guild=True)
async def r34watch_list(self, interaction: discord.Interaction):
# No defer needed if _watch_list_logic handles it or is quick
await self._watch_list_logic(interaction)
@r34watch.command(name="remove", description="Stop watching for new Rule34 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 r34watch_remove(self, interaction: discord.Interaction, subscription_id: str):
# No defer needed if _watch_remove_logic handles it or is quick
await self._watch_remove_logic(interaction, subscription_id)
async def setup(bot: commands.Bot):
await bot.add_cog(Rule34Cog(bot))
log.info("Rule34Cog (refactored) added to bot.")