Update commands that no longer worked with new database
This commit is contained in:
parent
6e2ab01cbf
commit
f99e419a2b
176
cogs/stats.py
176
cogs/stats.py
|
@ -1,9 +1,9 @@
|
||||||
import discord
|
|
||||||
from discord.ext import commands
|
|
||||||
|
|
||||||
import utils
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import utils
|
||||||
|
import discord
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from discord.ext import commands
|
||||||
|
|
||||||
|
|
||||||
class Stats:
|
class Stats:
|
||||||
|
@ -12,6 +12,61 @@ class Stats:
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
|
async def _get_guild_usage(self, guild):
|
||||||
|
embed = discord.Embed(title="Server Command Usage")
|
||||||
|
count = await self.bot.db.fetchrow("SELECT COUNT(*), MIN(executed) FROM command_usage WHERE guild=$1", guild.id)
|
||||||
|
|
||||||
|
embed.description = f"{count[0]} total commands used"
|
||||||
|
embed.set_footer(text='Tracking command usage since').timestamp = count[1] or datetime.datetime.utcnow()
|
||||||
|
|
||||||
|
query = """
|
||||||
|
SELECT
|
||||||
|
command, COUNT(*) as uses
|
||||||
|
FROM
|
||||||
|
command_usage
|
||||||
|
WHERE
|
||||||
|
guild = $1
|
||||||
|
GROUP BY
|
||||||
|
command
|
||||||
|
ORDER BY
|
||||||
|
"uses" DESC
|
||||||
|
LIMIT 5
|
||||||
|
"""
|
||||||
|
|
||||||
|
results = await self.bot.db.fetch(query, guild.id)
|
||||||
|
value = "\n".join(f"{command} ({uses} uses)" for command, uses in results or "No Commands")
|
||||||
|
embed.add_field(name='Top Commands', value=value)
|
||||||
|
|
||||||
|
async def _get_member_usage(self, member):
|
||||||
|
embed = discord.Embed(title=f"{member.display_name} command usage")
|
||||||
|
count = await self.bot.db.fetchrow(
|
||||||
|
"SELECT COUNT(*), MIN(executed) FROM command_usage WHERE author=$1",
|
||||||
|
member.id
|
||||||
|
)
|
||||||
|
|
||||||
|
embed.description = f"{count[0]} total commands used"
|
||||||
|
embed.set_footer(text='Tracking command usage since').timestamp = count[1] or datetime.datetime.utcnow()
|
||||||
|
|
||||||
|
query = """
|
||||||
|
SELECT
|
||||||
|
command, COUNT(*) as uses
|
||||||
|
FROM
|
||||||
|
command_usage
|
||||||
|
WHERE
|
||||||
|
author = $1
|
||||||
|
GROUP BY
|
||||||
|
command
|
||||||
|
ORDER BY
|
||||||
|
"uses" DESC
|
||||||
|
LIMIT 5
|
||||||
|
"""
|
||||||
|
|
||||||
|
results = await self.bot.db.fetch(query, member.id)
|
||||||
|
value = "\n".join(f"{command} ({uses} uses)" for command, uses in results or "No Commands")
|
||||||
|
embed.add_field(name='Top Commands', value=value)
|
||||||
|
|
||||||
|
return embed
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@utils.can_run(send_messages=True)
|
@utils.can_run(send_messages=True)
|
||||||
|
@ -87,83 +142,17 @@ class Stats:
|
||||||
@command.command(name="stats")
|
@command.command(name="stats")
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@utils.can_run(send_messages=True)
|
@utils.can_run(send_messages=True)
|
||||||
async def command_stats(self, ctx, *, command):
|
async def command_stats(self, ctx, *, member: discord.Member = None):
|
||||||
"""This command can be used to view some usage stats about a specific command
|
"""This command can be used to view some usage stats about commands from either a user, or the server. Provide
|
||||||
|
a member if you want to view their usage, provide no one and the server's usage will be looked up"""
|
||||||
|
|
||||||
EXAMPLE: !command stats play
|
if member is None:
|
||||||
RESULT: The realization that this is the only reason people use me ;-;"""
|
embed = await self._get_guild_usage(ctx.guild)
|
||||||
cmd = self.bot.get_command(command)
|
else:
|
||||||
if cmd is None:
|
embed = await self._get_member_usage(member)
|
||||||
await ctx.send("`{}` is not a valid command".format(command))
|
|
||||||
return
|
|
||||||
|
|
||||||
command_stats = self.bot.db.load('command_usage', key=cmd.qualified_name)
|
|
||||||
if command_stats is None:
|
|
||||||
await ctx.send("That command has never been used! You know I worked hard on that! :c")
|
|
||||||
return
|
|
||||||
|
|
||||||
total_usage = command_stats['total_usage']
|
|
||||||
member_usage = command_stats['member_usage'].get(str(ctx.message.author.id), 0)
|
|
||||||
server_usage = command_stats['server_usage'].get(str(ctx.message.guild.id), 0)
|
|
||||||
|
|
||||||
embed = discord.Embed(title="Usage stats for {}".format(cmd.qualified_name))
|
|
||||||
embed.add_field(name="Total usage", value=total_usage, inline=False)
|
|
||||||
embed.add_field(name="Your usage", value=member_usage, inline=False)
|
|
||||||
embed.add_field(name="This server's usage", value=server_usage, inline=False)
|
|
||||||
|
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|
||||||
@command.command(name="leaderboard")
|
|
||||||
@utils.can_run(send_messages=True)
|
|
||||||
async def command_leaderboard(self, ctx, option="server"):
|
|
||||||
"""This command can be used to print a leaderboard of commands
|
|
||||||
Provide 'server' to print a leaderboard for this server
|
|
||||||
Provide 'me' to print a leaderboard for your own usage
|
|
||||||
|
|
||||||
EXAMPLE: !command leaderboard me
|
|
||||||
RESULT: The realization of how little of a life you have"""
|
|
||||||
if re.search('(author|me)', option):
|
|
||||||
mid = str(ctx.message.author.id)
|
|
||||||
# First lets get all the command usage
|
|
||||||
command_stats = self.bot.db.load('command_usage')
|
|
||||||
# Now use a dictionary comprehension to get just the command name, and usage
|
|
||||||
# Based on the author's usage of the command
|
|
||||||
|
|
||||||
stats = {
|
|
||||||
command: data["member_usage"].get(mid)
|
|
||||||
for command, data in command_stats.items()
|
|
||||||
if data["member_usage"].get(mid, 0) > 0
|
|
||||||
}
|
|
||||||
# Now sort it by the amount of times used
|
|
||||||
sorted_stats = sorted(stats.items(), key=lambda x: x[1], reverse=True)[:5]
|
|
||||||
embed = discord.Embed(title="Your top 5 commands", colour=ctx.author.colour)
|
|
||||||
embed.set_author(name=str(ctx.author), icon_url=ctx.author.avatar_url)
|
|
||||||
|
|
||||||
for cmd, amount in sorted_stats:
|
|
||||||
embed.add_field(name=cmd, value=amount, inline=False)
|
|
||||||
|
|
||||||
await ctx.send(embed=embed)
|
|
||||||
elif re.search('server', option):
|
|
||||||
# This is exactly the same as above, except server usage instead of member usage
|
|
||||||
sid = str(ctx.message.guild.id)
|
|
||||||
command_stats = self.bot.db.load('command_usage')
|
|
||||||
stats = {
|
|
||||||
command: data['server_usage'].get(sid)
|
|
||||||
for command, data in command_stats.items()
|
|
||||||
if data.get("server_usage", {}).get(sid, 0) > 0
|
|
||||||
}
|
|
||||||
sorted_stats = sorted(stats.items(), key=lambda x: x[1], reverse=True)[:5]
|
|
||||||
embed = discord.Embed(title="The server's top 5 commands")
|
|
||||||
embed.set_author(name=ctx.guild.name, icon_url=ctx.guild.icon_url)
|
|
||||||
|
|
||||||
for cmd, amount in sorted_stats:
|
|
||||||
embed.add_field(name=cmd, value=amount, inline=False)
|
|
||||||
|
|
||||||
await ctx.send(embed=embed)
|
|
||||||
|
|
||||||
else:
|
|
||||||
await ctx.send("That is not a valid option, valid options are: `server` or `me`")
|
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@utils.can_run(send_messages=True)
|
@utils.can_run(send_messages=True)
|
||||||
|
@ -188,7 +177,7 @@ LIMIT 1
|
||||||
members = [m.id for m in ctx.guild.members]
|
members = [m.id for m in ctx.guild.members]
|
||||||
most = await self.bot.db.fetchrow(query, ctx.author.id, members)
|
most = await self.bot.db.fetchrow(query, ctx.author.id, members)
|
||||||
|
|
||||||
if len(most) == 0:
|
if most is None or len(most) == 0:
|
||||||
await ctx.send(f"You have not booped anyone in this server {ctx.author.mention}")
|
await ctx.send(f"You have not booped anyone in this server {ctx.author.mention}")
|
||||||
else:
|
else:
|
||||||
member = ctx.guild.get_member(most['boopee'])
|
member = ctx.guild.get_member(most['boopee'])
|
||||||
|
@ -280,16 +269,35 @@ ORDER BY
|
||||||
RESULT: How good they are at winning a completely luck based game"""
|
RESULT: How good they are at winning a completely luck based game"""
|
||||||
member = member or ctx.message.author
|
member = member or ctx.message.author
|
||||||
# Get the different data that we'll display
|
# Get the different data that we'll display
|
||||||
server_rank = "{}/{}".format(*self.bot.br.get_server_rank(member))
|
query = """
|
||||||
overall_rank = "{}/{}".format(*self.bot.br.get_rank(member))
|
SELECT id, rank, battle_rating, battle_wins, battle_losses
|
||||||
rating = self.bot.br.get_rating(member)
|
FROM
|
||||||
record = self.bot.br.get_record(member)
|
(SELECT
|
||||||
|
id,
|
||||||
|
ROW_NUMBER () OVER (ORDER BY battle_rating DESC) as "rank",
|
||||||
|
battle_rating,
|
||||||
|
battle_wins,
|
||||||
|
battle_losses
|
||||||
|
FROM
|
||||||
|
users
|
||||||
|
WHERE
|
||||||
|
id = any($1::bigint[]) AND
|
||||||
|
battle_rating IS NOT NULL
|
||||||
|
) AS sub
|
||||||
|
WHERE id = $2
|
||||||
|
"""
|
||||||
|
member_list = [m.id for m in ctx.guild.members]
|
||||||
|
result = await ctx.bot.db.fetch(query, member_list, member.id)
|
||||||
|
server_rank = result["rank"]
|
||||||
|
# overall_rank = "{}/{}".format(*self.bot.br.get_rank(member))
|
||||||
|
rating = result["battle_rating"]
|
||||||
|
record = f"{result['battle_wins']} - {result['battle_losses']}"
|
||||||
|
|
||||||
embed = discord.Embed(title="Battling stats for {}".format(ctx.author.display_name), colour=ctx.author.colour)
|
embed = discord.Embed(title="Battling stats for {}".format(ctx.author.display_name), colour=ctx.author.colour)
|
||||||
embed.set_author(name=str(member), icon_url=member.avatar_url)
|
embed.set_author(name=str(member), icon_url=member.avatar_url)
|
||||||
embed.add_field(name="Record", value=record, inline=False)
|
embed.add_field(name="Record", value=record, inline=False)
|
||||||
embed.add_field(name="Server Rank", value=server_rank, inline=False)
|
embed.add_field(name="Server Rank", value=server_rank, inline=False)
|
||||||
embed.add_field(name="Overall Rank", value=overall_rank, inline=False)
|
# embed.add_field(name="Overall Rank", value=overall_rank, inline=False)
|
||||||
embed.add_field(name="Rating", value=rating, inline=False)
|
embed.add_field(name="Rating", value=rating, inline=False)
|
||||||
|
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|
|
@ -128,22 +128,26 @@ async def update_records(key, db, winner, loser):
|
||||||
wins = f"{key}_wins"
|
wins = f"{key}_wins"
|
||||||
losses = f"{key}_losses"
|
losses = f"{key}_losses"
|
||||||
key = f"{key}_rating"
|
key = f"{key}_rating"
|
||||||
query = """
|
winner_found = False
|
||||||
SELECT
|
loser_found = False
|
||||||
id, $1, $2, $3
|
query = f"SELECT id, {key}, {wins}, {losses} FROM users WHERE id = any($1::bigint[])"
|
||||||
FROM
|
results = await db.fetch(query, [winner.id, loser.id])
|
||||||
users
|
|
||||||
WHERE
|
|
||||||
id = any($4::bigint[])
|
|
||||||
"""
|
|
||||||
results = await db.fetch(key, wins, losses, [winner.id, loser.id])
|
|
||||||
|
|
||||||
|
# Set our defaults for the stats
|
||||||
winner_rating = loser_rating = 1000
|
winner_rating = loser_rating = 1000
|
||||||
|
winner_wins = loser_wins = 0
|
||||||
|
winner_losses = loser_losses = 0
|
||||||
for result in results:
|
for result in results:
|
||||||
if result['id'] == winner.id:
|
if result['id'] == winner.id:
|
||||||
|
winner_found = True
|
||||||
winner_rating = result[key]
|
winner_rating = result[key]
|
||||||
|
winner_wins = result[wins]
|
||||||
|
winner_losses = result[losses]
|
||||||
else:
|
else:
|
||||||
|
loser_found = True
|
||||||
loser_rating = result[key]
|
loser_rating = result[key]
|
||||||
|
loser_wins = result[wins]
|
||||||
|
loser_losses = result[losses]
|
||||||
|
|
||||||
# The scale is based off of increments of 25, increasing the change by 1 for each increment
|
# The scale is based off of increments of 25, increasing the change by 1 for each increment
|
||||||
# That is all this loop does, increment the "change" for every increment of 25
|
# That is all this loop does, increment the "change" for every increment of 25
|
||||||
|
@ -165,17 +169,19 @@ WHERE
|
||||||
winner_rating += 16 + rating_change
|
winner_rating += 16 + rating_change
|
||||||
loser_rating -= 16 + rating_change
|
loser_rating -= 16 + rating_change
|
||||||
|
|
||||||
# Just increase wins/losses for each person, making sure it's at least 0
|
# Just increase wins/losses for each person
|
||||||
winner_wins = winner_stats.get('wins', 0)
|
|
||||||
winner_losses = winner_stats.get('losses', 0)
|
|
||||||
loser_wins = loser_stats.get('wins', 0)
|
|
||||||
loser_losses = loser_stats.get('losses', 0)
|
|
||||||
winner_wins += 1
|
winner_wins += 1
|
||||||
loser_losses += 1
|
loser_losses += 1
|
||||||
|
|
||||||
# Now save the new wins, losses, and ratings
|
update_query = f"UPDATE users SET {key}=$1, {wins}=$2, {losses}=$3 WHERE id = $4"
|
||||||
winner_stats = {'wins': winner_wins, 'losses': winner_losses, 'rating': winner_rating, 'member_id': str(winner.id)}
|
create_query = f"INSERT INTO users ({key}, {wins}, {losses}, id) VALUES ($1, $2, $3, $4)"
|
||||||
loser_stats = {'wins': loser_wins, 'losses': loser_losses, 'rating': loser_rating, 'member_id': str(loser.id)}
|
if winner_found:
|
||||||
|
await db.execute(update_query, winner_rating, winner_wins, winner_losses, winner.id)
|
||||||
|
else:
|
||||||
|
await db.execute(create_query, winner_rating, winner_wins, winner_losses, winner.id)
|
||||||
|
if loser_found:
|
||||||
|
await db.execute(update_query, loser_rating, loser_wins, loser_losses, loser.id)
|
||||||
|
else:
|
||||||
|
await db.execute(create_query, loser_rating, loser_wins, loser_losses, loser.id)
|
||||||
|
|
||||||
|
|
||||||
await db.save(key, winner_stats)
|
|
||||||
await db.save(key, loser_stats)
|
|
||||||
|
|
Loading…
Reference in a new issue