async def uptime(self, ctx): """Shows the bots current uptime""" try: start = self.bot.start_time rc = self.bot.reconnect_time await ctx.send("Bot Uptime: {}\n" "Last Reconnect Time: {}" "".format(timefmt.time_ago(start.timestamp()), timefmt.time_ago(rc.timestamp()))) except Exception as e: await ctx.send("Error getting bot uptime. Reason: {}".format( type(e).__name__))
async def info(self, ctx, *, user=None): """Show info of a member Optional Argument: Mention or User ID No Argument will return your own info""" # https://discordpy.readthedocs.io/en/latest/api.html#member # target = None target = await self.bot.find_member_from_id_or_mention(ctx, user) # self, if target is None: await ctx.send("Couldn't find that user") return name = str(target) if target.nick: name += " (aka '{}')".format(target.nick) result = discord.Embed(title="", description="[Avatar]({}) - {}".format(target.avatar_url, target.mention), colour=target.colour) result.set_author(name="{}".format(name), icon_url=target.avatar_url) role_list = target.roles roles = [] for role in role_list: if role.name == "@everyone": continue roles.append(role.mention) roles.reverse() if len(roles) != 0: result.add_field(name="Roles", value="{}".format(" ".join(roles))) else: result.add_field(name="Roles", value="No Roles") result.add_field(name="Created Account at:", value="{}\n({} ago)".format(str(target.created_at).split(".")[0], timefmt.time_ago(target.created_at, brief=True))) result.add_field(name="Joined Server at:", value="{}\n({} ago)".format(str(target.joined_at).split(".")[0], timefmt.time_ago(target.joined_at, brief=True))) result.set_footer(text="ID: {}".format(target.id)) result.timestamp = datetime.utcnow() await ctx.send(embed=result)
async def check_member(self, ctx): """List users who didn't read the rules Lists all users in server who don't have the member role (i.e. didn't read the rules)""" is_not_member = [] all_members = ctx.message.guild.members for member in all_members: if member.bot: continue roles = member.roles role_count = len(roles) if role_count == 0: is_not_member.append(member) else: add = True for role in roles: if role.name == "Member": add = False continue if add is True: is_not_member.append(member) users = [] for user in is_not_member: new = "{} - Joined: {}".format(user.mention, timefmt.time_ago(user.joined_at)) users.append(new) if len(is_not_member) == 0: await ctx.send("No users missing member role.") return await ctx.send("Server members who do not have the member role (didn't read rules): ") await ctx.send("\n".join(users))
async def check_all(self, ctx): """List all server members who have never spoken""" users = [] for member in ctx.guild.members: user_id = member.id query = """ SELECT * FROM activity WHERE user_id = "{}" """.format(user_id) erq = self.bot.execute_read_query(query) if member.bot: continue if len(erq) == 0: new = "{} - Joined: {}".format(member.mention, timefmt.time_ago(member.joined_at)) users.append(new) continue if len(users) >= 1: await ctx.send("Members who have never spoken: ") await ctx.send("\n".join(users)) else: await ctx.send("Every member has spoken at least once")
async def on_member_join(self, member): gid = str(member.guild.id) config = self.bot.servers_config[gid] if config['logging']['join_leave_log'] is not None: channel = discord.utils.get(member.guild.text_channels, id=config['logging']["join_leave_log"]) account_age = timefmt.time_ago(member.created_at) age_stamp = datetime.utcnow().timestamp( ) - member.created_at.timestamp() if age_stamp < (60 * 60 * 24): account_age_msg = ":warning: {} :warning:".format(account_age) else: account_age_msg = account_age result = discord.Embed(title="User Joined", colour=discord.Colour.green(), description="**User:** {}\n" "**Member Count:** {}\n" "**Created:** {}" "".format(member.mention, member.guild.member_count, account_age_msg)) result.set_author(name="{}".format(member), icon_url=member.avatar_url) result.timestamp = datetime.utcnow() result.set_footer(text="ID: {}".format(member.id)) await channel.send(embed=result)
async def server(self, ctx): """Server Info""" dt = ctx.guild.created_at year = dt.year # month = f'{dt.month:02}' day = f'{dt.day:01}' hour = f'{dt.hour:02}' minute = f'{dt.minute:02}' # second = f'{dt.second:02}' total_count = ctx.guild.member_count member_count = len([m for m in ctx.guild.members if not m.bot]) bot_count = total_count - member_count res = discord.Embed(title="Server Info", description="Times in UTC", colour=ctx.guild.owner.colour) res.add_field(name="Creation Date", value="{}{} of {}, {} at {}:{}".format( day, timefmt.day_suffix(int(day)), dt.strftime("%B"), year, hour, minute)) res.add_field(name="Server Age", value="{} old".format(timefmt.time_ago(dt, brief=True))) res.add_field(name="Server Owner", value="{}\n({})".format(ctx.guild.owner, ctx.guild.owner.mention)) res.add_field(name="Member Count", value="{} Total Members\n" "{} Users\n" "{} Bots".format(total_count, member_count, bot_count)) await ctx.send(embed=res)
async def on_member_remove(self, member): gid = str(member.guild.id) config = self.bot.servers_config[gid] if config['logging']['join_leave_log'] is not None: # Log kick/ban if applicable and set in config if config['logging']['kick_ban_log'] is not None: async for entry in member.guild.audit_logs(limit=5): if entry.action == discord.AuditLogAction.kick and entry.target.name == member.name: channel = discord.utils.get( member.guild.text_channels, id=config['logging']["kick_ban_log"]) user = entry.target msg = discord.Embed(title="{} kicked".format(user), colour=discord.Colour.dark_gold(), description="**Offender:** {}\n" "**Reason:** {}\n" "**Responsible admin:** {}" "".format(entry.target, entry.reason, entry.user)) msg.set_footer(text="User ID: {}".format(user.id)) msg.timestamp = datetime.utcnow() await channel.send(embed=msg) # Log leave role_list = member.roles roles = [] for role in role_list: if role.name == "@everyone": continue roles.append(role.mention) roles.reverse() result = discord.Embed(title="User Left", colour=discord.Colour.red(), description="**User:** {}\n" "**Member for:** {}\n" "**Roles:** {}" "".format( member.mention, timefmt.time_ago(member.joined_at), " ".join(roles))) result.set_author(name="{}".format(member), icon_url=member.avatar_url) result.timestamp = datetime.utcnow() result.set_footer(text="ID: {}".format(member.id)) channel = discord.utils.get(member.guild.text_channels, id=config['logging']["join_leave_log"]) await channel.send(embed=result)
async def find_old(self, ctx): """Find previous reddit posts""" me = await self.reddit.user.me() async for post in me.new(): title = post.title age = timefmt.time_ago(post.created_utc, force_into_utc=True) sr = post.subreddit url = self.base_url + post.permalink await ctx.send(embed=ez_utils.quick_embed( title=title, description="Posted on r/{}".format(sr), fields=[("Post Age", age), ("URL", url)] ))
async def check_young(self, ctx): """List youngest server members""" users = [] for member in ctx.guild.members: users.append((member.created_at, member)) newest = sorted(users, key=lambda tup: tup[0])[-5:] msg = "" for join_time, member in newest: msg += "{} - Joined Discord {} ago\n".format(member.mention, timefmt.time_ago(join_time)) if len(newest) >= 1: await ctx.send("The five youngest server members: ") await ctx.send(msg) else: await ctx.send("No members detected (something broke)")
async def check_oldest(self, ctx): """List oldest server members""" users = [] for member in ctx.guild.members: users.append((member.joined_at, member)) oldest = sorted(users, key=lambda tup: tup[0])[:5] msg = "" for join_time, member in oldest: msg += "{} - Joined server {} ago\n".format(member.mention, timefmt.time_ago(join_time)) if len(oldest) >= 1: await ctx.send("The five oldest server members: ") await ctx.send(msg) else: await ctx.send("No members detected (something broke)")
async def _check(self, ctx, *, user: str): """Check member activity Use with a user id or mention to check when a member last spoke. Use with one of the below subcommands to list multiple users. """ target = await self.bot.find_member_from_id_or_mention(ctx, user) # self, if target is None: await ctx.send("Couldn't find that user") return try: result = discord.Embed(title="{}#{}".format(target.name, target.discriminator), description="{}".format(target.mention), colour=discord.Color.green()) except AttributeError: await ctx.send("The user with the ID '{}' is not part of this server.".format(user)) return if target.bot: result.add_field(name="Bot", value="The user ID provided is for a bot.") result.colour = discord.Color.blue() await ctx.send(embed=result) return erq = self.bot.db_quick_read(target.id, ctx.message.guild.id) if erq is None: result.add_field(name="Last Message Time:", value="Never") result.colour = discord.Color.red() await ctx.send(embed=result) return _, user, server, m_time, m_url = erq n_time = str(datetime.fromtimestamp(m_time)).split(".")[0] result.add_field(name="Last Message Time:", value="{} UTC".format(n_time)) result.add_field(name="Time Ago:", value="{} ago".format(timefmt.time_ago(m_time))) result.add_field(name="URL:", value="{}".format(m_url)) await ctx.send(embed=result)
async def check_early(self, ctx): """List earliest remaining members""" users = [] for member in ctx.guild.members: if member.bot is False: users.append((member.joined_at, member)) newest = sorted(users, key=lambda tup: tup[0])[:5] msg = "" for join_time, member in newest: msg += "{} - Joined server {} ago\n".format(member.mention, timefmt.time_ago(join_time)) if len(newest) >= 1: await ctx.send("The five earliest remaining server members: ") await ctx.send(msg) else: await ctx.send("No members detected (something broke)")
async def bot(self, ctx): """Bot Info""" bot_info = await self.bot.application_info() bot_name = bot_info.name bot_owner = bot_info.owner.mention discord_py_version = discord.__version__ python_version = py_v() github_link = "https://github.com/ExtraRandom/RobotExtra" uptime = timefmt.time_ago(self.bot.start_time.timestamp()) res = discord.Embed(title="Bot Info", colour=discord.colour.Colour.dark_blue()) res.add_field(name="Name", value="{}".format(bot_name)) res.add_field(name="Owner", value="{}".format(bot_owner)) res.add_field(name="Discord Py Version", value="{}".format(discord_py_version)) res.add_field(name="Python Version", value="{}".format(python_version)) res.add_field(name="Source Code", value="{}".format(github_link)) res.add_field(name="Uptime", value="{}".format(uptime)) await ctx.send(embed=res)
async def check_active(self, ctx): """List inactive members Lists server members who haven't spoken for 4 weeks or more""" await ctx.send("Members who haven't spoken for 4 weeks or more:") for member in ctx.guild.members: user_id = member.id query = """ SELECT * FROM activity WHERE user_id = "{}" AND server_id = {} """.format(user_id, ctx.guild.id) erq = self.bot.execute_read_query(query) if member.bot: continue if len(erq) == 0: continue else: _, server_id, last_id, last_time, last_url = erq[0] total_time = datetime.utcnow().timestamp() - last_time if total_time >= 2419200: result = discord.Embed(title="{}#{}".format(member.name, member.discriminator), description="{}".format(member.mention), colour=discord.Color.green()) n_time = str(datetime.fromtimestamp(last_time)).split(".")[0] result.add_field(name="Last Message Time:", value="{} UTC".format(n_time)) result.add_field(name="Time Ago:", value="{} ago".format(timefmt.time_ago(last_time))) result.add_field(name="URL:", value="{}".format(last_url)) await ctx.send(embed=result)
async def timeb(self, ctx, *, time_inp: int): """Time brief testing""" then_ts = datetime.utcnow().timestamp() - time_inp await ctx.send("time since {}:\n" "{}".format(datetime.fromtimestamp(then_ts), timefmt.time_ago(then_ts, brief=True)))
async def purge(self, ctx): """Purge inactive members""" yes = "✅" no = "❌" stop = "🛑" timeout_length = 60 total_count = 0 kicked_count = 0 immune_role = await self.get_role_from_id(ctx, self.purge_immune_role_id) for member in ctx.guild.members: if member.bot: continue if immune_role in member.roles: continue user_id = member.id query = """ SELECT * FROM activity WHERE user_id = "{}" """.format(user_id) erq = self.bot.execute_read_query(query) result = discord.Embed(title="Kick User?", description="{}".format(member.mention), colour=discord.Color.gold()) if len(erq) == 0: total_count += 1 join_time = member.joined_at kick_reason = "never spoke" result.add_field(name="Kick Reason:", value="Never spoke") result.add_field(name="Time ago:", value=timefmt.time_ago(join_time)) result.add_field(name="Joined Server:", value="{} UTC".format(join_time)) else: _, server_id, last_id, last_time, last_url = erq[0] total_time = datetime.utcnow().timestamp() - last_time if total_time >= 2419200: kick_reason = "inactive" total_count += 1 result.add_field(name="Kick Reason:", value="Inactivity") result.add_field(name="Time ago:", value=timefmt.time_ago(last_time)) result.add_field(name="Last Message Time:", value="{} UTC".format(datetime.fromtimestamp(last_time))) result.add_field(name="Last Message Link:", value=last_url) else: continue result.set_author(name="{}".format(member), icon_url=member.avatar_url) result.set_footer(text="Waiting {} seconds before cancelling".format(timeout_length)) role_list = member.roles roles = [] for role in role_list: if role.name == "@everyone": continue roles.append(role.mention) roles.reverse() if len(roles) != 0: result.add_field(name="Roles", value="{}".format(" ".join(roles))) else: result.add_field(name="Roles", value="No Roles") msg = await ctx.send(embed=result) await msg.add_reaction(yes) await msg.add_reaction(no) await msg.add_reaction(stop) def check(m_reaction, m_user): return m_user == ctx.author and m_reaction.message == msg \ and m_reaction.emoji in [yes, no, stop] try: reaction, user = await self.bot.wait_for('reaction_add', timeout=timeout_length, check=check) except Timeout: await msg.reply("No response within {} seconds, stopping purge :octagonal_sign:") return else: if reaction.emoji == yes: await member.kick(reason="{} - kicked in purge".format(kick_reason)) await ctx.send(":wave: Kicked {}".format(member)) kicked_count += 1 elif reaction.emoji == no: continue elif reaction.emoji == stop: await ctx.send(":octagonal_sign: Stopped purge :octagonal_sign:") break await ctx.send("Finished Purge:\nOut of {} users, {} were kicked".format(total_count, kicked_count))