update(cog|admin): add commands for warns

This commit is contained in:
Romain J 2019-09-22 04:18:28 +02:00
parent 0849c1bdff
commit 2d175b4453
6 changed files with 247 additions and 52 deletions

View file

@ -1,6 +1,8 @@
import datetime
import logging
from typing import Union
import asyncio
import discord
import humanize
from discord.ext import commands
@ -8,12 +10,13 @@ from discord.ext import commands
from bot import TuxBot
from .utils.lang import Texts
log = logging.getLogger(__name__)
class Admin(commands.Cog):
def __init__(self, bot: TuxBot):
self.bot = bot
self.db = bot.db
async def cog_check(self, ctx: commands.Context) -> bool:
permissions: discord.Permissions = ctx.channel.permissions_for(
@ -97,7 +100,7 @@ class Admin(commands.Cog):
"""---------------------------------------------------------------------"""
@commands.command(name='ban')
async def _ban(self, ctx: commands.Context, user: discord.User, *,
async def _ban(self, ctx: commands.Context, user: discord.Member, *,
reason=""):
try:
member: discord.Member = await ctx.guild.fetch_member(user.id)
@ -122,7 +125,7 @@ class Admin(commands.Cog):
"""---------------------------------------------------------------------"""
@commands.command(name='kick')
async def _kick(self, ctx: commands.Context, user: discord.User, *,
async def _kick(self, ctx: commands.Context, user: discord.Member, *,
reason=""):
try:
member: discord.Member = await ctx.guild.fetch_member(user.id)
@ -221,48 +224,189 @@ class Admin(commands.Cog):
"""---------------------------------------------------------------------"""
async def get_warn(self, ctx: commands.Context,
member: discord.Member = False):
query = """
SELECT * FROM warns
WHERE created_at >= $1 AND server_id = $2
"""
query += """AND user_id = $3""" if member else ""
query += """ORDER BY created_at DESC"""
week_ago = datetime.datetime.now() - datetime.timedelta(weeks=6)
async with self.bot.db.acquire() as con:
await ctx.trigger_typing()
args = [week_ago, ctx.guild.id]
if member:
args.append(member.id)
warns = await con.fetch(query, *args)
warns_list = ''
for warn in warns:
row_id = warn.get('id')
user_id = warn.get('user_id')
user = await self.bot.fetch_user(user_id)
reason = warn.get('reason')
ago = humanize.naturaldelta(
datetime.datetime.now() - warn.get('created_at')
)
warns_list += f"[{row_id}] **{user}**: `{reason}` " \
f"*({ago} ago)*\n"
return warns_list, warns
@commands.group(name='warn', aliases=['warns'])
async def _warn(self, ctx: commands.Context):
if ctx.invoked_subcommand is None:
query = """
SELECT user_id, reason, created_at FROM warns
WHERE created_at >= $1 AND server_id = $2
ORDER BY created_at
DESC LIMIT 10
"""
week_ago = datetime.datetime.now() - datetime.timedelta(weeks=6)
warns_list, warns = await self.get_warn(ctx)
e = discord.Embed(
title=f"{len(warns)} {Texts('admin').get('last warns')}: ",
description=warns_list
)
async with self.bot.db.acquire() as con:
await ctx.trigger_typing()
warns = await con.fetch(query, week_ago, ctx.guild.id)
warns_list = ''
await ctx.send(embed=e)
for warn in warns:
user_id = warn.get('user_id')
user = await self.bot.fetch_user(user_id)
reason = warn.get('reason')
ago = humanize.naturaldelta(
datetime.datetime.now() - warn.get('created_at')
)
async def add_warn(self, ctx: commands.Context, member: discord.Member,
reason):
warns_list += f"**{user}**: `{reason}` *({ago} ago)*\n"
query = """
INSERT INTO warns (server_id, user_id, reason, created_at)
VALUES ($1, $2, $3, $4)
"""
e = discord.Embed(
title=f"{len(warns)} {Texts('admin').get('last warns')}: ",
description=warns_list
)
await ctx.send(embed=e)
now = datetime.datetime.now()
await self.bot.db.execute(query, ctx.guild.id, member.id, reason, now)
@_warn.command(name='add', aliases=['new'])
async def _warn_new(self, ctx: commands.Context, member: discord.Member,
*, reason):
*, reason="N/A"):
member = await ctx.guild.fetch_member(member.id)
if not member:
return await ctx.send(
Texts('utils').get("Unable to find the user...")
)
query = """
SELECT user_id, reason, created_at FROM warns
WHERE created_at >= $1 AND server_id = $2 and user_id = $3
"""
todo: push in database
if warn > 2 for member:
todo: ask for confirmation to kick or ban
week_ago = datetime.datetime.now() - datetime.timedelta(weeks=6)
def check(payload: discord.RawReactionActionEvent):
if payload.message_id != choice.id \
or payload.user_id != ctx.author.id:
return False
return payload.emoji.name in ('1⃣', '2⃣', '3⃣')
async with self.bot.db.acquire() as con:
await ctx.trigger_typing()
warns = await con.fetch(query, week_ago, ctx.guild.id, member.id)
if len(warns) >= 2:
e = discord.Embed(
title=Texts('admin').get('More than 2 warns'),
description=f"{member.mention} "
+ Texts('admin').get('has more than 2 warns')
)
e.add_field(
name='__Actions__',
value=':one: kick\n'
':two: ban\n'
':three: ' + Texts('admin').get('ignore')
)
choice = await ctx.send(embed=e)
for reaction in ('1⃣', '2⃣', '3⃣'):
await choice.add_reaction(reaction)
try:
payload = await self.bot.wait_for(
'raw_reaction_add',
check=check,
timeout=50.0
)
except asyncio.TimeoutError:
return await ctx.send(
Texts('admin').get('Took too long. Aborting.')
)
finally:
await choice.delete()
if payload.emoji.name == '1⃣':
from jishaku.models import copy_context_with
alt_ctx = await copy_context_with(
ctx,
content=f"{ctx.prefix}"
f"kick "
f"{member} "
f"{Texts('admin').get('More than 2 warns')}"
)
return await alt_ctx.command.invoke(alt_ctx)
elif payload.emoji.name == '2⃣':
from jishaku.models import copy_context_with
alt_ctx = await copy_context_with(
ctx,
content=f"{ctx.prefix}"
f"ban "
f"{member} "
f"{Texts('admin').get('More than 2 warns')}"
)
return await alt_ctx.command.invoke(alt_ctx)
await self.add_warn(ctx, member, reason)
await ctx.send(
content=f"{member.mention} **{Texts('admin').get('got a warn')}**"
f"\n**{Texts('admin').get('Reason')}:** `{reason}`"
if reason != 'N/A' else ''
)
@_warn.command(name='remove', aliases=['revoke'])
async def _warn_remove(self, ctx: commands.Context, warn_id: int):
query = """
DELETE FROM warns
WHERE id = $1
"""
async with self.bot.db.acquire() as con:
await ctx.trigger_typing()
await con.fetch(query, warn_id)
await ctx.send(f"{Texts('admin').get('Warn with id')} `{warn_id}`"
f" {Texts('admin').get('successfully removed')}")
@_warn.command(name='show', aliases=['list'])
async def _warn_show(self, ctx: commands.Context, member: discord.Member):
warns_list, warns = await self.get_warn(ctx, member)
e = discord.Embed(
title=f"{len(warns)} {Texts('admin').get('last warns')}: ",
description=warns_list
)
await ctx.send(embed=e)
@_warn.command(name='edit', aliases=['change'])
async def _warn_edit(self, ctx: commands.Context, warn_id: int, *,
reason):
query = """
UPDATE warns
SET reason = $2
WHERE id = $1
"""
async with self.bot.db.acquire() as con:
await ctx.trigger_typing()
await con.fetch(query, warn_id, reason)
await ctx.send(f"{Texts('admin').get('Warn with id')} `{warn_id}`"
f" {Texts('admin').get('successfully edited')}")
def setup(bot: TuxBot):
bot.add_cog(Admin(bot))

View file

@ -15,7 +15,22 @@ class Utility(commands.Cog):
"""---------------------------------------------------------------------"""
async def fetch_api(self, ctx: commands.Context, ip, addr):
@commands.command(name='iplocalise')
async def _iplocalise(self, ctx: commands.Context, addr, ip_type=''):
addr = re.sub(r'http(s?)://', '', addr)
addr = addr[:-1] if addr.endswith('/') else addr
await ctx.trigger_typing()
if ip_type in ('v6', 'ipv6'):
try:
ip = socket.getaddrinfo(addr, None, socket.AF_INET6)[1][4][0]
except socket.gaierror:
return await ctx.send(
Texts('utility').get('ipv6 not available'))
else:
ip = socket.gethostbyname(addr)
async with self.bot.session.get(f"http://ip-api.com/json/{ip}") as s:
response: dict = await s.json()
@ -55,24 +70,6 @@ class Utility(commands.Cog):
content=f"{Texts('utility').get('info not available')}"
f"``{response.get('query')}``")
@commands.command(name='iplocalise')
async def _iplocalise(self, ctx: commands.Context, addr, ip_type=''):
addr = re.sub(r'http(s?)://', '', addr)
addr = addr[:-1] if addr.endswith('/') else addr
await ctx.trigger_typing()
if ip_type in ('v6', 'ipv6'):
try:
ip = socket.getaddrinfo(addr, None, socket.AF_INET6)[1][4][0]
except socket.gaierror:
return await ctx.send(
Texts('utility').get('ipv6 not available'))
else:
ip = socket.gethostbyname(addr)
await self.fetch_api(ctx, ip, addr)
def setup(bot: TuxBot):
bot.add_cog(Utility(bot))

View file

@ -25,4 +25,31 @@ msgid "Unable to kick this user"
msgstr ""
msgid "last warns"
msgstr ""
msgid "More than 2 warns"
msgstr ""
msgid "has more than 2 warns"
msgstr "has more than 2 warns, what do you want to do ?"
msgid "ignore"
msgstr ""
msgid "Took too long. Aborting."
msgstr ""
msgid "got a warn"
msgstr ""
msgid "Reason"
msgstr ""
msgid "Warn with id"
msgstr ""
msgid "successfully removed"
msgstr ""
msgid "successfully edited"
msgstr ""

View file

@ -25,4 +25,31 @@ msgid "Unable to kick this user"
msgstr "Impossible d'expulser cet utilisateur"
msgid "last warns"
msgstr "derniers avertissements"
msgstr "derniers avertissements"
msgid "More than 2 warns"
msgstr "Plus de 2 avertissements"
msgid "has more than 2 warns"
msgstr "a plus de 2 avertissements, que voulez-vous faire?"
msgid "ignore"
msgstr "ignorer"
msgid "Took too long. Aborting."
msgstr "Temps expiré. Abandons."
msgid "got a warn"
msgstr "a recu un avertissement"
msgid "Reason"
msgstr "Raison"
msgid "Warn with id"
msgstr "L'avertissement avec l'id"
msgid "successfully removed"
msgstr "a été enlevé avec succes"
msgid "successfully edited"
msgstr "a été édité avec succes"