mod_timed: Allow non-hours as duration values

This commit is contained in:
Ave Ozkal 2018-12-29 22:07:58 +03:00
parent d57f4b9db0
commit 4d27ab9af5
No known key found for this signature in database
GPG key ID: 09356ABAA42C842B
4 changed files with 45 additions and 18 deletions

View file

@ -103,7 +103,7 @@ Main goal of this project is to get Robocop functionality done, secondary goal i
<p> <p>
[ ] Reduce code repetition on mod_timed.py [ ] Reduce code repetition on mod_timed.py
[ ] Allow non-hour values on timed bans [x] Allow non-hour values on timed bans
the following require me to rethink some of the lockdown code, which I don't feel like the following require me to rethink some of the lockdown code, which I don't feel like

View file

@ -2,6 +2,9 @@ import asyncio
import traceback import traceback
import datetime import datetime
import humanize import humanize
import time
import math
import parsedatetime
class Common: class Common:
@ -18,6 +21,13 @@ class Common:
self.bot.aiogetbytes = self.aiogetbytes self.bot.aiogetbytes = self.aiogetbytes
self.bot.get_relative_timestamp = self.get_relative_timestamp self.bot.get_relative_timestamp = self.get_relative_timestamp
self.bot.escape_message = self.escape_message self.bot.escape_message = self.escape_message
self.bot.parse_time = self.parse_time
def parse_time(self, delta_str):
cal = parsedatetime.Calendar()
time_struct, parse_status = cal.parse(delta_str)
res_timestamp = math.floor(time.mktime(time_struct))
return res_timestamp
def get_relative_timestamp(self, time_from=None, time_to=None, def get_relative_timestamp(self, time_from=None, time_to=None,
humanized=False, include_from=False, humanized=False, include_from=False,
@ -29,7 +39,7 @@ class Common:
if not time_to: if not time_to:
time_to = datetime.datetime.utcnow() time_to = datetime.datetime.utcnow()
if humanized: if humanized:
humanized_string = humanize.naturaltime(time_to - time_from) humanized_string = humanize.naturaltime(time_from - time_to)
if include_from and include_to: if include_from and include_to:
str_with_from_and_to = f"{humanized_string} "\ str_with_from_and_to = f"{humanized_string} "\
f"({str(time_from).split('.')[0]} "\ f"({str(time_from).split('.')[0]} "\
@ -40,7 +50,8 @@ class Common:
f"({str(time_from).split('.')[0]})" f"({str(time_from).split('.')[0]})"
return str_with_from return str_with_from
elif include_to: elif include_to:
str_with_to = f"{humanized_string} ({str(time_to).split('.')[0]})" str_with_to = f"{humanized_string} "\
f"({str(time_to).split('.')[0]})"
return str_with_to return str_with_to
return humanized_string return humanized_string
else: else:

View file

@ -1,6 +1,7 @@
import discord import discord
import config import config
import time import time
from datetime import datetime
from discord.ext import commands from discord.ext import commands
from helpers.checks import check_if_staff from helpers.checks import check_if_staff
from helpers.robocronp import add_job from helpers.robocronp import add_job
@ -20,8 +21,8 @@ class ModTimed:
@commands.check(check_if_staff) @commands.check(check_if_staff)
@commands.command() @commands.command()
async def timeban(self, ctx, target: discord.Member, async def timeban(self, ctx, target: discord.Member,
hours: int, *, reason: str = ""): duration: str, *, reason: str = ""):
"""Bans a user for a specified amount of hours, staff only.""" """Bans a user for a specified amount of time, staff only."""
# 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.")
@ -29,7 +30,14 @@ class ModTimed:
return await ctx.send("I can't ban this user as " return await ctx.send("I can't ban this user as "
"they're a member of staff.") "they're a member of staff.")
userlog(target.id, ctx.author, f"{reason} (Timed, for {hours}h)", expiry_timestamp = self.bot.parse_time(duration)
expiry_datetime = datetime.utcfromtimestamp(expiry_timestamp)
duration_text = self.bot.get_relative_timestamp(time_to=expiry_datetime,
include_to=True,
humanized=True)
userlog(target.id, ctx.author, f"{reason} (Timed, until "
f"{duration_text})",
"bans", target.name) "bans", target.name)
safe_name = self.bot.escape_message(str(target)) safe_name = self.bot.escape_message(str(target))
@ -37,7 +45,7 @@ class ModTimed:
dm_message = f"You were banned from {ctx.guild.name}." dm_message = f"You were banned from {ctx.guild.name}."
if reason: if reason:
dm_message += f" The given reason is: \"{reason}\"." dm_message += f" The given reason is: \"{reason}\"."
dm_message += f"\n\nThis ban will expire in {hours} hours." dm_message += f"\n\nThis ban will expire {duration_text}."
try: try:
await target.send(dm_message) await target.send(dm_message)
@ -49,7 +57,7 @@ class ModTimed:
await target.ban(reason=f"{ctx.author}, reason: {reason}", await target.ban(reason=f"{ctx.author}, reason: {reason}",
delete_message_days=0) delete_message_days=0)
chan_message = f"⛔ **Timed Ban**: {ctx.author.mention} banned "\ chan_message = f"⛔ **Timed Ban**: {ctx.author.mention} banned "\
f"{target.mention} for {hours} hours | {safe_name}\n"\ f"{target.mention} for {duration_text} | {safe_name}\n"\
f"🏷 __User ID__: {target.id}\n" f"🏷 __User ID__: {target.id}\n"
if reason: if reason:
chan_message += f"✏️ __Reason__: \"{reason}\"" chan_message += f"✏️ __Reason__: \"{reason}\""
@ -58,19 +66,19 @@ class ModTimed:
", it is recommended to use `.ban <user> [reason]`"\ ", it is recommended to use `.ban <user> [reason]`"\
" as the reason is automatically sent to the user." " as the reason is automatically sent to the user."
expiry_timestamp = time.time() + (hours * 3600)
add_job("unban", target.id, {"guild": ctx.guild.id}, expiry_timestamp) add_job("unban", target.id, {"guild": ctx.guild.id}, expiry_timestamp)
log_channel = self.bot.get_channel(config.log_channel) log_channel = self.bot.get_channel(config.log_channel)
await log_channel.send(chan_message) await log_channel.send(chan_message)
await ctx.send(f"{safe_name} is now b& for {hours} hours. 👍") await ctx.send(f"{safe_name} is now b&. "
f"It will expire {duration_text}. 👍")
@commands.guild_only() @commands.guild_only()
@commands.check(check_if_staff) @commands.check(check_if_staff)
@commands.command() @commands.command()
async def timemute(self, ctx, target: discord.Member, async def timemute(self, ctx, target: discord.Member,
hours: int, *, reason: str = ""): duration: str, *, reason: str = ""):
"""Mutes a user for a specified amount of hours, staff only.""" """Mutes a user for a specified amount of time, staff only."""
# 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.")
@ -78,7 +86,14 @@ class ModTimed:
return await ctx.send("I can't mute this user as " return await ctx.send("I can't mute this user as "
"they're a member of staff.") "they're a member of staff.")
userlog(target.id, ctx.author, f"{reason} (Timed, for {hours}h)", expiry_timestamp = self.bot.parse_time(duration)
expiry_datetime = datetime.utcfromtimestamp(expiry_timestamp)
duration_text = self.bot.get_relative_timestamp(time_to=expiry_datetime,
include_to=True,
humanized=True)
userlog(target.id, ctx.author, f"{reason} (Timed, until "
f"{duration_text})",
"mutes", target.name) "mutes", target.name)
safe_name = self.bot.escape_message(str(target)) safe_name = self.bot.escape_message(str(target))
@ -86,7 +101,7 @@ class ModTimed:
dm_message = f"You were muted!" dm_message = f"You were muted!"
if reason: if reason:
dm_message += f" The given reason is: \"{reason}\"." dm_message += f" The given reason is: \"{reason}\"."
dm_message += f"\n\nThis mute will expire in {hours} hours." dm_message += f"\n\nThis mute will expire {duration_text}."
try: try:
await target.send(dm_message) await target.send(dm_message)
@ -100,7 +115,7 @@ class ModTimed:
await target.add_roles(mute_role, reason=str(ctx.author)) await target.add_roles(mute_role, reason=str(ctx.author))
chan_message = f"🔇 **Timed Mute**: {ctx.author.mention} muted "\ chan_message = f"🔇 **Timed Mute**: {ctx.author.mention} muted "\
f"{target.mention} for {hours} hours | {safe_name}\n"\ f"{target.mention} for {duration_text} | {safe_name}\n"\
f"🏷 __User ID__: {target.id}\n" f"🏷 __User ID__: {target.id}\n"
if reason: if reason:
chan_message += f"✏️ __Reason__: \"{reason}\"" chan_message += f"✏️ __Reason__: \"{reason}\""
@ -109,12 +124,12 @@ class ModTimed:
"it is recommended to use `.mute <user> [reason]`"\ "it is recommended to use `.mute <user> [reason]`"\
" as the reason is automatically sent to the user." " as the reason is automatically sent to the user."
expiry_timestamp = time.time() + (hours * 3600)
add_job("unmute", target.id, {"guild": ctx.guild.id}, expiry_timestamp) add_job("unmute", target.id, {"guild": ctx.guild.id}, expiry_timestamp)
log_channel = self.bot.get_channel(config.log_channel) log_channel = self.bot.get_channel(config.log_channel)
await log_channel.send(chan_message) await log_channel.send(chan_message)
await ctx.send(f"{target.mention} can no longer speak.") await ctx.send(f"{target.mention} can no longer speak. "
f"It will expire {duration_text}.")
add_restriction(target.id, config.mute_role) add_restriction(target.id, config.mute_role)

View file

@ -3,3 +3,4 @@ git+https://github.com/Rapptz/discord.py@rewrite
asyncio asyncio
python-dateutil python-dateutil
humanize humanize
parsedatetime