"""Deprecated module This was intended to be the resources module. A user-submitted, curated directory of resources for a guild. For the time being, forum channels serve as enough of an equivalent for the needs of NLL. So this is to be considered deprecated. """ from naff import ( slash_command, slash_option, Extension, Client, Permissions, InteractionContext, OptionTypes, Embed, Member, EmbedField, EmbedAuthor, Modal, InputText, TextStyles, ChannelTypes, GuildText, ) import logging from database import ( Resources as ResourcesModel, ResourceTags as ResourceTagsModel, ResourceAuthors as ResourceAuthorsModel, ResourcesUnpublished as ResourcesUnpublishedModel, ResourceChannels as ResourceChannelsModel, ) class Resources(Extension): def __init__(self, client: Client) -> None: self.client = client @slash_command( name="adm", group_name="set", group_description="Set settings for this guild", sub_cmd_name="submitted_resources_channel", sub_cmd_description="Set whether or not to use the name filter", dm_permission=False, default_member_permissions=Permissions.MANAGE_GUILD, ) @slash_option( name="channel", description="The channel in which submitted/unpublished resources should appear", opt_type=OptionTypes.CHANNEL, channel_types=[ChannelTypes.GUILD_TEXT], ) async def adm_set_submitted_resources_channel( self, ctx: InteractionContext, channel: GuildText|None = None ): if channel is None: resource_channel = ResourceChannelsModel.get_or_none(guild_id=ctx.guild.id) if resource_channel is not None: resource_channel.delete_instance() await ctx.send(ephemeral=True, content="Submitted resource channel unset.") return resource_channel: ResourceChannelsModel resource_channel, _ = ResourceChannelsModel.get_or_create(guild_id=ctx.guild.id) resource_channel.channel_id = channel.id resource_channel.save() await ctx.send(ephemeral=True, content=f"Submitted resource channel set to {channel.mention}." ) @slash_command( name="resources", description="Get or add resources", default_member_permissions=Permissions.SEND_MESSAGES, dm_permission=False, ) async def resources(self, ctx: InteractionContext): ... @resources.subcommand( sub_cmd_name="list", sub_cmd_description="List resources", ) @slash_option( name="page", description="Page of resources to show", opt_type=OptionTypes.INTEGER, required=False, ) async def resources_list(self, ctx: InteractionContext, page: int = 1): await ctx.defer(ephemeral=True) LIMIT = 10 resources: list[ResourcesModel] = ( ResourcesModel.select() .paginate(page, LIMIT) .order_by(ResourcesModel.id.asc()) ) embeds: list[Embed] = [] for resource in resources: resource_authors: list[ ResourceAuthorsModel ] = ResourceAuthorsModel.select().where( ResourceAuthorsModel.resource_id == resource.id ) authors: list[str] = [] for author in resource_authors: member = await self.client.fetch_member(author.user_id, ctx.guild_id) if member is None: authors.append(author.name) else: authors.append( f"{member.display_name} ({member.username}#{member.discriminator})" ) embed = Embed(title=resource.title, description=resource.description) embed.add_field("**Authors**", "\n".join(authors)) no_resources = ResourcesModel.select().count() pages = no_resources // LIMIT if no_resources % LIMIT != 0: pages += 1 await ctx.send(ephemeral=True, content=f"Page {page} of {pages}", embeds=embeds) @resources.subcommand( sub_cmd_name="submit", sub_cmd_description="Submit a resource for approval", ) async def resources_submit(self, ctx: InteractionContext): modal_wait = await ctx.send_modal( Modal( title="New resource", components=[ InputText( label="Title", custom_id="title", style=TextStyles.SHORT, placeholder="A title!", min_length=8, max_length=64, ), InputText( label="Content", custom_id="content", style=TextStyles.PARAGRAPH, placeholder="A description of the resource.", min_length=16, ), InputText( label="Tags", custom_id="tags", style=TextStyles.SHORT, placeholder="Tags separated by spaces; e.g: grammar language-dialects tag", max_length=128, ), ], ) ) modal_ctx = await self.client.wait_for_modal(modal_wait, author=ctx.author.id) await modal_ctx.defer(ephemeral=True) title = modal_ctx.responses.get("title") content = modal_ctx.responses.get("content") tags = modal_ctx.responses.get("tags") if title is None: await modal_ctx.send("Title cannot be empty.") return if content is None: await modal_ctx.send("Content cannot be empty.") return resource: ResourcesUnpublishedModel = ResourcesUnpublishedModel.create( guild_id=modal_ctx.guild.id, title=title, description=content, tags=tags, author=modal_ctx.author.id, ) await modal_ctx.send(f"Your resource *{title}* has been submitted!") await self.__post_to_resources_submission_channel(resource) async def __post_to_resources_submission_channel(self, resource: ResourcesUnpublishedModel): res_unpublished_channel: ResourceChannelsModel | None = ResourceChannelsModel.get_or_none( ResourceChannelsModel.guild_id == resource.guild_id ) if res_unpublished_channel is None: return # No unpublished resources channel has been set. channel_id = int(res_unpublished_channel.channel_id) channel = await self.client.fetch_channel(channel_id) guild_id = int(resource.guild_id) user_id = int(resource.author) author: Member | None = await self.client.fetch_member(guild_id=guild_id, user_id=user_id) author_text = None author_icon_url = None if author is None: author_text = f"<@{int(resource.author)}>" else: author_icon_url = author.display_avatar.as_url() if author.display_name != author.username: author_text = f"{author.display_name} ({author.username}#{author.discriminator})" else: author_text = f"{author.username}#{author.discriminator}" await channel.send( embed=Embed( title=str(resource.title), description=str(resource.description), author=EmbedAuthor( name=author_text, icon_url=author_icon_url, ) ) ) def setup(bot: Client): ResourcesModel.create_table(safe=True) ResourceTagsModel.create_table(safe=True) ResourcesUnpublishedModel.create_table(safe=True) ResourceChannelsModel.create_table(safe=True) Resources(bot) logging.info("Resources extension loaded")