diff --git a/bot.py b/bot.py index e7b3bc0..4efe24d 100755 --- a/bot.py +++ b/bot.py @@ -10,11 +10,11 @@ import discord import git from discord.ext import commands -from utils import Config -from utils import Database -from utils import Texts -from utils import Version -from utils import ContextPlus +from utils.functions import Config +from utils.functions import Database +from utils.functions import Texts +from utils.functions import Version +from utils.functions import ContextPlus description = """ Je suis TuxBot, le bot qui vit de l'OpenSource ! ;) @@ -52,7 +52,7 @@ async def _prefix_callable(bot, message: discord.message) -> list: class TuxBot(commands.AutoShardedBot): - def __init__(self, database): + def __init__(self,): super().__init__(command_prefix=_prefix_callable, pm_help=None, help_command=None, description=description, help_attrs=dict(hidden=True), @@ -63,20 +63,20 @@ class TuxBot(commands.AutoShardedBot): self.socket_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.prefixes = Config('./configs/prefixes.cfg') self.blacklist = Config('./configs/blacklist.cfg') self.fallbacks = Config('./configs/fallbacks.cfg') 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 = Database(self.config) + self.version = Version(*version, pre_release='rc2', build=build) - self.owner: discord.User = discord.User - self.owners: List[discord.User] = [] + self.owner_ids = self.config.get('permissions', 'Owners').split(', ') + self.owner_id = int(self.owner_ids[0]) for extension in l_extensions: try: @@ -93,8 +93,7 @@ class TuxBot(commands.AutoShardedBot): + extension, exc_info=e) async def is_owner(self, user: discord.User) -> bool: - return str(user.id) in self.config.get("permissions", "Owners").split( - ', ') + return str(user.id) in self.owner_ids async def get_context(self, message, *, cls=None): return await super().get_context(message, cls=cls or ContextPlus) @@ -114,6 +113,8 @@ class TuxBot(commands.AutoShardedBot): "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): ctx: commands.Context = await self.get_context(message) @@ -193,13 +194,13 @@ class TuxBot(commands.AutoShardedBot): @contextlib.contextmanager def setup_logging(): + logging.getLogger('discord').setLevel(logging.INFO) + logging.getLogger('discord.http').setLevel(logging.WARNING) + + log = logging.getLogger() + log.setLevel(logging.INFO) + 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', encoding='utf-8', mode='w') fmt = logging.Formatter('[{levelname:<7}] [{asctime}]' @@ -218,14 +219,12 @@ def setup_logging(): if __name__ == "__main__": - log = logging.getLogger() - print(Texts().get('Starting...')) - bot = TuxBot(Database(Config("./configs/config.cfg"))) + app = TuxBot() try: with setup_logging(): - bot.run() + app.run() except KeyboardInterrupt: - bot.close() + app.close() diff --git a/cogs/Admin.py b/cogs/Admin.py index b9dd6a3..80510eb 100644 --- a/cogs/Admin.py +++ b/cogs/Admin.py @@ -9,7 +9,7 @@ from discord.ext import commands from bot import TuxBot from utils import Texts -from utils import WarnModel, LangModel +from utils.models import WarnModel from utils import commandExtra, groupExtra log = logging.getLogger(__name__) diff --git a/cogs/Useful.py b/cogs/Useful.py index 6cdafd3..56506c1 100644 --- a/cogs/Useful.py +++ b/cogs/Useful.py @@ -150,13 +150,6 @@ class Useful(commands.Cog): ########################################################################### - @commands.Cog.listener() - 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): if (addr.startswith('http') or addr.startswith('ftp')) is not True: diff --git a/configs/langs.json b/configs/langs.json new file mode 100644 index 0000000..f7b1b6f --- /dev/null +++ b/configs/langs.json @@ -0,0 +1,5 @@ +{ + "default": "fr", + "available": ["en", "fr"], + "280805240977227776": "fr" +} \ No newline at end of file diff --git a/database.py b/database.py index 57a83e8..49127d5 100644 --- a/database.py +++ b/database.py @@ -1,7 +1,5 @@ -from utils import Config -from utils.models import Base -from utils import Database -from utils.models.lang import LangModel +import sqlalchemy +from utils.models import database, metadata import argparse parser = argparse.ArgumentParser() @@ -9,20 +7,13 @@ parser.add_argument("-m", "--migrate", action="store_true") parser.add_argument("-s", "--seed", action="store_true") args = parser.parse_args() -database = Database(Config("./configs/config.cfg")) - if args.migrate: print("Migrate...") - Base.metadata.create_all(database.engine) + engine = sqlalchemy.create_engine(str(database.url)) + metadata.create_all(engine) print("Done!") if args.seed: print('Seeding...') - default = LangModel(key="default", value="fr") - available = LangModel(key="available", value="fr,en") - - database.session.add(default) - database.session.add(available) - - database.session.commit() + # todo: add seeding print("Done!") diff --git a/requirements.txt b/requirements.txt index 41b86e1..442102d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,8 @@ humanize git+https://github.com/Rapptz/discord.py@master jishaku gitpython -sqlalchemy +orm +asyncpg psycopg2 configparser psutil diff --git a/utils/__init__.py b/utils/__init__.py index a60b691..ff23e97 100755 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -1,5 +1,3 @@ -from .models import * - from utils.functions.config import * from utils.functions.lang import * from utils.functions.version import * diff --git a/utils/functions/__init__.py b/utils/functions/__init__.py index e69de29..171e8cc 100644 --- a/utils/functions/__init__.py +++ b/utils/functions/__init__.py @@ -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 diff --git a/utils/functions/database.py b/utils/functions/database.py index 9a7e7a3..20388f0 100644 --- a/utils/functions/database.py +++ b/utils/functions/database.py @@ -1,7 +1,7 @@ from .config import Config -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker, session +import sqlalchemy +import databases class Database: @@ -10,8 +10,7 @@ class Database: postgresql = 'postgresql://{}:{}@{}/{}'.format( conf_postgresql.get("Username"), conf_postgresql.get("Password"), conf_postgresql.get("Host"), conf_postgresql.get("DBName")) - self.engine = create_engine(postgresql, echo=False) - Session = sessionmaker() - Session.configure(bind=self.engine) - self.session: session = Session() + self.database = databases.Database(postgresql) + self.metadata = sqlalchemy.MetaData() + self.engine = sqlalchemy.create_engine(str(self.database.url)) diff --git a/utils/functions/extra.py b/utils/functions/extra.py index d2779f6..26b7d05 100644 --- a/utils/functions/extra.py +++ b/utils/functions/extra.py @@ -1,5 +1,5 @@ from discord.ext import commands -from utils import Config +from utils.functions import Config class CommandsPlus(commands.Command): diff --git a/utils/functions/lang.py b/utils/functions/lang.py index 4be303b..64f2648 100644 --- a/utils/functions/lang.py +++ b/utils/functions/lang.py @@ -1,8 +1,6 @@ import gettext -from .config import Config -from .database import Database +import json -from utils.models.lang import LangModel from discord.ext import commands @@ -22,17 +20,10 @@ class Texts: @staticmethod def get_locale(ctx): - database = Database(Config("./configs/config.cfg")) + with open('./configs/langs.json') as f: + data = json.load(f) if ctx is not None: - current = database.session\ - .query(LangModel.value)\ - .filter(LangModel.key == str(ctx.guild.id)) - if current.count() > 0: - return current.one()[0] - - default = database.session\ - .query(LangModel.value)\ - .filter(LangModel.key == 'default')\ - .one()[0] - return default + return data.get(str(ctx.guild.id), data['default']) + else: + return data['default'] diff --git a/utils/models/__init__.py b/utils/models/__init__.py index 8407711..e3a855a 100644 --- a/utils/models/__init__.py +++ b/utils/models/__init__.py @@ -1,7 +1,15 @@ -from sqlalchemy.ext.declarative import declarative_base -Base = declarative_base() +import databases +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() -from .lang import LangModel from .warn import WarnModel from .poll import PollModel, ResponsesModel from .alias import AliasesModel diff --git a/utils/models/alias.py b/utils/models/alias.py index 7ab63df..4a1a96c 100644 --- a/utils/models/alias.py +++ b/utils/models/alias.py @@ -1,28 +1,14 @@ -from sqlalchemy import Column, String, BigInteger, Integer - -from . import Base +import orm +from . import database, metadata -class AliasesModel(Base): +class AliasesModel(orm.Model): __tablename__ = 'aliases' + __database__ = database + __metadata__ = metadata - id = Column(Integer, primary_key=True) - user_id = Column(BigInteger) - alias = Column(String) - command = Column(String) - guild = Column(String) - - def __repr__(self): - return "" % ( - self.id, - self.user_id, - self.alias, - self.command, - self.guild - ) + id = orm.Integer(primary_key=True) + user_id = orm.String(max_length=18) + alias = orm.String(max_length=255) + command = orm.String(max_length=255) + guild = orm.String(max_length=255) diff --git a/utils/models/lang.py b/utils/models/lang.py deleted file mode 100644 index 2ceb555..0000000 --- a/utils/models/lang.py +++ /dev/null @@ -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 "" % (self.key, self.value) diff --git a/utils/models/poll.py b/utils/models/poll.py index 2d3d69e..a2f793e 100644 --- a/utils/models/poll.py +++ b/utils/models/poll.py @@ -1,27 +1,29 @@ -from . import Base -from sqlalchemy import Column, Integer, BigInteger, JSON, ForeignKey, Boolean -from sqlalchemy.orm import relationship +import orm +from . import database, metadata -class PollModel(Base): - __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): +class ResponsesModel(orm.Model): __tablename__ = 'responses' + __database__ = database + __metadata__ = metadata - id = Column(Integer, primary_key=True, autoincrement=True) - user = Column(BigInteger) + id = orm.Integer(primary_key=True) + user = orm.String(max_length=18) - poll_id = Column(Integer, ForeignKey('polls.id')) - choice = Column(Integer) + choice = orm.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) diff --git a/utils/models/warn.py b/utils/models/warn.py index b9d4674..77f8833 100644 --- a/utils/models/warn.py +++ b/utils/models/warn.py @@ -1,19 +1,14 @@ -import datetime - -from . import Base -from sqlalchemy import Column, Integer, String, BIGINT, TIMESTAMP +import orm +from . import database, metadata -class WarnModel(Base): +class WarnModel(orm.Model): __tablename__ = 'warns' + __database__ = database + __metadata__ = metadata - id = Column(Integer, primary_key=True) - server_id = Column(BIGINT) - user_id = Column(BIGINT) - reason = Column(String) - created_at = Column(TIMESTAMP, default=datetime.datetime.now()) - - def __repr__(self): - return "" \ - % (self.server_id, self.user_id, self.reason, self.created_at) + id = orm.Integer(primary_key=True) + server_id = orm.String(max_length=18) + user_id = orm.String(max_length=18) + reason = orm.String(max_length=255) + created_at = orm.DateTime()