def __init__(self, bot) -> None: super().__init__(bot) self.running = True self.handling = {} self.bot.loop.create_task(self.delivery_service()) Pages.register("reminder_list", self.list_init, self.list_update)
def __init__(self, bot): super().__init__(bot) Pages.register("help", self.init_help, self.update_help) self.running = True self.bot.loop.create_task(self.taco_eater()) self.bot.loop.create_task(self.selfrole_updater())
def __init__(self, bot): self.bot: commands.Bot = bot self.cf_cache = dict() self.fetching = [] self.running = True self.bot.loop.create_task(expire_cache(self)) Pages.register("cf", self.init_cf, self.update_cf)
def __init__(self, bot): super().__init__(bot) self.commands = dict() self.bot.loop.create_task(self.reloadCommands()) self.loaded = False Pages.register("custom_command_list", self.command_list_init, self.command_list_update)
def __init__(self, bot): self.bot: commands.Bot = bot self.running = True self.handling = set() self.bot.loop.create_task(self.timed_actions()) Pages.register("roles", self.roles_init, self.roles_update) Pages.register("mass_failures", self._mass_failures_init, self._mass_failures_update)
async def initialize(bot): #lock event handling while we get ready bot.locked = True try: #database GearbotLogging.info("Connecting to the database.") DatabaseConnector.init() bot.database_connection = DatabaseConnector.connection GearbotLogging.info("Database connection established.") GearbotLogging.initialize_pump(bot) Emoji.initialize(bot) Pages.initialize(bot) Utils.initialize(bot) Translator.initialize(bot) InfractionUtils.initialize(bot) bot.data = { "forced_exits": set(), "unbans": set(), "message_deletes": set() } await GearbotLogging.initialize( bot, Configuration.get_master_var("BOT_LOG_CHANNEL")) if bot.redis_pool is None or not hasattr( bot, 'redis_raid_pool') or bot.redis_raid_pool is None: try: bot.redis_pool = await aioredis.create_redis_pool( (Configuration.get_master_var('REDIS_HOST', "localhost"), Configuration.get_master_var('REDIS_PORT', 6379)), encoding="utf-8", db=0) bot.redis_raid_pool = await aioredis.create_redis_pool( (Configuration.get_master_var('REDIS_HOST', "localhost"), Configuration.get_master_var('REDIS_PORT', 6379)), encoding="utf-8", db=1) except OSError: GearbotLogging.error( "==============Failed to connect to redis==============") await GearbotLogging.bot_log( f"{Emoji.get_chat_emoji('NO')} Failed to connect to redis, caching and anti-raid connections unavailable" ) else: GearbotLogging.info("Redis connection established") await GearbotLogging.bot_log( f"{Emoji.get_chat_emoji('YES')} Redis connection established, caching and anti-raid connections established" ) if bot.aiosession is None: bot.aiosession = aiohttp.ClientSession() bot.being_cleaned.clear() await Configuration.initialize(bot) except Exception as ex: #make sure we always unlock, even when something went wrong! bot.locked = False raise ex bot.locked = False
def __init__(self, bot): super().__init__(bot, { "min": 0, "max": 6, "required": 0, "commands": {} }) Pages.register("help", self.init_help, self.update_help) self.running = True self.bot.loop.create_task(self.taco_eater()) self.bot.loop.create_task(self.selfrole_updater())
def gen_roles_pages(guild: discord.Guild, mode): role_list = dict() longest_name = 1 for role in guild.roles: role_list[f"{role.name} - {role.id}"] = role longest_name = max(longest_name, len(role.name)) if mode == "alphabetic": return Pages.paginate("\n".join( f"{role_list[r].name} {' ' * (longest_name - len(role_list[r].name))} - {role_list[r].id}" for r in sorted(role_list.keys()))) else: return Pages.paginate("\n".join( f"{role_list[r].name} {' ' * (longest_name - len(role_list[r].name))} - {role_list[r].id}" for r in reversed(list(role_list.keys()))))
async def yes(interaction: Interaction): await interaction.response.edit_message( content=MessageUtils.assemble(ctx, "REFRESH", "processing"), view=None) failures = await Actions.mass_action(ctx, "warning", targets, self._warn, max_targets=10, allow_bots=False, message=False, reason=reason, dm_action=True) await interaction.edit_original_message( content=MessageUtils.assemble(ctx, "YES", "mwarn_confirmation", count=len(targets) - len(failures))) if len(failures) > 0: f = "\n".join(failures) pipe = self.bot.redis_pool.pipeline() k = f'mass_failures:{ctx.message.id}' pipe.set(k, f) pipe.expire(k, 7 * 24 * 60 * 60) await pipe.execute() pages = Pages.paginate(f, prefix='```\n', suffix='```') content, view, _ = SimplePager.get_parts( pages, 0, ctx.guild.id, f'mass_failures:{ctx.message.id}:warn') await ctx.send( f"**{Translator.translate('mass_failures_warn', ctx, page_num=1, pages=len(pages))}**{content}", view=view)
async def gen_command_help(bot, ctx, command): if ctx is None: return [] if ctx.prefix is None: ctx.prefix = "" bot.help_command.context = ctx usage = ctx.bot.help_command.get_command_signature(command) sub_info = None if isinstance(command, GroupMixin) and hasattr(command, "all_commands"): subcommands, longest = await gen_commands_list( bot, ctx, command.all_commands.values()) if subcommands is not None: sub_info = "\nSub commands:\n" for command_name, info in subcommands.items(): sub_info += " " + command_name + ( " " * (longest - len(command_name) + 4)) + info + "\n" sub_info += Translator.translate( 'help_footer', ctx, prefix=ctx.prefix, signature=ctx.bot.help_command.get_command_signature( command).replace(ctx.prefix, "")) return Pages.paginate( f"{usage}\n\n{Translator.translate(command.help, ctx)}\n{'' if sub_info is None else sub_info}" .replace(ctx.me.mention, f"@{ctx.me.name}"))
async def get_infraction_pages(guild_id, query): if f"{guild_id}_{query}" not in cache.keys(): infs = Infraction.select().where((Infraction.guild_id == guild_id) & ( (Infraction.user_id == query) | (Infraction.mod_id == query))).order_by(Infraction.id.desc()) out = "" longest_user = 0 longest_mod = 9 longest_type = 4 longest_id = len(str(infs[0].id)) if len(infs) > 0 else 2 for inf in infs: user = await Utils.username(inf.user_id) longest_user = max(longest_user, len(user)) mod = await Utils.username(inf.mod_id) longest_mod = max(longest_mod, len(mod)) longest_type = max(longest_type, len(inf.type)) for inf in infs: user = await Utils.username(inf.user_id) mod = await Utils.username(inf.mod_id) out += f"{Utils.pad(str(inf.id), longest_id)} | {Utils.pad(user, longest_user)} | {Utils.pad(mod, longest_mod)} | {inf.timestamp} | {Utils.pad(inf.type, longest_type)} | {inf.reason}\n" prefix = f"{Utils.pad('id', longest_id)} | {Utils.pad('user', longest_user)} | {Utils.pad('moderator', longest_mod)} | timestamp | {Utils.pad('type', longest_type)} | reason" prefix = f"```\n{prefix}\n{'-' * len(prefix)}\n" pages = Pages.paginate(out, prefix=prefix, suffix="```") cache[f"{guild_id}_{query}"] = pages if len(cache.keys()) > 20: del cache[list(cache.keys())[0]] return cache[f"{guild_id}_{query}"]
async def yes(): pmessage = await GearbotLogging.send_to(ctx, "REFRESH", "processing") valid = 0 failures = [] for t in targets: try: member = await MemberConverter().convert(ctx, str(t)) except BadArgument: try: user = await DiscordUser().convert(ctx, str(t)) except BadArgument as bad: failures.append(f"{t}: {bad}") else: await self._ban(ctx, user, reason, False) valid += 1 else: allowed, message = self._can_act("ban", ctx, member) if allowed: await self._ban(ctx, member, reason, False) valid += 1 else: failures.append(f"{t}: {message}") await pmessage.delete() await GearbotLogging.send_to(ctx, "YES", "mban_confirmation", count=valid) if len(failures) > 0: await Pages.create_new("mass_failures", ctx, action="ban", failures=Pages.paginate( "\n".join(failures)))
async def gen_command_help(bot, member, guild, command): signature = "" parent = command.parent while parent is not None: if not parent.signature or parent.invoke_without_command: signature = f"{parent.name} {signature}" else: signature = f"{parent.name} {parent.signature} {signature}" parent = parent.parent if len(command.aliases) > 0: aliases = '|'.join(command.aliases) signature = f"{signature} [{command.name}|{aliases}]" else: signature = f"{signature} {command.name}" prefix = Configuration.get_var(guild.id, "GENERAL", "PREFIX") if guild is not None else "!" usage = f"{prefix}{signature}" sub_info = None if isinstance(command, GroupMixin) and hasattr(command, "all_commands"): subcommands, longest = await gen_commands_list( bot, member, guild, command.all_commands.values()) if subcommands is not None: sub_info = "\nSub commands:\n" for command_name, info in subcommands.items(): sub_info += " " + command_name + ( " " * (longest - len(command_name) + 4)) + info + "\n" sub_info += Translator.translate('help_footer', guild, prefix=prefix, signature=signature) return Pages.paginate( f"{usage}\n\n{Translator.translate(command.help, guild)}\n{'' if sub_info is None else sub_info}" .replace(bot.user.mention, f"@{bot.user.name}"))
async def mutuals(self, ctx, user:UserID): mutuals = [] for guild in self.bot.guilds: if guild.get_member(user) is not None: mutuals.append(guild) for page in Pages.paginate("\n".join(f"{guild.id} - {guild.name}" for guild in mutuals), prefix="```py\n", suffix="```"): await ctx.send(page)
async def gen_cf_pages(self, ctx, project_name, log): info = await self.get_info(ctx, project_name, log) if info is None: return None else: latest_mc = list(info["versions"].values())[0] latest_v = list(latest_mc.values())[0] latest = Translator.translate('cf_latest', ctx, name=latest_v['name'], version=latest_v['version'], downloads='{:,}'.format( latest_v['downloads'])) fields = { Translator.translate('cf_project_name', ctx): info["title"], Translator.translate('downloads', ctx): "{:,}".format(info["downloads"]), Translator.translate('latest', ctx): latest, Translator.translate('project_categories', ctx): "\n".join(info["categories"]), Translator.translate('links', ctx): "\n".join(f"[{k}]({v})" for k, v in info["links"].items()) } return Pages.paginate_fields([fields])
async def update_eval(self, ctx, message, page_num, action, data): if action == "REFRESH" and ctx is not None: await ctx.invoke(self.eval, code=data.get("code")) pages = data["pages"].split("----NEW PAGE----") page, page_num = Pages.basic_pages(pages, page_num, action) data["page"] = page_num return f"**Eval output {page_num + 1}/{len(pages)}**\n```py\n{page}```", None, data
async def post_info(self, ctx, name): with open(f"{name}.txt", "r") as file: pages = Pages.paginate("".join(file.readlines()), 500, 2000) await ctx.channel.purge(limit=len(pages) + 2) await ctx.send(file=disnake.File(f"{name}.png")) for page in pages: await ctx.send(page)
async def roles_update(self, ctx, message, page_num, action, data): pages = self.gen_roles_pages(message.guild) page, page_num = Pages.basic_pages(pages, page_num, action) embed = discord.Embed(title=Translator.translate('roles', message.guild.id, server_name=ctx.guild.name), color=0x54d5ff) embed.add_field(name="\u200b", value=page["roles"], inline=True) embed.add_field(name="\u200b", value=page["ids"], inline=True) return None, embed, page_num
async def yes(): pmessage = await MessageUtils.send_to(ctx, "REFRESH", "processing") failures = await Actions.mass_action(ctx, "warning", targets, self._warn, max_targets=10, allow_bots=False, message=False, reason=reason, dm_action=True) await pmessage.delete() await MessageUtils.send_to(ctx, "YES", "mwarn_confirmation", count=len(targets) - len(failures)) if len(failures) > 0: await Pages.create_new(self.bot, "mass_failures", ctx, action="warn", failures="----NEW PAGE----".join( Pages.paginate( "\n".join(failures))))
async def uid(self, ctx, *, text: str): """uid_help""" parts = await Utils.get_user_ids(text) if len(parts) > 0: for chunk in Pages.paginate("\n".join(parts), 200): await ctx.send(chunk) else: await MessageUtils.send_to(ctx, "NO", "no_uids_found")
async def update_cf(self, ctx, message, page_num, action, data): pages = await self.gen_cf_pages(ctx, data["project_name"], False) if pages is None: return Translator.translate('cf_not_found', ctx), None, False embed = disnake.Embed(title=Translator.translate('cf_info_title', ctx, project_name=data['project_name'])) page, page_num = Pages.basic_pages(pages, page_num, action) for k, v in page.items(): embed.add_field(name=k, value=v) return None, embed, page_num
def gen_roles_pages(guild: discord.Guild): role_list = dict() longest_name = 1 for role in guild.roles: role_list[f"{role.name} - {role.id}"] = role longest_name = max(longest_name, len(role.name)) return Pages.paginate("\n".join( f"{role_list[r].name} {' ' * (longest_name - len(role_list[r].name))} - {role_list[r].id}" for r in sorted(role_list.keys())))
def __init__(self, bot): super().__init__(bot, { "min": 3, "max": 5, "required": 3, "commands": { "configure": { "min": 3, "max": 5, "required": 3, "commands": { "lvl4": {"required": 5, "min": 4, "max": 6} } } } }) bot.to_cache = [] Pages.register("blacklist", self._blacklist_init, self._blacklist_update)
def __init__(self, bot): super().__init__(bot) async def noop(): pass async def migrate_emoji(ctx, message, page_num, action, data): amount = len(ctx.guild.emojis) + 1 content, view, _ = SimplePager.get_parts(range(amount), 0, ctx.guild.id, 'emoji') await message.edit(embed=self.gen_emoji_page(ctx.guild, 0), view=view) try: await message.clear_reactions() except Exception: pass Pages.register("emoji", noop, migrate_emoji)
async def gen_cog_help(bot, cog, member, guild): commands, longest = await cog_commands(bot, cog, member, guild) output = f'- {cog}\n' if commands is not None: for command_name, info in commands.items(): output += command_name + ( " " * (longest - len(command_name) + 4)) + info + "\n" return Pages.paginate(output) else: return None
def gen_role_pages(self, guild: discord.Guild): roles = Configuration.get_var(guild.id, "SELF_ROLES") current_roles = "" count = 1 for role in roles: current_roles += f"{count}) <@&{role}>\n\n" count += 1 if count > 10: count = 1 return Pages.paginate(current_roles, max_lines=20)
async def update_infs(self, ctx, message, page_num, action, data): pages = await InfractionUtils.get_infraction_pages( data["guild_id"], data["query"], data["amount"] if "amount" in data else 25) page, page_num = Pages.basic_pages(pages, page_num, action) name = await Utils.username( data['query'] ) if data['query'] is not None else self.bot.get_guild( data["guild_id"]).name return f"{Translator.translate('inf_search_header', ctx.guild.id, name=name, page_num=page_num + 1, pages=len(pages))}{page}", None, page_num
async def fetch_infraction_pages(guild_id, query, amount, fields, requested): key = get_key(guild_id, query, fields, amount) if query == "": infs = await Infraction.filter(guild_id=guild_id ).order_by("-id").limit(50) else: subfilters = [] if "[user]" in fields and isinstance(query, int): subfilters.append(Q(user_id=query)) if "[mod]" in fields and isinstance(query, int): subfilters.append(Q(mod_id=query)) if "[reason]" in fields: subfilters.append(Q(reason__icontains=str(query))) infs = await Infraction.filter( Q(Q(*subfilters, join_type="OR"), guild_id=guild_id, join_type="AND")).order_by("-id").limit(int(amount)) longest_type = 4 longest_id = len(str(infs[0].id)) if len(infs) > 0 else len( Translator.translate('id', guild_id)) longest_timestamp = max(len(Translator.translate('timestamp', guild_id)), 19) types = dict() for inf in infs: t = inf.type.lower() longest_type = max(longest_type, len(Translator.translate(t, guild_id))) if t not in types: types[t] = 1 else: types[t] += 1 header = ", ".join( Translator.translate(f"{k}s", guild_id, count=v) for k, v in types.items()) name = await Utils.username(query) if isinstance( query, int) else await Utils.clean(bot.get_guild(guild_id).name) title = f"{Emoji.get_chat_emoji('SEARCH')} {Translator.translate('inf_search_header', guild_id, name=name, page_num=100, pages=100)}\n```md\n\n```" page_header = get_header(longest_id, 37, longest_type, longest_timestamp, guild_id) mcount = 2000 - len(header) - len(page_header) - len(title) out = "\n".join( f"{Utils.pad(str(inf.id), longest_id)} | <@{Utils.pad(str(inf.user_id), 37)}> | <@{Utils.pad(str(inf.mod_id), 37)}> | {datetime.fromtimestamp(inf.start)} | {Utils.pad(Translator.translate(inf.type.lower(), guild_id), longest_type)} | {Utils.trim_message(inf.reason, 1000)}" for inf in infs) pages = Pages.paginate(out, max_chars=mcount) if bot.redis_pool is not None: GearbotLogging.debug(f"Pushing placeholders for {key}") pipe = bot.redis_pool.pipeline() for page in pages: pipe.lpush(key, "---NO PAGE YET---") await pipe.execute() bot.loop.create_task( update_pages(guild_id, query, fields, amount, pages, requested, longest_id, longest_type, longest_timestamp, header)) return len(pages)
async def update_role(self, ctx, message, page_num, action, data): pages = self.gen_role_pages(message.guild) page, page_num = Pages.basic_pages(pages, page_num, action) embed = discord.Embed(title=Translator.translate( "assignable_roles", ctx, server_name=message.channel.guild.name, page_num=page_num + 1, page_count=len(pages)), color=0x54d5ff, description=page) return None, embed, page_num
def __init__(self, bot): super().__init__( bot, { "min": 2, "max": 6, "required": 3, "commands": { "emoji": { "min": 2, "max": 6, "required": 3, "commands": { "list": { "min": 0, "max": 6, "required": 3 } } } } }) Pages.register("emoji", self.emoji_list_init, self.emoji_list_update)