async def afk_status(self, message): await self.bot.wait_until_ready() if message.author.bot: return if not message.guild: return afks = CM.get(self.bot, 'afk', f'{str(message.guild.id)}, {str(message.author.id)}') afks2 = CM.get(self.bot, 'afk', f'{str(message.author.id)}') if afks: await message.channel.send(_( "Welcome back {0}! You were away for **{1}**. Your AFK state has been removed." ).format(message.author.mention, btime.human_timedelta(afks['time'], suffix=None)), allowed_mentions=discord. AllowedMentions(users=True)) await self.bot.db.execute( "DELETE FROM afk WHERE user_id = $1 AND guild_id = $2", message.author.id, message.guild.id) self.bot.afk.pop( f'{str(message.guild.id)}, {str(message.author.id)}') elif afks2: await message.channel.send(_( "Welcome back {0}! You were away for **{1}**. Your AFK state has been removed." ).format(message.author.mention, btime.human_timedelta(afks2['time'], suffix=None)), allowed_mentions=discord. AllowedMentions(users=True)) await self.bot.db.execute("DELETE FROM afk WHERE user_id = $1", message.author.id) self.bot.afk.pop(f'{str(message.author.id)}') to_send = '' for user in message.mentions: check = CM.get(self.bot, 'afk', f'{str(message.guild.id)}, {str(user.id)}') check2 = CM.get(self.bot, 'afk', f'{str(user.id)}') if check or check2: check = check if check else check2 afkmsg = check['note'] afkmsg = afkmsg.strip() member = message.guild.get_member(user.id) to_send += (_("Hey! **{0}** has been AFK for **{1}**" " for - **{2}**.").format( member.display_name, btime.human_timedelta(check['time'], suffix=None), afkmsg)) try: await message.reply( f"{to_send}", allowed_mentions=discord.AllowedMentions( replied_user=True)) except Exception: try: await message.author.send(to_send) except Exception: return
async def newusers(self, ctx, *, count: int): """ See the newest members in the server. Limit is set to 10. """ if len(ctx.guild.members) < count: return await ctx.send( _("This server has {0} members").format(len(ctx.guild.members)) ) counts = max(min(count, 10), 1) if not ctx.guild.chunked: await self.bot.request_offline_members(ctx.guild) members = sorted(ctx.guild.members, key=lambda m: m.joined_at.replace(tzinfo=None), reverse=True)[:counts] e = discord.Embed(title=_('Newest member(s) in this server:'), colour=self.bot.settings['colors']['embed_color']) for num, member in enumerate(members, start=1): data = _( '**Joined Server at** {0}\n**Account created at** {1}').format( btime.human_timedelta(member.joined_at), btime.human_timedelta( member.created_at.replace(tzinfo=None))) e.add_field(name=f'`[{num}]` **{member}** ({member.id})', value=data, inline=False) if count > 10: e.set_footer(text=_("The limit is set to 10")) await ctx.send(embed=e)
async def remind_list(self, ctx): """ Check your reminders list """ check_reminders = CM.get(self.bot, 'reminders', ctx.author.id) if not check_reminders: return await ctx.send( _("{0} You have no reminders.").format( self.bot.settings['emojis']['misc']['warn'])) reminders = [] for result in check_reminders: when = btime.human_timedelta(check_reminders[result]['time'], source=ctx.message.created_at) content = check_reminders[result]['content'] reminders.append( _("`[{0}]` Reminding in **{1}**\n{2}\n").format( result, when, content[:150] + '...' if len(content) > 150 else content)) paginator = Pages( ctx, entries=reminders, thumbnail=None, per_page=10, embed_color=ctx.bot.settings['colors']['embed_color'], embed_author=_("{0}'s Reminders").format(ctx.author), show_entry_count=True) await paginator.paginate()
async def todo_info(self, ctx, pos: int): """ Get more information about your todo item """ todo = await self.bot.db.fetch( "SELECT DISTINCT todo, time, jump_url, ROW_NUMBER () OVER (ORDER BY time) FROM todos WHERE user_id = $1 ORDER BY time", ctx.author.id) if not todo: return await ctx.send( _("{0} You don't have any items in your todo list.").format( self.bot.settings['emojis']['misc']['warn'])) if pos not in [t['row_number'] for t in todo]: return await ctx.send( _("{0} There is no todo item with an id of **{1}** in your todo list." ).format(self.bot.settings['emojis']['misc']['warn'], pos)) e = discord.Embed(color=self.bot.settings['colors']['embed_color']) e.set_author(name=_("Information about your todo item"), icon_url=ctx.author.avatar_url) dots = '...' e.description = _( """**Todo:** {0}\n\n**Todo position:** {1}/{2}\n**Todo added:** {3}\n**Jump url:** [click here to jump]({4})""" ).format( f"{todo[pos-1]['todo']}" if len(todo[pos - 1]['todo']) < 1800 else f"{escape_markdown(todo[pos - 1]['todo'][:1800] + dots, as_needed=False)}", pos, len(todo), btime.human_timedelta(todo[pos - 1]['time']), todo[pos - 1]['jump_url']) await ctx.send(embed=e)
async def remind(self, ctx, *, remind: btime.UserFriendlyTime(commands.context, default="\u2026")): """ Create a reminder for yourself. Example usage: `remind 1h do homework`""" await self.create_reminder(ctx, remind.arg, remind.dt) time = btime.human_timedelta(remind.dt, source=ctx.message.created_at) await ctx.send( _("Alright, reminding you in {0}: {1}").format(time, remind.arg))
def format_commit(self, commit): short, _, _ = commit.message.partition('\n') short_sha2 = commit.hex[0:6] commit_tz = timezone(timedelta(minutes=commit.commit_time_offset)) commit_time = datetime.fromtimestamp(commit.commit_time).astimezone(commit_tz) # [`hash`](url) message (offset) offset = btime.human_timedelta(commit_time.astimezone(timezone.utc).replace(tzinfo=None), source=datetime.utcnow(), accuracy=1) return f'• [`{short_sha2}`](https://github.com/TheMoksej/Dredd/commit/{commit.hex}) {short} ({offset})'
async def partnerslist(self, ctx): """ Displays a list of partners and information how to become a partner """ partners = await self.bot.db.fetch( "SELECT * FROM partners ORDER BY time ASC") partner = [] for res in partners: if res['type'] == 0: partnered = f"{self.bot.get_user(res['_id'])} ({res['_id']})" ptype = f"Bot: [{self.bot.get_user(res['bot_id'])}](https://discord.com/users/{res['bot_id']})" if partnered is None: partnered = f"({res['_id']})" elif res['type'] == 1: guild = self.bot.get_guild(res['_id']) if guild is not None: try: guildinv = await guild.invites() for inv in guildinv[:1]: partnered = f"[{guild}]({inv}) ({res['_id']}) | Owner: {guild.owner} ({guild.owner.id})" except Exception: partnered = f"{guild} ({res['_id']}) | Owner: {guild.owner} ({guild.owner.id})" ptype = _('Server') elif not guild and res['valid']: partnered = f"[{res['name']}]({res['invite']})" ptype = _('Server') else: partnered = f"({res['_id']})" ptype = 'Invalid type, unpartner.' partner.append( _("**Partner:** {0}\n" "**Partnered for:** {1}\n" "**Partner type:** {2}\n" "**Partnered message:**\n>>> {3}").format( partnered, btime.human_timedelta(res['time'], source=datetime.utcnow(), suffix=None), ptype, res['message'])) msg = await self.bot.get_channel( self.bot.settings['channels']['partners'] ).fetch_message(741690217379135569) partner.append( _("Interested in partnering? Here's the official message:\n\n{0}" " or [join the support server]({1})").format( msg.content, self.bot.support)) paginator = Pages( ctx, title=_("Partnered people with Dredd"), entries=partner, thumbnail=None, per_page=1, embed_color=self.bot.settings['colors']['embed_color'], show_entry_count=True) await paginator.paginate()
async def snipe(self, ctx, *, channel: discord.TextChannel = None): channel = channel or ctx.channel snipe = CM.get(self.bot, 'snipes', channel.id) if snipe is None: return await ctx.send( _("{0} I haven't yet logged any messages from {1}.").format( self.bot.settings['emojis']['misc']['warn'], channel.mention if channel != ctx.channel else _('this channel'))) if snipe['nsfw'] and not ctx.channel.is_nsfw(): return await ctx.send( _("{0} I can't let you snipe messages from an NSFW channel!"). format(self.bot.settings['emojis']['logs']['nsfw'])) else: try: user = await self.bot.fetch_user(snipe['author']) name = user except discord.errors.NotFound: try: user = await self.bot.fetch_webhook(snipe['author']) name = user.name except discord.errors.NotFound: return await ctx.send( _("{0} Looks like I can't fetch the user that sent the snipped message." ).format(self.bot.settings['emojis']['logs']['nsfw']) ) except discord.errors.Forbidden: return await ctx.send( _("{0} That message looks like it was a webhook, and I'm missing permissions to look for more information." ).format(self.bot.settings['emojis']['logs']['nsfw']) ) message = snipe['message'] or _( "*[Couldn't get the sniped content]*") message = message.replace('[', '\[') e = discord.Embed(color=self.bot.settings['colors']['embed_color'], description=message) e.set_author(name=_("Deleted by {0}").format(name), icon_url=user.avatar_url) e.set_footer(text=_("Deleted {0} in #{1}").format( btime.human_timedelta(snipe['deleted_at']), channel.name)) await ctx.send(embed=e)
async def about(self, ctx): version = self.bot.version channel_types = Counter(type(c) for c in self.bot.get_all_channels()) voice = channel_types[discord.channel.VoiceChannel] text = channel_types[discord.channel.TextChannel] te = len([ c for c in set(self.bot.walk_commands()) if c.cog_name == "Owner" ]) se = len([ c for c in set(self.bot.walk_commands()) if c.cog_name == "Staff" ]) xd = len([c for c in set(self.bot.walk_commands())]) if await ctx.bot.is_owner(ctx.author): ts = 0 elif await ctx.bot.is_admin(ctx.author): ts = te elif not await ctx.bot.is_admin(ctx.author): ts = te + se totcmd = xd - ts mems = sum([x.member_count for x in self.bot.guilds]) website = 'https://dredd-bot.xyz/' Moksej = self.bot.get_user(345457928972533773) embed = discord.Embed(color=self.bot.settings['colors']['embed_color']) embed.set_author(name=_("About {0}").format(self.bot.user), icon_url=self.bot.user.avatar_url) embed.description = _(""" Dredd is a bot that will help your server with moderation, provide fun to your members, and much more! The bot is currently running on **V{0}** and is currently maintained. **Developer:** [{1}](https://discord.com/users/345457928972533773) **Library & version:** {2} [enhanced discord.py {3}](https://github.com/iDutchy/discord.py) **Last boot:** {4} **Created:** {5} ({6}) **Links:** • [Support server]({7}) • [Bot invite]({8}) • [Website]({17}) **Latest Changes:** {9} **Total:** • Commands: **{10}** • Members: **{11}** • Servers: **{12}** • Channels: {13} **{14}** | {15} **{16}**\n """).format( version, escape_markdown(str(Moksej), as_needed=False), self.bot.settings['emojis']['misc']['python'], discord.__version__, btime.human_timedelta(self.bot.uptime), default.date(self.bot.user.created_at), default.timeago(datetime.utcnow() - self.bot.user.created_at.replace(tzinfo=None)), self.bot.support, self.bot.invite, self.get_last_commits(), f'{totcmd:,}', f'{mems:,}', f'{len(self.bot.guilds):,}', self.bot.settings['emojis']['logs']['unlock'], f'{text:,}', self.bot.settings['emojis']['logs']['vcunlock'], f'{voice:,}', website) embed.set_image(url=self.bot.settings['banners']['default']) await ctx.send(embed=embed)
async def serverinfo(self, ctx): """ Overview about the information of a server """ if not ctx.guild.chunked: await ctx.guild.chunk(cache=True) acks = default.server_badges(ctx, ctx.guild) ack = _("\n**Acknowledgements:** {0}").format(acks) if acks else '' unique_members = set(ctx.guild.members) unique_online = sum(1 for m in unique_members if m.status is discord.Status.online and not type(m.activity) == discord.Streaming) unique_offline = sum(1 for m in unique_members if m.status is discord.Status.offline and not type(m.activity) == discord.Streaming) unique_idle = sum(1 for m in unique_members if m.status is discord.Status.idle and not type(m.activity) == discord.Streaming) unique_dnd = sum(1 for m in unique_members if m.status is discord.Status.dnd and not type(m.activity) == discord.Streaming) unique_streaming = sum(1 for m in unique_members if type(m.activity) == discord.Streaming) humann = sum(1 for member in ctx.guild.members if not member.bot) botts = sum(1 for member in ctx.guild.members if member.bot) num = 0 for user in ctx.guild.members: if ctx.channel.permissions_for(user).kick_members or \ ctx.channel.permissions_for(user).ban_members: if not user.bot: num += 1 bans = '' if ctx.channel.permissions_for(ctx.guild.me).ban_members: bans += _("\n**Banned:** {0}").format( f'{len(await ctx.guild.bans()):,}') nitromsg = _("This server has **{0}** boosts").format( ctx.guild.premium_subscription_count) nitromsg += _("\n{0}").format(default.next_level(ctx)) region = default.region_flags(ctx) e = discord.Embed(color=self.bot.settings['colors']['embed_color']) e.set_author(name=_("{0} Information").format(ctx.guild.name), icon_url=ctx.guild.icon_url) e.add_field(name=_('General Information:'), value=_(""" **Name:** {0} **ID:** {1} **Guild created:** {2} ({3}) **Region:** {4} **Verification level:** {5} **Owner:** {6} **Owner ID:** {7}{8} **Nitro status:** {9} """).format( ctx.guild.name, ctx.guild.id, default.date(ctx.guild.created_at), btime.human_timedelta( ctx.guild.created_at.replace(tzinfo=None), source=datetime.utcnow()), region, str(ctx.guild.verification_level).capitalize(), ctx.guild.owner or 'Unknown', ctx.guild.owner.id, ack, nitromsg)) members_info = ( f"{self.bot.settings['emojis']['misc']['pc-online']} {unique_online:,}\n" f"{self.bot.settings['emojis']['misc']['pc-idle']} {unique_idle:,}\n" f"{self.bot.settings['emojis']['misc']['pc-dnd']} {unique_dnd:,}\n" f"{self.bot.settings['emojis']['misc']['offline']} {unique_offline:,}\n" f"{self.bot.settings['emojis']['misc']['streaming']} {unique_streaming:,}" ) e.add_field(name=_('Other Information:'), value=_("""**Members:** (Total: {0}) {1} **Bots:** {2} | **Humans:** {3} **Staff:** {4}{5} **Channels:** {6} {7} | {8} {9} """).format(f'{ctx.guild.member_count:,}', members_info, f'{botts:,}', f'{humann:,}', f'{num:,}', bans, self.bot.settings['emojis']['logs']['unlock'], f'{len(ctx.guild.text_channels):,}', self.bot.settings['emojis']['logs']['vcunlock'], f'{len(ctx.guild.voice_channels):,}')) info = [] features = set(ctx.guild.features) all_features = { 'PARTNERED': 'Partnered', 'VERIFIED': 'Verified', 'DISCOVERABLE': 'Server Discovery', 'COMMUNITY': 'Community server', 'INVITE_SPLASH': 'Invite Splash', 'VIP_REGIONS': 'VIP Voice Servers', 'VANITY_URL': 'Vanity Invite', 'MORE_EMOJI': 'More Emoji', 'COMMERCE': 'Commerce', 'LURKABLE': 'Lurkable', 'NEWS': 'News Channels', 'ANIMATED_ICON': 'Animated Icon', 'BANNER': 'Banner', 'WELCOME_SCREEN_ENABLED': "Welcome screen" } for feature, label in all_features.items(): if feature in features: info.append(label) if info: e.add_field(name=_("Features"), value=', '.join(info), inline=False) if not ctx.guild.is_icon_animated(): e.set_thumbnail(url=ctx.guild.icon_url_as(format="png")) elif ctx.guild.is_icon_animated(): e.set_thumbnail(url=ctx.guild.icon_url_as(format="gif")) if ctx.guild.banner: e.set_image(url=ctx.guild.banner_url_as(format="png")) await ctx.send(embed=e)
async def userinfo(self, ctx, *, user: typing.Union[discord.User, str] = None): """ Overview about the information of an user """ embcolor = self.bot.settings['colors']['embed_color'] user = await default.find_user(ctx, user) if not user: return await ctx.send( _("{0} | That user could not be found.").format( ctx.bot.settings['emojis']['misc']['warn'])) if not self.bot.get_user(user.id): embcolor = ctx.bot.settings['colors']['fetch_color'] discord_badges = await default.public_flags(ctx, user) if user.bot and not discord_badges: discord_badges = f"{self.bot.settings['emojis']['badges']['bot']}" e = discord.Embed(color=embcolor) e.set_author(name=_("{0}'s Information").format(user), icon_url=user.avatar_url) member = ctx.guild.get_member(user.id) if member: nick = member.nick or 'N/A' nicks = '' status = default.member_status(ctx, member) act = default.member_activity(ctx, member) uroles = [] for role in member.roles: if role.is_default(): continue uroles.append(role.mention) uroles.reverse() if len(uroles) > 15: uroles = [ f"{', '.join(uroles[:10])} (+{len(member.roles) - 11})" ] if not member.bot: if CM.get(self.bot, 'nicks_op', member.id) is None: nicks += _('\n**Latest nicknames:** ') nicknames = await self.bot.db.fetch( "SELECT * FROM nicknames WHERE user_id = $1 AND guild_id = $2 ORDER BY time DESC LIMIT 5", user.id, ctx.guild.id) if nicknames: for nickk in nicknames: nicks += f"{escape_markdown(nickk['nickname'], as_needed=False)}, " if not nicknames: nicks += 'N/A ' user_roles = _(' **({0} Total)**').format( len(member.roles) - 1) if uroles != [] else _('No roles') e.add_field(name=_("General Information:"), value=_(""" {0} {1} {2} {3} **User ID:** {4} **Account created:** {5} ({6})""").format( status, user, discord_badges, act, user.id, user.created_at.__format__('%A %d %B %Y, %H:%M'), btime.human_timedelta( user.created_at.replace(tzinfo=None), source=datetime.utcnow())), inline=False) e.add_field(name=_("Server Information:"), value=_(""" **Nickname:** {0}{1} **Joined at:** {2} ({3}) **Roles:** {4}""").format( nick, nicks[:-2], default.date(member.joined_at), btime.human_timedelta( member.joined_at.replace(tzinfo=None), source=datetime.utcnow()), ', '.join(uroles) + user_roles)) else: guilds = [x for x in self.bot.guilds if x.get_member(user.id)] try: member = guilds[0].get_member(user.id) status = default.member_status(ctx, member) act = default.member_activity(ctx, member) except Exception: status = '' act = '' e.add_field(name=_("General Information:"), value=_(""" {0} {1} {2} {3} **User ID:** {4} **Account created:** {5} ({6})""").format( status, user, discord_badges, act, user.id, user.created_at.__format__('%A %d %B %Y, %H:%M'), btime.human_timedelta( user.created_at.replace(tzinfo=None), source=datetime.utcnow())), inline=False) if await self.bot.is_booster(user): media = await default.medias(ctx, user) if media: e.add_field(name=_('Social media:'), value=media, inline=False) if not user.is_avatar_animated(): e.set_thumbnail(url=user.avatar_url_as(format='png')) elif user.is_avatar_animated(): e.set_thumbnail(url=user.avatar_url_as(format='gif')) else: e.set_thumbnail(url=user.avatar_url) await ctx.send(embed=e)
def member_presence(ctx, member): if not member.activity or not member.activities: return "\n" message = "\n" for activity in member.activities: try: if activity.type == discord.ActivityType.custom: message += '' elif activity.type == discord.ActivityType.playing: message += _("{0} Playing **{1}** for {2}\n").format( ctx.bot.settings['emojis']['misc']['activity'], clean(activity.name), human_timedelta(activity.start.replace(tzinfo=None), source=datetime.utcnow(), suffix=None)) elif activity.type == discord.ActivityType.streaming: try: if activity.name == activity.platform: act = "Twitch" elif activity.name != activity.platform: act = activity.platform message += _( "{0} Streaming **[{1}]({2})** on **{3}** for {4}\n" ).format( ctx.bot.settings['emojis']['misc']['streaming'], escape_markdown(activity.name, as_needed=False), activity.url, act, human_timedelta(activity.start.replace(tzinfo=None), source=datetime.utcnow(), suffix=None)) except AttributeError as e: print(e) message += _( "{0} Shit broke while trying to figure out streaming details.\n" ).format(ctx.bot.settings['emojis']['misc']['streaming']) elif activity.type == discord.ActivityType.watching: message += _("{0} Watching **{1}** for {2}\n").format( ctx.bot.settings['emojis']['misc']['activity'], clean(activity.name), human_timedelta(activity.start.replace(tzinfo=None), source=datetime.utcnow(), suffix=None)) elif activity.type == discord.ActivityType.listening: if isinstance(activity, discord.Spotify): url = f"https://open.spotify.com/track/{activity.track_id}" message += _( "{0} Listening to **[{1}]({2})** by **{3}**").format( ctx.bot.settings['emojis']['misc']['music'], escape_markdown(activity.title, as_needed=False), url, ', '.join(activity.artists)) if activity.album and not activity.album == activity.title: message += _(", album Рђћ **{0}** ").format( activity.album) message += _(" for {0}\n").format( human_timedelta(activity.start.replace(tzinfo=None), source=datetime.utcnow(), suffix=None)) else: message += _("{0} Listening to **{1}** for {2}\n").format( ctx.bot.settings['emojis']['misc']['music'], clean(activity.name), human_timedelta(activity.start.replace(tzinfo=None), source=datetime.utcnow(), suffix=None)) elif activity.type == discord.ActivityType.competing: # This might be broken as I cannot test the url. if activity.url is None: message += _( "{0} Competing in a **{1}** for {2}\n").format( ctx.bot.settings['emojis']['misc']['activity'], clean(activity.name), human_timedelta( activity.start.replace(tzinfo=None), source=datetime.utcnow(), suffix=None)) if activity.emoji: message += f" {activity.emoji}\n" elif activity.url is not None: message += _( "{0} Competing in a **[{1}]({2})** for {3}\n").format( ctx.bot.settings['emojis']['misc']['activity'], escape_markdown(activity.name, as_needed=False), activity.url, human_timedelta( activity.start.replace(tzinfo=None), source=datetime.utcnow(), suffix=None)) if activity.emoji: message += f" {activity.emoji}\n" except Exception: pass if message == '\n\n': message = "\nN/A\n" return message
async def execute_punishment(self, action, message, reason, time=None): automod = cm.get(self.bot, 'automod', message.guild.id) logchannel = message.guild.get_channel(automod['channel']) muterole = await default.get_muterole(self, message.guild) audit_reason = _("Automod Action | {0}").format(reason) anti_raid = cm.get(self.bot, 'raidmode', message.guild.id) error_msg = _("{0} Something failed while punishing the member, sent the error to my developers. " "This is most likely due to me either missing permissions or not being able to access the person and/or role").format(self.bot.settings['emojis']['misc']['warn']) try: if action == 1: if not message.guild.me.guild_permissions.manage_roles: return try: if muterole and muterole not in message.author.roles and muterole.position < message.guild.me.top_role.position: await message.author.add_roles(muterole, reason=audit_reason) await default.execute_temporary(self, 1, message.author, message.guild.me, message.guild, muterole, None, reason) await message.channel.send(_("{0} Muted **{1}** for {2}.").format(self.bot.settings['emojis']['logs']['memberedit'], message.author, reason)) elif not muterole: if not message.author.permissions_in(message.channel).send_messages: return await self.update_channel_permissions(self, message, action) else: await self.update_channel_permissions(self, message, action) time = None except Exception as e: await default.background_error(self, '`automod punishment execution (mute)`', e, message.guild, message.channel) return await message.channel.send(error_msg) elif action == 2: if not message.guild.me.guild_permissions.manage_roles: return try: if muterole and muterole not in message.author.roles and muterole.position < message.guild.me.top_role.position: await message.author.add_roles(muterole, reason=audit_reason) await default.execute_temporary(self, 1, message.author, message.guild.me, message.guild, muterole, time, reason) time = btime.human_timedelta(time.dt, source=datetime.utcnow(), suffix=None) await message.channel.send(_("{0} Muted **{1}** for {2}, reason: {3}.").format(self.bot.settings['emojis']['logs']['memberedit'], message.author, time, reason)) elif not muterole: if not message.author.permissions_in(message.channel).send_messages: return await self.update_channel_permissions(self, message, action) else: await self.update_channel_permissions(self, message, action) except Exception as e: await default.background_error(self, '`automod punishment execution (tempmute)`', e, message.guild, message.channel) return await message.channel.send(error_msg) elif action == 3: if not message.guild.me.guild_permissions.kick_members: return try: if message.author.top_role.position < message.guild.me.top_role.position: await message.guild.kick(message.author, reason=audit_reason) await message.channel.send(_("{0} Kicked **{1}** for {2}.").format(self.bot.settings['emojis']['logs']['memberedit'], message.author, reason)) else: await self.update_channel_permissions(self, message, action) time = None except Exception as e: await default.background_error(self, '`automod punishment execution (kick)`', e, message.guild, message.channel) return await message.channel.send(error_msg) elif action == 4: if not message.guild.me.guild_permissions.ban_members: return try: if message.author.top_role.position < message.guild.me.top_role.position: await message.guild.ban(message.author, reason=audit_reason) await default.execute_temporary(self, 2, message.author, message.guild.me, message.guild, None, None, reason) await message.channel.send(_("{0} Banned **{1}** for {2}.").format(self.bot.settings['emojis']['logs']['ban'], message.author, reason)) else: await self.update_channel_permissions(self, message, action) time = None except Exception as e: await default.background_error(self, '`automod punishment execution (ban)`', e, message.guild, message.channel) return await message.channel.send(error_msg) elif action == 5: if not message.guild.me.guild_permissions.ban_members: return try: if message.author.top_role.position < message.guild.me.top_role.position: await message.guild.ban(message.author, reason=audit_reason) await default.execute_temporary(self, 2, message.author, message.guild.me, message.guild, None, time, reason) time = btime.human_timedelta(time.dt, source=datetime.utcnow(), suffix=None) await message.channel.send(_("{0} Banned **{1}** for {2}, reason: {3}.").format(self.bot.settings['emojis']['logs']['ban'], message.author, time, reason)) else: await self.update_channel_permissions(self, message, action) except Exception as e: await default.background_error(self, '`automod punishment execution (tempban)`', e, message.guild, message.channel) return await message.channel.send(error_msg) elif action == 6: if not message.guild.me.guild_permissions.kick_members: return try: self.bot.join_counter.update({message.id}) if self.bot.join_counter[message.id] >= 5: del self.bot.join_counter[message.id] return await self.execute_punishment(9, message, audit_reason) await message.guild.kick(message, reason=audit_reason) log_channel = message.guild.get_channel(anti_raid['channel']) if anti_raid['dm']: with suppress(Exception): await message.send(_("{0} {1} has anti raid mode activated, please try joining again later.").format(self.bot.settings['emojis']['misc']['warn'], message.guild)) time = None except Exception as e: return await default.background_error(self, '`automod punishment execution (raidmode kick)`', e, message.guild, message.channel if hasattr(message, 'channel') else log_channel) elif action == 7: if not message.guild.me.guild_permissions.ban_members: return try: await message.guild.ban(message, reason=audit_reason) log_channel = message.guild.get_channel(anti_raid['channel']) if anti_raid['dm']: with suppress(Exception): await message.send(_("{0} {1} has anti raid mode activated, you're not allowed to join that server.").format(self.bot.settings['emojis']['misc']['warn'], message.guild)) time = None except Exception as e: return await default.background_error(self, '`automod punishment execution (raidmode ban)`', e, message.guild, message.channel if hasattr(message, 'channel') else log_channel) elif action == 8: if not message.guild.me.guild_permissions.kick_members: return try: self.bot.join_counter.update({message.id}) if self.bot.join_counter[message.id] >= 5: del self.bot.join_counter[message.id] return await self.execute_punishment(9, message, audit_reason) await message.guild.kick(message, reason=audit_reason) log_channel = message.guild.get_channel(anti_raid['channel']) if anti_raid['dm']: with suppress(Exception): await message.send(_("{0} {1} has strict anti raid mode activated, please try joining again later.").format(self.bot.settings['emojis']['misc']['warn'], message.guild)) time = None except Exception as e: return await default.background_error(self, '`automod punishment execution (raidmode kick all)`', e, message.guild, message.channel if hasattr(message, 'channel') else log_channel) elif action == 9: if not message.guild.me.guild_permissions.ban_members: return try: await message.guild.ban(message, reason=audit_reason) log_channel = message.guild.get_channel(anti_raid['channel']) if anti_raid['dm']: with suppress(Exception): await message.send(_("{0} {1} has anti raid mode activated, you're not allowed to join that server.").format(self.bot.settings['emojis']['misc']['warn'], message.guild)) time = None except Exception as e: return await default.background_error(self, '`automod punishment execution (raidmode ban all)`', e, message.guild, message.channel if hasattr(message, 'channel') else log_channel) await logchannel.send(embed=self.embed(member=message if not hasattr(message, 'author') else message.author, reason=reason, action=action, time=time)) if action in [6, 8]: await asyncio.sleep(60) # delete them from the counter after 60 seconds if self.bot.join_counter[message.id] <= 2: del self.bot.join_counter[message.id] except Exception as e: await default.background_error(self, '`automod punishment execution`', e, message.guild, message.channel if hasattr(message, 'channel') else log_channel) if action not in [6, 7, 8, 9]: return await message.channel.send(_("{0} I'm not sure what happened, but something broke. Please make sure that my role is above everyone's else, " "otherwise you'll see these errors more often. I've also sent this error to my developers."))
async def poll(self, ctx, *, data: str = None): """ creates a poll that allows your community to vote on whatever you are polling! requires the `Community Manager` role to create a poll, use the following format: ``` !poll --title MyTitle --desc this is for a test --add :MyEmoji: - blue is better --add :MyOtherEmoji: - red is better +timer 1m ``` all fields are optional. one field per line. you may add as many emojis as you wish. for info on the timer formatting, see the ``!help time`` command." """ if not data: await ctx.send_help(ctx.command) return pdb = {"queries": {}, "end": 0, "endtxt": "", "title": "", "desc": "", "channel": ctx.channel.id, "msg": None} parser = Arguments() parser.add_argument("--title", "-t", nargs="+") parser.add_argument("--add", "-a", "--append", nargs="+", action="append") parser.add_argument("--timer", "-timer", nargs="+") parser.add_argument("--description", "--desc", "-d", nargs="+") try: parsed = parser.parse_args(parse.split(data)) except Exception as e: return await ctx.send(str(e)) if not parsed.add: return await ctx.send(f"No options passed!") for i in parsed.add: i = i[0] c = i.split() emoji = c[0] r = " ".join(c[1:]) try: emoji = await commands.EmojiConverter().convert(ctx, emoji) except commands.BadArgument: if ":" in emoji: return await ctx.send("unusable emoji!") pdb['queries'][emoji] = r if parsed.timer: c = btime.FutureTime(" ".join(parsed.timer)) end = btime.human_timedelta(c.dt, brief=True) pdb['endtxt'] = end pdb['end'] = round(c.dt.timestamp()) if parsed.description: pdb['desc'] = " ".join(parsed.description) if parsed.title: pdb['title'] = " ".join(parsed.title) e = discord.Embed() if pdb['end'] != 0 and pdb['desc']: e.description = pdb['desc'] + f"\n*poll will close after* "+pdb['endtxt'] elif pdb['end'] != 0: e.description = f"*poll will close after* {pdb['endtxt']}" e.colour = discord.Color.purple() e.title = pdb['title'] e.timestamp = datetime.datetime.utcnow() for emoji, desc in pdb['queries'].items(): try: emoj = str(self.bot.get_emoji(int(emoji))) except: emoj = emoji e.add_field(name=desc, value=f"*react with* {emoj}", inline=False) v = await ctx.send(embed=e) pdb['msg'] = v.id id = str(uuid.uuid4()) if pdb['end'] != 0: await self.db.execute("INSERT INTO polls " "VALUES (?, ?, ?, ?, ?, ?, ?, ?)", (ctx.guild.id, id, pdb['end'], pdb['endtxt'], pdb['title'], pdb['desc'], pdb['channel'], pdb['msg'])) for emoji, desc in pdb['queries'].items(): await self.db.execute("INSERT INTO poll_nodes VALUES (?, ?, ?, ?)", (ctx.guild.id, id, str(emoji.id), desc)) for emote in pdb['queries'].keys(): try: r = self.bot.get_emoji(int(emote)) except Exception: r = emote await v.add_reaction(r)
async def status(self, ctx, *, member: discord.Member = None): member = member or ctx.author if member.bot: return await ctx.send( _("{0} I do not track bot's activity...").format( self.bot.settings['emojis']['misc']['warn'])) member_check = CM.get(self.bot, 'status_op', member.id) author_check = CM.get(self.bot, 'status_op', ctx.author.id) afks = CM.get(self.bot, 'afk', f'{str(ctx.guild.id)}, {str(ctx.author.id)}') if member_check is None: return await ctx.send( _("{0} {1} has opted-out of status logging." "{2}"). format( self.bot.settings['emojis']['misc']['warn'], member, _("You can opt-in to status logging by using `{0}toggle status`" ).format(ctx.prefix) if member == ctx.author else '')) elif member_check is not None and author_check is None: return await ctx.send( _("{0} you cannot view **{1}**'s activity because you've opted out of status logging!" "You can opt back in using `{2}toggle status`").format( self.bot.settings['emojis']['misc']['warn'], member, ctx.prefix)) elif member_check is not None and author_check is not None: status = await self.bot.db.fetch( "SELECT * FROM status WHERE user_id = $1", member.id) if status is None: return await ctx.send( _("{0} I don't have {1}").format( self.bot.settings['emojis']['misc']['warn'], _("{0}'s status logged.").format(member) if member != ctx.author else _("your status logged."))) elif status is not None: bslash = '\n' the_status = default.member_status(ctx, member) afk = _("They've been AFK for **{0}**{1}").format( btime.human_timedelta(afks['time'], suffix=None), bslash) if afks else '' s = status[0]['status_type'] s = "**{0}**".format( _("idle") if s == 'idle' else _("online") if s == 'online' else _('do not disturb') if s == 'dnd' else _("offline")) presence = _( "**{0}** has been{1} {2} **{3}** for {4}.\n{5}\n".format( ctx.guild.get_member(status[0]['user_id']), _(' on') if status[0]['status_type'] == 'dnd' else '', the_status, s, btime.human_timedelta(status[0]['since'], suffix=None), afk)) activity = default.member_presence(ctx, member) e = discord.Embed( color=self.bot.settings['colors']['embed_color']) e.set_author(name=_("{0}'s Activity").format(member), icon_url=member.avatar_url) b = '\n' e.description = _("""{0}{1}""").format( presence, _("**They've also been:**{0}").format(activity) if activity != f"{b}" else '') return await ctx.send(embed=e)