🤔
This commit is contained in:
commit
7eac932a4e
20 changed files with 264 additions and 207 deletions
91
bot.py
91
bot.py
|
@ -1,5 +1,6 @@
|
||||||
import contextlib
|
import contextlib
|
||||||
import datetime
|
import datetime
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
from collections import deque, Counter
|
from collections import deque, Counter
|
||||||
|
@ -8,12 +9,15 @@ from typing import List
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import discord
|
import discord
|
||||||
import git
|
import git
|
||||||
|
import sqlalchemy
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from utils import Config
|
from utils.functions import Config
|
||||||
from utils import Database
|
from utils.functions import Texts
|
||||||
from utils import Texts
|
from utils.functions import Version
|
||||||
from utils import Version
|
from utils.functions import ContextPlus
|
||||||
|
|
||||||
|
from utils.models import metadata, database
|
||||||
|
|
||||||
description = """
|
description = """
|
||||||
Je suis TuxBot, le bot qui vit de l'OpenSource ! ;)
|
Je suis TuxBot, le bot qui vit de l'OpenSource ! ;)
|
||||||
|
@ -26,6 +30,7 @@ log = logging.getLogger(__name__)
|
||||||
|
|
||||||
l_extensions: List[str] = [
|
l_extensions: List[str] = [
|
||||||
'cogs.Admin',
|
'cogs.Admin',
|
||||||
|
'cogs.API',
|
||||||
'cogs.Help',
|
'cogs.Help',
|
||||||
'cogs.Logs',
|
'cogs.Logs',
|
||||||
# 'cogs.Monitoring',
|
# 'cogs.Monitoring',
|
||||||
|
@ -37,6 +42,7 @@ l_extensions: List[str] = [
|
||||||
|
|
||||||
|
|
||||||
async def _prefix_callable(bot, message: discord.message) -> list:
|
async def _prefix_callable(bot, message: discord.message) -> list:
|
||||||
|
<<<<<<< HEAD
|
||||||
extras = [bot.cluster.get('Name') + '.']
|
extras = [bot.cluster.get('Name') + '.']
|
||||||
if message.guild is not None:
|
if message.guild is not None:
|
||||||
if str(message.guild.id) in bot.prefixes:
|
if str(message.guild.id) in bot.prefixes:
|
||||||
|
@ -45,13 +51,25 @@ async def _prefix_callable(bot, message: discord.message) -> list:
|
||||||
bot.config.get("misc", "Separator")
|
bot.config.get("misc", "Separator")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
=======
|
||||||
|
try:
|
||||||
|
with open(f'./configs/guilds/{message.guild.id}.json', 'r') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
custom_prefix = data['prefixes']
|
||||||
|
except FileNotFoundError:
|
||||||
|
custom_prefix = ['']
|
||||||
|
|
||||||
|
extras = [bot.cluster.get('Name') + '.']
|
||||||
|
extras.extend(custom_prefix)
|
||||||
|
>>>>>>> cce7bb409303e9ad27ef4e5617d0bc9068810f13
|
||||||
|
|
||||||
return commands.when_mentioned_or(*extras)(bot, message)
|
return commands.when_mentioned_or(*extras)(bot, message)
|
||||||
|
|
||||||
|
|
||||||
class TuxBot(commands.AutoShardedBot):
|
class TuxBot(commands.AutoShardedBot):
|
||||||
|
|
||||||
def __init__(self, database):
|
def __init__(self, ):
|
||||||
super().__init__(command_prefix=_prefix_callable, pm_help=None,
|
super().__init__(command_prefix=_prefix_callable, pm_help=None,
|
||||||
help_command=None, description=description,
|
help_command=None, description=description,
|
||||||
help_attrs=dict(hidden=True),
|
help_attrs=dict(hidden=True),
|
||||||
|
@ -62,20 +80,22 @@ class TuxBot(commands.AutoShardedBot):
|
||||||
self.socket_stats = Counter()
|
self.socket_stats = Counter()
|
||||||
self.command_stats = Counter()
|
self.command_stats = Counter()
|
||||||
|
|
||||||
self.uptime: datetime = datetime.datetime.utcnow()
|
|
||||||
self._prev_events = deque(maxlen=10)
|
|
||||||
self.session = aiohttp.ClientSession(loop=self.loop)
|
|
||||||
self.database = database
|
|
||||||
|
|
||||||
self.config = Config('./configs/config.cfg')
|
self.config = Config('./configs/config.cfg')
|
||||||
self.prefixes = Config('./configs/prefixes.cfg')
|
|
||||||
self.blacklist = Config('./configs/blacklist.cfg')
|
self.blacklist = Config('./configs/blacklist.cfg')
|
||||||
self.fallbacks = Config('./configs/fallbacks.cfg')
|
self.fallbacks = Config('./configs/fallbacks.cfg')
|
||||||
self.cluster = self.fallbacks.find('True', key='This', first=True)
|
self.cluster = self.fallbacks.find('True', key='This', first=True)
|
||||||
|
|
||||||
|
self.uptime: datetime = datetime.datetime.utcnow()
|
||||||
|
self._prev_events = deque(maxlen=10)
|
||||||
|
self.session = aiohttp.ClientSession(loop=self.loop)
|
||||||
|
|
||||||
|
self.database, self.metadata = database, metadata
|
||||||
|
self.engine = sqlalchemy.create_engine(str(self.database.url))
|
||||||
|
self.metadata.create_all(self.engine)
|
||||||
|
|
||||||
self.version = Version(*version, pre_release='rc2', build=build)
|
self.version = Version(*version, pre_release='rc2', build=build)
|
||||||
self.owner: discord.User = discord.User
|
self.owners_id = [int(owner_id) for owner_id in self.config.get('permissions', 'Owners').split(', ')]
|
||||||
self.owners: List[discord.User] = []
|
self.owner_id = int(self.owners_id[0])
|
||||||
|
|
||||||
for extension in l_extensions:
|
for extension in l_extensions:
|
||||||
try:
|
try:
|
||||||
|
@ -91,9 +111,19 @@ class TuxBot(commands.AutoShardedBot):
|
||||||
log.error(Texts().get("Failed to load extension : ")
|
log.error(Texts().get("Failed to load extension : ")
|
||||||
+ extension, exc_info=e)
|
+ extension, exc_info=e)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def owner(self):
|
||||||
|
return self.get_user(self.owner_id)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def owners(self):
|
||||||
|
return [self.get_user(owner_id) for owner_id in self.owners_id]
|
||||||
|
|
||||||
async def is_owner(self, user: discord.User) -> bool:
|
async def is_owner(self, user: discord.User) -> bool:
|
||||||
return str(user.id) in self.config.get("permissions", "Owners").split(
|
return user in self.owners
|
||||||
', ')
|
|
||||||
|
async def get_context(self, message, *, cls=None):
|
||||||
|
return await super().get_context(message, cls=cls or ContextPlus)
|
||||||
|
|
||||||
async def on_socket_response(self, msg):
|
async def on_socket_response(self, msg):
|
||||||
self._prev_events.append(msg)
|
self._prev_events.append(msg)
|
||||||
|
@ -110,9 +140,11 @@ class TuxBot(commands.AutoShardedBot):
|
||||||
"Sorry. This command is disabled and cannot be used."
|
"Sorry. This command is disabled and cannot be used."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
elif isinstance(error, commands.CommandOnCooldown):
|
||||||
|
await ctx.send(str(error))
|
||||||
|
|
||||||
async def process_commands(self, message: discord.message):
|
async def process_commands(self, message: discord.message):
|
||||||
ctx = await self.get_context(message)
|
ctx: commands.Context = await self.get_context(message)
|
||||||
|
|
||||||
if ctx.command is None:
|
if ctx.command is None:
|
||||||
return
|
return
|
||||||
|
@ -151,13 +183,6 @@ class TuxBot(commands.AutoShardedBot):
|
||||||
print('-' * 60)
|
print('-' * 60)
|
||||||
|
|
||||||
await self.change_presence(**presence)
|
await self.change_presence(**presence)
|
||||||
self.owner = await self.fetch_user(
|
|
||||||
int(self.config.get('permissions', 'Owners').split(', ')[0])
|
|
||||||
)
|
|
||||||
for owner in self.config.get('permissions', 'Owners').split(', '):
|
|
||||||
self.owners.append(
|
|
||||||
await self.fetch_user(int(owner))
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def on_resumed():
|
async def on_resumed():
|
||||||
|
@ -189,13 +214,13 @@ class TuxBot(commands.AutoShardedBot):
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def setup_logging():
|
def setup_logging():
|
||||||
|
logging.getLogger('discord').setLevel(logging.INFO)
|
||||||
|
logging.getLogger('discord.http').setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
log = logging.getLogger()
|
||||||
|
log.setLevel(logging.INFO)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logging.getLogger('discord').setLevel(logging.INFO)
|
|
||||||
logging.getLogger('discord.http').setLevel(logging.WARNING)
|
|
||||||
|
|
||||||
log = logging.getLogger()
|
|
||||||
log.setLevel(logging.INFO)
|
|
||||||
|
|
||||||
handler = logging.FileHandler(filename='logs/tuxbot.log',
|
handler = logging.FileHandler(filename='logs/tuxbot.log',
|
||||||
encoding='utf-8', mode='w')
|
encoding='utf-8', mode='w')
|
||||||
fmt = logging.Formatter('[{levelname:<7}] [{asctime}]'
|
fmt = logging.Formatter('[{levelname:<7}] [{asctime}]'
|
||||||
|
@ -214,14 +239,12 @@ def setup_logging():
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
log = logging.getLogger()
|
|
||||||
|
|
||||||
print(Texts().get('Starting...'))
|
print(Texts().get('Starting...'))
|
||||||
|
|
||||||
bot = TuxBot(Database(Config("./configs/config.cfg")))
|
app = TuxBot()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with setup_logging():
|
with setup_logging():
|
||||||
bot.run()
|
app.run()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
bot.close()
|
app.close()
|
||||||
|
|
56
cogs/API.py
Normal file
56
cogs/API.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import discord
|
||||||
|
from aiohttp import web
|
||||||
|
from discord.ext import commands
|
||||||
|
|
||||||
|
from bot import TuxBot
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class API(commands.Cog):
|
||||||
|
|
||||||
|
def __init__(self, bot: TuxBot):
|
||||||
|
self.bot = bot
|
||||||
|
self.site = web.TCPSite
|
||||||
|
|
||||||
|
app = web.Application()
|
||||||
|
app.add_routes([web.get('/users/{user_id}', self.users)])
|
||||||
|
|
||||||
|
self.runner = web.AppRunner(app)
|
||||||
|
self.bot.loop.create_task(self.start_HTTPMonitoring_server())
|
||||||
|
|
||||||
|
async def start_HTTPMonitoring_server(self):
|
||||||
|
host = self.bot.config.get('API', 'Host')
|
||||||
|
port = self.bot.config.get('API', 'Port')
|
||||||
|
|
||||||
|
print(f"Starting API server on {host}:{port}")
|
||||||
|
|
||||||
|
await self.runner.setup()
|
||||||
|
self.site = web.TCPSite(self.runner, host, port)
|
||||||
|
await self.site.start()
|
||||||
|
|
||||||
|
async def users(self, request):
|
||||||
|
try:
|
||||||
|
user = await self.bot.fetch_user(request.match_info['user_id'])
|
||||||
|
except discord.NotFound:
|
||||||
|
return web.Response(status=404)
|
||||||
|
|
||||||
|
json = {
|
||||||
|
'id': user.id,
|
||||||
|
'username': user.name,
|
||||||
|
'discriminator': user.discriminator,
|
||||||
|
'avatar': user.avatar,
|
||||||
|
'default_avatar': user.default_avatar.value,
|
||||||
|
'bot': user.bot,
|
||||||
|
'system': user.system,
|
||||||
|
}
|
||||||
|
|
||||||
|
return web.json_response(
|
||||||
|
json
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot: TuxBot):
|
||||||
|
bot.add_cog(API(bot))
|
|
@ -9,8 +9,8 @@ from discord.ext import commands
|
||||||
|
|
||||||
from bot import TuxBot
|
from bot import TuxBot
|
||||||
from utils import Texts
|
from utils import Texts
|
||||||
from utils import WarnModel, LangModel
|
from utils.models import WarnModel
|
||||||
from utils import commandExtra, groupExtra
|
from utils import command_extra, group_extra
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@groupExtra(name='say', invoke_without_command=True, category='text')
|
@group_extra(name='say', invoke_without_command=True, category='text')
|
||||||
async def _say(self, ctx: commands.Context, *, content: str):
|
async def _say(self, ctx: commands.Context, *, content: str):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
try:
|
try:
|
||||||
|
@ -105,7 +105,7 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='ban', category='administration')
|
@command_extra(name='ban', category='administration')
|
||||||
async def _ban(self, ctx: commands.Context, user: discord.Member, *,
|
async def _ban(self, ctx: commands.Context, user: discord.Member, *,
|
||||||
reason=""):
|
reason=""):
|
||||||
try:
|
try:
|
||||||
|
@ -132,7 +132,7 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='kick', category='administration')
|
@command_extra(name='kick', category='administration')
|
||||||
async def _kick(self, ctx: commands.Context, user: discord.Member, *,
|
async def _kick(self, ctx: commands.Context, user: discord.Member, *,
|
||||||
reason=""):
|
reason=""):
|
||||||
try:
|
try:
|
||||||
|
@ -159,7 +159,7 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='clear', category='text')
|
@command_extra(name='clear', category='text')
|
||||||
async def _clear(self, ctx: commands.Context, count: int):
|
async def _clear(self, ctx: commands.Context, count: int):
|
||||||
try:
|
try:
|
||||||
await ctx.message.delete()
|
await ctx.message.delete()
|
||||||
|
@ -169,7 +169,7 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@groupExtra(name='react', category='text')
|
@group_extra(name='react', category='text')
|
||||||
async def _react(self, ctx: commands.Context):
|
async def _react(self, ctx: commands.Context):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await ctx.send_help('react')
|
await ctx.send_help('react')
|
||||||
|
@ -203,7 +203,7 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@groupExtra(name='delete', invoke_without_command=True, category='text')
|
@group_extra(name='delete', invoke_without_command=True, category='text')
|
||||||
async def _delete(self, ctx: commands.Context, message_id: int):
|
async def _delete(self, ctx: commands.Context, message_id: int):
|
||||||
try:
|
try:
|
||||||
await ctx.message.delete()
|
await ctx.message.delete()
|
||||||
|
@ -229,12 +229,14 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
message: discord.Message = await channel.fetch_message(
|
message: discord.Message = await channel.fetch_message(
|
||||||
message_id)
|
message_id
|
||||||
|
)
|
||||||
await message.delete()
|
await message.delete()
|
||||||
except (discord.errors.NotFound, discord.errors.Forbidden):
|
except (discord.errors.NotFound, discord.errors.Forbidden):
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
Texts('utils', ctx).get("Unable to find the message"),
|
Texts('utils', ctx).get("Unable to find the message"),
|
||||||
delete_after=5)
|
delete_after=5
|
||||||
|
)
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
|
@ -242,24 +244,18 @@ class Admin(commands.Cog):
|
||||||
member: discord.Member = False):
|
member: discord.Member = False):
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
|
|
||||||
week_ago = datetime.datetime.now() - datetime.timedelta(weeks=6)
|
|
||||||
|
|
||||||
if member:
|
if member:
|
||||||
warns = self.bot.database.session \
|
warns = WarnModel.objects.filter(
|
||||||
.query(WarnModel) \
|
server_id=str(ctx.guild.id),
|
||||||
.filter(WarnModel.user_id == member.id,
|
user_id=member.id
|
||||||
WarnModel.created_at > week_ago,
|
)
|
||||||
WarnModel.server_id == ctx.guild.id) \
|
|
||||||
.order_by(WarnModel.created_at.desc())
|
|
||||||
else:
|
else:
|
||||||
warns = self.bot.database.session \
|
warns = WarnModel.objects.filter(
|
||||||
.query(WarnModel) \
|
server_id=str(ctx.guild.id)
|
||||||
.filter(WarnModel.created_at > week_ago,
|
)
|
||||||
WarnModel.server_id == ctx.guild.id) \
|
|
||||||
.order_by(WarnModel.created_at.desc())
|
|
||||||
warns_list = ''
|
warns_list = ''
|
||||||
|
|
||||||
for warn in warns:
|
for warn in await warns.all():
|
||||||
row_id = warn.id
|
row_id = warn.id
|
||||||
user_id = warn.user_id
|
user_id = warn.user_id
|
||||||
user = await self.bot.fetch_user(user_id)
|
user = await self.bot.fetch_user(user_id)
|
||||||
|
@ -283,7 +279,7 @@ class Admin(commands.Cog):
|
||||||
self.bot.database.session.add(warn)
|
self.bot.database.session.add(warn)
|
||||||
self.bot.database.session.commit()
|
self.bot.database.session.commit()
|
||||||
|
|
||||||
@groupExtra(name='warn', aliases=['warns'], category='administration')
|
@group_extra(name='warn', aliases=['warns'], category='administration')
|
||||||
async def _warn(self, ctx: commands.Context):
|
async def _warn(self, ctx: commands.Context):
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
|
@ -411,7 +407,7 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='language', aliases=['lang', 'langue', 'langage'], category='server')
|
@command_extra(name='language', aliases=['lang', 'langue', 'langage'], category='server')
|
||||||
async def _language(self, ctx: commands.Context, locale: str):
|
async def _language(self, ctx: commands.Context, locale: str):
|
||||||
available = self.bot.database.session \
|
available = self.bot.database.session \
|
||||||
.query(LangModel.value) \
|
.query(LangModel.value) \
|
||||||
|
@ -442,7 +438,7 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@groupExtra(name='prefix', aliases=['prefixes'], category='server')
|
@group_extra(name='prefix', aliases=['prefixes'], category='server')
|
||||||
async def _prefix(self, ctx: commands.Context):
|
async def _prefix(self, ctx: commands.Context):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await ctx.send_help('prefix')
|
await ctx.send_help('prefix')
|
||||||
|
|
|
@ -20,7 +20,7 @@ from discord.ext import commands, tasks
|
||||||
|
|
||||||
from bot import TuxBot
|
from bot import TuxBot
|
||||||
from utils import Texts
|
from utils import Texts
|
||||||
from utils import commandExtra
|
from utils import command_extra
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ class Logs(commands.Cog):
|
||||||
msg = f'{emoji} `[{dt:%Y-%m-%d %H:%M:%S}] {record.message}`'
|
msg = f'{emoji} `[{dt:%Y-%m-%d %H:%M:%S}] {record.message}`'
|
||||||
await self.webhook.send(msg)
|
await self.webhook.send(msg)
|
||||||
|
|
||||||
@commandExtra(name='commandstats', hidden=True, category='misc')
|
@command_extra(name='commandstats', hidden=True, category='misc')
|
||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
async def _commandstats(self, ctx, limit=20):
|
async def _commandstats(self, ctx, limit=20):
|
||||||
counter = self.bot.command_stats
|
counter = self.bot.command_stats
|
||||||
|
@ -258,7 +258,7 @@ class Logs(commands.Cog):
|
||||||
|
|
||||||
await ctx.send(f'```\n{output}\n```')
|
await ctx.send(f'```\n{output}\n```')
|
||||||
|
|
||||||
@commandExtra(name='socketstats', hidden=True, category='misc')
|
@command_extra(name='socketstats', hidden=True, category='misc')
|
||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
async def _socketstats(self, ctx):
|
async def _socketstats(self, ctx):
|
||||||
delta = datetime.datetime.utcnow() - self.bot.uptime
|
delta = datetime.datetime.utcnow() - self.bot.uptime
|
||||||
|
@ -268,7 +268,7 @@ class Logs(commands.Cog):
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f'{total} socket events observed ({cpm:.2f}/minute):\n{self.bot.socket_stats}')
|
f'{total} socket events observed ({cpm:.2f}/minute):\n{self.bot.socket_stats}')
|
||||||
|
|
||||||
@commandExtra(name='uptime', category='misc')
|
@command_extra(name='uptime', category='misc')
|
||||||
async def _uptime(self, ctx):
|
async def _uptime(self, ctx):
|
||||||
uptime = humanize.naturaltime(
|
uptime = humanize.naturaltime(
|
||||||
datetime.datetime.utcnow() - self.bot.uptime)
|
datetime.datetime.utcnow() - self.bot.uptime)
|
||||||
|
|
|
@ -10,7 +10,7 @@ from bot import TuxBot
|
||||||
from utils import PollModel, ResponsesModel
|
from utils import PollModel, ResponsesModel
|
||||||
from utils import Texts
|
from utils import Texts
|
||||||
from utils.functions import emotes as utils_emotes
|
from utils.functions import emotes as utils_emotes
|
||||||
from utils import groupExtra
|
from utils import group_extra
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ class Poll(commands.Cog):
|
||||||
poll.content = json.dumps(content)
|
poll.content = json.dumps(content)
|
||||||
self.bot.database.session.commit()
|
self.bot.database.session.commit()
|
||||||
|
|
||||||
@groupExtra(name='poll', aliases=['sondage'], category='poll')
|
@group_extra(name='poll', aliases=['sondage'], category='poll')
|
||||||
async def _poll(self, ctx: commands.Context):
|
async def _poll(self, ctx: commands.Context):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await ctx.send_help('poll')
|
await ctx.send_help('poll')
|
||||||
|
|
|
@ -23,7 +23,7 @@ from tcp_latency import measure_latency
|
||||||
|
|
||||||
from bot import TuxBot
|
from bot import TuxBot
|
||||||
from utils import Texts
|
from utils import Texts
|
||||||
from utils import commandExtra, groupExtra
|
from utils import command_extra, group_extra
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ class Useful(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='iplocalise', category='network')
|
@command_extra(name='iplocalise', category='network')
|
||||||
async def _iplocalise(self, ctx: commands.Context, addr, ip_type=''):
|
async def _iplocalise(self, ctx: commands.Context, addr, ip_type=''):
|
||||||
addr = re.sub(r'http(s?)://', '', addr)
|
addr = re.sub(r'http(s?)://', '', addr)
|
||||||
addr = addr[:-1] if addr.endswith('/') else addr
|
addr = addr[:-1] if addr.endswith('/') else addr
|
||||||
|
@ -150,14 +150,7 @@ class Useful(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@command_extra(name='getheaders', category='network')
|
||||||
async def on_command_error(self, ctx, error):
|
|
||||||
if isinstance(error, commands.CommandOnCooldown):
|
|
||||||
await ctx.send(error)
|
|
||||||
|
|
||||||
###########################################################################
|
|
||||||
|
|
||||||
@commandExtra(name='getheaders', category='network')
|
|
||||||
async def _getheaders(self, ctx: commands.Context, addr: str):
|
async def _getheaders(self, ctx: commands.Context, addr: str):
|
||||||
if (addr.startswith('http') or addr.startswith('ftp')) is not True:
|
if (addr.startswith('http') or addr.startswith('ftp')) is not True:
|
||||||
addr = f"http://{addr}"
|
addr = f"http://{addr}"
|
||||||
|
@ -187,7 +180,7 @@ class Useful(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='git', aliases=['sources', 'source', 'github'], category='misc')
|
@command_extra(name='git', aliases=['sources', 'source', 'github'], category='misc')
|
||||||
async def _git(self, ctx):
|
async def _git(self, ctx):
|
||||||
e = discord.Embed(
|
e = discord.Embed(
|
||||||
title=Texts('useful', ctx).get('git repo'),
|
title=Texts('useful', ctx).get('git repo'),
|
||||||
|
@ -202,7 +195,7 @@ class Useful(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='quote', category='misc')
|
@command_extra(name='quote', category='misc')
|
||||||
async def _quote(self, ctx, message_id: discord.Message):
|
async def _quote(self, ctx, message_id: discord.Message):
|
||||||
e = discord.Embed(
|
e = discord.Embed(
|
||||||
colour=message_id.author.colour,
|
colour=message_id.author.colour,
|
||||||
|
@ -224,7 +217,7 @@ class Useful(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='ping', category='network')
|
@command_extra(name='ping', category='network')
|
||||||
async def _ping(self, ctx: commands.Context):
|
async def _ping(self, ctx: commands.Context):
|
||||||
start = time.perf_counter()
|
start = time.perf_counter()
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
|
@ -242,7 +235,7 @@ class Useful(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='info', aliases=['about'], category='misc')
|
@command_extra(name='info', aliases=['about'], category='misc')
|
||||||
async def _info(self, ctx: commands.Context):
|
async def _info(self, ctx: commands.Context):
|
||||||
proc = psutil.Process()
|
proc = psutil.Process()
|
||||||
total, python = self.fetch_info()
|
total, python = self.fetch_info()
|
||||||
|
@ -325,7 +318,7 @@ class Useful(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@commandExtra(name='credits', aliases=['contributors', 'authors'], category='misc')
|
@command_extra(name='credits', aliases=['contributors', 'authors'], category='misc')
|
||||||
async def _credits(self, ctx: commands.Context):
|
async def _credits(self, ctx: commands.Context):
|
||||||
e = discord.Embed(
|
e = discord.Embed(
|
||||||
title=Texts('useful', ctx).get('Contributors'),
|
title=Texts('useful', ctx).get('Contributors'),
|
||||||
|
@ -349,7 +342,7 @@ class Useful(commands.Cog):
|
||||||
await ctx.send(embed=e)
|
await ctx.send(embed=e)
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
@groupExtra(name='cb', aliases=['cc'], category='misc')
|
@group_extra(name='cb', aliases=['cc'], category='misc')
|
||||||
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
||||||
async def _cb(self, ctx: commands.Context):
|
async def _cb(self, ctx: commands.Context):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
|
|
|
@ -5,7 +5,7 @@ from discord.ext import commands
|
||||||
from bot import TuxBot
|
from bot import TuxBot
|
||||||
from utils import AliasesModel
|
from utils import AliasesModel
|
||||||
from utils import Texts
|
from utils import Texts
|
||||||
from utils import groupExtra
|
from utils import group_extra
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class User(commands.Cog):
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@groupExtra(name='alias', aliases=['aliases'], category='alias')
|
@group_extra(name='alias', aliases=['aliases'], category='alias')
|
||||||
async def _alias(self, ctx: commands.Context):
|
async def _alias(self, ctx: commands.Context):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await ctx.send_help('alias')
|
await ctx.send_help('alias')
|
||||||
|
|
|
@ -18,3 +18,7 @@ Token =
|
||||||
|
|
||||||
[misc]
|
[misc]
|
||||||
Separator =
|
Separator =
|
||||||
|
|
||||||
|
[API]
|
||||||
|
Host =
|
||||||
|
Port =
|
19
database.py
19
database.py
|
@ -1,7 +1,5 @@
|
||||||
from utils import Config
|
import sqlalchemy
|
||||||
from utils.models import Base
|
from utils.models import database, metadata
|
||||||
from utils import Database
|
|
||||||
from utils.models.lang import LangModel
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
@ -9,20 +7,13 @@ parser.add_argument("-m", "--migrate", action="store_true")
|
||||||
parser.add_argument("-s", "--seed", action="store_true")
|
parser.add_argument("-s", "--seed", action="store_true")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
database = Database(Config("./configs/config.cfg"))
|
|
||||||
|
|
||||||
if args.migrate:
|
if args.migrate:
|
||||||
print("Migrate...")
|
print("Migrate...")
|
||||||
Base.metadata.create_all(database.engine)
|
engine = sqlalchemy.create_engine(str(database.url))
|
||||||
|
metadata.create_all(engine)
|
||||||
print("Done!")
|
print("Done!")
|
||||||
|
|
||||||
if args.seed:
|
if args.seed:
|
||||||
print('Seeding...')
|
print('Seeding...')
|
||||||
default = LangModel(key="default", value="fr")
|
# todo: add seeding
|
||||||
available = LangModel(key="available", value="fr,en")
|
|
||||||
|
|
||||||
database.session.add(default)
|
|
||||||
database.session.add(available)
|
|
||||||
|
|
||||||
database.session.commit()
|
|
||||||
print("Done!")
|
print("Done!")
|
||||||
|
|
|
@ -3,7 +3,8 @@ humanize
|
||||||
git+https://github.com/Rapptz/discord.py@master
|
git+https://github.com/Rapptz/discord.py@master
|
||||||
jishaku
|
jishaku
|
||||||
gitpython
|
gitpython
|
||||||
sqlalchemy
|
orm
|
||||||
|
asyncpg
|
||||||
psycopg2
|
psycopg2
|
||||||
configparser
|
configparser
|
||||||
psutil
|
psutil
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
from .models import *
|
|
||||||
|
|
||||||
from utils.functions.config import *
|
from utils.functions.config import *
|
||||||
from utils.functions.lang import *
|
from utils.functions.lang import *
|
||||||
from utils.functions.version import *
|
from utils.functions.version import *
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
from .config import Config
|
||||||
|
from .database import Database
|
||||||
|
from .extra import *
|
||||||
|
from .lang import Texts
|
||||||
|
from .paginator import *
|
||||||
|
from .version import Version
|
|
@ -1,7 +1,7 @@
|
||||||
from .config import Config
|
from .config import Config
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
import sqlalchemy
|
||||||
from sqlalchemy.orm import sessionmaker, session
|
import databases
|
||||||
|
|
||||||
|
|
||||||
class Database:
|
class Database:
|
||||||
|
@ -10,8 +10,7 @@ class Database:
|
||||||
postgresql = 'postgresql://{}:{}@{}/{}'.format(
|
postgresql = 'postgresql://{}:{}@{}/{}'.format(
|
||||||
conf_postgresql.get("Username"), conf_postgresql.get("Password"),
|
conf_postgresql.get("Username"), conf_postgresql.get("Password"),
|
||||||
conf_postgresql.get("Host"), conf_postgresql.get("DBName"))
|
conf_postgresql.get("Host"), conf_postgresql.get("DBName"))
|
||||||
self.engine = create_engine(postgresql, echo=False)
|
|
||||||
|
|
||||||
Session = sessionmaker()
|
self.database = databases.Database(postgresql)
|
||||||
Session.configure(bind=self.engine)
|
self.metadata = sqlalchemy.MetaData()
|
||||||
self.session: session = Session()
|
self.engine = sqlalchemy.create_engine(str(self.database.url))
|
||||||
|
|
|
@ -1,20 +1,32 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
from utils.functions import Config
|
||||||
|
|
||||||
|
|
||||||
class commandsPlus(commands.Command):
|
class CommandsPlus(commands.Command):
|
||||||
def __init__(self, func, **kwargs):
|
def __init__(self, func, **kwargs):
|
||||||
super().__init__(func, **kwargs)
|
super().__init__(func, **kwargs)
|
||||||
self.category = kwargs.get("category", 'other')
|
self.category = kwargs.get("category", 'other')
|
||||||
|
|
||||||
|
|
||||||
def commandExtra(*args, **kwargs):
|
|
||||||
return commands.command(*args, **kwargs, cls=commandsPlus)
|
|
||||||
|
|
||||||
|
|
||||||
class GroupPlus(commands.Group):
|
class GroupPlus(commands.Group):
|
||||||
def __init__(self, func, **kwargs):
|
def __init__(self, func, **kwargs):
|
||||||
super().__init__(func, **kwargs)
|
super().__init__(func, **kwargs)
|
||||||
self.category = kwargs.get("category", 'other')
|
self.category = kwargs.get("category", 'other')
|
||||||
|
|
||||||
def groupExtra(*args, **kwargs):
|
|
||||||
|
class ContextPlus(commands.Context):
|
||||||
|
async def send(self, content=None, **kwargs):
|
||||||
|
config = Config('./configs/config.cfg')
|
||||||
|
|
||||||
|
content = content.replace(config.get("bot", "Token"), 'Whoops! leaked token')
|
||||||
|
content = content.replace(config.get("webhook", "Token"), 'Whoops! leaked token')
|
||||||
|
|
||||||
|
return await super().send(content, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def command_extra(*args, **kwargs):
|
||||||
|
return commands.command(*args, **kwargs, cls=CommandsPlus)
|
||||||
|
|
||||||
|
|
||||||
|
def group_extra(*args, **kwargs):
|
||||||
return commands.group(*args, **kwargs, cls=GroupPlus)
|
return commands.group(*args, **kwargs, cls=GroupPlus)
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import gettext
|
import gettext
|
||||||
from .config import Config
|
import json
|
||||||
from .database import Database
|
|
||||||
|
|
||||||
from utils.models.lang import LangModel
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,18 +19,16 @@ class Texts:
|
||||||
self.locale = lang
|
self.locale = lang
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_locale(ctx):
|
def get_locale(ctx: commands.Context):
|
||||||
database = Database(Config("./configs/config.cfg"))
|
lang = 'fr'
|
||||||
|
|
||||||
if ctx is not None:
|
if ctx is not None:
|
||||||
current = database.session\
|
try:
|
||||||
.query(LangModel.value)\
|
with open(f'./configs/guilds/{ctx.guild.id}.json', 'r') as f:
|
||||||
.filter(LangModel.key == str(ctx.guild.id))
|
data = json.load(f)
|
||||||
if current.count() > 0:
|
|
||||||
return current.one()[0]
|
|
||||||
|
|
||||||
default = database.session\
|
lang = data['lang']
|
||||||
.query(LangModel.value)\
|
|
||||||
.filter(LangModel.key == 'default')\
|
except FileNotFoundError:
|
||||||
.one()[0]
|
pass
|
||||||
return default
|
|
||||||
|
return lang
|
||||||
|
|
|
@ -1,7 +1,18 @@
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
import databases
|
||||||
Base = declarative_base()
|
import sqlalchemy
|
||||||
|
from utils.functions import Config
|
||||||
|
|
||||||
|
conf_postgresql = Config('./configs/config.cfg')["postgresql"]
|
||||||
|
postgresql = 'postgresql://{}:{}@{}/{}'.format(
|
||||||
|
conf_postgresql.get("Username"), conf_postgresql.get("Password"),
|
||||||
|
conf_postgresql.get("Host"), conf_postgresql.get("DBName"))
|
||||||
|
|
||||||
|
database = databases.Database(postgresql)
|
||||||
|
metadata = sqlalchemy.MetaData()
|
||||||
|
|
||||||
|
engine = sqlalchemy.create_engine(str(database.url))
|
||||||
|
metadata.create_all(engine)
|
||||||
|
|
||||||
from .lang import LangModel
|
|
||||||
from .warn import WarnModel
|
from .warn import WarnModel
|
||||||
from .poll import PollModel, ResponsesModel
|
from .poll import PollModel, ResponsesModel
|
||||||
from .alias import AliasesModel
|
from .alias import AliasesModel
|
||||||
|
|
|
@ -1,28 +1,14 @@
|
||||||
from sqlalchemy import Column, String, BigInteger, Integer
|
import orm
|
||||||
|
from . import database, metadata
|
||||||
from . import Base
|
|
||||||
|
|
||||||
|
|
||||||
class AliasesModel(Base):
|
class AliasesModel(orm.Model):
|
||||||
__tablename__ = 'aliases'
|
__tablename__ = 'aliases'
|
||||||
|
__database__ = database
|
||||||
|
__metadata__ = metadata
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
id = orm.Integer(primary_key=True)
|
||||||
user_id = Column(BigInteger)
|
user_id = orm.String(max_length=18)
|
||||||
alias = Column(String)
|
alias = orm.String(max_length=255)
|
||||||
command = Column(String)
|
command = orm.String(max_length=255)
|
||||||
guild = Column(String)
|
guild = orm.String(max_length=255)
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<AliasesModel(" \
|
|
||||||
"id='%s', " \
|
|
||||||
"user_id='%s', " \
|
|
||||||
"alias='%s', " \
|
|
||||||
"command='%s', " \
|
|
||||||
"guild='%s', " \
|
|
||||||
")>" % (
|
|
||||||
self.id,
|
|
||||||
self.user_id,
|
|
||||||
self.alias,
|
|
||||||
self.command,
|
|
||||||
self.guild
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
from . import Base
|
|
||||||
from sqlalchemy import Column, String
|
|
||||||
|
|
||||||
|
|
||||||
class LangModel(Base):
|
|
||||||
__tablename__ = 'langs'
|
|
||||||
|
|
||||||
key = Column(String, primary_key=True)
|
|
||||||
value = Column(String)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<LangModel(key='%s', locale='%s')>" % (self.key, self.value)
|
|
|
@ -1,27 +1,29 @@
|
||||||
from . import Base
|
import orm
|
||||||
from sqlalchemy import Column, Integer, BigInteger, JSON, ForeignKey, Boolean
|
from . import database, metadata
|
||||||
from sqlalchemy.orm import relationship
|
|
||||||
|
|
||||||
|
|
||||||
class PollModel(Base):
|
class ResponsesModel(orm.Model):
|
||||||
__tablename__ = 'polls'
|
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
||||||
channel_id = Column(BigInteger)
|
|
||||||
message_id = Column(BigInteger)
|
|
||||||
|
|
||||||
content = Column(JSON)
|
|
||||||
is_anonymous = Column(Boolean)
|
|
||||||
|
|
||||||
available_choices = Column(Integer)
|
|
||||||
choice = relationship("ResponsesModel")
|
|
||||||
|
|
||||||
|
|
||||||
class ResponsesModel(Base):
|
|
||||||
__tablename__ = 'responses'
|
__tablename__ = 'responses'
|
||||||
|
__database__ = database
|
||||||
|
__metadata__ = metadata
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
id = orm.Integer(primary_key=True)
|
||||||
user = Column(BigInteger)
|
user = orm.String(max_length=18)
|
||||||
|
|
||||||
poll_id = Column(Integer, ForeignKey('polls.id'))
|
choice = orm.Integer()
|
||||||
choice = Column(Integer)
|
|
||||||
|
|
||||||
|
class PollModel(orm.Model):
|
||||||
|
__tablename__ = 'polls'
|
||||||
|
__database__ = database
|
||||||
|
__metadata__ = metadata
|
||||||
|
|
||||||
|
id = orm.Integer(primary_key=True)
|
||||||
|
channel_id = orm.String(max_length=18)
|
||||||
|
message_id = orm.String(max_length=18)
|
||||||
|
|
||||||
|
content = orm.JSON()
|
||||||
|
is_anonymous = orm.Boolean()
|
||||||
|
|
||||||
|
available_choices = orm.Integer()
|
||||||
|
choice = orm.ForeignKey(ResponsesModel)
|
||||||
|
|
|
@ -1,19 +1,14 @@
|
||||||
import datetime
|
import orm
|
||||||
|
from . import database, metadata
|
||||||
from . import Base
|
|
||||||
from sqlalchemy import Column, Integer, String, BIGINT, TIMESTAMP
|
|
||||||
|
|
||||||
|
|
||||||
class WarnModel(Base):
|
class WarnModel(orm.Model):
|
||||||
__tablename__ = 'warns'
|
__tablename__ = 'warns'
|
||||||
|
__database__ = database
|
||||||
|
__metadata__ = metadata
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
id = orm.Integer(primary_key=True)
|
||||||
server_id = Column(BIGINT)
|
server_id = orm.String(max_length=18)
|
||||||
user_id = Column(BIGINT)
|
user_id = orm.String(max_length=18)
|
||||||
reason = Column(String)
|
reason = orm.String(max_length=255)
|
||||||
created_at = Column(TIMESTAMP, default=datetime.datetime.now())
|
created_at = orm.DateTime()
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<WarnModel(server_id='%s', user_id='%s', reason='%s', " \
|
|
||||||
"created_at='%s')>" \
|
|
||||||
% (self.server_id, self.user_id, self.reason, self.created_at)
|
|
||||||
|
|
Loading…
Reference in a new issue