add(command|kick/ban): rewrite kick and ban commands

This commit is contained in:
Romain J 2019-09-12 15:43:57 +02:00
parent 806ddf0540
commit c0af425383
11 changed files with 225 additions and 56 deletions

42
bot.py
View file

@ -11,12 +11,13 @@ from discord.ext import commands
import config import config
from cogs.utils.config import Config from cogs.utils.config import Config
from cogs.utils.lang import gettext from cogs.utils.lang import Texts
from cogs.utils.version import Version from cogs.utils.version import Version
description = """ description = """
Je suis TuxBot, le bot qui vit de l'OpenSource ! ;) Je suis TuxBot, le bot qui vit de l'OpenSource ! ;)
""" """
build = git.Repo(search_parent_directories=True).head.object.hexsha
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -38,7 +39,10 @@ class TuxBot(commands.AutoShardedBot):
__slots__ = ('uptime', 'config', 'session') __slots__ = ('uptime', 'config', 'session')
def __init__(self, unload: list): def __init__(self, unload: list):
super().__init__(command_prefix=_prefix_callable, description=description, pm_help=None, help_command=None, help_attrs=dict(hidden=True)) super().__init__(command_prefix=_prefix_callable, pm_help=None,
help_command=None, description=description,
help_attrs=dict(hidden=True),
activity=discord.Game(name=Texts().get('Stating...')))
self.uptime: datetime = datetime.datetime.utcnow() self.uptime: datetime = datetime.datetime.utcnow()
self.config = config self.config = config
@ -48,15 +52,17 @@ class TuxBot(commands.AutoShardedBot):
self.prefixes = Config('prefixes.json') self.prefixes = Config('prefixes.json')
self.blacklist = Config('blacklist.json') self.blacklist = Config('blacklist.json')
self.version = Version(10, 0, 0, pre_release='a20', build=git.Repo(search_parent_directories=True).head.object.hexsha) self.version = Version(10, 0, 0, pre_release='a20', build=build)
for extension in l_extensions: for extension in l_extensions:
if extension not in unload: if extension not in unload:
try: try:
self.load_extension(extension) self.load_extension(extension)
except Exception as e: except Exception as e:
print(gettext("Failed to load extension : ") + extension, file=sys.stderr) print(Texts().get("Failed to load extension : ")
log.error(gettext("Failed to load extension : ") + extension, exc_info=e) + extension, file=sys.stderr)
log.error(Texts().get("Failed to load extension : ")
+ extension, exc_info=e)
async def is_owner(self, user: discord.User) -> bool: async def is_owner(self, user: discord.User) -> bool:
return user.id in config.authorized_id return user.id in config.authorized_id
@ -66,15 +72,21 @@ class TuxBot(commands.AutoShardedBot):
async def on_command_error(self, ctx: discord.ext.commands.Context, error): async def on_command_error(self, ctx: discord.ext.commands.Context, error):
if isinstance(error, commands.NoPrivateMessage): if isinstance(error, commands.NoPrivateMessage):
await ctx.author.send(gettext('This command cannot be used in private messages.')) await ctx.author.send(
Texts().get("This command cannot be used in private messages.")
)
elif isinstance(error, commands.DisabledCommand): elif isinstance(error, commands.DisabledCommand):
await ctx.author.send(gettext('Sorry. This command is disabled and cannot be used.')) await ctx.author.send(
Texts().get("Sorry. This command is disabled and cannot be used.")
)
elif isinstance(error, commands.CommandInvokeError): elif isinstance(error, commands.CommandInvokeError):
print(gettext('In ') + f'{ctx.command.qualified_name}:', file=sys.stderr) print(Texts().get("In ") + f'{ctx.command.qualified_name}:',
file=sys.stderr)
traceback.print_tb(error.original.__traceback__) traceback.print_tb(error.original.__traceback__)
print(f'{error.original.__class__.__name__}: {error.original}', file=sys.stderr) print(f'{error.original.__class__.__name__}: {error.original}',
file=sys.stderr)
elif isinstance(error, commands.ArgumentParsingError): elif isinstance(error, commands.ArgumentParsingError):
await ctx.send(error.__str__()) await ctx.send(error.__str__())
@ -88,7 +100,9 @@ class TuxBot(commands.AutoShardedBot):
await self.invoke(ctx) await self.invoke(ctx)
async def on_message(self, message: discord.message): async def on_message(self, message: discord.message):
if message.author.bot or message.author.id in self.blacklist or message.guild.id in self.blacklist: if message.author.bot \
or message.author.id in self.blacklist \
or message.guild.id in self.blacklist:
return return
await self.process_commands(message) await self.process_commands(message)
@ -97,7 +111,7 @@ class TuxBot(commands.AutoShardedBot):
if not hasattr(self, 'uptime'): if not hasattr(self, 'uptime'):
self.uptime = datetime.datetime.utcnow() self.uptime = datetime.datetime.utcnow()
print(gettext('Ready:') + f' {self.user} (ID: {self.user.id})') print(Texts().get("Ready:") + f' {self.user} (ID: {self.user.id})')
print(self.version) print(self.version)
presence: dict = dict(status=discord.Status.dnd) presence: dict = dict(status=discord.Status.dnd)
@ -113,7 +127,11 @@ class TuxBot(commands.AutoShardedBot):
@property @property
def logs_webhook(self) -> discord.Webhook: def logs_webhook(self) -> discord.Webhook:
logs_webhook = self.config.logs_webhook logs_webhook = self.config.logs_webhook
webhook = discord.Webhook.partial(id=logs_webhook.get('id'), token=logs_webhook.get('token'), adapter=discord.AsyncWebhookAdapter(self.session)) webhook = discord.Webhook.partial(id=logs_webhook.get('id'),
token=logs_webhook.get('token'),
adapter=discord.AsyncWebhookAdapter(
self.session)
)
return webhook return webhook

