Refactor command definitions across multiple cogs to replace hybrid commands with regular commands for consistency. This change enhances clarity and standardizes command handling throughout the bot.
Some checks failed
CI / Bot (Python) (push) Successful in 12s
CI / Dashboard (Next.js) (push) Failing after 8s

This commit is contained in:
TheOnlyMace
2026-07-21 22:50:11 +02:00
parent 20193404e8
commit 1da2085087
47 changed files with 203 additions and 153 deletions

View File

@@ -50,7 +50,7 @@ class Birthdays(commands.Cog):
self.client = client
self.check_birthdays.start()
@commands.hybrid_command(
@commands.command(
name="birthdaysetup",
help="Set up the birthday log channel and role.")
@commands.has_permissions(administrator=True)
@@ -69,7 +69,7 @@ class Birthdays(commands.Cog):
await ctx.send(view=CV2("Birthday Setup", f"Birthday log channel set to {channel.mention} and birthday role set to {role.mention}."))
@commands.hybrid_command(
@commands.command(
name="setbirthday",
help="Set your birthday.")
@commands.guild_only()
@@ -112,7 +112,7 @@ class Birthdays(commands.Cog):
except asyncio.TimeoutError:
await ctx.send(view=CV2("Error", "You took too long to respond. Please try again."))
@commands.hybrid_command(
@commands.command(
name="removebirthday",
help="Remove your birthday.")
@commands.guild_only()
@@ -126,7 +126,7 @@ class Birthdays(commands.Cog):
else:
await ctx.send(view=CV2("Error", "You have no birthday set."))
@commands.hybrid_command(
@commands.command(
name="listbirthdays",
help="List all members who have their birthday today.")
@commands.guild_only()
@@ -143,7 +143,7 @@ class Birthdays(commands.Cog):
else:
await ctx.send(view=CV2("Birthdays", "No birthdays today."))
@commands.hybrid_command(
@commands.command(
name="birthday",
help="Check your birthday.")
@commands.guild_only()

View File

@@ -144,7 +144,7 @@ class Games(Cog):
game = btn.BetaBattleShip(player1=ctx.author, player2=player)
await game.start(ctx)
@commands.hybrid_group(name="country-guesser",
@commands.group(name="country-guesser",
help="Guess name of the country by flag.",
aliases=["guess", "guesser", "countryguesser"],
usage="country-guesser")

View File

@@ -36,7 +36,7 @@ class Invcrole(commands.Cog):
''')
await db.commit()
@commands.hybrid_group(name='vcrole', help="Vcrole Setup commands", invoke_without_command=True)
@commands.group(name='vcrole', help="Vcrole Setup commands", invoke_without_command=True)
@blacklist_check()
@ignore_check()
@commands.has_permissions(administrator=True)

View File

@@ -52,7 +52,7 @@ class AutoReaction(commands.Cog):
cursor = await db.execute("SELECT 1 FROM autoreact WHERE guild_id = ? AND trigger = ?", (guild_id, trigger))
return await cursor.fetchone()
@commands.hybrid_group(name="react", aliases=["autoreact"], help="Lists all subcommands of autoreact group.", invoke_without_command=True)
@commands.group(name="react", aliases=["autoreact"], help="Lists all subcommands of autoreact group.", invoke_without_command=True)
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 4, commands.BucketType.user)

View File

@@ -46,7 +46,7 @@ class AutoResponder(commands.Cog):
''')
await db.commit()
@commands.hybrid_group(name="autoresponder", invoke_without_command=True, aliases=['ar'], help="Manage autoresponders in the server.")
@commands.group(name="autoresponder", invoke_without_command=True, aliases=['ar'], help="Manage autoresponders in the server.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)

View File

@@ -92,7 +92,7 @@ class AutoRole(commands.Cog):
@commands.hybrid_group(name="autorole", invoke_without_command=True)
@commands.group(name="autorole", invoke_without_command=True)
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()

View File

@@ -123,7 +123,7 @@ class Blackjack(commands.Cog):
total_sum += 1
return total_sum
@commands.hybrid_command(aliases=['bj', 'blackjacks'], help="Play a simple game of blackjack.", usage="blackjack")
@commands.command(aliases=['bj', 'blackjacks'], help="Play a simple game of blackjack.", usage="blackjack")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)

View File

@@ -207,7 +207,7 @@ class Blacklist(commands.Cog):
await warning_message.delete(delay=3)
break
@commands.hybrid_group(name="blacklistword", aliases=["blword"], invoke_without_command=True)
@commands.group(name="blacklistword", aliases=["blword"], invoke_without_command=True)
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)

View File

@@ -54,7 +54,7 @@ class Block(commands.Cog):
@commands.hybrid_group(name="blacklist", aliases=["bl"], invoke_without_command=True)
@commands.group(name="blacklist", aliases=["bl"], invoke_without_command=True)
@commands.is_owner()
async def blacklist(self, ctx):
if ctx.subcommand_passed is None:

View File

@@ -122,7 +122,7 @@ class calculator(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command(name='calculator', help='Starts a calculator session', aliases=['calc', 'calculate', 'math'])
@commands.command(name='calculator', help='Starts a calculator session', aliases=['calc', 'calculate', 'math'])
async def calculator(self, ctx):
"""Starts a new calculator session."""
# Ensure we pass the author to the view so it knows who triggered it

View File

@@ -74,7 +74,7 @@ class Counting(commands.Cog):
"**counting stats** — View current counting stats"
))
@commands.hybrid_group(name="counting", invoke_without_command=True)
@commands.group(name="counting", invoke_without_command=True)
async def counting(self, ctx):
if not self.is_enabled(ctx.guild.id):
await self.not_enabled_embed(ctx)

View File

@@ -81,7 +81,7 @@ class StaffDMCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command(name="dmstaff")
@commands.command(name="dmstaff")
async def dm_staff(self, ctx, member: discord.Member, *, message: str):
if ctx.author.id not in STAFF_IDS:
view = PermissionErrorView()

View File

@@ -406,7 +406,7 @@ class Emergency(commands.Cog):
) as cursor:
return await cursor.fetchone() is not None
@commands.hybrid_group(name="emergency", aliases=["emg"], invoke_without_command=True)
@commands.group(name="emergency", aliases=["emg"], invoke_without_command=True)
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 4, commands.BucketType.user)
@@ -614,7 +614,7 @@ class Emergency(commands.Cog):
roles = await cursor.fetchall()
await ctx.reply(view=RoleListView(roles, is_auth))
@commands.hybrid_command(name="emergencysituation", aliases=["emgs"])
@commands.command(name="emergencysituation", aliases=["emgs"])
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 40, commands.BucketType.user)
@@ -736,7 +736,7 @@ class Emergency(commands.Cog):
await anti.commit()
await proc_msg.delete()
@commands.hybrid_command(name="emergencyrestore", aliases=["emgrestore"])
@commands.command(name="emergencyrestore", aliases=["emgrestore"])
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 30, commands.BucketType.user)

