Как сделать длину бана в discord.py?
У меня получилось сделать время бана:
@client.command()
@commands.has_permissions(administrator = True)
async def ban(ctx, member: discord.Member, time: int, reason):
await ctx.send(f'{member.mention} **забанен** \n Продолжительность бана: *{time}h* \n Причина бана: *{reason}*')
await member.send(f'Тебя забанили на сервере {ctx.guild.name} по причине {reason}')
await member.ban(reason=reason)
await asyncio.sleep(time * 3600)
await member.unban()
await ctx.send(f'*У {member.mention} закончился бан*')
link = await ctx.channel.create_invite(max_age=300)
await member.send(f'У тебя закончился бан на сервере "{ctx.guild.name}"! {link}')
Но я пытаюсь сделать так, чтобы пользователь мог вводить не только время в часах, но и в других единицах. Например: !ban @тест 1h тест или !ban @тест 10d тест 2m и т.д...
Как можно это реализовать?
Ответы (1 шт):
Автор решения: RAINGM
→ Ссылка
Пример: !ban 1час2минуты3секунды
Время бана делать лучше через db, так как после перезапуска бота время бана слетит, а с db можно проверять, прошло время или нет через tasks
import datetime
import re
def str_time_to_seconds(str_time, language='ru'):
conv_dict = {
'w': 'weeks',
'week': 'weeks',
'weeks': 'weeks',
'н': 'weeks',
'нед': 'weeks',
'неделя': 'weeks',
'недели': 'weeks',
'недель': 'weeks',
'неделю': 'weeks',
'd': 'days',
'day': 'days',
'days': 'days',
'д': 'days',
'день': 'days',
'дня': 'days',
'дней': 'days',
'h': 'hours',
'h': 'hours',
'hour': 'hours',
'hours': 'hours',
'ч': 'hours',
'час': 'hours',
'часа': 'hours',
'часов': 'hours',
'm': 'minutes',
'min': 'minutes',
'mins': 'minutes',
'minute': 'minutes',
'minutes': 'minutes',
'мин': 'minutes',
'минута': 'minutes',
'минуту': 'minutes',
'минуты': 'minutes',
'минут': 'minutes',
's': 'seconds',
'sec': 'seconds',
'secs': 'seconds',
'second': 'seconds',
'seconds': 'seconds',
'сек': 'seconds',
'секунда': 'seconds',
'секунду': 'seconds',
'секунды': 'seconds',
'секунд': 'seconds'
}
pat = r'[0-9]+[w|week|weeks|н|нед|неделя|недели|недель|неделю|d|day|days|д|день|дня|дней|h|hour|hours|ч|час|часа|часов|min|mins|minute|minutes|мин|минута|минуту|минуты|минут|s|sec|secs|second|seconds|c|сек|секунда|секунду|секунды|секунд]{1}'
def timestr_to_dict(tstr):
#convert 1d2h3m4s to {"d": 1, "h": 2, "m": 3, "s": 4}
return {conv_dict[p[-1]]: int(p[:-1]) for p in re.findall(pat, str_time)}
def timestr_to_seconds(tstr):
return datetime.timedelta(**timestr_to_dict(tstr)).total_seconds()
def plural(n, arg):
days = []
if language == "ru":
if arg == 'weeks':
days = ['неделя', 'недели', 'недель']
elif arg == 'days':
days = ['день', 'дня', 'дней']
elif arg == 'hours':
days = ['час', 'часа', 'часов']
elif arg == 'minutes':
days = ['минута', 'минуты', 'минут']
elif arg == 'seconds':
days = ['секунда', 'секунды', 'секунд']
elif language == "en":
if arg == 'weeks':
days = ['week', 'weeks', 'weeks']
elif arg == 'days':
days = ['day', 'day', 'days']
elif arg == 'hours':
days = ['hour', 'hour', 'hours']
elif arg == 'minutes':
days = ['minute', 'minute', 'minutes']
elif arg == 'seconds':
days = ['second', 'second', 'seconds']
if n % 10 == 1 and n % 100 != 11:
p = 0
elif 2 <= n % 10 <= 4 and (n % 100 < 10 or n % 100 >= 20):
p = 1
else:
p = 2
return str(n) + ' ' + days[p]
counter_in_str = ""
for i in timestr_to_dict(str_time).items():
counter_in_str += f"{plural(i[1], i[0])} "
return int(timestr_to_seconds(str_time)), counter_in_str
@client.command()
@commands.has_permissions(administrator = True)
async def ban(ctx, member: discord.Member, time, reason):
await ctx.send(f'{member.mention} **забанен** \n Продолжительность бана: *{time}h* \n Причина бана: *{reason}*')
await member.send(f'Тебя забанили на сервере {ctx.guild.name} по причине {reason}')
await member.ban(reason=reason)
seconds, str_time = str_time_to_seconds(time)
await asyncio.sleep(seconds)
await member.unban()
await ctx.send(f'*У {member.mention} закончился бан*')
link = await ctx.channel.create_invite(max_age=300)
await member.send(f'У тебя закончился бан на сервере "{ctx.guild.name}"! {link}')