View file

@ -1,5 +1,10 @@
import datetime
import discord
from discord.ext import commands from discord.ext import commands
from bot import TuxBot from bot import TuxBot
from .utils.lang import Texts
class Admin(commands.Cog): class Admin(commands.Cog):
@ -9,17 +14,100 @@ class Admin(commands.Cog):
async def cog_check(self, ctx: commands.Context): async def cog_check(self, ctx: commands.Context):
permissions = ctx.channel.permissions_for(ctx.author) permissions = ctx.channel.permissions_for(ctx.author)
return permissions.administrator
has_permission = permissions.administrator
is_owner = await self.bot.is_owner(ctx.author)
return has_permission or is_owner
@staticmethod
async def kick_ban_message(ctx: commands.Context, **kwargs) -> discord.Embed:
member: discord.Member = kwargs.get('member')
reason = kwargs.get(
'reason',
Texts('admin').get("Please enter a reason")
)
if kwargs.get('type') == 'ban':
title = '**Ban** ' + str(len(await ctx.guild.bans()))
color = discord.Color.dark_red()
else:
title = '**Kick**'
color = discord.Color.red()
e = discord.Embed(
title=title,
description=reason,
timestamp=datetime.datetime.utcnow(),
color=color
)
e.set_author(
name=f'{member.name}#{member.discriminator} ({member.id})',
icon_url=member.avatar_url_as(format='jpg')
)
e.set_footer(
text=f'{ctx.author.name}#{ctx.author.discriminator}',
icon_url=ctx.author.avatar_url_as(format='png')
)
return e
"""---------------------------------------------------------------------""" """---------------------------------------------------------------------"""
@commands.command(name='say', pass_context=True) @commands.command(name='say')
async def _say(self, ctx: commands.Context, *, to_say: str): async def _say(self, ctx: commands.Context, *, to_say: str):
# try: try:
await ctx.message.delete() await ctx.message.delete()
await ctx.send(to_say) await ctx.send(to_say)
# except: except discord.errors.Forbidden:
# await ctx.send(to_say) await ctx.send(to_say)
"""---------------------------------------------------------------------"""
@commands.command(name="ban")
async def _ban(self, ctx: commands.Context, user: discord.User, *,
reason=""):
member: discord.Member = await ctx.guild.fetch_member(user.id)
if member:
try:
await member.ban(reason=reason)
e: discord.Embed = await self.kick_ban_message(
ctx,
member=member,
type='ban',
reason=reason
)
await ctx.send(embed=e)
except discord.Forbidden:
await ctx.send(Texts('admin').get("Unable to ban this user"))
else:
await ctx.send(Texts('admin').get("Unable to find the user..."))
"""---------------------------------------------------------------------"""
@commands.command(name="kick")
async def _kick(self, ctx: commands.Context, user: discord.User, *,
reason=""):
member: discord.Member = await ctx.guild.fetch_member(user.id)
if member:
try:
await member.kick(reason=reason)
e: discord.Embed = await self.kick_ban_message(
ctx,
member=member,
type='kick',
reason=reason
)
await ctx.send(embed=e)
except discord.Forbidden:
await ctx.send(Texts('admin').get("Unable to ban this user"))
else:
await ctx.send(Texts('admin').get("Unable to find the user..."))
"""---------------------------------------------------------------------"""
def setup(bot: TuxBot): def setup(bot: TuxBot):

View file

@ -1,8 +1,16 @@
import gettext import gettext
import config import config
lang = gettext.translation('base', localedir='locales',
languages=[config.lang])
lang.install()
gettext = lang.gettext class Texts:
def __init__(self, base: str = 'base'):
self.locale = config.locale
self.texts = gettext.translation(base, localedir='locales',
languages=[self.locale])
self.texts.install()
def __str__(self) -> str:
return self.texts
def get(self, text: str) -> str:
return self.texts.gettext(text)

