async def feature_disable(self, ctx, types:str): types = types.upper() disabled= [] ignored = [] known = [] unknown = [] for t2 in types.split(","): for t in t2.split(): t = t.strip(",").strip() if t != "": if t in Features.requires_logging: known.append(t) else: unknown.append(t) message = "" for t in known: if not Configuration.get_var(ctx.guild.id, t): ignored.append(t) else: disabled.append(t) Configuration.set_var(ctx.guild.id, t, False) if len(disabled) > 0: message += f"{Emoji.get_chat_emoji('YES')} {Translator.translate('features_disabled', ctx)}{', '.join(disabled)}" if len(ignored) > 0: message += f"\n{Emoji.get_chat_emoji('WARNING')}{Translator.translate('feature_already_disabled', ctx)}{', '.join(ignored)}" if len(unknown) > 0: message += f"\n {Emoji.get_chat_emoji('NO')}{Translator.translate('features_unknown', ctx)}{', '.join(unknown)}" await ctx.send(message, embed=self.get_features_status(ctx))
async def feature_disable(self, ctx, types:str): types = types.upper() disabled= [] ignored = [] known = [] unknown = [] for t2 in types.split(","): for t in t2.split(): t = t.strip(",").strip() if t != "": if t in Features.requires_logging: known.append(t) else: unknown.append(t) message = "" for t in known: if not Configuration.get_var(ctx.guild.id, t): ignored.append(t) else: disabled.append(t) Configuration.set_var(ctx.guild.id, t, False) if len(disabled) > 0: message += MessageUtils.assemble(ctx.guild.id, 'YES', 'features_disabled', count=len(disabled)) + ', '.join(disabled) if len(ignored) > 0: message += MessageUtils.assemble(ctx.guild.id, 'WARNING', 'feature_already_disabled', count=len(ignored)) + ', '.join(ignored) if len(unknown) > 0: message += MessageUtils.assemble(ctx.guild.id, 'NO', 'features_unknown', count=len(unknown)) + ', '.join(unknown) await ctx.send(message, embed=self.get_features_status(ctx))
def validate_self_roles(bot, guild): roles = Configuration.get_var(guild.id, "ROLES", "SELF_ROLES") to_remove = {role for role in roles if guild.get_role(role) is None} if len(to_remove) > 0: Configuration.set_var(guild.id, "ROLES", "SELF_ROLES", set(roles) - to_remove) bot.dispatch("self_roles_update", guild.id)
async def enable_feature(self, ctx, types): types = types.upper() enabled = [] ignored = [] known = [] unknown = [] for t2 in types.split(","): for t in t2.split(): t = t.strip(",").strip() if t != "": if t in Features.requires_logging: known.append(t) else: unknown.append(t) message = "" for t in known: if Configuration.get_var(ctx.guild.id, "MESSAGE_LOGS" if t == "EDIT_LOGS" else "CENSORING", "ENABLED"): ignored.append(t) else: enabled.append(t) Configuration.set_var(ctx.guild.id, "MESSAGE_LOGS" if t == "EDIT_LOGS" else "CENSORING", "ENABLED", True) if t == "EDIT_LOGS": await ctx.send(Translator.translate('minor_log_caching_start', ctx)) self.bot.to_cache.append(ctx) if len(enabled) > 0: message += MessageUtils.assemble(ctx.guild.id, 'YES', 'features_enabled', count=len(enabled)) + ', '.join(enabled) if len(ignored) > 0: message += MessageUtils.assemble(ctx.guild.id, 'WARNING', 'feature_already_enabled', count=len(ignored)) + ', '.join(ignored) if len(unknown) > 0: message += MessageUtils.assemble(ctx.guild.id, 'NO', 'logs_unknown', count=len(unknown)) + ', '.join(unknown) await ctx.send(message, embed=self.get_features_status(ctx))
async def enable_feature(self, ctx, types): types = types.upper() enabled = [] ignored = [] known = [] unknown = [] for t2 in types.split(","): for t in t2.split(): t = t.strip(",").strip() if t != "": if t in Features.requires_logging: known.append(t) else: unknown.append(t) message = "" for t in known: if Configuration.get_var(ctx.guild.id, t): ignored.append(t) else: enabled.append(t) Configuration.set_var(ctx.guild.id, t, True) if t == "EDIT_LOGS": await ctx.send(Translator.translate('minor_log_caching_start', ctx)) self.bot.to_cache.append(ctx) if len(enabled) > 0: message += f"{Emoji.get_chat_emoji('YES')} {Translator.translate('features_enabled', ctx)}{', '.join(enabled)}" if len(ignored) > 0: message += f"\n{Emoji.get_chat_emoji('WARNING')}{Translator.translate('feature_already_enabled', ctx)}{', '.join(ignored)}" if len(unknown) > 0: message += f"\n {Emoji.get_chat_emoji('NO')}{Translator.translate('logs_unknown', ctx)}{', '.join(unknown)}" await ctx.send(message, embed=self.get_features_status(ctx))
async def raid_disable(self, ctx): raid_settings = Configuration.get_var(ctx.guild.id, "RAID_HANDLING") if len(raid_settings.get('SHIELDS', [])) == 0: await MessageUtils.send_to(ctx, 'NO', 'raid_shields_not_configured') else: Configuration.set_var(ctx.guild.id, 'RAID_HANDLING', 'ENABLED', False) await MessageUtils.send_to(ctx, 'YES', 'raid_shields_disabled')
async def mute(self, ctx:commands.Context): """Disable the mute feature""" role = ctx.guild.get_role(Configuration.get_var(ctx.guild.id, "MUTE_ROLE")) if role is not None: for member in role.members: await member.remove_roles(role, reason=f"Mute feature has been disabled") Configuration.set_var(ctx.guild.id, "MUTE_ROLE", 0) await ctx.send("Mute feature has been disabled, all people muted have been unmuted and the role can now be removed.")
async def prefix(self, ctx:commands.Context, *, new_prefix:str = None): """Sets or show the server prefix""" if new_prefix is None: await ctx.send(f"{Translator.translate('current_server_prefix', ctx, prefix=Configuration.get_var(ctx.guild.id, 'PREFIX'))}") elif len(new_prefix) > 25: await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('prefix_too_long', ctx)}") else: Configuration.set_var(ctx.guild.id, "PREFIX", new_prefix) await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('prefix_set', ctx, new_prefix=new_prefix)}")
async def language(self, ctx, lang_code:str = None): """language_help""" if lang_code is None: await ctx.send(f"See https://crowdin.com/project/gearbot for all available languages and their translation statuses") else: if lang_code in Translator.LANGS: Configuration.set_var(ctx.guild.id, "LANG", lang_code) await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('lang_changed', ctx.guild.id, lang=lang_code)}") else: await ctx.send(f"{Emoji.get_chat_emoji('MUTE')} {Translator.translate('lang_unknown', ctx.guild.id)}")
async def enable_trusted_bypass(self, ctx: commands.Context, enabled_status: bool): config_status = Configuration.get_var(ctx.guild.id, "CENSORING", "ALLOW_TRUSTED_BYPASS") enabled_string = "enabled" if enabled_status else "disabled" enabled_string = Translator.translate(enabled_string, ctx.guild.id) message = MessageUtils.assemble(ctx, "YES", "censor_trusted_bypass", status=enabled_string) if enabled_status == config_status: message = MessageUtils.assemble(ctx, "NO", f"censor_trusted_bypass_unchanged", status=enabled_string) else: Configuration.set_var(ctx.guild.id, "CENSORING", "ALLOW_TRUSTED_BYPASS", enabled_status) await ctx.send(message)
async def timezone(self, ctx, new_zone=None): """timezone_help""" current_zone = Configuration.get_var(ctx.guild.id, "TIMEZONE") if new_zone is None: #no new zone, spit out the current one await MessageUtils.send_to(ctx, "CLOCK", "current_timezone", timezone=current_zone) else: try: zone = str(pytz.timezone(new_zone)) except UnknownTimeZoneError: await MessageUtils.send_to(ctx, "NO", "invalid_timezone") else: if current_zone == new_zone: await MessageUtils.send_to(ctx, "WHAT", "same_timezone", timezone=current_zone) else: Configuration.set_var(ctx.guild.id, "TIMEZONE", zone) await MessageUtils.send_to(ctx, "YES", "timezone_set", timezone=zone)
async def language(self, ctx, lang_code:str = None): """language_help""" if lang_code is None: await ctx.send(f"See https://crowdin.com/project/gearbot for all available languages and their translation statuses") else: code = None lang_code = lang_code.lower().replace("_", "-") for name, lcode in Translator.LANG_CODES.items(): if lang_code == lcode.lower() or lang_code == name.lower(): code = lcode break if code is None: for name, lcode in Translator.LANG_CODES.items(): if lang_code == lcode.lower()[:2]: code = lcode break if code is not None: Configuration.set_var(ctx.guild.id, "LANG", code) await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('lang_changed', ctx.guild.id, lang=code, lang_name=Translator.LANG_NAMES[code])}") else: await ctx.send(f"{Emoji.get_chat_emoji('MUTE')} {Translator.translate('lang_unknown', ctx.guild.id)}")
async def mute_role(self, ctx:commands.Context, role:discord.Role): """configure_mute_help""" if role == ctx.guild.default_role: return await ctx.send( f"{Emoji.get_chat_emoji('NO')} {Translator.translate(f'default_role_forbidden', ctx)}") guild:discord.Guild = ctx.guild perms = guild.me.guild_permissions if not perms.manage_roles: await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('mute_missing_perm', ctx)}") return if not guild.me.top_role > role: await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('mute_missing_perm', ctx, role=role.mention)}") return Configuration.set_var(ctx.guild.id, "MUTE_ROLE", int(role.id)) await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('mute_role_confirmation', ctx, role=role.mention)}") failed = [] for channel in guild.text_channels: try: await channel.set_permissions(role, reason=Translator.translate('mute_setup', ctx), send_messages=False, add_reactions=False) except discord.Forbidden as ex: failed.append(channel.mention) for channel in guild.voice_channels: try: await channel.set_permissions(role, reason=Translator.translate('mute_setup', ctx), speak=False, connect=False) except discord.Forbidden as ex: failed.append(Translator.translate('voice_channel', ctx, channel=channel.name)) if len(failed) > 0: message = f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('mute_setup_failures', ctx, role=role.mention)}\n" for fail in failed: if len(message) + len(fail) > 2048: await ctx.send(message) message = "" message = message + fail if len(message) > 0: await ctx.send(message) else: await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('mute_setup_complete', ctx)}")
async def on_interaction(self, interaction): guild = self.bot.get_guild(interaction.guild_id) if interaction.type == InteractionType.component: cid = interaction.data.custom_id if cid.startswith('self_role'): parts = cid.split(':') if parts[1] == 'role': rid = parts[2] if rid.isnumeric(): rid = int(rid) roles = Configuration.get_var(interaction.guild_id, "ROLES", "SELF_ROLES") if rid in roles: role = guild.get_role(rid) if role is None: roles.remove(rid) Configuration.set_var(interaction.guild_id, "ROLES", "SELF_ROLES", roles) v = SelfRoleView(guild=guild, page=0) interaction.response.edit_message( content=Translator.translate( "assignable_roles", interaction.guild_id, server_name=guild.name, page_num=1, page_count=v.pages), view=v) interaction.followup.send_message( MessageUtils.assemble( interaction.guild_id, 'WARNING', 'self_role_missing'), ephemeral=True) else: try: if role in interaction.user.roles: await interaction.user.remove_roles( role) await interaction.response.send_message( Translator.translate( "role_left", interaction.guild_id, role_name=role.name, user=interaction.user), ephemeral=True) else: await interaction.user.add_roles(role) await interaction.response.send_message( Translator.translate( "role_joined", interaction.guild_id, role_name=role.name, user=interaction.user), ephemeral=True) except disnake.Forbidden: await interaction.response.send_message( f"{Emoji.get_chat_emoji('NO')} {Translator.translate('role_too_high_add', interaction.guild_id, role=role.name)}", ephemeral=True) elif parts[1] == "page": v = SelfRoleView(guild=interaction.guild, page=int(parts[2])) await interaction.response.edit_message( content=Translator.translate( "assignable_roles", interaction.guild_id, server_name=interaction.guild.name, page_num=int(parts[2]) + 1, page_count=v.pages), view=v) elif cid.startswith('help:'): parts = cid.split(':') if parts[1] == 'page': q = parts[3] if parts[3] != 'None' else None content, view = await Help.message_parts( self.bot, q, guild, interaction.user, int(parts[2])) await interaction.response.edit_message(content=content, view=view) elif parts[1] == 'selector': q = interaction.values[0] q = q if q != 'None' else None content, view = await Help.message_parts( self.bot, q, guild, interaction.user, 0) await interaction.response.edit_message(content=content, view=view) elif cid.startswith('pager:'): parts = cid.split(':') t = parts[2] if t == 'eval': if interaction.user.id not in Configuration.get_master_var( 'BOT_ADMINS'): return output = await self.bot.redis_pool.get(f'eval:{parts[3]}') if output is None: await interaction.response.send_message( "Eval output no longer available", ephemeral=True) else: pages = Pages.paginate(output, prefix='```py\n', suffix='```') content, view, page_num = SimplePager.get_parts( pages, int(parts[1]), interaction.guild_id, f'eval:{parts[3]}') await interaction.response.edit_message( content= f'Eval output {page_num + 1}/{len(pages)}{content}', view=view) elif t == 'commands': cog = self.bot.get_command("CustCommands") if cog is not None: pages = cog.get_command_pages(interaction.guild_id) content, view, page_num = SimplePager.get_parts( pages, int(parts[1]), guild.id, 'commands') page = cog.gen_command_page(pages, page_num, interaction.guild) await interaction.response.edit_message(embed=page, view=view) elif t == 'emoji': cog = self.bot.get_cog('Emoji') if cog is not None: amount = len(guild.emojis) + 1 content, view, page_num = SimplePager.get_parts( range(amount), int(parts[1]), interaction.guild.id, 'emoji') await interaction.response.edit_message( embed=cog.gen_emoji_page(guild, page_num), view=view) elif t == 'role_list': cog = self.bot.get_cog('Moderation') if cog is not None: pages = cog.gen_roles_pages(interaction.guild, parts[3]) content, view, page_num = SimplePager.get_parts( pages, int(parts[1]), guild.id, f'role_list:{parts[3]}') await interaction.response.edit_message( content= f"**{Translator.translate('roles', interaction.guild_id, server_name=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{pages[page_num]}```", view=view) elif t == 'censor_list': cog = self.bot.get_cog('Moderation') if cog is not None: censor_list = Configuration.get_var( interaction.guild.id, "CENSORING", "TOKEN_CENSORLIST") pages = Pages.paginate("\n".join(censor_list)) page, view, page_num = SimplePager.get_parts( pages, int(parts[1]), interaction.guild.id, 'censor_list') await interaction.response.edit_message( content= f"**{Translator.translate(f'censor_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```", view=view) elif t == 'word_censor_list': cog = self.bot.get_cog('Moderation') if cog is not None: censor_list = Configuration.get_var( guild.id, "CENSORING", "WORD_CENSORLIST") pages = Pages.paginate("\n".join(censor_list)) page, view, page_num = SimplePager.get_parts( pages, int(parts[1]), guild.id, 'word_censor_list') await interaction.response.edit_message( content= f"**{Translator.translate(f'word_censor_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```", view=view) elif t == 'full_censor_list': cog = self.bot.get_cog('Moderation') if cog is not None: censor_list = Configuration.get_var( guild.id, "CENSORING", "FULL_MESSAGE_LIST") pages = Pages.paginate("\n".join(censor_list)) page, view, page_num = SimplePager.get_parts( pages, int(parts[1]), guild.id, 'full_censor_list') await interaction.response.edit_message( content= f"**{Translator.translate(f'full_censor_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```", view=view) elif t == 'flag_list': cog = self.bot.get_cog('Moderation') if cog is not None: censor_list = Configuration.get_var( guild.id, "FLAGGING", "TOKEN_LIST") pages = Pages.paginate("\n".join(censor_list)) page, view, page_num = SimplePager.get_parts( pages, int(parts[1]), guild.id, 'flag_list') await interaction.response.edit_message( content= f"**{Translator.translate(f'flagged_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```", view=view) elif t == 'word_flag_list': cog = self.bot.get_cog('Moderation') if cog is not None: censor_list = Configuration.get_var( guild.id, "FLAGGING", "WORD_LIST") pages = Pages.paginate("\n".join(censor_list)) page, view, page_num = SimplePager.get_parts( pages, int(parts[1]), guild.id, 'word_flag_list') await interaction.response.edit_message( content= f"**{Translator.translate(f'flagged_word_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```", view=view) elif t == 'mass_failures': output = await self.bot.redis_pool.get( f'mass_failures:{parts[3]}') if output is None: await interaction.response.send_message( MessageUtils.assemble(interaction.guild_id, 'NO', 'view_expired'), ephemeral=True) else: pages = Pages.paginate(output, prefix='```\n', suffix='```') content, view, page_num = SimplePager.get_parts( pages, int(parts[1]), interaction.guild_id, f'mass_failures:{parts[3]}:{parts[4]}') await interaction.response.edit_message( content= f"**{Translator.translate(f'mass_failures_{parts[4]}', interaction.guild_id, page_num=page_num+1, pages=len(pages))}**{content}", view=view) elif cid.startswith('einf_search:'): parts = cid.split(':') uid = int(parts[1]) old_page = int(parts[2]) t = parts[3] if t == 'first_page': page, current, pages, query, fields = await get_ephemeral_cached_page( interaction, uid, 0) await interaction.response.edit_message( content=await InfractionUtils.assemble_message( interaction.guild_id, page, query, current, pages), view=EphemeralInfSearch(filters=fields, pages=pages, current_page=current, guild_id=interaction.guild_id, userid=uid)) elif t == 'prev_page': page, current, pages, query, fields = await get_ephemeral_cached_page( interaction, uid, old_page - 1) await interaction.response.edit_message( content=await InfractionUtils.assemble_message( interaction.guild_id, page, query, current, pages), view=EphemeralInfSearch(filters=fields, pages=pages, current_page=current, guild_id=interaction.guild_id, userid=uid)) elif t == 'blank': await interaction.response.send_message( Emoji.get_chat_emoji('AE'), ephemeral=True) elif t == 'next_page': page, current, pages, query, fields = await get_ephemeral_cached_page( interaction, uid, old_page + 1) await interaction.response.edit_message( content=await InfractionUtils.assemble_message( interaction.guild_id, page, query, current, pages), view=EphemeralInfSearch(filters=fields, pages=pages, current_page=current, guild_id=interaction.guild_id, userid=uid)) elif t == 'last_page': page, current, pages, query, fields = await get_ephemeral_cached_page( interaction, uid, 1000) await interaction.response.edit_message( content=await InfractionUtils.assemble_message( interaction.guild_id, page, query, current, pages), view=EphemeralInfSearch(filters=fields, pages=pages, current_page=current, guild_id=interaction.guild_id, userid=uid)) elif interaction.type == InteractionType.application_command: if interaction.data.name == "Extract user IDs": self.bot.metrics.uid_usage.labels( type="channel", cluster=self.bot.cluster).inc() await interaction.response.defer(ephemeral=True) parts = await Utils.get_user_ids(interaction.target.content) if len(parts) > 0: for chunk in Pages.paginate("\n".join(parts), 200): await interaction.followup.send(chunk) else: await interaction.followup.send( MessageUtils.assemble(interaction.guild, "NO", "no_uids_found")) elif interaction.data.name == "Send user IDs to DM": self.bot.metrics.uid_usage.labels( type="DM", cluster=self.bot.cluster).inc() await interaction.response.defer(ephemeral=True) parts = await Utils.get_user_ids(interaction.target.content) if len(parts) > 0: try: for chunk in Pages.paginate("\n".join(parts), 200): await interaction.user.send(chunk) except Forbidden: await interaction.followup.send("Unable to send DM") else: await interaction.followup.send("IDs sent in DM") else: try: await interaction.user.send( MessageUtils.assemble(interaction.guild, "NO", "no_uids_found")) except Forbidden: await interaction.followup.send("Unable to send DM") else: await interaction.followup.send("IDs sent in DM") elif interaction.data.name == "Userinfo": if await Permissioncheckers.check_permission( self.bot.get_command("userinfo"), interaction.guild, interaction.user, self.bot): t = "allowed" target = interaction.data.target embed = await Utils.generate_userinfo_embed( target, target if isinstance(target, Member) else None, interaction.guild, interaction.user) await interaction.response.send_message(embed=embed, ephemeral=True) else: t = "denied" await interaction.response.send_message( MessageUtils.assemble(interaction.guild, 'LOCK', 'permission_denied'), ephemeral=True) self.bot.metrics.userinfo_usage.labels( type=t, cluster=self.bot.cluster).inc() elif interaction.data.name == "Search Infractions": if await Permissioncheckers.check_permission( self.bot.get_command("inf search"), interaction.guild, interaction.user, self.bot): uid = interaction.data.target.id t = "allowed" await interaction.response.send_message( MessageUtils.assemble(interaction.guild, 'SEARCH', 'inf_search_compiling'), ephemeral=True) pages = await InfractionUtils.fetch_infraction_pages( interaction.guild.id, uid, 100, ["[user]", "[mod]", "[reason]"], 0) page = await self.bot.wait_for( 'page_assembled', check=lambda l: l['key'] == get_key( interaction.guild.id, uid, [ "[user]", "[mod]", "[reason]" ], 100) and l['page_num'] == 0) await interaction.edit_original_message( content=await InfractionUtils.assemble_message( interaction.guild.id, page['page'], uid, 0, pages), view=EphemeralInfSearch( filters=["[user]", "[mod]", "[reason]"], pages=pages, guild_id=interaction.guild.id, userid=uid)) else: t = "denied" await interaction.response.send_message( MessageUtils.assemble(interaction.guild, 'LOCK', 'permission_denied'), ephemeral=True) self.bot.metrics.inf_search_usage.labels( type=t, cluster=self.bot.cluster).inc()
async def role_list_mode(self, ctx, mode:ListMode): """configure_role_list_mode""" Configuration.set_var(ctx.guild.id, "ROLE_WHITELIST", mode) mode = "whitelist" if mode else "blacklist" await MessageUtils.send_to(ctx, "YES", f"role_list_mode_{mode}")
async def log_embeds(self, ctx, value: bool): Configuration.set_var(ctx.guild.id, "EMBED_EDIT_LOGS", value) await ctx.send( f"{Emoji.get_chat_emoji('YES')} {Translator.translate('embed_log_' + ('enabled' if value else 'disabled'), ctx.guild.id)}")
async def dm_on_warn(self, ctx, value: bool): """dm_on_warn_help""" Configuration.set_var(ctx.guild.id, "DM_ON_WARN", value) await ctx.send( f"{Emoji.get_chat_emoji('YES')} {Translator.translate('dm_on_warn_msg_' + ('enabled' if value else 'disabled'), ctx.guild.id)}")
async def perm_denied_message(self, ctx, value:bool): """perm_denied_message_help""" Configuration.set_var(ctx.guild.id, "PERM_DENIED_MESSAGE", value) await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('configure_perm_msg_' + ('enabled' if value else 'disabled'), ctx.guild.id)}")