diff --git a/.gitignore b/.gitignore index fbaf594e7c01ffb7446825d0dd25ef424d76e76b..a7f0dac4e81c92b41e2dd7ddbf5d69ede899ce8f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ __pycache__/* # Idea files .idea/* +# Secret files +*/tokens.ini */config.py \ No newline at end of file diff --git a/All-In-One-bot/bot.py b/All-In-One-bot/bot.py new file mode 100644 index 0000000000000000000000000000000000000000..f776cea34ce6bf2250ccfde290b0baa6bc49e1e6 --- /dev/null +++ b/All-In-One-bot/bot.py @@ -0,0 +1,149 @@ +# Author: samip5 +# Version: 0.7 + +from discord.ext import commands +import discord +from cogs.utils import checks, context, db +from cogs.utils.config import Config +import datetime, re +import json +import asyncio +import copy +import logging +import traceback +import aiohttp +import sys +from collections import Counter, deque +import configparser as parser +import asyncpg +import config + +def _prefix_callable(bot, msg): + user_id = bot.user.id + base = [f'<@!{user_id}> ', f'<@{user_id}> '] + if msg.guild is None: + base.append('!') + base.append('?') + else: + base.extend(bot.prefixes.get(msg.guild.id, ['?', '!'])) + return base + + + +log = logging.getLogger(__name__) + +initial_extensions = ( + 'cogs.admin', + 'cogs.buttons', + 'cogs.general', + 'cogs.meta', + 'cogs.misc', + 'cogs.mod', + 'cogs.ombi', + 'cogs.plex', + 'cogs.polls', + 'cogs.music' +) + + +class RoboSamip(commands.Bot): + def __init__(self): + super().__init__(command_prefix=_prefix_callable, pm_help=None, help_attrs=dict(hidden=True), + fetch_offline_members=False) + self.session = aiohttp.ClientSession(loop=self.loop) + self.add_command(self.do) + self._prev_events = deque(maxlen=10) + + self.prefixes = Config('prefixes.json') + + for extension in initial_extensions: + try: + self.load_extension(extension) + except Exception as e: + print(f'Failed to load extension {extension}.', file=sys.stderr) + traceback.print_exc() + + async def on_socket_response(self, msg): + self._prev_events.append(msg) + + async def on_command_error(self, ctx, error): + if isinstance(error, commands.NoPrivateMessage): + await ctx.author.send('This command cannot be used in private messages.') + elif isinstance(error, commands.DisabledCommand): + await ctx.author.send('Sorry. This command is disabled and cannot be used.') + elif isinstance(error, commands.CommandInvokeError): + print(f'In {ctx.command.qualified_name}:', file=sys.stderr) + traceback.print_tb(error.original.__traceback__) + print(f'{error.original.__class__.__name__}: {error.original}', file=sys.stderr) + + def get_guild_prefixes(self, guild, *, local_inject=_prefix_callable): + proxy_msg = discord.Object(id=None) + proxy_msg.guild = guild + return local_inject(self, proxy_msg) + + def get_raw_guild_prefixes(self, guild_id): + return self.prefixes.get(guild_id, ['?', '!']) + + async def set_guild_prefixes(self, guild, prefixes): + if len(prefixes) == 0: + await self.prefixes.put(guild.id, []) + elif len(prefixes) > 10: + raise RuntimeError('Cannot have more than 10 custom prefixes.') + else: + await self.prefixes.put(guild.id, sorted(set(prefixes), reverse=True)) + + async def on_ready(self): + if not hasattr(self, 'uptime'): + self.uptime = datetime.datetime.utcnow() + print(f'Ready: {self.user} (ID: {self.user.id})') + + async def on_resumed(self): + print('resumed...') + + async def process_commands(self, message): + ctx = await self.get_context(message, cls=context.Context) + + if ctx.command is None: + return + + async with ctx.acquire(): + await self.invoke(ctx) + + async def on_message(self, message): + if message.author.bot: + return + await self.process_commands(message) + + async def close(self): + await super().close() + await self.session.close() + + def run(self): + try: + super().run(config.token, reconnect=True) + finally: + with open('prev_events.log', 'w', encoding='utf-8') as fp: + for data in self._prev_events: + try: + x = json.dumps(data, ensure_ascii=True, ident=4) + except: + fp.write(f'{data}\n') + else: + fp.write(f'{x}\n') + + @property + def config(self): + return __import__('config') + + @commands.command(hidden=True) + @commands.is_owner() + async def do(self, ctx, times: int, *, command): + """Repeats a command a specified number of times.""" + msg = copy.copy(ctx.message) + msg.content = command + + new_ctx = await self.get_context(msg, cls=context.Context) + new_ctx.db = ctx.db + + for i in range(times): + await new_ctx.reinvoke()