View File

@@ -88,12 +88,12 @@ class encryption(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_group(invoke_without_command=True)
@commands.group(invoke_without_command=True)
async def encode(self, ctx):
"""All encode methods"""
await ctx.send_help(ctx.command)
@commands.hybrid_group(invoke_without_command=True)
@commands.group(invoke_without_command=True)
async def decode(self, ctx):
"""All decode methods"""
await ctx.send_help(ctx.command)
@@ -204,7 +204,7 @@ class encryption(commands.Cog):
except Exception:
await ctx.send(view=DecodeErrorView("ASCII85"))
@commands.hybrid_command(name="password")
@commands.command(name="password")
async def password(self, ctx):
"""Generates a random secure password for you"""
if hasattr(ctx, "guild") and ctx.guild is not None:

View File

@@ -197,7 +197,7 @@ class Extra(commands.Cog):
@commands.hybrid_command(name="uptime", description="Shows the Bot's Uptime.")
@commands.command(name="uptime", description="Shows the Bot's Uptime.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -447,7 +447,7 @@ class Extra(commands.Cog):
@commands.hybrid_command(name="boostcount",
@commands.command(name="boostcount",
help="Shows boosts count",
usage="boosts",
aliases=["bco"],
@@ -788,7 +788,7 @@ class Extra(commands.Cog):
@commands.hybrid_command(name="joined-at",
@commands.command(name="joined-at",
help="Shows when a user joined",
usage="joined-at [user]",
with_app_command=True)
@@ -799,7 +799,7 @@ class Extra(commands.Cog):
joined = ctx.author.joined_at.strftime("%a, %d %b %Y %I:%M %p")
await ctx.send(view=CV2("joined-at", f"**`{joined}`**"))
@commands.hybrid_command(name="github", usage="github [search]")
@commands.command(name="github", usage="github [search]")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -906,7 +906,7 @@ class Extra(commands.Cog):
@commands.hybrid_command(name="permissions", aliases= ["perms"],
@commands.command(name="permissions", aliases= ["perms"],
help="Check and list the key permissions of a specific user",
usage="perms <user>",
with_app_command=True)

View File

@@ -35,7 +35,7 @@ class FastGreet(commands.Cog):
)
""")
@commands.hybrid_command(name="fastgreet_add")
@commands.command(name="fastgreet_add")
@commands.has_permissions(administrator=True)
async def add_greet_channel(self, ctx, channel: discord.TextChannel):
with sqlite3.connect(DB_PATH) as conn:
@@ -45,7 +45,7 @@ class FastGreet(commands.Cog):
""", (ctx.guild.id, channel.id))
await ctx.send(f"{channel.mention} added as a greet channel.")
@commands.hybrid_command(name="fastgreet_remove")
@commands.command(name="fastgreet_remove")
@commands.has_permissions(administrator=True)
async def remove_greet_channel(self, ctx, channel: discord.TextChannel):
with sqlite3.connect(DB_PATH) as conn:
@@ -54,7 +54,7 @@ class FastGreet(commands.Cog):
""", (ctx.guild.id, channel.id))
await ctx.send(f"{channel.mention} removed from greet channels.")
@commands.hybrid_command(name="fastgreet_list")
@commands.command(name="fastgreet_list")
async def list_greet_channels(self, ctx):
with sqlite3.connect(DB_PATH) as conn:
cursor = conn.execute("""

View File

@@ -56,58 +56,58 @@ class Fun(commands.Cog):
async def meter_command(self, ctx, title, user, text):
await ctx.send(view=CV2(title, text))
@commands.hybrid_command(name="shipp")
@commands.command(name="shipp")
@blacklist_check()
@ignore_check()
async def shipp(self, ctx, user1: discord.Member, user2: discord.Member):
percentage = random.randint(0, 100)
await ctx.send(view=CV2(f"{self.random_emoji()} Ship Result", f"**{user1.mention} x {user2.mention} = {percentage}% Love**"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def hug(self, ctx, user: discord.Member):
await self.action_command(ctx, user, "hug")
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def kiss(self, ctx, user: discord.Member):
await self.action_command(ctx, user, "kiss")
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def pat(self, ctx, user: discord.Member):
await self.action_command(ctx, user, "pat")
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def slap(self, ctx, user: discord.Member):
await self.action_command(ctx, user, "slap")
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def tickle(self, ctx, user: discord.Member):
await self.action_command(ctx, user, "tickle")
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def coinflip(self, ctx):
result = random.choice(["Heads", "Tails"])
await ctx.send(view=CV2("🪙 Coin Flip", f"**Result: {result}**"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def dice(self, ctx):
result = random.randint(1, 6)
await ctx.send(view=CV2("🎲 Dice Roll", f"**You rolled a {result}!**"))
@commands.hybrid_command(name="8ball")
@commands.command(name="8ball")
@blacklist_check()
@ignore_check()
async def eight_ball(self, ctx, *, question: str):
@@ -116,7 +116,7 @@ class Fun(commands.Cog):
"Don't count on it.", "My sources say no.", "Very doubtful."]
await ctx.send(view=CV2("🎱 Magic 8Ball", f"**Q:** {question}\n**A:** {random.choice(responses)}"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def roast(self, ctx, user: discord.Member):
@@ -127,56 +127,56 @@ class Fun(commands.Cog):
]
await ctx.send(view=CV2("🔥 Roast Time", random.choice(roasts)))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def iq(self, ctx, user: discord.Member = None):
user = user or ctx.author
await ctx.send(view=CV2("🧠 IQ Test", f"**{user.mention} has an IQ of {random.randint(50, 200)}!**"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def dumb(self, ctx, user: discord.Member = None):
user = user or ctx.author
await ctx.send(view=CV2("🤪 Dumbness Test", f"**{user.mention} is {random.randint(0, 100)}% dumb!**"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def simprate(self, ctx, user: discord.Member = None):
user = user or ctx.author
await ctx.send(view=CV2("😳 Simp Rate", f"**{user.mention} is {random.randint(0, 100)}% simp!**"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def toxic(self, ctx, user: discord.Member = None):
user = user or ctx.author
await ctx.send(view=CV2("☠️ Toxic Meter", f"**{user.mention} is {random.randint(0, 100)}% toxic!**"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def intelligence(self, ctx, user: discord.Member = None):
user = user or ctx.author
await ctx.send(view=CV2("🧠 Intelligence Meter", f"**{user.mention} has {random.randint(0, 200)} IQ Points!**"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def genius(self, ctx, user: discord.Member = None):
user = user or ctx.author
await ctx.send(view=CV2("🤓 Genius Rate", f"**{user.mention} is {random.randint(0, 100)}% genius!**"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def brainrate(self, ctx, user: discord.Member = None):
user = user or ctx.author
await ctx.send(view=CV2("🧠 Brain Power", f"**{user.mention} is using {random.randint(0, 100)}% of their brain!**"))
@commands.hybrid_command()
@commands.command()
@blacklist_check()
@ignore_check()
async def howhot(self, ctx, user: discord.Member = None):

View File

@@ -208,7 +208,7 @@ class General(commands.Cog):
await msg.add_reaction(CROSS)
@commands.hybrid_command(name="users", help=f"checks total users of {BotName}.")
@commands.command(name="users", help=f"checks total users of {BotName}.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -251,7 +251,7 @@ class General(commands.Cog):
except:
pass
@commands.hybrid_command(name="rickroll",
@commands.command(name="rickroll",
help="Detects if provided url is a rick-roll",
usage="Rickroll <url>")
@blacklist_check()
@@ -271,7 +271,7 @@ class General(commands.Cog):
title = "Rick Roll {} in webpage".format("was found" if rickRoll else "was not found")
await ctx.reply(view=CV2(title, "🎵 Never gonna give you up..." if rickRoll else "✅ Safe to click!"), mention_author=True)
@commands.hybrid_command(name="hash",
@commands.command(name="hash",
help="Hashes provided text with provided algorithm")
@blacklist_check()
@ignore_check()
@@ -297,7 +297,7 @@ class General(commands.Cog):
hash_lines = f"**{algorithm}:** `{algos[algorithm.lower()]}`"
await ctx.reply(view=CV2(f"Hashed \"{message}\"", hash_lines), mention_author=True)
@commands.hybrid_command(
@commands.command(
name="invite",
aliases=['invite-bot'],
description="Get Support & Bot invite link!"

View File

@@ -118,7 +118,7 @@ class Ignore(commands.Cog):
)
await db.commit()
@commands.hybrid_group(
@commands.group(
name="ignore",
help="Manage ignored commands, channels, users, and bypassed users.",
invoke_without_command=True,

View File

@@ -53,22 +53,22 @@ class ImageCommands(commands.Cog):
else:
await ctx.send(view=CV2("❌ Error", f"No image found for {title.lower()}."))
@commands.hybrid_command(name="boy")
@commands.command(name="boy")
async def boy_image(self, ctx):
url = await self.fetch_pexels_image("handsome boy")
await self.send_image_view(ctx, "👦 Boy Pic", url)
# @commands.hybrid_command(name="girl")
# @commands.command(name="girl")
# async def girl_image(self, ctx):
# url = await self.fetch_pexels_image("beautiful girl")
# await self.send_image_view(ctx, "👧 Girl Pic", url)
@commands.hybrid_command(name="couple")
@commands.command(name="couple")
async def couple_image(self, ctx):
url = await self.fetch_pexels_image("romantic couple")
await self.send_image_view(ctx, "💑 Couple Pic", url)
@commands.hybrid_command(name="anime")
@commands.command(name="anime")
async def anime_image(self, ctx):
url = await self.fetch_waifu_image("waifu")
await self.send_image_view(ctx, "🧚 Anime Waifu", url)

View File

@@ -190,7 +190,7 @@ class JoinToCreate(commands.Cog):
print(f"Error in J2C on_ready: {e}")
continue
@commands.hybrid_command(name='j2csetup')
@commands.command(name='j2csetup')
@commands.has_permissions(administrator=True)
async def setup_private_channels(self, ctx):
if ctx.guild.id in self.setup_data:
@@ -225,7 +225,7 @@ class JoinToCreate(commands.Cog):
await ctx.send(view=CV2("✅ Success", f"J2C system setup complete! Join {join_channel.mention} to create a private VC."))
@commands.hybrid_command(name='j2creset')
@commands.command(name='j2creset')
@commands.has_permissions(administrator=True)
async def reset_private_channels(self, ctx):
if ctx.guild.id not in self.setup_data:

View File

@@ -129,7 +129,7 @@ class Jail(commands.Cog):
)
await log_channel.send(view=CV2("🔓 Member Unjailed", desc))
@commands.hybrid_command(name="jail")
@commands.command(name="jail")
@commands.has_permissions(manage_roles=True)
async def jail(self, ctx, member: discord.Member, duration: str = None, *, reason="No reason provided"):
jail_role_id = self.get_setting(ctx.guild.id, "jail_role")
@@ -182,13 +182,13 @@ class Jail(commands.Cog):
)
await log_channel.send(view=CV2("🔒 Member Jailed", desc))
@commands.hybrid_command(name="unjail")
@commands.command(name="unjail")
@commands.has_permissions(manage_roles=True)
async def unjail(self, ctx, member: discord.Member):
await self.unjail_member(ctx.guild, member)
await ctx.send(view=CV2("✅ Success", f"{member.mention} has been unjailed."))
@commands.hybrid_command(name="jailhistory")
@commands.command(name="jailhistory")
async def jailhistory(self, ctx, member: discord.Member):
cursor = self.conn.execute("""
SELECT reason, jailed_at, duration, mod_id FROM jailed

View File

@@ -37,7 +37,7 @@ class joindm(commands.Cog):
with open(jsondb_path('joindm_messages.json'), 'w') as f:
json.dump(self.joindm_messages, f)
@commands.hybrid_group(invoke_without_command=True)
@commands.group(invoke_without_command=True)
@commands.has_permissions(administrator=True)
async def joindm(self, ctx):
# Display the current join DM message

View File

@@ -293,7 +293,7 @@ class Leveling (commands .Cog ):
self .last_level_cache ={}
self .db_path =db_path("leveling.db")
@commands.hybrid_group (name ="level",invoke_without_command =True ,description ="Leveling system")
@commands.group (name ="level",invoke_without_command =True ,description ="Leveling system")
async def level (self ,ctx ):
"""Main leveling command"""
if ctx .invoked_subcommand is None :

View File

@@ -81,7 +81,7 @@ class Messages(commands.Cog):
conn.commit()
conn.close()
@commands.hybrid_command(name="messages", aliases=["msg"])
@commands.command(name="messages", aliases=["msg"])
async def messages(self, ctx, member: discord.Member = None):
member = member or ctx.author
today = datetime.utcnow().strftime("%Y-%m-%d")

View File

@@ -21,7 +21,7 @@ class Messagespack(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command(name="addmessages", aliases=["addmsg"])
@commands.command(name="addmessages", aliases=["addmsg"])
@commands.has_permissions(manage_messages=True)
async def addmessages(self, ctx, member: discord.Member, amount: int):
if amount <= 0:
@@ -46,7 +46,7 @@ class Messagespack(commands.Cog):
conn.close()
await ctx.send(f"Added {amount} messages to {member.mention} for today.")
@commands.hybrid_command(name="removemessages", aliases=["removemsg"])
@commands.command(name="removemessages", aliases=["removemsg"])
@commands.has_permissions(manage_messages=True)
async def removemessages(self, ctx, member: discord.Member, amount: int):
if amount <= 0:
@@ -70,7 +70,7 @@ class Messagespack(commands.Cog):
await ctx.send(f"{member.mention} has no messages recorded for today.")
conn.close()
@commands.hybrid_command(name="clearmessage", aliases=["clearmsg"])
@commands.command(name="clearmessage", aliases=["clearmsg"])
@commands.has_permissions(manage_messages=True)
async def clearmessage(self, ctx, member: discord.Member):
conn = sqlite3.connect(db_path("messages.db"))

View File

@@ -585,7 +585,7 @@ class Music(commands.Cog):
bar = '' * filled_length + '' * (length - filled_length)
return bar
@commands.hybrid_command(name="play", aliases=['p'], usage="play <query>", help="Plays a song or playlist.")
@commands.command(name="play", aliases=['p'], usage="play <query>", help="Plays a song or playlist.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -594,7 +594,7 @@ class Music(commands.Cog):
await self.play_source(ctx, query)
@commands.hybrid_command(name="search", usage="search <query>", help="Searches music from multiple platforms.")
@commands.command(name="search", usage="search <query>", help="Searches music from multiple platforms.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -606,7 +606,7 @@ class Music(commands.Cog):
await ctx.send(view=PlatformSelectView(ctx, query))
@commands.hybrid_command(name="nowplaying", aliases=["nop"], usage="nowplaying", help="Shows the info about current playing song.")
@commands.command(name="nowplaying", aliases=["nop"], usage="nowplaying", help="Shows the info about current playing song.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -659,7 +659,7 @@ class Music(commands.Cog):
await ctx.send(view=view)
@commands.hybrid_command(name="autoplay", usage="autoplay", help="Toggles autoplay mode.")
@commands.command(name="autoplay", usage="autoplay", help="Toggles autoplay mode.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -679,7 +679,7 @@ class Music(commands.Cog):
)
await ctx.send(view=CV2(f"{TICK} Autoplay {'enabled' if vc.autoplay == wavelink.AutoPlayMode.enabled else 'disabled'} by {ctx.author.mention}."))
@commands.hybrid_command(name="loop", usage="loop", help="Toggles loop mode.")
@commands.command(name="loop", usage="loop", help="Toggles loop mode.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -700,7 +700,7 @@ class Music(commands.Cog):
await ctx.send(view=CV2("I'm not connected to a voice channel."))
@commands.hybrid_command(name="pause", usage="pause", help="Pauses the current song.")
@commands.command(name="pause", usage="pause", help="Pauses the current song.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -721,7 +721,7 @@ class Music(commands.Cog):
else:
await ctx.send(view=CV2(f"{WARNING} Nothing is playing or already paused."))
@commands.hybrid_command(name="resume", usage="resume", help="Resumes the paused song.")
@commands.command(name="resume", usage="resume", help="Resumes the paused song.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -742,7 +742,7 @@ class Music(commands.Cog):
else:
await ctx.send(view=CV2("Player is not paused."))
@commands.hybrid_command(name="skip", usage="skip", help="Skips the current song.")
@commands.command(name="skip", usage="skip", help="Skips the current song.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -767,7 +767,7 @@ class Music(commands.Cog):
else:
await ctx.send(view=CV2(f"{WARNING} No song is playing or in the queue to skip."))
@commands.hybrid_command(name="shuffle", usage="shuffle", help="Shuffles the queue.")
@commands.command(name="shuffle", usage="shuffle", help="Shuffles the queue.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -787,7 +787,7 @@ class Music(commands.Cog):
else:
await ctx.send(view=CV2("Queue is empty."))
@commands.hybrid_command(name="stop", usage="stop", help="Stops the current song and clears the queue.")
@commands.command(name="stop", usage="stop", help="Stops the current song and clears the queue.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -810,7 +810,7 @@ class Music(commands.Cog):
else:
await ctx.send(view=CV2("Nothing is playing to stop."))
@commands.hybrid_command(name="volume", aliases=["vol"], usage="volume <level>", help="Sets the volume of the player.")
@commands.command(name="volume", aliases=["vol"], usage="volume <level>", help="Sets the volume of the player.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -834,7 +834,7 @@ class Music(commands.Cog):
else:
await ctx.send(view=CV2("Bot is not connected to a voice channel."))
@commands.hybrid_command(name="queue", usage="queue", help="Shows the current queue.")
@commands.command(name="queue", usage="queue", help="Shows the current queue.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -860,7 +860,7 @@ class Music(commands.Cog):
ctx=ctx)
await paginator.paginate()
@commands.hybrid_command(name="clearqueue", usage="clearqueue", help="Clears the queue.")
@commands.command(name="clearqueue", usage="clearqueue", help="Clears the queue.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -881,7 +881,7 @@ class Music(commands.Cog):
else:
await ctx.send(view=CV2("No queue to clear."))
@commands.hybrid_command(name="replay", usage="replay", help="Replays the current song.")
@commands.command(name="replay", usage="replay", help="Replays the current song.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -902,7 +902,7 @@ class Music(commands.Cog):
else:
await ctx.send(view=CV2("No track is currently playing."))
@commands.hybrid_command(name="join", aliases=["connect"], usage="join", help="Joins the voice channel.")
@commands.command(name="join", aliases=["connect"], usage="join", help="Joins the voice channel.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -933,7 +933,7 @@ class Music(commands.Cog):
else:
await ctx.send(view=CV2("Bot is not connected to any voice channel."))
@commands.hybrid_command(name="seek", usage="seek <percentage>", help="Seeks to a specific percentage of the song.")
@commands.command(name="seek", usage="seek <percentage>", help="Seeks to a specific percentage of the song.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)

View File

@@ -28,7 +28,7 @@ class Nitro(commands.Cog):
ctx = await self.bot.get_context(message)
await self.bot.invoke(ctx)
@commands.hybrid_command(name="nitro")
@commands.command(name="nitro")
async def nitro(self, ctx):
embed = discord.Embed(color=0x2B2D31)
embed.add_field(

View File

@@ -34,7 +34,7 @@ class NotifCommands(commands.Cog):
channel_id INTEGER NOT NULL)""")
await db.commit()
@commands.hybrid_group(invoke_without_command=True)
@commands.group(invoke_without_command=True)
async def setnotif(self, ctx):
view = CV2(
"Notification Commands",

View File

@@ -465,7 +465,7 @@ class NoPrefix(commands.Cog):
await ctx.reply(view=embed)
@commands.hybrid_group(name="autonp", help="Manage auto no-prefix for partner guilds.")
@commands.group(name="autonp", help="Manage auto no-prefix for partner guilds.")
@commands.is_owner()
async def autonp(self, ctx):
if ctx.invoked_subcommand is None:

View File

@@ -160,7 +160,7 @@ class Owner(commands.Cog):
async with db.execute('SELECT id FROM staff') as cursor:
self.staff = {row[0] for row in await cursor.fetchall()}
@commands.hybrid_command(name="staff_add", aliases=["staffadd", "addstaff"], help="Adds a user to the staff list.")
@commands.command(name="staff_add", aliases=["staffadd", "addstaff"], help="Adds a user to the staff list.")
@commands.is_owner()
async def staff_add(self, ctx, user: discord.User):
if user.id in self.staff:
@@ -174,7 +174,7 @@ class Owner(commands.Cog):
sonu2 = discord.Embed(title=f"{TICK} Success", description=f"Added {user} to the staff list.", color=0xFF0000)
await ctx.reply(embed=sonu2, mention_author=False)
@commands.hybrid_command(name="staff_remove", aliases=["staffremove", "removestaff"], help="Removes a user from the staff list.")
@commands.command(name="staff_remove", aliases=["staffremove", "removestaff"], help="Removes a user from the staff list.")
@commands.is_owner()
async def staff_remove(self, ctx, user: discord.User):
if user.id not in self.staff:
@@ -188,7 +188,7 @@ class Owner(commands.Cog):
sonu2 = discord.Embed(title=f"{TICK} Success", description=f"Removed {user} from the staff list.", color=0xFF0000)
await ctx.reply(embed=sonu2, mention_author=False)
@commands.hybrid_command(name="staff_list", aliases=["stafflist", "liststaff", "staffs"], help="Lists all staff members.")
@commands.command(name="staff_list", aliases=["stafflist", "liststaff", "staffs"], help="Lists all staff members.")
@commands.is_owner()
async def staff_list(self, ctx):
if not self.staff:
@@ -202,7 +202,7 @@ class Owner(commands.Cog):
sonu = discord.Embed(title=f"{TICK} {BotName} Staffs", description=f"\n{staff_display}", color=0xFF0000)
await ctx.send(embed=sonu)
@commands.hybrid_command(name="slist")
@commands.command(name="slist")
@commands.check(is_owner_or_staff)
async def _slist(self, ctx):
servers = sorted(self.client.guilds, key=lambda g: g.member_count, reverse=True)
@@ -220,7 +220,7 @@ class Owner(commands.Cog):
await paginator.paginate()
@commands.hybrid_command(name="mutuals", aliases=["mutual"])
@commands.command(name="mutuals", aliases=["mutual"])
@commands.is_owner()
async def mutuals(self, ctx, user: discord.User):
guilds = [guild for guild in self.client.guilds if user in guild.members]
@@ -272,13 +272,13 @@ class Owner(commands.Cog):
await ctx.send("Forbidden.")
@commands.hybrid_command(name="reload", help="Restarts the client.")
@commands.command(name="reload", help="Restarts the client.")
@commands.is_owner()
async def _restart(self, ctx: Context):
await ctx.reply(f"{TICK} | **Successfully Restarting {BotName} It Takes 10 seconds**")
restart_program()
@commands.hybrid_command(name="sync", help="Syncs all database.")
@commands.command(name="sync", help="Syncs all database.")
@commands.is_owner()
async def _sync(self, ctx):
await ctx.reply("Syncing...", mention_author=False)
@@ -328,7 +328,7 @@ class Owner(commands.Cog):
)
@commands.hybrid_command(name="owners")
@commands.command(name="owners")
@commands.is_owner()
async def own_list(self, ctx):
nplist = OWNER_IDS
@@ -351,7 +351,7 @@ class Owner(commands.Cog):
@commands.hybrid_command()
@commands.command()
@commands.is_owner()
async def dm(self, ctx, user: discord.User, *, message: str):
""" DM the user of your choice """
@@ -363,7 +363,7 @@ class Owner(commands.Cog):
@commands.hybrid_group()
@commands.group()
@commands.is_owner()
async def change(self, ctx):
if ctx.invoked_subcommand is None:
@@ -384,7 +384,7 @@ class Owner(commands.Cog):
await ctx.send(err)
@commands.hybrid_command(name="ownerban", aliases=["forceban", "dna"])
@commands.command(name="ownerban", aliases=["forceban", "dna"])
@commands.is_owner()
async def _ownerban(self, ctx: Context, user_id: int, *, reason: str = "No reason provided"):
@@ -418,7 +418,7 @@ class Owner(commands.Cog):
await ctx.reply("User not found in this guild.", mention_author=False, delete_after=3)
await ctx.message.delete()
@commands.hybrid_command(name="ownerunban", aliases=["forceunban"])
@commands.command(name="ownerunban", aliases=["forceunban"])
@commands.is_owner()
async def _ownerunban(self, ctx: Context, user_id: int, *, reason: str = "No reason provided"):
user = self.client.get_user(user_id)
@@ -450,7 +450,7 @@ class Owner(commands.Cog):
@commands.hybrid_command(name="globalunban")
@commands.command(name="globalunban")
@commands.is_owner()
async def globalunban(self, ctx: Context, user: discord.User):
success_guilds = []
@@ -474,7 +474,7 @@ class Owner(commands.Cog):
await ctx.reply(f"{success_message}\n{error_message}", mention_author=False)
@commands.hybrid_command(name="guildban")
@commands.command(name="guildban")
@commands.is_owner()
async def guildban(self, ctx: Context, guild_id: int, user_id: int, *, reason: str = "No reason provided"):
guild = self.client.get_guild(guild_id)
@@ -494,7 +494,7 @@ class Owner(commands.Cog):
else:
await ctx.reply(f"User not found in the specified guild {guild.name}.", mention_author=False)
@commands.hybrid_command(name="guildunban")
@commands.command(name="guildunban")
@commands.is_owner()
async def guildunban(self, ctx: Context, guild_id: int, user_id: int, *, reason: str = "No reason provided"):
guild = self.client.get_guild(guild_id)
@@ -519,7 +519,7 @@ class Owner(commands.Cog):
await ctx.reply(f"An error occurred while unbanning user ID {user_id} in {guild.name}: {str(e)}", mention_author=False)
@commands.hybrid_command(name="leaveguild", aliases=["leavesv"])
@commands.command(name="leaveguild", aliases=["leavesv"])
@commands.is_owner()
async def leave_guild(self, ctx, guild_id: int):
guild = self.client.get_guild(guild_id)
@@ -530,7 +530,7 @@ class Owner(commands.Cog):
await guild.leave()
await ctx.send(f"Left the guild: {guild.name} ({guild.id})")
@commands.hybrid_command(name="guildinfo")
@commands.command(name="guildinfo")
@commands.check(is_owner_or_staff)
async def guild_info(self, ctx, guild_id: int):
guild = self.client.get_guild(guild_id)
@@ -554,7 +554,7 @@ class Owner(commands.Cog):
await ctx.send(embed=embed)
@commands.hybrid_command()
@commands.command()
@commands.is_owner()
async def servertour(self, ctx, time_in_seconds: int, member: discord.Member):
guild = ctx.guild
@@ -621,7 +621,7 @@ class Owner(commands.Cog):
@commands.hybrid_group()
@commands.group()
@commands.check(is_owner_or_staff)
@blacklist_check()
@ignore_check()
@@ -684,7 +684,7 @@ class Owner(commands.Cog):
await ctx.send(embed=embed)
@commands.hybrid_command(name="forcepurgebots",
@commands.command(name="forcepurgebots",
aliases=["fpb"],
help="Clear recently bot messages in channel (Bot owner only)")
@commands.cooldown(1, 3, commands.BucketType.user)
@@ -700,7 +700,7 @@ class Owner(commands.Cog):
await do_removal(ctx, search, predicate)
@commands.hybrid_command(name="forcepurgeuser",
@commands.command(name="forcepurgeuser",
aliases=["fpu"],
help="Clear recent messages of a user in channel (Bot owner only)")
@commands.cooldown(1, 3, commands.BucketType.user)

View File

@@ -25,14 +25,14 @@ class Global(commands.Cog):
self.local_frozen_nicks = {}
self.client.frozen_nicknames = {}
@commands.hybrid_group(name="global", invoke_without_command=True)
@commands.group(name="global", invoke_without_command=True)
@commands.is_owner()
async def global_command(self, ctx: commands.Context):
if ctx.subcommand_passed is None:
await ctx.send_help(ctx.command)
ctx.command.reset_cooldown(ctx)
@commands.hybrid_command(name="gb", aliases=["GB"], help="Bans the user from all mutual guilds.")
@commands.command(name="gb", help="Bans the user from all mutual guilds.")
@commands.is_owner()
async def global_ban(self, ctx: commands.Context, user: discord.User, reason: str = "Severe violations of Discord's terms of service."):
mutual_guilds = [guild for guild in self.client.guilds if guild.get_member(user.id)]
@@ -563,7 +563,7 @@ class Global(commands.Cog):
await ctx.send(f"✅ | Nickname freezing stopped for {user.name}.")
@commands.hybrid_command(name="freezenick", help="Freezes a member's nickname in the current server.")
@commands.command(name="freezenick", help="Freezes a member's nickname in the current server.")
@commands.has_permissions(manage_nicknames=True)
async def freeze_nickname(self, ctx: commands.Context, member: Member, *, nickname: str):
guild_id = ctx.guild.id
@@ -597,7 +597,7 @@ class Global(commands.Cog):
self.client.loop.create_task(monitor_nickname())
@commands.hybrid_command(name="unfreezenick", help="Unfreezes a member's nickname in the current server.")
@commands.command(name="unfreezenick", help="Unfreezes a member's nickname in the current server.")
@commands.has_permissions(manage_nicknames=True)
async def unfreeze_nickname(self, ctx: commands.Context, member: Member):
guild_id = ctx.guild.id

View File

@@ -19,7 +19,7 @@ class QR(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command(
@commands.command(
name="qr",
aliases=["qrcode"],
help="Sends a QR code image.",

View File

@@ -25,7 +25,7 @@ class Slots(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command(aliases=['slot'])
@commands.command(aliases=['slot'])
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)

View File

@@ -23,7 +23,7 @@ class Status(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command(name="status", help="Shows the status of the user in detail.")
@commands.command(name="status", help="Shows the status of the user in detail.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 3, commands.BucketType.user)

View File

@@ -130,7 +130,7 @@ class StickyMessage(commands.Cog):
)
await db.commit()
@commands.hybrid_group(aliases=['sticky', 'sm'], invoke_without_command=True)
@commands.group(aliases=['sticky', 'sm'], invoke_without_command=True)
@commands.has_permissions(manage_messages=True)
async def stickymessage(self, ctx: commands.Context):
if ctx.invoked_subcommand is None:

View File

@@ -51,10 +51,24 @@ TICKET_LIMIT_PER_USER = 3
# --- Database Class ---
class TicketDatabase:
def __init__(self, path):
self.conn = sqlite3.connect(path, check_same_thread=False)
self.path = path
self.conn = None
self._connect()
def _connect(self):
self.conn = sqlite3.connect(self.path, check_same_thread=False)
self.conn.row_factory = sqlite3.Row
self._create_tables()
def _ensure_open(self):
if self.conn is None:
self._connect()
return
try:
self.conn.execute("SELECT 1")
except (sqlite3.ProgrammingError, sqlite3.OperationalError):
self._connect()
def _create_tables(self):
with self.conn:
self.conn.execute("CREATE TABLE IF NOT EXISTS guild_configs (guild_id INTEGER PRIMARY KEY, panel_channel_id INTEGER, logging_channel_id INTEGER, panel_message_id INTEGER, panel_type TEXT, embed_title TEXT, embed_description TEXT, embed_color INTEGER, embed_image_url TEXT, embed_thumbnail_url TEXT, closed_category_id INTEGER)")
@@ -63,13 +77,29 @@ class TicketDatabase:
self.conn.execute("CREATE TABLE IF NOT EXISTS user_ticket_counts (guild_id INTEGER, user_id INTEGER, ticket_count INTEGER DEFAULT 0, PRIMARY KEY (guild_id, user_id))")
def execute(self, q, p=()):
with self.conn: return self.conn.execute(q, p)
self._ensure_open()
with self.conn:
return self.conn.execute(q, p)
def fetchone(self, q, p=()):
cur = self.conn.cursor(); cur.execute(q, p); return cur.fetchone()
self._ensure_open()
cur = self.conn.cursor()
cur.execute(q, p)
return cur.fetchone()
def fetchall(self, q, p=()):
cur = self.conn.cursor(); cur.execute(q, p); return cur.fetchall()
self._ensure_open()
cur = self.conn.cursor()
cur.execute(q, p)
return cur.fetchall()
def close(self):
if self.conn: self.conn.close()
if self.conn is not None:
try:
self.conn.close()
except Exception:
pass
self.conn = None
# --- Utility Functions ---
async def get_or_create_log_channel(db, guild):
@@ -270,13 +300,30 @@ class CategoryConfigView(discord.ui.View):
class TicketCog(commands.Cog, name="Ticket System"):
def __init__(self, bot):
self.bot, self.db = bot, TicketDatabase(DB_PATH)
self.bot.loop.create_task(self.load_persistent_views())
self.bot = bot
self.db = TicketDatabase(DB_PATH)
self._views_task: asyncio.Task | None = None
async def cog_load(self):
# Start after inject succeeds — avoids closed-DB race when add_cog fails/unloads
self._views_task = asyncio.create_task(self.load_persistent_views())
async def load_persistent_views(self):
await self.bot.wait_until_ready()
for config in self.db.fetchall("SELECT guild_id, panel_message_id FROM guild_configs WHERE panel_message_id IS NOT NULL"):
if view := self.create_panel_view(config['guild_id']): self.bot.add_view(view, message_id=config['panel_message_id'])
try:
await self.bot.wait_until_ready()
configs = self.db.fetchall(
"SELECT guild_id, panel_message_id FROM guild_configs WHERE panel_message_id IS NOT NULL"
)
for config in configs:
if view := self.create_panel_view(config["guild_id"]):
self.bot.add_view(view, message_id=config["panel_message_id"])
except asyncio.CancelledError:
raise
except sqlite3.ProgrammingError:
# Cog unloaded / DB closed before ready — ignore
return
except Exception as e:
print(f"Ticket persistent views load failed: {e}")
def create_panel_view(self, guild_id):
config = self.db.fetchone("SELECT panel_type FROM guild_configs WHERE guild_id=?", (guild_id,))
@@ -290,7 +337,10 @@ class TicketCog(commands.Cog, name="Ticket System"):
for c in categories: view.add_item(discord.ui.Button(label=c['name'], style=discord.ButtonStyle(c['button_style']), emoji=c['emoji'], custom_id=f"create_ticket_{c['category_id']}"))
return view
def cog_unload(self): self.db.close()
def cog_unload(self):
if self._views_task and not self._views_task.done():
self._views_task.cancel()
self.db.close()
@commands.Cog.listener()
async def on_interaction(self, inter):

View File

@@ -136,7 +136,7 @@ class Tracking(commands.Cog):
row = await cursor.fetchone()
return row[0] if row else 0
@commands.hybrid_command(aliases=["inv"])
@commands.command(aliases=["inv"])
async def invites(self, ctx, member: discord.Member = None):
member = member or ctx.author
await self.ensure_tables(ctx.guild.id)
@@ -161,7 +161,7 @@ class Tracking(commands.Cog):
)
await ctx.send(view=CV2(f"Invite Log - {member.name}", desc))
@commands.hybrid_command(aliases=["addinvs"])
@commands.command(aliases=["addinvs"])
@commands.has_permissions(administrator=True)
async def addinvites(self, ctx, member: discord.Member, amount: int):
await self.ensure_tables(ctx.guild.id)
@@ -171,7 +171,7 @@ class Tracking(commands.Cog):
await db.commit()
await ctx.send(view=CV2("✅ Success", f"Added **{amount}** invites to {member.mention}."))
@commands.hybrid_command(aliases=["setinvs"])
@commands.command(aliases=["setinvs"])
@commands.has_permissions(administrator=True)
async def setinvites(self, ctx, member: discord.Member, amount: int):
await self.ensure_tables(ctx.guild.id)
@@ -180,7 +180,7 @@ class Tracking(commands.Cog):
await db.commit()
await ctx.send(view=CV2("✅ Success", f"Set invites of {member.mention} to **{amount}**."))
@commands.hybrid_command(aliases=["resetinvs"])
@commands.command(aliases=["resetinvs"])
@commands.has_permissions(administrator=True)
async def resetinvites(self, ctx, member: discord.Member):
await self.ensure_tables(ctx.guild.id)
@@ -189,7 +189,7 @@ class Tracking(commands.Cog):
await db.commit()
await ctx.send(view=CV2("✅ Success", f"Reset invites of {member.mention}."))
@commands.hybrid_command(aliases=["invlb"])
@commands.command(aliases=["invlb"])
async def invitesleaderboard(self, ctx):
await self.ensure_tables(ctx.guild.id)
async with aiosqlite.connect(INVITE_DB) as db:
@@ -208,7 +208,7 @@ class Tracking(commands.Cog):
await ctx.send(view=CV2("📊 Invite Leaderboard", leaderboard))
@commands.hybrid_command(aliases=["invlog"])
@commands.command(aliases=["invlog"])
@commands.has_permissions(administrator=True)
async def invitelogging(self, ctx, channel: discord.TextChannel):
await self.ensure_tables(ctx.guild.id)

View File

@@ -49,7 +49,7 @@ class VanityRoles(commands.Cog):
await db.execute("ALTER TABLE vanity_roles ADD COLUMN current_status TEXT")
await db.commit()
@commands.hybrid_group(name="vanityroles", invoke_without_command=True)
@commands.group(name="vanityroles", invoke_without_command=True)
@blacklist_check()
@ignore_check()
async def vanityroles(self, ctx):

View File

@@ -29,7 +29,7 @@ class Voice(commands.Cog):
self.bot = bot
self.color = 0xFF0000
@commands.hybrid_group(name="voice", invoke_without_command=True, aliases=['vc'])
@commands.group(name="voice", invoke_without_command=True, aliases=['vc'])
@blacklist_check()
@ignore_check()
async def vc(self, ctx: commands.Context):

View File

@@ -22,7 +22,7 @@ class Youtube(commands.Cog):
self.bot = bot
@commands.hybrid_command(name='yt', aliases=['youtube'])
@commands.command(name='yt', aliases=['youtube'])
async def search_youtube(self, ctx, *, search_query):
query_string = urllib.parse.urlencode({'search_query': search_query})
html_content = urllib.request.urlopen('http://www.youtube.com/results?' + query_string)