Skip to content

Commit 04d0f57

Browse files
committed
Implement prefix commands
1 parent cb88f09 commit 04d0f57

File tree

1 file changed

+110
-1
lines changed

1 file changed

+110
-1
lines changed

bot/cogs/config.py

+110-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, Optional
3+
from typing import TYPE_CHECKING, Annotated, Optional
44

55
import asyncpg
66
import discord
77
import msgspec
88
from async_lru import alru_cache
9+
from discord import app_commands
910
from discord.ext import commands
1011
from libs.utils import GuildContext
1112
from libs.utils.checks import bot_check_permissions, check_permissions
13+
from libs.utils.embeds import Embed
14+
from libs.utils.prefix import get_prefix
1215

1316
if TYPE_CHECKING:
1417
from rodhaj import Rodhaj
@@ -96,6 +99,16 @@ class SetupFlags(commands.FlagConverter):
9699
)
97100

98101

102+
class PrefixConverter(commands.Converter):
103+
async def convert(self, ctx: commands.Context, argument: str):
104+
user_id = ctx.bot.user.id
105+
if argument.startswith((f"<@{user_id}>", f"<@!{user_id}>")):
106+
raise commands.BadArgument("That is a reserved prefix already in use.")
107+
if len(argument) > 100:
108+
raise commands.BadArgument("That prefix is too long.")
109+
return argument
110+
111+
99112
class Config(commands.Cog):
100113
"""Config and setup commands for Rodhaj"""
101114

@@ -334,6 +347,102 @@ async def delete(self, ctx: GuildContext) -> None:
334347
else:
335348
await ctx.send("Cancelling.")
336349

350+
@check_permissions(manage_guild=True)
351+
@commands.guild_only()
352+
@config.group(name="prefix", fallback="info")
353+
async def prefix(self, ctx: GuildContext) -> None:
354+
"""Manages custom prefixes for the guild.
355+
356+
Passing in no subcommands will effectively show the currently set prefixes.
357+
"""
358+
user_id = self.bot.user.id # type: ignore
359+
prefixes = await get_prefix(self.bot, ctx.message)
360+
cleaned = ", ".join(
361+
f"`{prefix}`" for prefix in prefixes if str(user_id) not in prefix
362+
)
363+
embed = Embed()
364+
embed.add_field(name="Prefixes", value=cleaned)
365+
embed.set_author(name=ctx.guild.name, icon_url=ctx.guild.icon.url) # type: ignore
366+
await ctx.send(embed=embed)
367+
368+
@prefix.command(name="add")
369+
@app_commands.describe(prefix="The new prefix to add")
370+
async def prefix_add(
371+
self, ctx: GuildContext, prefix: Annotated[str, PrefixConverter]
372+
) -> None:
373+
"""Adds an custom prefix"""
374+
prefixes = await get_prefix(self.bot, ctx.message)
375+
if isinstance(prefixes, list) and len(prefixes) > 12 or prefix in prefixes:
376+
desc = (
377+
"There was a validation issue. "
378+
"This is caused by these reasons: \n"
379+
"- You have more than 12 prefixes for your server\n"
380+
"- Your prefix fails the validation rules\n"
381+
"- The prefix you want to set already exists"
382+
)
383+
await ctx.send(desc)
384+
return
385+
386+
query = """
387+
UPDATE guild_config
388+
SET prefix = ARRAY_APPEND(prefix, $1)
389+
WHERE id = $2;
390+
"""
391+
await self.pool.execute(query, prefix, ctx.guild.id)
392+
get_prefix.cache_invalidate(self.bot, ctx.message)
393+
await ctx.send(f"Added prefix: `{prefix}`")
394+
395+
@prefix.command(name="edit")
396+
@app_commands.describe(
397+
old="The prefix to edit", new="A new prefix to replace the old"
398+
)
399+
@app_commands.rename(old="old_prefix", new="new_prefix")
400+
async def prefix_edit(
401+
self,
402+
ctx: GuildContext,
403+
old: Annotated[str, PrefixConverter],
404+
new: Annotated[str, PrefixConverter],
405+
) -> None:
406+
"""Edits and replaces a prefix"""
407+
query = """
408+
UPDATE guild_config
409+
SET prefix = ARRAY_REPLACE(prefix, $1, $2)
410+
WHERE id = $3;
411+
"""
412+
prefixes = await get_prefix(self.bot, ctx.message)
413+
414+
guild_id = ctx.guild.id
415+
if old in prefixes:
416+
await self.pool.execute(query, old, new, guild_id)
417+
get_prefix.cache_invalidate(self.bot, ctx.message)
418+
await ctx.send(f"Prefix updated to from `{old}` to `{new}`")
419+
else:
420+
await ctx.send("The prefix is not in the list of prefixes for your server")
421+
422+
@prefix.command(name="delete")
423+
@app_commands.describe(prefix="The prefix to delete")
424+
async def prefix_delete(
425+
self, ctx: GuildContext, prefix: Annotated[str, PrefixConverter]
426+
) -> None:
427+
"""Deletes a set prefix"""
428+
query = """
429+
UPDATE guild_config
430+
SET prefix = ARRAY_REMOVE(prefix, $1)
431+
WHERE id=$2;
432+
"""
433+
msg = f"Do you want to delete the following prefix: {prefix}"
434+
confirm = await ctx.prompt(msg, timeout=120.0, delete_after=True)
435+
if confirm:
436+
await self.pool.execute(query, prefix, ctx.guild.id)
437+
get_prefix.cache_invalidate(self.bot, ctx.message)
438+
await ctx.send(f"The prefix `{prefix}` has been successfully deleted")
439+
return
440+
elif confirm is None:
441+
await ctx.send("Confirmation timed out. Cancelled deletion...")
442+
return
443+
else:
444+
await ctx.send("Confirmation cancelled. Please try again")
445+
337446

338447
async def setup(bot: Rodhaj) -> None:
339448
await bot.add_cog(Config(bot))

0 commit comments

Comments
 (0)