Use reply message to target a specific member & Add aliases for macros (#26)
* Remove command message when using macros * macro: Reply to the same message as the author invoking the command * logfilereader: Increase size of empty logs * meme: Add reply targets * mod: Add reply targets * mod_timed: Add reply targets * macro: Add aliases for macros * macro: Fix list_macros not listing any macros * Apply black formatting
This commit is contained in:
parent
9912df774d
commit
4ad2527a59
6 changed files with 371 additions and 67 deletions
|
@ -227,7 +227,7 @@ class LogFileReader(Cog):
|
||||||
2) Ensure the following default logs are enabled: `Info`, `Warning`, `Error`, `Guest` and `Stub`.
|
2) Ensure the following default logs are enabled: `Info`, `Warning`, `Error`, `Guest` and `Stub`.
|
||||||
3) Start a game up.
|
3) Start a game up.
|
||||||
4) Play until your issue occurs.
|
4) Play until your issue occurs.
|
||||||
5) Upload the latest log file which is larger than 2KB.""",
|
5) Upload the latest log file which is larger than 3KB.""",
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -10,7 +10,10 @@ from robocop_ng.helpers.macros import (
|
||||||
add_macro,
|
add_macro,
|
||||||
edit_macro,
|
edit_macro,
|
||||||
remove_macro,
|
remove_macro,
|
||||||
get_macros,
|
get_macros_dict,
|
||||||
|
add_aliases,
|
||||||
|
remove_aliases,
|
||||||
|
clear_aliases,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,11 +21,17 @@ class Macro(Cog):
|
||||||
@commands.cooldown(3, 30, BucketType.member)
|
@commands.cooldown(3, 30, BucketType.member)
|
||||||
@commands.command(aliases=["m"])
|
@commands.command(aliases=["m"])
|
||||||
async def macro(self, ctx: Context, target: Optional[discord.Member], key: str):
|
async def macro(self, ctx: Context, target: Optional[discord.Member], key: str):
|
||||||
|
await ctx.message.delete()
|
||||||
if len(key) > 0:
|
if len(key) > 0:
|
||||||
text = get_macro(key)
|
text = get_macro(key)
|
||||||
if text is not None:
|
if text is not None:
|
||||||
if target is not None:
|
if target is not None:
|
||||||
await ctx.send(f"{target.mention}:\n{text}")
|
await ctx.send(f"{target.mention}:\n{text}")
|
||||||
|
else:
|
||||||
|
if ctx.message.reference is not None:
|
||||||
|
await ctx.send(
|
||||||
|
text, reference=ctx.message.reference, mention_author=True
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
await ctx.send(text)
|
await ctx.send(text)
|
||||||
else:
|
else:
|
||||||
|
@ -38,6 +47,19 @@ class Macro(Cog):
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Error: Macro '{key}' already exists.")
|
await ctx.send(f"Error: Macro '{key}' already exists.")
|
||||||
|
|
||||||
|
@commands.check(check_if_staff)
|
||||||
|
@commands.command(name="aliasadd", aliases=["addalias", "add_alias"])
|
||||||
|
async def add_alias_macro(self, ctx: Context, existing_key: str, *new_keys: str):
|
||||||
|
if len(new_keys) == 0:
|
||||||
|
await ctx.send("Error: You need to add at least one alias.")
|
||||||
|
else:
|
||||||
|
if add_aliases(existing_key, list(new_keys)):
|
||||||
|
await ctx.send(
|
||||||
|
f"Added {len(new_keys)} aliases to macro '{existing_key}'!"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.send(f"Error: No new and unique aliases found.")
|
||||||
|
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command(name="macroedit", aliases=["me", "editmacro", "edit_macro"])
|
@commands.command(name="macroedit", aliases=["me", "editmacro", "edit_macro"])
|
||||||
async def edit_macro(self, ctx: Context, key: str, *, text: str):
|
async def edit_macro(self, ctx: Context, key: str, *, text: str):
|
||||||
|
@ -46,6 +68,33 @@ class Macro(Cog):
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Error: Macro '{key}' not found.")
|
await ctx.send(f"Error: Macro '{key}' not found.")
|
||||||
|
|
||||||
|
@commands.check(check_if_staff)
|
||||||
|
@commands.command(
|
||||||
|
name="aliasremove",
|
||||||
|
aliases=[
|
||||||
|
"aliasdelete",
|
||||||
|
"delalias",
|
||||||
|
"aliasdel",
|
||||||
|
"removealias",
|
||||||
|
"remove_alias",
|
||||||
|
"delete_alias",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def remove_alias_macro(
|
||||||
|
self, ctx: Context, existing_key: str, *remove_keys: str
|
||||||
|
):
|
||||||
|
if len(remove_keys) == 0:
|
||||||
|
await ctx.send("Error: You need to remove at least one alias.")
|
||||||
|
else:
|
||||||
|
if remove_aliases(existing_key, list(remove_keys)):
|
||||||
|
await ctx.send(
|
||||||
|
f"Removed {len(remove_keys)} aliases from macro '{existing_key}'!"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.send(
|
||||||
|
f"Error: None of the specified aliases were found for macro '{existing_key}'."
|
||||||
|
)
|
||||||
|
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command(
|
@commands.command(
|
||||||
name="macroremove",
|
name="macroremove",
|
||||||
|
@ -65,12 +114,20 @@ class Macro(Cog):
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Error: Macro '{key}' not found.")
|
await ctx.send(f"Error: Macro '{key}' not found.")
|
||||||
|
|
||||||
|
@commands.check(check_if_staff)
|
||||||
|
@commands.command(name="aliasclear", aliases=["clearalias", "clear_alias"])
|
||||||
|
async def clear_alias_macro(self, ctx: Context, existing_key: str):
|
||||||
|
if clear_aliases(existing_key):
|
||||||
|
await ctx.send(f"Removed all aliases of macro '{existing_key}'!")
|
||||||
|
else:
|
||||||
|
await ctx.send(f"Error: No aliases found for macro '{existing_key}'.")
|
||||||
|
|
||||||
@commands.cooldown(3, 30, BucketType.channel)
|
@commands.cooldown(3, 30, BucketType.channel)
|
||||||
@commands.command(name="macros", aliases=["ml", "listmacros", "list_macros"])
|
@commands.command(name="macros", aliases=["ml", "listmacros", "list_macros"])
|
||||||
async def list_macros(self, ctx: Context):
|
async def list_macros(self, ctx: Context):
|
||||||
macros = get_macros()
|
macros = get_macros_dict()
|
||||||
if len(macros) > 0:
|
if len(macros["macros"]) > 0:
|
||||||
macros = [f"- {key}\n" for key in sorted(macros.keys())]
|
macros = [f"- {key}\n" for key in sorted(macros["macros"].keys())]
|
||||||
message = "📝 **Macros**:\n"
|
message = "📝 **Macros**:\n"
|
||||||
for macro_key in macros:
|
for macro_key in macros:
|
||||||
message += macro_key
|
message += macro_key
|
||||||
|
@ -78,6 +135,19 @@ class Macro(Cog):
|
||||||
else:
|
else:
|
||||||
await ctx.send("Couldn't find any macros.")
|
await ctx.send("Couldn't find any macros.")
|
||||||
|
|
||||||
|
@commands.cooldown(3, 30, BucketType.channel)
|
||||||
|
@commands.command(name="aliases", aliases=["listaliases", "list_aliases"])
|
||||||
|
async def list_aliases(self, ctx: Context, existing_key: str):
|
||||||
|
macros = get_macros_dict()
|
||||||
|
existing_key = existing_key.lower()
|
||||||
|
if existing_key in macros["aliases"].keys():
|
||||||
|
message = f"📝 **Aliases for '{existing_key}'**:\n"
|
||||||
|
for alias in sorted(macros["aliases"][existing_key]):
|
||||||
|
message += f"- {alias}\n"
|
||||||
|
await ctx.send(message)
|
||||||
|
else:
|
||||||
|
await ctx.send(f"Couldn't find any aliases for macro '{existing_key}'.")
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
await bot.add_cog(Macro(bot))
|
await bot.add_cog(Macro(bot))
|
||||||
|
|
|
@ -2,6 +2,7 @@ import datetime
|
||||||
import math
|
import math
|
||||||
import platform
|
import platform
|
||||||
import random
|
import random
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
@ -28,8 +29,24 @@ class Meme(Cog):
|
||||||
|
|
||||||
@commands.check(check_if_staff_or_ot)
|
@commands.check(check_if_staff_or_ot)
|
||||||
@commands.command(hidden=True, name="warm")
|
@commands.command(hidden=True, name="warm")
|
||||||
async def warm_member(self, ctx, user: discord.Member):
|
async def warm_member(self, ctx, user: Optional[discord.Member]):
|
||||||
"""Warms a user :3"""
|
"""Warms a user :3"""
|
||||||
|
if user is None and ctx.message.reference is None:
|
||||||
|
celsius = random.randint(15, 20)
|
||||||
|
fahrenheit = self.c_to_f(celsius)
|
||||||
|
kelvin = self.c_to_k(celsius)
|
||||||
|
await ctx.send(
|
||||||
|
f"{ctx.author.mention} tries to warm themself."
|
||||||
|
f" User is now {celsius}°C "
|
||||||
|
f"({fahrenheit}°F, {kelvin}K).\n"
|
||||||
|
"You might have more success warming someone else :3"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if user is None:
|
||||||
|
user = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
|
|
||||||
celsius = random.randint(15, 100)
|
celsius = random.randint(15, 100)
|
||||||
fahrenheit = self.c_to_f(celsius)
|
fahrenheit = self.c_to_f(celsius)
|
||||||
kelvin = self.c_to_k(celsius)
|
kelvin = self.c_to_k(celsius)
|
||||||
|
@ -41,8 +58,23 @@ class Meme(Cog):
|
||||||
|
|
||||||
@commands.check(check_if_staff_or_ot)
|
@commands.check(check_if_staff_or_ot)
|
||||||
@commands.command(hidden=True, name="chill", aliases=["cold"])
|
@commands.command(hidden=True, name="chill", aliases=["cold"])
|
||||||
async def chill_member(self, ctx, user: discord.Member):
|
async def chill_member(self, ctx, user: Optional[discord.Member]):
|
||||||
"""Chills a user >:3"""
|
"""Chills a user >:3"""
|
||||||
|
if user is None and ctx.message.reference is None:
|
||||||
|
celsius = random.randint(-75, 10)
|
||||||
|
fahrenheit = self.c_to_f(celsius)
|
||||||
|
kelvin = self.c_to_k(celsius)
|
||||||
|
await ctx.send(
|
||||||
|
f"{ctx.author.mention} chills themself."
|
||||||
|
f" User is now {celsius}°C "
|
||||||
|
f"({fahrenheit}°F, {kelvin}K).\n"
|
||||||
|
"🧊 Don't be so hard on yourself. 😔"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if user is None:
|
||||||
|
user = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
celsius = random.randint(-50, 15)
|
celsius = random.randint(-50, 15)
|
||||||
fahrenheit = self.c_to_f(celsius)
|
fahrenheit = self.c_to_f(celsius)
|
||||||
kelvin = self.c_to_k(celsius)
|
kelvin = self.c_to_k(celsius)
|
||||||
|
@ -54,16 +86,30 @@ class Meme(Cog):
|
||||||
|
|
||||||
@commands.check(check_if_staff_or_ot)
|
@commands.check(check_if_staff_or_ot)
|
||||||
@commands.command(hidden=True, aliases=["thank", "reswitchedgold"])
|
@commands.command(hidden=True, aliases=["thank", "reswitchedgold"])
|
||||||
async def gild(self, ctx, user: discord.Member):
|
async def gild(self, ctx, user: Optional[discord.Member]):
|
||||||
"""Gives a star to a user"""
|
"""Gives a star to a user"""
|
||||||
|
if user is None and ctx.message.reference is None:
|
||||||
|
await ctx.send(f"No stars for you, {ctx.author.mention}!")
|
||||||
|
else:
|
||||||
|
if user is None:
|
||||||
|
user = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
await ctx.send(f"{user.mention} gets a :star:, yay!")
|
await ctx.send(f"{user.mention} gets a :star:, yay!")
|
||||||
|
|
||||||
@commands.check(check_if_staff_or_ot)
|
@commands.check(check_if_staff_or_ot)
|
||||||
@commands.command(
|
@commands.command(
|
||||||
hidden=True, aliases=["reswitchedsilver", "silv3r", "reswitchedsilv3r"]
|
hidden=True, aliases=["reswitchedsilver", "silv3r", "reswitchedsilv3r"]
|
||||||
)
|
)
|
||||||
async def silver(self, ctx, user: discord.Member):
|
async def silver(self, ctx, user: Optional[discord.Member]):
|
||||||
"""Gives a user ReSwitched Silver™"""
|
"""Gives a user ReSwitched Silver™"""
|
||||||
|
if user is None and ctx.message.reference is None:
|
||||||
|
await ctx.send(f"{ctx.author.mention}, you can't reward yourself.")
|
||||||
|
else:
|
||||||
|
if user is None:
|
||||||
|
user = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title="ReSwitched Silver™!",
|
title="ReSwitched Silver™!",
|
||||||
description=f"Here's your ReSwitched Silver™," f"{user.mention}!",
|
description=f"Here's your ReSwitched Silver™," f"{user.mention}!",
|
||||||
|
@ -131,8 +177,15 @@ class Meme(Cog):
|
||||||
|
|
||||||
@commands.check(check_if_staff_or_ot)
|
@commands.check(check_if_staff_or_ot)
|
||||||
@commands.command(hidden=True, name="bam")
|
@commands.command(hidden=True, name="bam")
|
||||||
async def bam_member(self, ctx, target: discord.Member):
|
async def bam_member(self, ctx, target: Optional[discord.Member]):
|
||||||
"""Bams a user owo"""
|
"""Bams a user owo"""
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
await ctx.reply("https://tenor.com/view/bonk-gif-26414884")
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
if target == ctx.author:
|
if target == ctx.author:
|
||||||
if target.id == 181627658520625152:
|
if target.id == 181627658520625152:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import io
|
import io
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
@ -38,8 +39,17 @@ class Mod(Cog):
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def mute(self, ctx, target: discord.Member, *, reason: str = ""):
|
async def mute(self, ctx, target: Optional[discord.Member], *, reason: str = ""):
|
||||||
"""Mutes a user, staff only."""
|
"""Mutes a user, staff only."""
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
# Hedge-proofing the code
|
# Hedge-proofing the code
|
||||||
if target == ctx.author:
|
if target == ctx.author:
|
||||||
return await ctx.send("You can't do mod actions on yourself.")
|
return await ctx.send("You can't do mod actions on yourself.")
|
||||||
|
@ -123,8 +133,17 @@ class Mod(Cog):
|
||||||
@commands.bot_has_permissions(kick_members=True)
|
@commands.bot_has_permissions(kick_members=True)
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def kick(self, ctx, target: discord.Member, *, reason: str = ""):
|
async def kick(self, ctx, target: Optional[discord.Member], *, reason: str = ""):
|
||||||
"""Kicks a user, staff only."""
|
"""Kicks a user, staff only."""
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
# Hedge-proofing the code
|
# Hedge-proofing the code
|
||||||
if target == ctx.author:
|
if target == ctx.author:
|
||||||
return await ctx.send("You can't do mod actions on yourself.")
|
return await ctx.send("You can't do mod actions on yourself.")
|
||||||
|
@ -184,8 +203,17 @@ class Mod(Cog):
|
||||||
@commands.bot_has_permissions(ban_members=True)
|
@commands.bot_has_permissions(ban_members=True)
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command(aliases=["yeet"])
|
@commands.command(aliases=["yeet"])
|
||||||
async def ban(self, ctx, target: discord.Member, *, reason: str = ""):
|
async def ban(self, ctx, target: Optional[discord.Member], *, reason: str = ""):
|
||||||
"""Bans a user, staff only."""
|
"""Bans a user, staff only."""
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
# Hedge-proofing the code
|
# Hedge-proofing the code
|
||||||
if target == ctx.author:
|
if target == ctx.author:
|
||||||
if target.id == 181627658520625152:
|
if target.id == 181627658520625152:
|
||||||
|
@ -246,9 +274,18 @@ class Mod(Cog):
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def bandel(
|
async def bandel(
|
||||||
self, ctx, day_count: int, target: discord.Member, *, reason: str = ""
|
self, ctx, day_count: int, target: Optional[discord.Member], *, reason: str = ""
|
||||||
):
|
):
|
||||||
"""Bans a user for a given number of days, staff only."""
|
"""Bans a user for a given number of days, staff only."""
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
# Hedge-proofing the code
|
# Hedge-proofing the code
|
||||||
if target == ctx.author:
|
if target == ctx.author:
|
||||||
if target.id == 181627658520625152:
|
if target.id == 181627658520625152:
|
||||||
|
@ -488,13 +525,25 @@ class Mod(Cog):
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def approve(self, ctx, target: discord.Member, role: str = "community"):
|
async def approve(
|
||||||
|
self, ctx, target: Optional[discord.Member], role: str = "community"
|
||||||
|
):
|
||||||
"""Add a role to a user (default: community), staff only."""
|
"""Add a role to a user (default: community), staff only."""
|
||||||
if role not in config.named_roles:
|
if role not in config.named_roles:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"No such role! Available roles: " + ",".join(config.named_roles)
|
"No such role! Available roles: " + ",".join(config.named_roles)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(config.modlog_channel)
|
||||||
target_role = ctx.guild.get_role(config.named_roles[role])
|
target_role = ctx.guild.get_role(config.named_roles[role])
|
||||||
|
|
||||||
|
@ -514,13 +563,25 @@ class Mod(Cog):
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command(aliases=["unapprove"])
|
@commands.command(aliases=["unapprove"])
|
||||||
async def revoke(self, ctx, target: discord.Member, role: str = "community"):
|
async def revoke(
|
||||||
|
self, ctx, target: Optional[discord.Member], role: str = "community"
|
||||||
|
):
|
||||||
"""Remove a role from a user (default: community), staff only."""
|
"""Remove a role from a user (default: community), staff only."""
|
||||||
if role not in config.named_roles:
|
if role not in config.named_roles:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"No such role! Available roles: " + ",".join(config.named_roles)
|
"No such role! Available roles: " + ",".join(config.named_roles)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(config.modlog_channel)
|
||||||
target_role = ctx.guild.get_role(config.named_roles[role])
|
target_role = ctx.guild.get_role(config.named_roles[role])
|
||||||
|
|
||||||
|
@ -555,8 +616,17 @@ class Mod(Cog):
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def warn(self, ctx, target: discord.Member, *, reason: str = ""):
|
async def warn(self, ctx, target: Optional[discord.Member], *, reason: str = ""):
|
||||||
"""Warns a user, staff only."""
|
"""Warns a user, staff only."""
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
# Hedge-proofing the code
|
# Hedge-proofing the code
|
||||||
if target == ctx.author:
|
if target == ctx.author:
|
||||||
return await ctx.send("You can't do mod actions on yourself.")
|
return await ctx.send("You can't do mod actions on yourself.")
|
||||||
|
@ -631,10 +701,19 @@ class Mod(Cog):
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command(aliases=["setnick", "nick"])
|
@commands.command(aliases=["setnick", "nick"])
|
||||||
async def nickname(self, ctx, target: discord.Member, *, nick: str = ""):
|
async def nickname(self, ctx, target: Optional[discord.Member], *, nick: str = ""):
|
||||||
"""Sets a user's nickname, staff only.
|
"""Sets a user's nickname, staff only.
|
||||||
|
|
||||||
Just send .nickname <user> to wipe the nickname."""
|
Just send .nickname <user> to wipe the nickname."""
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if nick:
|
if nick:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
@ -23,9 +24,18 @@ class ModTimed(Cog):
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def timeban(
|
async def timeban(
|
||||||
self, ctx, target: discord.Member, duration: str, *, reason: str = ""
|
self, ctx, target: Optional[discord.Member], duration: str, *, reason: str = ""
|
||||||
):
|
):
|
||||||
"""Bans a user for a specified amount of time, staff only."""
|
"""Bans a user for a specified amount of time, staff only."""
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
# Hedge-proofing the code
|
# Hedge-proofing the code
|
||||||
if target == ctx.author:
|
if target == ctx.author:
|
||||||
return await ctx.send("You can't do mod actions on yourself.")
|
return await ctx.send("You can't do mod actions on yourself.")
|
||||||
|
@ -89,9 +99,18 @@ class ModTimed(Cog):
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def timemute(
|
async def timemute(
|
||||||
self, ctx, target: discord.Member, duration: str, *, reason: str = ""
|
self, ctx, target: Optional[discord.Member], duration: str, *, reason: str = ""
|
||||||
):
|
):
|
||||||
"""Mutes a user for a specified amount of time, staff only."""
|
"""Mutes a user for a specified amount of time, staff only."""
|
||||||
|
if target is None and ctx.message.reference is None:
|
||||||
|
return await ctx.send(
|
||||||
|
f"I'm sorry {ctx.author.mention}, I'm afraid I can't do that."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target is None:
|
||||||
|
target = ctx.channel.fetch_message(
|
||||||
|
ctx.message.reference.message_id
|
||||||
|
).author
|
||||||
# Hedge-proofing the code
|
# Hedge-proofing the code
|
||||||
if target == ctx.author:
|
if target == ctx.author:
|
||||||
return await ctx.send("You can't do mod actions on yourself.")
|
return await ctx.send("You can't do mod actions on yourself.")
|
||||||
|
|
|
@ -1,55 +1,138 @@
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from typing import Optional
|
from typing import Optional, Union
|
||||||
|
|
||||||
MACROS_FILE = "data/macros.json"
|
MACROS_FILE = "data/macros.json"
|
||||||
|
|
||||||
|
|
||||||
def get_macros() -> dict[str, str]:
|
def get_macros_dict() -> dict[str, dict[str, Union[list[str], str]]]:
|
||||||
if os.path.isfile(MACROS_FILE):
|
if os.path.isfile(MACROS_FILE):
|
||||||
with open(MACROS_FILE, "r") as f:
|
with open(MACROS_FILE, "r") as f:
|
||||||
return json.load(f)
|
macros = json.load(f)
|
||||||
return {}
|
|
||||||
|
# Migration code
|
||||||
|
if "aliases" not in macros.keys():
|
||||||
|
new_macros = {"macros": macros, "aliases": {}}
|
||||||
|
unique_macros = set(new_macros["macros"].values())
|
||||||
|
for macro_text in unique_macros:
|
||||||
|
first_macro_key = ""
|
||||||
|
duplicate_num = 0
|
||||||
|
for key, macro in new_macros["macros"].copy().items():
|
||||||
|
if macro == macro_text and duplicate_num == 0:
|
||||||
|
first_macro_key = key
|
||||||
|
duplicate_num += 1
|
||||||
|
continue
|
||||||
|
elif macro == macro_text:
|
||||||
|
if first_macro_key not in new_macros["aliases"].keys():
|
||||||
|
new_macros["aliases"][first_macro_key] = []
|
||||||
|
new_macros["aliases"][first_macro_key].append(key)
|
||||||
|
del new_macros["macros"][key]
|
||||||
|
duplicate_num += 1
|
||||||
|
|
||||||
|
set_macros(new_macros)
|
||||||
|
return new_macros
|
||||||
|
|
||||||
|
return macros
|
||||||
|
return {"macros": {}, "aliases": {}}
|
||||||
|
|
||||||
|
|
||||||
def set_macros(contents: dict[str, str]):
|
def is_macro_key_available(
|
||||||
|
key: str, macros: dict[str, dict[str, Union[list[str], str]]] = None
|
||||||
|
) -> bool:
|
||||||
|
if macros is None:
|
||||||
|
macros = get_macros_dict()
|
||||||
|
if key in macros["macros"].keys():
|
||||||
|
return False
|
||||||
|
for aliases in macros["aliases"].values():
|
||||||
|
if key in aliases:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def set_macros(contents: dict[str, dict[str, Union[list[str], str]]]):
|
||||||
with open(MACROS_FILE, "w") as f:
|
with open(MACROS_FILE, "w") as f:
|
||||||
json.dump(contents, f)
|
json.dump(contents, f)
|
||||||
|
|
||||||
|
|
||||||
def get_macro(key: str) -> Optional[str]:
|
def get_macro(key: str) -> Optional[str]:
|
||||||
macros = get_macros()
|
macros = get_macros_dict()
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
if key in macros.keys():
|
if key in macros["macros"].keys():
|
||||||
return macros[key]
|
return macros["macros"][key]
|
||||||
|
for main_key, aliases in macros["aliases"].items():
|
||||||
|
if key in aliases:
|
||||||
|
return macros["macros"][main_key]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def add_macro(key: str, message: str) -> bool:
|
def add_macro(key: str, message: str) -> bool:
|
||||||
macros = get_macros()
|
macros = get_macros_dict()
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
if key not in macros.keys():
|
if is_macro_key_available(key, macros):
|
||||||
macros[key] = message
|
macros["macros"][key] = message
|
||||||
set_macros(macros)
|
set_macros(macros)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def add_aliases(key: str, aliases: list[str]) -> bool:
|
||||||
|
macros = get_macros_dict()
|
||||||
|
key = key.lower()
|
||||||
|
success = False
|
||||||
|
if key in macros["macros"].keys():
|
||||||
|
for alias in aliases:
|
||||||
|
alias = alias.lower()
|
||||||
|
if is_macro_key_available(alias, macros):
|
||||||
|
macros["aliases"][key].append(alias)
|
||||||
|
success = True
|
||||||
|
if success:
|
||||||
|
set_macros(macros)
|
||||||
|
return success
|
||||||
|
|
||||||
|
|
||||||
def edit_macro(key: str, message: str) -> bool:
|
def edit_macro(key: str, message: str) -> bool:
|
||||||
macros = get_macros()
|
macros = get_macros_dict()
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
if key in macros.keys():
|
if key in macros["macros"].keys():
|
||||||
macros[key] = message
|
macros["macros"][key] = message
|
||||||
set_macros(macros)
|
set_macros(macros)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def remove_aliases(key: str, aliases: list[str]) -> bool:
|
||||||
|
macros = get_macros_dict()
|
||||||
|
key = key.lower()
|
||||||
|
success = False
|
||||||
|
if key not in macros["aliases"].keys():
|
||||||
|
return False
|
||||||
|
for alias in aliases:
|
||||||
|
alias = alias.lower()
|
||||||
|
if alias in macros["aliases"][key]:
|
||||||
|
macros["aliases"][key].remove(alias)
|
||||||
|
if len(macros["aliases"][key]) == 0:
|
||||||
|
del macros["aliases"][key]
|
||||||
|
success = True
|
||||||
|
if success:
|
||||||
|
set_macros(macros)
|
||||||
|
return success
|
||||||
|
|
||||||
|
|
||||||
def remove_macro(key: str) -> bool:
|
def remove_macro(key: str) -> bool:
|
||||||
macros = get_macros()
|
macros = get_macros_dict()
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
if key in macros.keys():
|
if key in macros["macros"].keys():
|
||||||
del macros[key]
|
del macros["macros"][key]
|
||||||
|
set_macros(macros)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def clear_aliases(key: str) -> bool:
|
||||||
|
macros = get_macros_dict()
|
||||||
|
key = key.lower()
|
||||||
|
if key in macros["macros"].keys() and key in macros["aliases"].keys():
|
||||||
|
del macros["aliases"][key]
|
||||||
set_macros(macros)
|
set_macros(macros)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
Loading…
Reference in a new issue