async def commandstats_single(self, ctx, command_name): """Stats of a single command.""" command = self.bot.get_command(command_name) if command is None: return await ctx.send(f"> Command `>{command_name}` does not exist.") content = discord.Embed(title=f"`>{command}`") command_name = str(command) # get data from database usage_data = db.query( """SELECT SUM(count) FROM command_usage WHERE command = ?""", (command_name,), )[0][0] usage_data_server = db.query( """SELECT SUM(count) FROM command_usage WHERE command = ? AND guild_id = ?""", (command_name, ctx.guild.id), )[0][0] most_uses_server = db.query( """SELECT guild_id, MAX(countsum) FROM ( SELECT guild_id, SUM(count) as countsum FROM command_usage WHERE command = ? GROUP BY guild_id )""", (command_name,), )[0] most_uses_user = db.query( """SELECT user_id, MAX(countsum) FROM ( SELECT user_id, SUM(count) as countsum FROM command_usage WHERE command = ? GROUP BY user_id )""", (command_name,), )[0] # show the data in embed fields content.add_field(name="Uses", value=usage_data) content.add_field(name="on this server", value=usage_data_server) content.add_field( name="Server most used in", value=f"{self.bot.get_guild(most_uses_server[0])} ({most_uses_server[1]})", inline=False, ) content.add_field( name="Most total uses by", value=f"{self.bot.get_user(most_uses_user[0])} ({most_uses_user[1]})", ) # additional data for command groups if hasattr(command, "commands"): content.description = "command group" subcommands_string = ", ".join(f"'{command.name} {x.name}'" for x in command.commands) subcommand_usage = db.query( """SELECT SUM(count) FROM command_usage WHERE command IN (%s)""" % subcommands_string )[0][0] content.add_field(inline=False, name="Total subcommand uses", value=subcommand_usage) await ctx.send(embed=content)
async def get_rank(self, ctx, user, table, _global=False): """Get user's xp ranking from given table.""" if user.bot: return 'BOT' users = [] if _global: rows = db.query( "SELECT user_id, %s FROM %s GROUP BY user_id ORDER BY %s DESC" % (ALLSUM, table, ALLSUM)) else: rows = db.query( "SELECT user_id, %s FROM %s WHERE guild_id = ? GROUP BY user_id ORDER BY %s DESC" % (ALLSUM, table, ALLSUM), (ctx.guild.id, )) total = 0 i = 0 ranking = 'N/A' for user_id, total_x in rows: this_user = self.bot.get_user(user_id) if this_user is None or this_user.bot: continue else: total += 1 i += 1 if user_id == user.id: ranking = i return f"#{ranking}/{total}"
async def commandstats_server(self, ctx, user: discord.Member = None): """Most used commands on this server.""" content = discord.Embed( title=f"`>_` Most used commands in {ctx.guild.name}" + ('' if user is None else f' by {user}')) if user is not None: data = db.query( "SELECT command, SUM(count) FROM command_usage WHERE guild_id = ? AND user_id = ? GROUP BY command", (ctx.guild.id, user.id)) else: data = db.query( "SELECT command, SUM(count) FROM command_usage WHERE guild_id = ? GROUP BY command", (ctx.guild.id, )) rows = [] total = 0 for command, count in sorted(data, key=itemgetter(1), reverse=True): total += count biggest_user = None if user is None: userdata = db.query( "SELECT user_id, MAX(count) AS highest FROM command_usage WHERE command = ? AND guild_id = ?", (command, ctx.guild.id)) biggest_user = (self.bot.get_user(userdata[0][0]), userdata[0][1]) rows.append(f"**{count}** x `>{command}`" + ('' if biggest_user is None else f" ( {biggest_user[1]} by {biggest_user[0]} )")) content.set_footer(text=f"Total {total} commands") await util.send_as_pages(ctx, content, rows)
async def typing_stats(self, ctx, user: discord.Member = None): if user is None: user = ctx.author data = db.query( "SELECT * FROM typingdata WHERE user_id = ? ORDER BY `timestamp` DESC", (user.id, ), ) if data is None: return await ctx.send(("You haven't" if user is ctx.author else f"**{user.name}** hasn't") + " taken any typing tests yet!") racedata = db.query( "SELECT SUM(wins) FROM typeracer WHERE user_id = ?", (user.id, )) wpm_list = [x[2] for x in data] wpm_avg = sum(wpm_list) / len(wpm_list) acc_list = [x[3] for x in data] acc_avg = sum(acc_list) / len(acc_list) wpm_list_re = [x[2] for x in data[:10]] wpm_avg_re = sum(wpm_list_re) / len(wpm_list_re) acc_list_re = [x[3] for x in data[:10]] acc_avg_re = sum(acc_list_re) / len(acc_list_re) wins = racedata[0][0] if racedata is not None else "N/A" content = discord.Embed(title=f":keyboard: {user.name} typing stats", color=discord.Color.gold()) content.description = ( f"Tests taken: **{len(data)}**\n" f"Races won: **{wins}**\n" f"Average WPM: **{int(wpm_avg)}**\n" f"Average Accuracy: **{acc_avg:.1f}%**\n" f"Recent average WPM: **{int(wpm_avg_re)}**\n" f"Recent average Accuracy: **{acc_avg_re:.1f}%**\n") await ctx.send(embed=content)
async def commandstats_global(self, ctx, user: discord.Member = None): """Most used commands globally.""" content = discord.Embed( title="`>_` Most used commands" + ("" if user is None else f" by {user}") ) if user is not None: data = db.query( """SELECT command, SUM(count) FROM command_usage WHERE user_id = ? GROUP BY command""", (user.id,), ) else: data = db.query("""SELECT command, SUM(count) FROM command_usage GROUP BY command""") rows = [] total = 0 for command, count in sorted(data, key=itemgetter(1), reverse=True): total += count biggest_user = None if user is None: userdata = db.query( """SELECT user_id, MAX(countsum) FROM ( SELECT user_id, SUM(count) as countsum FROM command_usage WHERE command = ? GROUP BY user_id )""", (command,), ) biggest_user = (self.bot.get_user(userdata[0][0]), userdata[0][1]) rows.append( f"**{count}** x `>{command}`" + ("" if biggest_user is None else f" ( {biggest_user[1]} by {biggest_user[0]} )") ) content.set_footer(text=f"Total {total} commands") await util.send_as_pages(ctx, content, rows)
async def leaderboard_levels(self, ctx, scope="", timeframe=""): _global_ = scope == "global" if timeframe == "": timeframe = scope users = [] guild = ctx.guild time, table = get_activity_table(timeframe) if _global_: user_rows = db.query( "SELECT user_id, %s, SUM(messages) FROM %s GROUP BY user_id " "ORDER BY %s DESC" % (ALLSUM, table, ALLSUM)) for user_id, xp, messages in user_rows: if _global_: user = self.bot.get_user(user_id) else: user = ctx.guild.get_member(user_id) if user is None or user.bot: continue users.append((user, messages, xp)) else: # guild selector for owner only if ctx.author.id == self.bot.owner_id and scope != "": try: guild = self.bot.get_guild(int(scope)) if guild is None: guild = ctx.guild except ValueError: pass data = db.query("SELECT * FROM %s WHERE guild_id = ?" % table, (guild.id, )) for row in data: user = guild.get_member(row[1]) if user is None or user.bot: continue users.append((user, row[2], sum(row[3:]))) rows = [] for i, (user, messages, xp) in enumerate(sorted(users, key=itemgetter(2), reverse=True), start=1): rows.append( f"`#{i:2}` " + (f"LVL **{util.get_level(xp)}** - " if time is None else "") + f"**{util.displayname(user)}** `[{xp} XP | {messages} messages]`" ) content = discord.Embed(color=discord.Color.teal()) content.title = f"{'Global' if _global_ else guild.name} levels leaderboard" if time is not None: content.title += f" - {time}" await util.send_as_pages(ctx, content, rows)
async def on_raw_reaction_add(self, payload): """Starboard""" if payload.emoji.name == "⭐": starboard_settings = db.query( "SELECT starboard_toggle, starboard_amount, starboard_channel FROM guilds WHERE guild_id = ?", (payload.guild_id,) ) if starboard_settings is None: # starboard not configured on this server return else: starboard_settings = starboard_settings[0] if not util.int_to_bool(starboard_settings[0]): return message = await self.bot.get_channel(payload.channel_id).fetch_message(payload.message_id) for react in message.reactions: if react.emoji == payload.emoji.name: if react.count < starboard_settings[1]: return else: reaction_count = react.count break channel_id = starboard_settings[2] channel = payload.member.guild.get_channel(channel_id) if channel is None: return board_msg_id = db.query( "SELECT starboard_message_id FROM starboard WHERE message_id = ?", (payload.message_id,) ) if board_msg_id is None: # message is not on board yet, content = discord.Embed(color=discord.Color.gold()) content.set_author( name=f"{message.author}", icon_url=message.author.avatar_url ) jump = f"\n\n[context]({message.jump_url})" content.description = message.content[:2048-len(jump)] + jump content.timestamp = message.created_at content.set_footer(text=f"{reaction_count} ⭐ #{message.channel.name}") if len(message.attachments) > 0: content.set_image(url=message.attachments[0].url) board_message = await channel.send(embed=content) db.execute("INSERT INTO starboard VALUES(?, ?)", (payload.message_id, board_message.id)) else: # message is on board, update star count board_message = await channel.fetch_message(board_msg_id[0][0]) content = board_message.embeds[0] content.set_footer(text=f"{reaction_count} ⭐ #{message.channel.name}") await board_message.edit(embed=content)
async def check_reminders(self): """Checks all current reminders""" if self.cache_needs_refreshing: self.cache_needs_refreshing = False self.reminder_list = db.query("SELECT * FROM reminders") if not self.reminder_list: return now = arrow.utcnow().timestamp for reminder in self.reminder_list: # check if timestamp is in future # don't set variables yet to make runs as lightweight as possible if reminder[3] > now: continue user_id, guild_id, created_on, timestamp, thing, message_link = reminder user = self.bot.get_user(user_id) if user is not None: guild = self.bot.get_guild(guild_id) if guild is None: guild = "Deleted guild" date = arrow.get(created_on) try: await user.send(f":alarm_clock: The reminder you set {date.humanize()} `[ {date.format('DD/MM/YYYY HH:mm:ss')} ]` " f"in **{guild}** has expired!\n> {thing}\nContext: {message_link}") logger.info(f'reminded {user} to "{thing}"') except discord.errors.Forbidden: logger.warning(f'Unable to remind {user}, missing permissions') else: logger.info(f'deleted expired reminder by unknown user {user_id}') db.execute("""DELETE FROM reminders WHERE user_id = ? AND guild_id = ? AND message_link = ?""", (user_id, guild_id, message_link)) self.cache_needs_refreshing = True
async def remove(self, ctx, *, keyword): """Remove notification.""" dm = ctx.guild is None if dm: guild_id = 0 else: await ctx.message.delete() guild_id = ctx.guild.id check = db.query( "SELECT * FROM notifications WHERE guild_id = ? and user_id = ? and keyword = ?", (guild_id, ctx.author.id, keyword), ) if check is None: return await ctx.send(":warning: You don't have that notification." ) db.execute( "DELETE FROM notifications where guild_id = ? and user_id = ? and keyword = ?", (guild_id, ctx.author.id, keyword), ) await ctx.author.send( f":white_check_mark: Keyword notification `{keyword}` that you set " + ("globally" if dm else f"in `{ctx.guild.name}`") + " has been removed.") if not dm: await ctx.send("removed a notification!" + ( "" if dm else f" Check your DMs {emojis.VIVISMIRK}"))
async def list(self, ctx): """List your current notifications.""" words = db.query( "SELECT guild_id, keyword FROM notifications where user_id = ? ORDER BY keyword", (ctx.author.id, ), ) if words is None: return await ctx.send("You have not set any notifications yet!") guilds = {} for guild_id, keyword in words: guilds[guild_id] = guilds.get(guild_id, []) + [keyword] content = discord.Embed(title=":love_letter: Your notifications", color=discord.Color.red()) for guild_id in guilds: if guild_id == 0: guild_name = "Global" else: server = self.bot.get_guild(guild_id) if server is None: continue guild_name = server.name content.add_field( name=guild_name, value="\n".join(f"└`{x}`" for x in guilds.get(guild_id)), ) await ctx.author.send(embed=content) if ctx.guild is not None: await ctx.send( f"Notification list sent to your DMs {emojis.VIVISMIRK}")
async def donators(self, ctx): """List of people who have donated.""" tier_badges = [":coffee:", ":beer:", ":moneybag:"] patrons = db.query("select tier, user_id, currently_active from patrons") content = discord.Embed( title="Patreon supporters ❤", color=int("f96854", 16), description="https://patreon.com/joinemm\nhttps://ko-fi.com/joinemm", ) current = [] former = [] for tier, user_id, state in sorted(patrons, key=lambda x: x[0], reverse=True): user = self.bot.get_user(user_id) if util.int_to_bool(state): current.append(f"**{user or user_id}** {tier_badges[tier-1]}") else: former.append(f"{user or user_id}") if current: content.add_field(inline=False, name="Current patrons", value="\n".join(current)) if former: content.add_field(inline=False, name="Former patrons", value="\n".join(former)) await ctx.send(embed=content)
async def leaderboard_fishy(self, ctx, scope=''): _global_ = scope == 'global' users = db.query( "select user_id, fishy from fishy order by fishy desc") rows = [] rank_icon = [':first_place:', ':second_place:', ':third_place:'] rank = 1 for user_id, fishy in users: if _global_: user = self.bot.get_user(user_id) else: user = ctx.guild.get_member(user_id) if user is None: continue if fishy == 0: continue if rank <= len(rank_icon): ranking = rank_icon[rank - 1] else: ranking = f"`{rank}.`" rows.append(f"{ranking} {user.name} - **{fishy}** fishy") rank += 1 if not rows: return await ctx.send("Nobody has been fishing yet on this server!" ) content = discord.Embed( title= f"{'global' if _global_ else ctx.guild.name} fishy leaderboard", color=discord.Color.blue()) await util.send_as_pages(ctx, content, rows)
async def add(self, ctx, *, keyword): """Add a notification""" dm = ctx.guild is None if dm: guild_id = 0 else: await ctx.message.delete() guild_id = ctx.guild.id check = db.query( "SELECT * FROM notifications WHERE guild_id = ? and user_id = ? and keyword = ?", (guild_id, ctx.author.id, keyword), ) if check is not None: return await ctx.send( ":warning: You already have this notification!") db.execute( "REPLACE INTO notifications values(?, ?, ?)", (guild_id, ctx.author.id, keyword), ) await ctx.author.send( f":white_check_mark: New keyword notification `{keyword}` set " + ("globally" if dm else f"in `{ctx.guild.name}`")) if not dm: await ctx.send("Set a notification!" + ( "" if dm else f" Check your DMs {emojis.VIVISMIRK}"))
async def on_message_delete(self, message): """Listener that gets called when any message is deleted.""" # ignore bots if message.author.bot: return # ignore DMs if message.guild is None: return # ignore empty messages if len(message.content) == 0 and len(message.attachments) == 0: return # ignored channels if (db.query( "select * from deleted_messages_mask where channel_id = ?", (message.channel.id, ), ) is not None): return channel_id = db.get_setting(message.guild.id, "deleted_messages_channel") if channel_id is None: return channel = message.guild.get_channel(channel_id) if channel is None or message.channel == channel: return try: await channel.send(embed=util.message_embed(message)) except discord.errors.Forbidden: pass
async def topservers(self, ctx, user: discord.User = None): """See your top servers with miso bot.""" if user is None: user = ctx.author data = db.query( """SELECT guild_id, %s FROM activity WHERE user_id = ? GROUP BY guild_id ORDER BY %s DESC""" % (ALLSUM, ALLSUM), (user.id, ), ) rows = [] total_xp = 0 for i, (guild_id, xp) in enumerate(data, start=1): guild = self.bot.get_guild(guild_id) if guild is None: guild = guild_id else: guild = guild.name level = util.get_level(xp) total_xp += xp rows.append(f"`#{i}` **{guild}** — Level **{level}**") content = discord.Embed() content.set_author(name=f"{user.name}'s top servers", icon_url=ctx.author.avatar_url) content.set_footer(text=f"Global level {util.get_level(total_xp)}") content.colour = ctx.author.color await util.send_as_pages(ctx, content, rows)
async def remove(self, ctx, name): """Remove a role from the picker.""" roles = db.query("select rolename from roles where guild_id = ?", (ctx.guild.id,)) if name in [x[0] for x in roles]: db.execute("DELETE FROM roles WHERE guild_id = ? and rolename = ?", (ctx.guild.id, name)) await ctx.send(f"Removed `{name}` from the role picker.") else: return await ctx.send(":warning: Could not find this role from the picker")
def predicate(ctx): if ctx.author.id == ctx.bot.owner_id: return True else: patrons = db.query("select user_id from patrons where currently_active = 1") if ctx.author.id in [x[0] for x in patrons]: return True else: raise PatronCheckFailure
async def patron_toggle(self, ctx, user: discord.User): """Toggle user's patron status.""" current = util.int_to_bool( db.query("SELECT currently_active FROM patrons WHERE user_id = ?", (user.id, ))[0][0]) db.execute( "UPDATE patrons SET currently_active = ? WHERE user_id = ?", (util.bool_to_int(not current), user.id), ) await ctx.send(f"**{user}** patreon activity set to **{not current}**")
def custom_command_list(guild_id, match=""): """:returns list of custom commands on server""" command_list = set() data = db.query("SELECT command FROM customcommands WHERE guild_id = ?", (guild_id,)) if data is not None and len(data) > 0: for command in data: command = command[0] if match in command: command_list.add(command) return command_list
async def leaderboard_wpm(self, ctx, scope=''): _global_ = scope == 'global' userids = db.query("SELECT DISTINCT user_id FROM typingdata") if userids is None: return await ctx.send("No typing data exists yet!") users = [] for userid in userids: userid = userid[0] data = db.query( "SELECT MAX(wpm), `timestamp` FROM typingdata WHERE user_id = ?", (userid, ))[0] wpm = data[0] timestamp = data[1] if _global_: user = self.bot.get_user(userid) else: user = ctx.guild.get_member(userid) if user is None: continue users.append((user, wpm, timestamp)) if not users: return await ctx.send("No typing data exists yet on this server!") rows = [] rank_icon = [':first_place:', ':second_place:', ':third_place:'] for i, (user, wpm, timestamp) in enumerate(sorted(users, key=itemgetter(1), reverse=True), start=1): if i <= len(rank_icon): ranking = rank_icon[i - 1] else: ranking = f"`{i}.`" rows.append( f"{ranking} **{int(wpm)}** WPM — **{user.name}** ( {arrow.get(timestamp).humanize()} )" ) content = discord.Embed(title=":keyboard: WPM Leaderboard", color=discord.Color.orange()) await util.send_as_pages(ctx, content, rows)
async def determine_prefix(bot, message): """Get the prefix used in the invocation context.""" guild = message.guild prefix = bot.default_prefix if guild: data = db.query("SELECT prefix FROM prefixes WHERE guild_id = ?", (guild.id,)) if data is not None: prefix = data[0][0] return prefix
def __init__(self, ctx, blacklist_type): super().__init__() self.blacklist_type = blacklist_type delete = db.query( """SELECT delete_blacklisted FROM guilds WHERE guild_id = ?""", (ctx.guild.id, ), ) delete = delete[0][0] if delete is not None else 0 self.do_delete = delete == 1
def cache_emojis(self): for emoji in ['vivismirk', 'hyunjinwtf']: try: self.emojis[emoji] = self.bot.get_emoji( db.query("select id from emojis where name = ?", (emoji,))[0][0] ) except TypeError as e: self.emojis[emoji] = None if self.emojis[emoji] is None: logger.error(f"Unable to retrieve {emoji}")
async def emojistats(self, ctx, scope="server"): """ See most used emojis on server, globally, and optionally filtered by user. Usage: >emojistats >emojistats [mention] >emojistats global >emojistats global [mention] """ g = scope == "global" usertarget = ctx.message.mentions[0] if ctx.message.mentions else None query = "SELECT emoji, sum(count), emojitype FROM emoji_usage" params = [] if not g: query += " WHERE guild_id = ?" params.append(ctx.guild.id) if usertarget is not None: if not g: query += " AND user_id = ?" else: query += " WHERE user_id = ?" params.append(usertarget.id) query += " GROUP BY emoji ORDER BY sum(count) DESC" data = db.query(query, tuple(params)) if data is None: return await ctx.send("No emojis found!") rows = [] for i, (emoji, count, emojitype) in enumerate(data, start=1): if emojitype == "unicode": emoji_repr = unicode_codes.EMOJI_ALIAS_UNICODE.get(emoji) else: emoji_obj = self.bot.get_emoji(int(emoji.split(":")[-1].strip(">"))) if emoji_obj is not None and emoji_obj.is_usable(): emoji_repr = str(emoji_obj) else: emojiname = emoji.split(":")[0].strip("<") if len(emojiname) < 2: emojiname = emoji.split(":")[1] emoji_repr = "`" + emojiname + "`" rows.append(f"`#{i:2}` {emoji_repr} — **{count}** Use" + ("s" if count > 1 else "")) content = discord.Embed( title="Most used emojis" + (f" by {usertarget.name}" if usertarget is not None else "") + (", globally" if g else " on this server"), color=int("ffcc4d", 16), ) await util.send_as_pages(ctx, content, rows, maxrows=10)
async def editprofile_background(self, ctx, url): patrons = db.query( "select user_id from patrons where currently_active = 1") if ctx.author != self.bot.owner: if ctx.author.id not in [x[0] for x in patrons]: return await ctx.send( "Sorry, only patreon supporters can use this feature!") db.execute("INSERT OR IGNORE INTO profiles VALUES (?, ?, ?, ?)", (ctx.author.id, None, None, None)) db.execute("UPDATE profiles SET background_url = ? WHERE user_id = ?", (url, ctx.author.id)) await ctx.send("Background image updated!")
async def minecraft(self, ctx, address=None, port=None): """Get the status of a minecraft server.""" if address == "set": if port is None: return await ctx.send( f"Save minecraft server address for this discord server:\n" f"`{ctx.prefix}minecraft set <address>` (port defaults to 25565)\n" f"`{ctx.prefix}minecraft set <address>:<port>`") address = port.split(":")[0] try: port = int(port.split(":")[1]) except IndexError: port = 25565 db.execute( """REPLACE INTO minecraft VALUES (?, ?, ?)""", (ctx.guild.id, address, port), ) return await ctx.send( f"Minecraft server of this discord set to `{address}:{port}`") if address is None: serverdata = db.query( """SELECT address, port FROM minecraft WHERE guild_id = ?""", (ctx.guild.id, ), ) if serverdata is None: return await ctx.send( "No minecraft server saved for this discord server!") else: address, port = serverdata[0] server = await self.bot.loop.run_in_executor( None, lambda: minestat.MineStat(address, int(port or "25565"))) content = discord.Embed() content.colour = discord.Color.green() if server.online: content.add_field(name="Server Address", value=f"`{server.address}`") content.add_field(name="Version", value=server.version) content.add_field( name="Players", value=f"{server.current_players}/{server.max_players}") content.add_field(name="Latency", value=f"{server.latency}ms") content.set_footer(text=f"Message of the day: {server.motd}") else: content.description = ":warning: **Server is offline**" content.set_thumbnail( url="https://vignette.wikia.nocookie.net/potcoplayers/images/c/c2/" "Minecraft-icon-file-gzpvzfll.png/revision/latest?cb=20140813205910" ) await ctx.send(embed=content)
async def votechannel_remove(self, ctx, *, channel: discord.TextChannel): """Remove voting channel.""" if db.query( "SELECT * FROM votechannels WHERE guild_id = ? and channel_id = ?", (ctx.guild.id, channel.id)) is None: return await ctx.send( f":warning: {channel.mention} is not a voting channel!") db.execute( "DELETE FROM votechannels where guild_id = ? and channel_id = ?", (ctx.guild.id, channel_id)) await ctx.send(f"{channel.mention} is no longer a voting channel.")
async def remove(self, ctx, *, keyword): """Remove notification""" await ctx.message.delete() check = db.query("SELECT * FROM notifications WHERE guild_id = ? and user_id = ? and keyword = ?", (ctx.guild.id, ctx.author.id, keyword)) if check is None: return await ctx.send(f"You don't have that notification {self.emojis.get('hyunjinwtf')}") db.execute("DELETE FROM notifications where guild_id = ? and user_id = ? and keyword = ?", (ctx.guild.id, ctx.author.id, keyword)) await ctx.author.send(f"Notification for keyword `{keyword}` removed for `{ctx.guild.name}` ") await ctx.send(f"removed a notification! Check your DMs {self.emojis.get('vivismirk')}")
async def stats(self, ctx): """Get various bot statistics.""" most_used_command = db.query( """ SELECT command, MAX(countsum) FROM( SELECT command, SUM(count) as countsum FROM command_usage GROUP BY command )""" )[0] most_command_uses_by = db.query( """ SELECT user_id, MAX(countsum) FROM( SELECT user_id, SUM(count) as countsum FROM command_usage GROUP BY user_id )""" )[0] most_used_emoji = db.query( """ SELECT emoji, MAX(countsum) FROM( SELECT emoji, sum(count) as countsum FROM emoji_usage GROUP BY emoji )""" )[0] emoji_repr = unicode_codes.EMOJI_ALIAS_UNICODE.get(most_used_emoji[0]) data = [ ("Amount of commands", len(self.bot.commands)), ("Most used command", f"`>{most_used_command[0]}` ({most_used_command[1]})",), ( "Most total command uses", f"{self.bot.get_user(most_command_uses_by[0])} ({most_command_uses_by[1]})", ), ("Most used emoji", f"{emoji_repr} ({most_used_emoji[1]})",), ] content = discord.Embed( title=":bar_chart: Bot stats", description="\n".join(f"**{x[0]}** {x[1]}" for x in data), ) await ctx.send(embed=content)
async def add(self, ctx, *, keyword): """Add a notification""" await ctx.message.delete() check = db.query("SELECT * FROM notifications WHERE guild_id = ? and user_id = ? and keyword = ?", (ctx.guild.id, ctx.author.id, keyword)) if check is not None: return await ctx.send(f"You already have this notification {self.emojis.get('hyunjinwtf')}") db.execute("REPLACE INTO notifications values(?, ?, ?)", (ctx.guild.id, ctx.author.id, keyword)) await ctx.author.send(f"New notification for keyword `{keyword}` set in `{ctx.guild.name}` ") await ctx.send(f"Set a notification! Check your DMs {self.emojis.get('vivismirk')}")