update(cog|admin): add commands for warns
This commit is contained in:
parent
0849c1bdff
commit
2d175b4453
6 changed files with 247 additions and 52 deletions
208
cogs/admin.py
208
cogs/admin.py
|
@ -1,6 +1,8 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import discord
|
import discord
|
||||||
import humanize
|
import humanize
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
@ -8,12 +10,13 @@ from discord.ext import commands
|
||||||
from bot import TuxBot
|
from bot import TuxBot
|
||||||
from .utils.lang import Texts
|
from .utils.lang import Texts
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Admin(commands.Cog):
|
class Admin(commands.Cog):
|
||||||
|
|
||||||
def __init__(self, bot: TuxBot):
|
def __init__(self, bot: TuxBot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.db = bot.db
|
|
||||||
|
|
||||||
async def cog_check(self, ctx: commands.Context) -> bool:
|
async def cog_check(self, ctx: commands.Context) -> bool:
|
||||||
permissions: discord.Permissions = ctx.channel.permissions_for(
|
permissions: discord.Permissions = ctx.channel.permissions_for(
|
||||||
|
@ -97,7 +100,7 @@ class Admin(commands.Cog):
|
||||||
"""---------------------------------------------------------------------"""
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
@commands.command(name='ban')
|
@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=""):
|
reason=""):
|
||||||
try:
|
try:
|
||||||
member: discord.Member = await ctx.guild.fetch_member(user.id)
|
member: discord.Member = await ctx.guild.fetch_member(user.id)
|
||||||
|
@ -122,7 +125,7 @@ class Admin(commands.Cog):
|
||||||
"""---------------------------------------------------------------------"""
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
@commands.command(name='kick')
|
@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=""):
|
reason=""):
|
||||||
try:
|
try:
|
||||||
member: discord.Member = await ctx.guild.fetch_member(user.id)
|
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'])
|
@commands.group(name='warn', aliases=['warns'])
|
||||||
async def _warn(self, ctx: commands.Context):
|
async def _warn(self, ctx: commands.Context):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
query = """
|
warns_list, warns = await self.get_warn(ctx)
|
||||||
SELECT user_id, reason, created_at FROM warns
|
e = discord.Embed(
|
||||||
WHERE created_at >= $1 AND server_id = $2
|
title=f"{len(warns)} {Texts('admin').get('last warns')}: ",
|
||||||
ORDER BY created_at
|
description=warns_list
|
||||||
DESC LIMIT 10
|
)
|
||||||
"""
|
|
||||||
week_ago = datetime.datetime.now() - datetime.timedelta(weeks=6)
|
|
||||||
|
|
||||||
async with self.bot.db.acquire() as con:
|
await ctx.send(embed=e)
|
||||||
await ctx.trigger_typing()
|
|
||||||
warns = await con.fetch(query, week_ago, ctx.guild.id)
|
|
||||||
warns_list = ''
|
|
||||||
|
|
||||||
for warn in warns:
|
async def add_warn(self, ctx: commands.Context, member: discord.Member,
|
||||||
user_id = warn.get('user_id')
|
reason):
|
||||||
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"**{user}**: `{reason}` *({ago} ago)*\n"
|
query = """
|
||||||
|
INSERT INTO warns (server_id, user_id, reason, created_at)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
"""
|
||||||
|
|
||||||
e = discord.Embed(
|
now = datetime.datetime.now()
|
||||||
title=f"{len(warns)} {Texts('admin').get('last warns')}: ",
|
await self.bot.db.execute(query, ctx.guild.id, member.id, reason, now)
|
||||||
description=warns_list
|
|
||||||
)
|
|
||||||
|
|
||||||
await ctx.send(embed=e)
|
|
||||||
|
|
||||||
@_warn.command(name='add', aliases=['new'])
|
@_warn.command(name='add', aliases=['new'])
|
||||||
async def _warn_new(self, ctx: commands.Context, member: discord.Member,
|
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
|
week_ago = datetime.datetime.now() - datetime.timedelta(weeks=6)
|
||||||
if warn > 2 for member:
|
|
||||||
todo: ask for confirmation to kick or ban
|
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):
|
def setup(bot: TuxBot):
|
||||||
bot.add_cog(Admin(bot))
|
bot.add_cog(Admin(bot))
|
||||||
|
|
|
@ -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:
|
async with self.bot.session.get(f"http://ip-api.com/json/{ip}") as s:
|
||||||
response: dict = await s.json()
|
response: dict = await s.json()
|
||||||
|
|
||||||
|
@ -55,24 +70,6 @@ class Utility(commands.Cog):
|
||||||
content=f"{Texts('utility').get('info not available')}"
|
content=f"{Texts('utility').get('info not available')}"
|
||||||
f"``{response.get('query')}``")
|
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):
|
def setup(bot: TuxBot):
|
||||||
bot.add_cog(Utility(bot))
|
bot.add_cog(Utility(bot))
|
||||||
|
|
Binary file not shown.
|
@ -25,4 +25,31 @@ msgid "Unable to kick this user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "last warns"
|
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 ""
|
msgstr ""
|
Binary file not shown.
|
@ -25,4 +25,31 @@ msgid "Unable to kick this user"
|
||||||
msgstr "Impossible d'expulser cet utilisateur"
|
msgstr "Impossible d'expulser cet utilisateur"
|
||||||
|
|
||||||
msgid "last warns"
|
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"
|
Loading…
Reference in a new issue