async def on_guild_role_update(self, before: discord.Role, after): if not Features.is_logged(before.guild.id, "ROLE_CHANGES"): return await self.handle_simple_changes( before, after, "role_update_simple", "ROLE_CHANGES", AuditLogAction.role_update, ["name", "color", "hoist", "mentionable"]) if before.permissions != after.permissions: for perm, value in before.permissions: av = getattr(after.permissions, perm) if av != value: entry = await self.find_log( before.guild, AuditLogAction.role_update, lambda e: e.target.id == after.id and hasattr( e.before, "permissions" ) and e.before.permissions == before.permissions and e. after.permissions == after.permissions) key = f"role_update_perm_{'added' if av else 'revoked'}" parts = dict(role=await Utils.clean(after.name), role_id=after.id, perm=perm) if entry is not None: key += "_by" parts.update(person=Utils.clean_user(entry.user), person_id=entry.user.id) logging = Translator.assemble("ALTER", key, before.guild.id, **parts) GearbotLogging.log_to(after.guild.id, "ROLE_CHANGES", logging)
async def _kick(self, ctx, user, reason, confirm): self.bot.data["forced_exits"].add(f"{ctx.guild.id}-{user.id}") await ctx.guild.kick( user, reason=Utils.trim_message( f"Moderator: {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id}) Reason: {reason}", 500)) translated = Translator.translate('kick_log', ctx.guild.id, user=Utils.clean_user(user), user_id=user.id, moderator=Utils.clean_user( ctx.author), moderator_id=ctx.author.id, reason=reason) GearbotLogging.log_to(ctx.guild.id, "MOD_ACTIONS", f":boot: {translated}") InfractionUtils.add_infraction(ctx.guild.id, user.id, ctx.author.id, Translator.translate( 'kick', ctx.guild.id), reason, active=False) if confirm: await GearbotLogging.send_to(ctx, "YES", "kick_confirmation", ctx.guild.id, user=Utils.clean_user(user), user_id=user.id, reason=reason)
async def shield_terminated(self, bot, guild, raid_id, raider_ids, shield): GearbotLogging.log_to(guild.id, "raid_shield_terminated", raid_id=raid_id, name=self.shield_name) await self.handle_actions(self.termination_actions, bot, guild, raid_id, raider_ids, shield)
async def on_member_join(self, member: discord.Member): now = datetime.datetime.fromtimestamp(time.time()) if Infraction.get_or_none(Infraction.type == "Mute", Infraction.active == True, Infraction.end >= now, Infraction.guild_id == member.guild.id, Infraction.user_id == member.id): roleid = Configuration.get_var(member.guild.id, "MUTE_ROLE") if roleid is not 0: role = member.guild.get_role(roleid) if role is not None: if member.guild.me.guild_permissions.manage_roles: await member.add_roles(role, reason=Translator.translate( 'mute_reapply_reason', member.guild.id)) GearbotLogging.log_to( member.guild.id, "MOD_ACTIONS", f"{Emoji.get_chat_emoji('MUTE')} {Translator.translate('mute_reapply_log', member.guild.id, user=Utils.clean_user(member), user_id=member.id)}" ) else: GearbotLogging.log_to( member.guild.id, "MOD_ACTIONS", Translator.translate('mute_reapply_failed_log', member.build.id))
async def on_member_remove(self, member: discord.Member): if member.id == self.bot.user.id: return exits = self.bot.data["forced_exits"] fid = f"{member.guild.id}-{member.id}" if fid in exits: exits.remove(fid) return if member.guild.me.guild_permissions.view_audit_log and Features.is_logged(member.guild.id, "MOD_ACTIONS"): try: async for entry in member.guild.audit_logs(action=AuditLogAction.kick, limit=25): if member.joined_at is None or member.joined_at > entry.created_at or entry.created_at < datetime.datetime.utcfromtimestamp( time.time() - 30): break if entry.target == member: if entry.reason is None: reason = Translator.translate("no_reason", member.guild.id) else: reason = entry.reason InfractionUtils.add_infraction(member.guild.id, entry.target.id, entry.user.id, "Kick", reason, active=False) GearbotLogging.log_to(member.guild.id, "MOD_ACTIONS", f":boot: {Translator.translate('kick_log', member.guild.id, user=Utils.clean_user(member), user_id=member.id, moderator=Utils.clean_user(entry.user), moderator_id=entry.user.id, reason=reason)}") return except discord.Forbidden: permissions = member.guild.me.guild_permissions perm_info = ", ".join(f"{name}: {value}" for name, value in permissions) await GearbotLogging.bot_log( f"{Emoji.get_chat_emoji('WARNING')} Tried to fetch audit log for {member.guild.name} ({member.guild.id}) but got denied even though it said i have access, guild permissions: ```{perm_info}```") if Features.is_logged(member.guild.id, "JOIN_LOGS"): GearbotLogging.log_to(member.guild.id, "JOIN_LOGS", f"{Emoji.get_chat_emoji ('LEAVE')} {Translator.translate('leave_logging', member.guild.id, user=Utils.clean_user(member), user_id=member.id)}")
async def handle_simple_changes(self, before, after, base_key, log_key, action, attributes): for attr in attributes: if hasattr(before, attr): ba = getattr(before, attr) aa = getattr(after, attr) key = base_key if ba != aa: entry = await self.find_log( before.guild, action, lambda e: e.target.id == before.id and hasattr( e.changes.before, attr) and getattr( e.changes.before, attr) == ba and getattr( e.changes.after, attr) == aa) parts = dict(before=self.prep_attr(ba), after=self.prep_attr(aa), thing=after, thing_id=after.id, attr=attr) if entry is not None: parts.update(person=entry.user, person_id=entry.user.id) key += "_by" logging = Translator.assemble("ALTER", key, before.guild, **parts) GearbotLogging.log_to(before.guild.id, log_key, logging)
async def yes(): infraction.delete_instance() await MessageUtils.send_to(ctx, "YES", "inf_delete_deleted", id=infraction.id) GearbotLogging.log_to(ctx.guild.id, 'inf_delete_log', id=infraction.id, target=Utils.clean_user(target), target_id=target.id, mod=Utils.clean_user(mod), mod_id=mod.id, reason=reason, user=Utils.clean_user(ctx.author), user_id=ctx.author.id) await InfractionUtils.clear_cache(ctx.guild.id)
async def on_member_ban(self, guild, user): if user.id == self.bot.user.id or not Features.is_logged(guild.id, "MOD_ACTIONS"): return fid = f"{guild.id}-{user.id}" if fid in self.bot.data["forced_exits"]: return if guild.me.guild_permissions.view_audit_log: async for entry in guild.audit_logs(action=AuditLogAction.ban, limit=25): if entry.target == user and entry.created_at > datetime.datetime.utcfromtimestamp(time.time() - 30): if entry.reason is None: reason = Translator.translate("no_reason", guild.id) else: reason = entry.reason Infraction.update(active=False).where((Infraction.user_id == user.id) & (Infraction.type == "Unban") & (Infraction.guild_id == guild.id)).execute() InfractionUtils.add_infraction(guild.id, entry.target.id, entry.user.id, "Ban", "No reason given." if entry.reason is None else entry.reason) GearbotLogging.log_to(guild.id, "MOD_ACTIONS", f":door: {Translator.translate('ban_log', guild.id, user=Utils.clean_user(user), user_id=user.id, moderator=Utils.clean_user(entry.user), moderator_id=entry.user.id, reason=reason)}") return GearbotLogging.log_to(guild.id, "MOD_ACTIONS", f":door: {Translator.translate('manual_ban_log', guild.id, user=Utils.clean_user(user), user_id=user.id)}") Infraction.update(active=False).where((Infraction.user_id == user.id) & (Infraction.type == "Unban") & (Infraction.guild_id == guild.id)).execute() self.bot.data["forced_exits"].add(fid)
async def handle_simple_changes(self, before, after, base_key, action, attributes): for attr in attributes: if hasattr(before, attr): ba = getattr(before, attr) if isinstance(ba, str) and ba.strip() == "": ba = None aa = getattr(after, attr) if isinstance(aa, str) and aa.strip() == "": aa = None key = base_key if ba != aa: entry = await self.find_log( before.guild, action, lambda e: e.target.id == before.id and hasattr( e.changes.before, attr) and getattr( e.changes.before, attr) == ba and getattr( e.changes.after, attr) == aa) parts = dict(before=self.prep_attr(ba), after=self.prep_attr(aa), thing=after, thing_id=after.id, attr=attr) if entry is not None: parts.update(person=entry.user, person_id=entry.user.id) key += "_by" GearbotLogging.log_to(before.guild.id, key, **parts)
async def raid_detected(self, bot, guild, raid_id, raider_ids, shield): GearbotLogging.log_to(guild.id, "raid_shield_triggered", raid_id=raid_id, name=self.shield_name) await self.handle_actions(self.start_actions, bot, guild, raid_id, raider_ids, shield)
async def execute(self, bot, member, data, raid_id, raider_ids, shield): bot.data["forced_exits"].add(f"{member.guild.id}-{member.id}") reason = f"Raider banned by raid shield {shield['name']} in raid {raid_id}" try: await member.ban( reason=reason, delete_message_days=1 if data["clean_messages"] else 0) except Forbidden: log(member.guild.id, 'raid_ban_forbidden', shield, user_name=Utils.escape_markdown(member), user_id=member.id) except Exception as ex: log(member.guild.id, 'raid_ban_unknown_error', shield, user_name=Utils.escape_markdown(member), user_id=member.id) await TheRealGearBot.handle_exception('RAID BAN FAILURE', bot, ex) finally: i = InfractionUtils.add_infraction(member.guild.id, member.id, bot.user.id, "Ban", reason) GearbotLogging.log_to(member.guild.id, 'ban_log', user=Utils.clean_user(member), user_id=member.id, moderator=Utils.clean_user(bot.user), moderator_id=bot.user.id, reason=reason, inf=i.id)
async def on_voice_state_update(self, member, before, after): if Features.is_logged(member.guild.id, "VOICE_CHANGES_DETAILED"): simple = ["deaf", "mute", "self_mute", "self_deaf", "afk"] for s in simple: old = getattr(before, s) new = getattr(after, s) if old != new: key = f"voice_change_{s}_{str(new).lower()}" logging = Translator.assemble("VOICE", key, member.guild.id, user=Utils.clean_user(member), user_id=member.id) GearbotLogging.log_to(member.guild.id, "VOICE_CHANGES_DETAILED", logging) if Features.is_logged(member.guild.id, "VOICE_CHANGES"): if before.channel != after.channel: parts = dict(user=Utils.clean_user(member), user_id=member.id) if before.channel is None: key = "connected_to_voice" parts.update(channel_name=after.channel, channel_id=after.channel.id) elif after.channel is None: key = "disconnected_voice" parts.update(channel_name=before.channel, channel_id=before.channel.id) else: key = "moved_voice" parts.update(old_channel_name=before.channel, old_channel_id=before.channel.id, new_channel_name=after.channel, new_channel_id=after.channel.id) logging = Translator.assemble("VOICE", key, member.guild.id, **parts) GearbotLogging.log_to(member.guild.id, "VOICE_CHANGES", logging)
async def warn(self, ctx:commands.Context, member:discord.Member, *, reason:Reason): """warn_help""" if ctx.author != member and (ctx.author.top_role > member.top_role or ctx.guild.owner == ctx.author): if member.id == self.bot.user.id: async def yes(): channel = self.bot.get_channel(Configuration.get_master_var("inbox", 0)) if channel is not None: await channel.send(f"[`{ctx.message.created_at.strftime('%c')}`] {ctx.message.author} (`{ctx.message.author.id}`) submitted feedback: {reason}") await MessageUtils.send_to(ctx, 'YES', 'feedback_submitted') message = MessageUtils.assemble(ctx, "THINK", "warn_to_feedback") await Confirmation.confirm(ctx, message, on_yes=yes) else: InfractionUtils.add_infraction(ctx.guild.id, member.id, ctx.author.id, "Warn", reason) name = Utils.clean_user(member) await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('warning_added', ctx.guild.id, user=name)}") aname = Utils.clean_user(ctx.author) GearbotLogging.log_to(ctx.guild.id, "MOD_ACTIONS", f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('warning_added_modlog', ctx.guild.id, user=name, moderator=aname, reason=reason)}") if Configuration.get_var(ctx.guild.id, "DM_ON_WARN"): try: dm_channel = await member.create_dm() await dm_channel.send(f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('warning_dm', ctx.guild.id, server=ctx.guild.name)}```{reason}```") except discord.Forbidden: GearbotLogging.log_to(ctx.guild.id, "MOD_ACTIONS", f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('warning_could_not_dm', ctx.guild.id, user=name, userid=member.id)}") else: await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('warning_not_allowed', ctx.guild.id, user=member)}")
async def unmute(self, ctx: commands.Context, target: discord.Member, *, reason: Reason = ""): """unmute_help""" if reason == "": reason = Translator.translate("no_reason", ctx.guild.id) roleid = Configuration.get_var(ctx.guild.id, "MUTE_ROLE") if roleid is 0: await ctx.send( f"{Emoji.get_chat_emoji('NO')} The mute feature has been disabled on this server, as such i cannot unmute that person" ) else: role = ctx.guild.get_role(roleid) if role is None: await ctx.send( f"{Emoji.get_chat_emoji('NO')} Unable to comply, the role i've been told to use for muting no longer exists" ) else: await target.remove_roles( role, reason=f"Unmuted by {ctx.author.name}, {reason}") await ctx.send( f"{Emoji.get_chat_emoji('INNOCENT')} {target.display_name} has been unmuted" ) GearbotLogging.log_to( ctx.guild.id, "MOD_ACTIONS", f"{Emoji.get_chat_emoji('INNOCENT')} {target.name}#{target.discriminator} (`{target.id}`) has been unmuted by {ctx.author.name}" ) InfractionUtils.add_infraction(ctx.guild.id, target.id, ctx.author.id, "Unmute", reason)
async def unban(self, ctx, member: BannedMember, *, reason: Reason = ""): """unban_help""" if reason == "": reason = Translator.translate("no_reason", ctx.guild.id) fid = f"{ctx.guild.id}-{member.user.id}" self.bot.data["unbans"].add(fid) try: await ctx.guild.unban( member.user, reason=Utils.trim_message( f"Moderator: {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id}) Reason: {reason}", 500)) except Exception as e: self.bot.data["unbans"].remove(fid) raise e Infraction.update(active=False).where( (Infraction.user_id == member.user.id) & (Infraction.type == "Ban") & (Infraction.guild_id == ctx.guild.id)).execute() InfractionUtils.add_infraction(ctx.guild.id, member.user.id, ctx.author.id, "Unban", reason) await ctx.send( f"{Emoji.get_chat_emoji('YES')} {Translator.translate('unban_confirmation', ctx.guild.id, user=Utils.clean_user(member.user), user_id=member.user.id, reason=reason)}" ) GearbotLogging.log_to( ctx.guild.id, "MOD_ACTIONS", f"{Emoji.get_chat_emoji('INNOCENT')} {Translator.translate('unban_log', ctx.guild.id, user=Utils.clean_user(member.user), user_id=member.user.id, moderator=Utils.clean_user(ctx.author), moderator_id=ctx.author.id, reason=reason)}" )
async def on_guild_channel_delete(self, channel): if not Features.is_logged(channel.guild.id, "CHANNEL_CHANGES"): return e = await self.find_log(channel.guild, AuditLogAction.channel_delete, lambda e: e.target.id == channel.id) if e is not None: logging = Translator.assemble("DELETE", "channel_deleted_by", channel.guild, channel=channel, person=e.user) else: logging = Translator.assemble("DELETE", "channel_delete", channel.guild, channel=channel) GearbotLogging.log_to(channel.guild.id, "CHANNEL_CHANGES", logging)
async def on_guild_role_create(self, role): if not Features.is_logged(role.guild.id, "ROLE_CHANGES"): return entry = await self.find_log(role.guild, AuditLogAction.role_create, lambda e: e.target.id == role.id) if entry is None: logging = Translator.assemble("CREATE", "role_created", role.guild.id, role=role.name) else: logging = Translator.assemble("CREATE", "role_created_by", role.guild.id, role=role.name, person=Utils.clean_user(entry.user), person_id=entry.user.id) GearbotLogging.log_to(role.guild.id, "ROLE_CHANGES", logging)
async def mute(self, ctx: commands.Context, target: discord.Member, durationNumber: int, durationIdentifier: Duration, *, reason: Reason = ""): """mute_help""" if reason == "": reason = Translator.translate("no_reason", ctx.guild.id) roleid = Configuration.get_var(ctx.guild.id, "MUTE_ROLE") if roleid is 0: await ctx.send( f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('mute_not_configured', ctx.guild.id, user=target.mention)}" ) else: role = ctx.guild.get_role(roleid) if role is None: await ctx.send( f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('mute_role_missing', ctx.guild.id, user=target.mention)}" ) else: if (ctx.author != target and target != ctx.bot.user and ctx.author.top_role > target.top_role ) or ctx.guild.owner == ctx.author: duration = Utils.convertToSeconds(durationNumber, durationIdentifier) if duration > 0: until = time.time() + duration await target.add_roles( role, reason=Utils.trim_message( f"Moderator: {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id}) Reason: {reason}", 500)) InfractionUtils.add_infraction(ctx.guild.id, target.id, ctx.author.id, "Mute", reason, end=until) await ctx.send( f"{Emoji.get_chat_emoji('MUTE')} {Translator.translate('mute_confirmation', ctx.guild.id, user=Utils.clean_user(target), duration=f'{durationNumber} {durationIdentifier}')}" ) GearbotLogging.log_to( ctx.guild.id, "MOD_ACTIONS", f"{Emoji.get_chat_emoji('MUTE')} {Translator.translate('mute_log', ctx.guild.id, user=Utils.clean_user(target), user_id=target.id, moderator=Utils.clean_user(ctx.author), moderator_id=ctx.author.id, duration=f'{durationNumber} {durationIdentifier}', reason=reason)}" ) else: await ctx.send( f"{Emoji.get_chat_emoji('WHAT')} {Translator.translate('mute_negative_denied', ctx.guild.id, duration=f'{durationNumber} {durationIdentifier}')} {Emoji.get_chat_emoji('WHAT')}" ) else: await ctx.send( f"{Emoji.get_chat_emoji('NO')} {Translator.translate('mute_not_allowed', ctx.guild.id, user=target)}" )
async def archive_purge(bot, guild_id, messages): global archive_counter archive_counter += 1 channel = bot.get_channel(list(messages.values())[0].channel) out = f"purged at {datetime.datetime.now()} from {channel.name}\n" out += await pack_messages(messages.values()) filename = f"Purged messages archive {archive_counter}.txt" with open(filename, "w", encoding="utf-8") as file: file.write(out) file = open (filename, "rb") GearbotLogging.log_to(guild_id, "EDIT_LOGS", message=Translator.translate('purged_log', guild_id, count=len(messages), channel=channel.mention), file=discord.File(file, "Purged messages archive.txt"), cleaner=lambda: clean(file, filename))
async def censor_invite(ctx, code, server_name): try: await ctx.message.delete() clean_message = await clean_content().convert(ctx, ctx.message.content) clean_name = Utils.clean_user(ctx.message.author) GearbotLogging.log_to( ctx.guild.id, "CENSORED_MESSAGES", f":no_entry_sign: {Translator.translate('censored_invite', ctx.guild.id, user=clean_name, code=code, message=clean_message, server_name=server_name)}" ) except discord.NotFound: pass # we failed? guess we lost the race
async def terminate_shield(self, guild_id, handler, shield): del self.raid_trackers[guild_id]["SHIELDS"][shield["id"]] await handler.shield_terminated( self.bot, self.bot.get_guild(guild_id), self.raid_trackers[guild_id]["raid_id"], self.raid_trackers[guild_id]["raider_ids"], shield) if len(self.raid_trackers[guild_id]["SHIELDS"]) == 0: GearbotLogging.log_to( guild_id, 'raid_terminated', raid_id=self.raid_trackers[guild_id]['raid_id']) del self.raid_trackers[guild_id]
async def on_user_update(self, before: discord.User, after): # Username and discriminator changes if before.name != after.name or before.discriminator != after.discriminator: for guild in self.bot.guilds: if guild.get_member(before.id) is not None: after_clean_name = Utils.escape_markdown(after) GearbotLogging.log_to(guild.id, 'username_changed', after_clean=after_clean_name, before=before, user_id=after.id, after=after)
async def on_member_join(self, member: discord.Member): if Features.is_logged(member.guild.id, "JOIN_LOGS"): dif = (datetime.datetime.utcnow() - member.created_at) minutes, seconds = divmod(dif.days * 86400 + dif.seconds, 60) hours, minutes = divmod(minutes, 60) age = (Translator.translate('days', member.guild.id, days=dif.days)) if dif.days > 0 else Translator.translate('hours', member.guild.id, hours=hours, minutes=minutes) GearbotLogging.log_to(member.guild.id, "JOIN_LOGS", f"{Emoji.get_chat_emoji('JOIN')} {Translator.translate('join_logging', member.guild.id, user=Utils.clean_user(member), user_id=member.id, age=age)}")
async def on_member_ban(self, guild, user): if user.id == self.bot.user.id or not Features.is_logged( guild.id, "MOD_ACTIONS"): return fid = f"{guild.id}-{user.id}" if fid in self.bot.data["forced_exits"]: return self.bot.data["forced_exits"].add(fid) Infraction.update( active=False).where((Infraction.user_id == user.id) & (Infraction.type == "Unban") & (Infraction.guild_id == guild.id)).execute() await asyncio.sleep( 1 ) # sometimes we get the event before things are in the log for some reason limit = datetime.datetime.utcfromtimestamp(time.time() - 60) log = await self.find_log( guild, AuditLogAction.ban, lambda e: e.target == user and e.created_at > limit) if log is None: await asyncio.sleep(1) #is the api having a fit or so? #this fails way to often for my liking, alternative is adding a delay but this seems to do the trick for now log = await self.find_log( guild, AuditLogAction.ban, lambda e: e.target == user and e.created_at > limit) if log is not None: if log.reason is None: reason = Translator.translate("no_reason", guild.id) else: reason = log.reason InfractionUtils.add_infraction(guild.id, log.target.id, log.user.id, "Ban", reason) GearbotLogging.log_to( guild.id, "MOD_ACTIONS", MessageUtils.assemble(guild.id, "BAN", 'ban_log', user=Utils.clean_user(user), user_id=user.id, moderator=Utils.clean_user(log.user), moderator_id=log.user.id, reason=reason)) else: InfractionUtils.add_infraction(guild.id, user.id, 0, "Ban", "Manual ban") GearbotLogging.log_to( guild.id, "MOD_ACTIONS", MessageUtils.assemble(guild.id, "BAN", 'manual_ban_log', user=Utils.clean_user(user), user_id=user.id))
async def yes(): infraction.delete_instance() key = f"{ctx.guild.id}_{infraction.user_id}" if key in InfractionUtils.cache.keys(): del InfractionUtils.cache[key] await GearbotLogging.send_to(ctx, "YES", "inf_delete_deleted", id=inf_id) GearbotLogging.log_to( ctx.guild.id, "MOD_ACTIONS", f":wastebasket: {Translator.translate('inf_delete_log', ctx.guild.id, id=inf_id, target=str(target), target_id=target.id, mod=str(mod), mod_id=mod.id, reason=reason, user=str(ctx.author), user_id=ctx.author.id)}" )
async def tempban(self, ctx: commands.Context, user: discord.Member, durationNumber: int, durationIdentifier: Duration, *, reason: Reason = ""): """ban_help""" if reason == "": reason = Translator.translate("no_reason", ctx.guild.id) allowed, message = self._can_act("ban", ctx, user) if allowed: duration = Utils.convertToSeconds(durationNumber, durationIdentifier) if duration > 0: until = time.time() + duration self.bot.data["forced_exits"].add(f"{ctx.guild.id}-{user.id}") await ctx.guild.ban( user, reason=Utils.trim_message( f"Moderator: {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id}) Reason: {reason}", 500), delete_message_days=0) InfractionUtils.add_infraction(ctx.guild.id, user.id, ctx.author.id, "Tempban", reason, end=until) translated = Translator.translate( 'tempban_log', ctx.guild.id, user=Utils.clean_user(user), user_id=user.id, moderator=Utils.clean_user(ctx.author), moderator_id=ctx.author.id, reason=reason, until=datetime.datetime.utcfromtimestamp(until)) GearbotLogging.log_to(ctx.guild.id, "MOD_ACTIONS", f":door: {translated}") await GearbotLogging.send_to( ctx, "YES", "tempban_confirmation", user=Utils.clean_user(user), user_id=user.id, reason=reason, until=datetime.datetime.utcfromtimestamp(until)) else: await GearbotLogging.send_to(ctx, "NO", message, translate=False)
async def censor_invite(ctx, code, server_name): ctx.bot.data["message_deletes"].add(ctx.message.id) clean_message = await clean_content().convert(ctx, ctx.message.content) clean_name = Utils.clean_user(ctx.message.author) try: await ctx.message.delete() GearbotLogging.log_to(ctx.guild.id, "CENSORED_MESSAGES", f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('censored_invite', ctx.guild.id, user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=ctx.message.author.id, channel=ctx.message.channel.mention)}") except discord.NotFound: if ctx.message.id in ctx.bot.data["message_deletes"]: ctx.bot.data["message_deletes"].remove(ctx.message.id) # we failed? guess we lost the race, log anyways GearbotLogging.log_to(ctx.guild.id, "CENSORED_MESSAGES", f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('invite_censor_fail', ctx.guild.id, user=clean_name, code = code, message = clean_message, server_name = server_name, user_id = ctx.message.author.id, channel = ctx.message.channel.mention)}")
async def on_command_completion(self, ctx): if ctx.guild is not None and Features.is_logged( ctx.guild.id, "COMMAND_EXECUTED"): logging = f"{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_used', ctx, user=ctx.author, user_id=ctx.author.id, channel=ctx.message.channel.mention)} " clean_content = await Utils.clean(ctx.message.content, ctx.guild, markdown=False, links=False, emoji=False) GearbotLogging.log_to( ctx.guild.id, "COMMAND_EXECUTED", logging, tag_on=f"``{Utils.trim_message(clean_content, 1994)}``")
async def on_guild_role_delete(self, role: discord.Role): if not Features.is_logged(role.guild.id, "ROLE_CHANGES"): return entry = await self.find_log(role.guild, AuditLogAction.role_delete, lambda e: e.target.id == role.id) if entry is None: GearbotLogging.log_to(role.guild.id, 'role_deleted', role=role.name) else: GearbotLogging.log_to(role.guild.id, 'role_deleted_by', role=role.name, person=Utils.clean_user(entry.user), person_id=entry.user.id)
async def resetting(self, guild_id, handler, shield, data): initialized_at = datetime.utcfromtimestamp(time.time()) while True: try: await self.bot.wait_for("member_add", check=lambda m: m.guild.id == guild_id, timeout=data["time"]) diff = abs((datetime.utcfromtimestamp(time.time()) - initialized_at).total_seconds()) if diff > 60*60: GearbotLogging.log_to(guild_id, 'shield_time_limit_reached', shield_name=shield["name"]) await self.terminate_shield(guild_id, handler, shield) return except asyncio.TimeoutError: # no more joins! turn off the handler if abs((datetime.utcfromtimestamp(time.time()) - initialized_at).total_seconds()) >= shield["trigger"]["seconds"]: await self.terminate_shield(guild_id, handler, shield) return # don't leak tasks