View file

@ -10,16 +10,15 @@ class Config:
'log_channel_id': '<INSERT_LOG_CHANNEL_HERE (in int)>', 'log_channel_id': '<INSERT_LOG_CHANNEL_HERE (in int)>',
'main_server_id': '<INSERT_MAIN_CHANNEL_ID_HERE (in int)>', 'main_server_id': '<INSERT_MAIN_CHANNEL_ID_HERE (in int)>',
'authorized_id': '[admin ids here (in int)]', 'authorized_id': '[admin ids here (in int)]',
'unkickable_id': '[unkickable ids here (in int)]'
} }
with open('requirements.txt', 'r') as f: with open('requirements.txt', 'r') as f:
self.packages = f.read().split('\n') self.packages = f.read().split('\n')
def input(self, key, **kwargs): def input(self, key, **kwargs):
lang = self.config.get('lang', 'multiple') locale = self.config.get('locale', 'multiple')
print('\n\033[4m' + texts.get(lang).get(key) + '\033[0m') print('\n\033[4m' + texts.get(locale).get(key) + '\033[0m')
response = input('> ') response = input('> ')
if kwargs.get('valid'): if kwargs.get('valid'):
@ -29,7 +28,7 @@ class Config:
if not kwargs.get('empty', True): if not kwargs.get('empty', True):
while len(response) == 0: while len(response) == 0:
print('\033[41m' + texts.get(lang).get('not_empty') print('\033[41m' + texts.get(locale).get('not_empty')
+ '\033[0m') + '\033[0m')
response = input('> ') response = input('> ')
else: else:
@ -39,31 +38,31 @@ class Config:
self.config[key] = response self.config[key] = response
def install(self): def install(self):
self.input('lang', valid=locales) self.input('locale', valid=locales)
print('\n\n\033[4;36m' print('\n\n\033[4;36m'
+ texts.get(self.config.get('lang')).get('install') + texts.get(self.config.get('locale')).get('install')
+ '\033[0m\n') + '\033[0m\n')
for package in self.packages: for package in self.packages:
pip(['install', package]) pip(['install', package])
def ask(self): def ask(self):
print('\n\n\033[4;36m' + texts.get(self.config.get('lang')).get('conf') print('\n\n\033[4;36m' + texts.get(self.config.get('locale'))
+ '\033[0m\n') .get('conf') + '\033[0m\n')
self.input('token', empty=False) self.input('token', empty=False)
self.input('postgresql_username', empty=False) self.input('postgresql_username', empty=False)
self.input('postgresql_password', empty=False) self.input('postgresql_password', empty=False)
self.input('postgresql_dbname', empty=False) self.input('postgresql_dbname', empty=False)
print('\n\n\033[4;36m' + texts.get(self.config.get('lang')).get('logs') print('\n\n\033[4;36m' + texts.get(self.config.get('locale'))
+ '\033[0m\n') .get('logs') + '\033[0m\n')
self.input('wh_id', empty=True) self.input('wh_id', empty=True)
self.input('wh_token', empty=True) self.input('wh_token', empty=True)
print('\n\n\033[4;36m' + texts.get(self.config.get('lang')).get('misc') print('\n\n\033[4;36m' + texts.get(self.config.get('locale'))
+ '\033[0m\n') .get('misc') + '\033[0m\n')
self.input('activity', empty=True) self.input('activity', empty=True)
@ -84,11 +83,11 @@ class Config:
and not key.startswith('wh_'): and not key.startswith('wh_'):
value = f"'{value}'" if type(value) is str else value value = f"'{value}'" if type(value) is str else value
file.write(f"{key} = {value}\n") file.write(f"{key} = {value}\n")
print('\n\n\033[4;36m' + texts.get(self.config.get('lang')).get('end') print('\n\n\033[4;36m' + texts.get(self.config.get('locale'))
+ '\033[0m\n') .get('end') + '\033[0m\n')
def clean(self): def clean(self):
print('\n\n\033[4;36m' print('\n\n\033[4;36m'
+ texts.get(self.config.get('lang')).get('clean') + texts.get(self.config.get('locale')).get('clean')
+ '\033[0m\n') + '\033[0m\n')
shutil.rmtree('first_run') shutil.rmtree('first_run')

View file

