I am trying to make a mute
command and I want it to be able to take time limit with space and without space both. So what I wanted to do is that I wanted to take the timelimit
and make two parts of it one int
and another one str
in the str
part I will check the first two alphabets and check for the multiplier now it works without space but with space it takes the unit part as reason
. Can someone please tell me how to fix this?
def parse_time_input(time_input: str) -> tuple[int, str]:
match = re.match(r'(\d+)\s*([a-z]+)', time_input)
if match:
return int(match.group(1)), match.group(2)
else:
match = re.match(r'(\d+)', time_input)
if match:
return int(match.group(1)), "s"
else:
return -1, ""
@bot.command(aliases=["shut", "zip"])
async def mute(ctx, member: Union[discord.Member, int], timelimit: str = '28d', *, reason: str = "No reason provided"):
if isinstance(member, int):
member = await bot.fetch_user(member)
elif isinstance(member, str):
member = discord.utils.get(ctx.guild.members, name=member)
time_value, time_unit = parse_time_input(timelimit.lower())
if time_value == -1:
await ctx.send("<:error:1131175466049470505> | Invalid time format")
return
unit_multipliers = {
's': 1,
'sec': 1,
'secs': 1,
'second': 1,
'seconds': 1,
'm': 60,
'min': 60,
'mins': 60,
'minute': 60,
'minutes': 60,
'h': 3600,
'hour': 3600,
'hours': 3600,
'd': 86400,
'day': 86400,
'days': 86400,
'w': 604800,
'week': 604800,
'weeks': 604800,
}
multiplier = unit_multipliers.get(time_unit, 1)
total_seconds = time_value * multiplier
mute_time = timedelta(seconds=total_seconds)
if mute_time.total_seconds() > 2419200:
await ctx.send("<:error:1131175466049470505> | Timeout limit can't be over 28 days!")
return
await member.edit(timed_out_until=discord.utils.utcnow() + mute_time)
await ctx.send(f"<:check:1132263275770429471> | {member.mention} has been muted for {mute_time} by {ctx.author.mention}\nReason: {reason}")
# My mute logging part
I found a way of doing it, but it's kind of different then what I did previously.
Thanks to anyone who tried to help me. I will leave this code here if anyone wants they can use it.
What I did here is I took the timelimit
variable and checked if there is time unit in it if not then I will check the next part [ which is in reason
part ] then check for the first part of reason
to get the time_unit
. After that for logging I will use the remove_unit
function to remove the unit part from the reason and if it was in the timelimit
var then we can just directly use it.
Sorry but my explanation is not that good, hope you will understand it
def extract_time_parts(time_input: str) -> tuple[str, str]:
match = re.match(r'(\d+)\s*([a-z]+)', time_input)
if match:
return match.group(1), match.group(2)
match = re.match(r'(\d+)([a-z]+)', time_input, re.IGNORECASE)
if match:
return match.group(1), match.group(2)
return "", ""
def remove_unit(input_str):
words = input_str.split()
if len(words) > 1:
return ' '.join(words[1:])
return ''
@bot.command(aliases=["shut", "zip"])
async def mute(ctx, member: commands.MemberConverter, timelimit: str = '28d', *, reason: str = None):
if isinstance(member, int):
member = await bot.fetch_user(member)
time_value, time_unit = extract_time_parts(timelimit)
time_unit = time_unit[:1]
main_reason = reason
if not time_value or not time_unit:
time_value = timelimit
if reason and reason[0].lower() in ['s', 'm', 'h', 'd', 'w']:
time_unit = reason[0].lower()
reason = reason[1:].strip()
reason_with_unit = reason
main_reason = remove_unit(reason_with_unit)
if main_reason == "":
main_reason = "No reason provided"
else:
await ctx.send("Invalid time format | `?mute @user 5s reason`")
return
unit_multipliers = {
's': 1,
'm': 60,
'h': 3600,
'd': 86400,
'w': 604800
}
multiplier = unit_multipliers.get(time_unit, 1)
mute_time = timedelta(seconds=int(time_value) * multiplier)
if mute_time.total_seconds() > 2419200:
await ctx.send("Timeout limit can't be over 28 days!")
return
await member.edit(timed_out_until=discord.utils.utcnow() + mute_time)
if reason is None:
reason = "No reason provided"
if time_unit == 's':
log_unit = 'second(s)'
elif time_unit == 'm':
log_unit = 'minute(s)'
elif time_unit == 'h':
log_unit = 'hour(s)'
elif time_unit == 'd':
log_unit = 'day(s)'
elif time_unit == 'w':
log_unit = 'week(s)'
await ctx.send(f"{member.mention} has been muted for {time_value} {log_unit} by {ctx.author.mention}\nReason: {main_reason}")
# Your logging part