Reputation: 547
I have looked for other answers on StackOverflow with no luck.
I have a mute command in discord.py, that looks like this:
@client.command()
@commands.has_permissions(kick_members=True)
async def mute(ctx, member: discord.Member, time: typing.Optional[str], *, reason = None):
guild = ctx.guild
for role in guild.roles:
if role.name == "Muted":
await member.add_roles(role)
await ctx.send("{} has has been muted because {}!" .format(member.username + "#" + member.discriminator, reason))
How do I make the time argument into milliseconds? Similar to the ms
module in node.js.
For example I want the duration of >mute @user 1h some reason
to be parsed into 3600000 milliseconds.
Upvotes: 0
Views: 116
Reputation: 6053
Python has the built-in module timedelta
that would work well for this.
If your string can have mixed time input like "1h", "1h10m", or "1h20m30s", you can use the following:
from datetime import timedelta
import re
def commandToMs(command):
# Check for string of type 1h40m5s, any part optional, surrounding by whitespace.
# Negative lookahead at beginning to prevent matching \s\s
timeMatch = re.search(
r"\s(?!\s)((?P<hrs>\d+)h)?((?P<mins>\d+)m)?((?P<secs>\d+)s)?\s",
command)
if not timeMatch:
return 0
timeDict = timeMatch.groupdict()
# Convert empty matches from None to 0
# keys() returns in arbitrary order. Sort to get "hrs", "mins", "secs"
hrs, mins, secs = (
int(timeDict[key]) if timeDict[key] else 0 for key in
sorted(timeDict.keys())
)
delta = timedelta(hours=hrs, minutes=mins, seconds=secs)
return delta.total_seconds() * 1000
commandToMs(">mute @user 1h some reason") # 3600000.0
Upvotes: 0
Reputation: 5242
I'm going to assume the formats are 1h, 1m and 1s
.
We pull the third item from the string (this doesn't perform error checking to ensure it has 3 items)
raw_time = command.split()[2] # Assuming the command is ">mute @user 1h..."
value = int(raw_time[0:-1]) # All but the last character
time_type = raw_time[-1] # The last character
Then, we evaluate to see if it's an hour, minute, or second:
if time_type == 'h':
return value * 3600000
elif time_type == 'm':
return value * 60000
else:
return value * 1000
You can expand this to include any period (e.g. milliseconds). However, it does not perform any error checking. To double check that the given command will work for this, you can run it through this regex:
if re.match('(\S+\s+){2}\d+(h|m|s).*', command) is not None:
raw_time = command.split()[2] # Assuming the command is ">mute @user 1h..."
value = int(raw_time[0:-1]) # All but the last character
time_type = raw_time[-1] # The last character
if time_type == 'h':
return value * 3600000
elif time_type == 'm':
return value * 60000
else:
return value * 1000
else:
# ...
Upvotes: 1