@ -53,7 +53,7 @@ texts = {
}, },
'multiple': { 'multiple': {
'lang': "Veuillez choisir une langue | Please choose a language " 'locale': "Veuillez choisir une langue | Please choose a language "
"[fr/en]", "[fr/en]",
'not_empty': "Cette valeur ne doit pas être vide |" 'not_empty': "Cette valeur ne doit pas être vide |"
" This value must not be empty" " This value must not be empty"

View file

@ -3,17 +3,17 @@ import contextlib
import logging import logging
import socket import socket
import sys import sys
import git
import requests
import click import click
import git
import requests
from bot import TuxBot from bot import TuxBot
from cogs.utils.db import Table from cogs.utils.db import Table
try: try:
import config import config
from cogs.utils.lang import gettext from cogs.utils.lang import Texts
except ModuleNotFoundError: except ModuleNotFoundError:
import first_run import first_run
@ -48,15 +48,16 @@ def run_bot(unload: list = []):
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
log = logging.getLogger() log = logging.getLogger()
print(gettext('Stating...')) print(Texts().get('Stating...'))
try: try:
pool = loop.run_until_complete( pool = loop.run_until_complete(
Table.create_pool(config.postgresql, command_timeout=60) Table.create_pool(config.postgresql, command_timeout=60)
) )
except socket.gaierror as e: except socket.gaierror as e:
click.echo(gettext('Could not set up PostgreSQL...'), file=sys.stderr) click.echo(Texts().get("Could not set up PostgreSQL..."),
log.exception(gettext('Could not set up PostgreSQL...')) file=sys.stderr)
log.exception(Texts().get("Could not set up PostgreSQL..."))
return return
bot = TuxBot(unload) bot = TuxBot(unload)
@ -65,8 +66,10 @@ def run_bot(unload: list = []):
@click.command() @click.command()
@click.option('-d', '--unload', multiple=True, type=str, help=gettext('Launch without loading the <TEXT> module')) @click.option('-d', '--unload', multiple=True, type=str,
@click.option('-u', '--update', help=gettext('Search for update'), is_flag=True) help=Texts().get("Launch without loading the <TEXT> module"))
@click.option('-u', '--update', help=Texts().get("Search for update"),
is_flag=True)
def main(**kwargs): def main(**kwargs):
if kwargs.get('update'): if kwargs.get('update'):
_update() _update()
@ -75,28 +78,31 @@ def main(**kwargs):
run_bot(kwargs.get('unload')) run_bot(kwargs.get('unload'))
@click.option('-d', '--update', help=gettext('Search for update'), is_flag=True) @click.option('-d', '--update', help=Texts().get("Search for update"),
is_flag=True)
def _update(): def _update():
print(gettext('Checking for update...')) print(Texts().get("Checking for update..."))
local = git.Repo(search_parent_directories=True) local = git.Repo(search_parent_directories=True)
current = local.head.object.hexsha current = local.head.object.hexsha
origin = requests.get('https://git.gnous.eu/api/v1/repos/gnouseu/tuxbot-bot/branches/rewrite') gitea = 'https://git.gnous.eu/api/v1/'
origin = requests.get(gitea + 'repos/gnouseu/tuxbot-bot/branches/rewrite')
last = origin.json().get('commit').get('id') last = origin.json().get('commit').get('id')
if current != last: if current != last:
print(gettext('A new version is available !')) print(Texts().get("A new version is available !"))
check = None check = None
while check not in ['', 'y', 'n', 'o']: while check not in ['', 'y', 'n', 'o']:
check = input(gettext('Update ? [Y/n] ')).lower().strip() check = input(Texts().get("Update ? [Y/n] ")).lower().strip()
print(check) print(check)
if check in ['y', '', 'o']: if check in ['y', '', 'o']:
print(gettext('Downloading...')) print(Texts().get("Downloading..."))
origin = git.Repo(search_parent_directories=True).remotes['origin'] origin = git.Repo(search_parent_directories=True) \
.remotes['origin']
origin.pull() origin.pull()
with setup_logging(): with setup_logging():
@ -105,7 +111,7 @@ def _update():
with setup_logging(): with setup_logging():
run_bot() run_bot()
else: else:
print(gettext('Tuxbot is up to date') + '\n') print(Texts().get("Tuxbot is up to date") + '\n')
with setup_logging(): with setup_logging():
run_bot() run_bot()

Binary file not shown.

View file

@ -0,0 +1,25 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2019-09-08 19:04+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
msgid "Please enter a reason"
msgstr ""
msgid "Unable to ban this user"
msgstr ""
msgid "Unable to find the user..."
msgstr ""

Binary file not shown.

View file

@ -0,0 +1,25 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2019-09-08 19:04+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
msgid "Please enter a reason"
msgstr "Merci d'entrer une raison"
msgid "Unable to ban this user"
msgstr "Impossible de bannir cet utilisateur"
msgid "Unable to find the user..."
msgstr "Impossibe de trouver l'utilisateur..."

View file

@ -1,5 +1,5 @@
{ {
"280805240977227776": [ "280805240977227776": [
"$", "b." "b."
] ]
} }