Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make command stats persistent #108

Merged
merged 1 commit into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions cogs/Info.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,34 +61,6 @@ async def weather(
else:
await inter.send(embed=e)

@commands.slash_command(description="Stats about the commands that have been ran")
@commands.cooldown(1, 5, commands.BucketType.user)
async def cmdstats(self, inter):
cmdsran = self.bot.commands_ran
sortdict = dict(sorted(cmdsran.items(), key=lambda x: x[1], reverse=True))
value_iterator = iter(sortdict.values())
key_iterator = iter(sortdict.keys())
emby = disnake.Embed(
title=f"{self.bot.user.display_name} command Stats",
description=f"{self.bot.total_commands_ran} Commands ran this boot\n",
color=disnake.Color.random(),
)
emby.add_field(
name="Top 10 commands ran",
value=f"🥇: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
f"🥈: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
f"🥉: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
f"🏅: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
f"🏅: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
f"🏅: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
f"🏅: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
f"🏅: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
f"🏅: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
f"🏅: /{next(key_iterator)} ({next(value_iterator)} uses)\n",
)

await inter.send(embed=emby)

@commands.slash_command(description="Display current price of BTC")
@commands.cooldown(1, 5, commands.BucketType.user)
async def btc(self, inter):
Expand Down
83 changes: 83 additions & 0 deletions cogs/Stats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import disnake
from disnake.ext import commands, tasks

from utils.bot import OGIROID


class Stats(commands.Cog):
def __init__(self, bot: OGIROID):
self.bot = bot
self.update_stats.start()

def cog_unload(self):
self.update_stats.cancel()

@tasks.loop(hours=1)
async def update_stats(self):
# add command usage to db
commands_ran = self.bot.commands_ran
total_commands_ran = self.bot.total_commands_ran

for guild_id, guild_commands_ran in commands_ran.items():
for command, count in guild_commands_ran.items():
await self.bot.db.execute(
"INSERT INTO commands (guild_id, command, command_used) VALUES ($1, $2, $3) ON CONFLICT (guild_id, command) DO UPDATE SET command_used = commands.command_used + $3;",
guild_id,
command,
count,
)

for guild_id, count in total_commands_ran.items():
await self.bot.db.execute(
"INSERT INTO total_commands (guild_id, total_commands_used) VALUES ($1, $2) ON CONFLICT (guild_id) DO UPDATE SET total_commands_used = total_commands.total_commands_used + $2;",
guild_id,
count,
)

# reset command usage
self.bot.commands_ran = {}
self.bot.total_commands_ran = {}

@commands.slash_command(description="Stats about the commands that have been ran")
@commands.cooldown(1, 5, commands.BucketType.user)
async def cmdstats(self, inter):
await inter.response.defer()
cmdsran = await self.bot.db.fetch(
"SELECT command, command_used FROM commands WHERE guild_id = $1 ORDER BY command_used DESC LIMIT 10;",
inter.guild.id,
)
cmdsran = dict(cmdsran)

total_commands_ran = await self.bot.db.fetchval(
"SELECT total_commands_used FROM total_commands WHERE guild_id = $1;",
inter.guild.id,
)
sortdict = dict(sorted(cmdsran.items(), key=lambda x: x[1], reverse=True))
value_iterator = iter(sortdict.values())
key_iterator = iter(sortdict.keys())
emby = disnake.Embed(
title=f"{self.bot.user.display_name} command Stats",
description=f"{total_commands_ran} Commands ran in total.\n",
color=self.bot.config.colors.white,
)

text = (
f"🥇: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
+ f"🥈: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
+ f"🥉: /{next(key_iterator)} ({next(value_iterator)} uses)\n"
)
i = 2
for key in key_iterator:
text += f"🏅: /{key} ({next(value_iterator)} uses)\n"
i += 1
# total 10
if i == 10:
break

emby.add_field(name="Top 10 commands ran", value=text)

await inter.send(embed=emby)


def setup(bot):
bot.add_cog(Stats(bot))
14 changes: 13 additions & 1 deletion setup.sql
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,16 @@ CREATE TABLE IF NOT EXISTS config
UNIQUE(guild_id)
);

DROP TABLE IF EXISTS xp_boosts_user;
CREATE TABLE IF NOT EXISTS commands
(
guild_id BIGINT,
command TEXT,
command_used INTEGER DEFAULT 0,
UNIQUE (guild_id, command)
);

CREATE TABLE IF NOT EXISTS total_commands
(
guild_id BIGINT UNIQUE,
total_commands_used INTEGER DEFAULT 0
);
28 changes: 15 additions & 13 deletions utils/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import disnake
from disnake import ApplicationCommandInteraction, OptionType
from disnake.ext import commands
from disnake.ext.commands.interaction_bot_base import CFT

from utils.CONSTANTS import __VERSION__
from utils.DBhandlers import BlacklistHandler
Expand All @@ -32,7 +33,7 @@ def __init__(self, *args, **kwargs):
self.session = HTTPSession(loop=self.loop)
self.config = Config()
self.commands_ran = {}
self.total_commands_ran = 0
self.total_commands_ran = {}
self.db = None
self.blacklist: BlacklistHandler = None
self.add_app_command_check(
Expand All @@ -49,13 +50,6 @@ async def blacklist_check(self, ctx):
except AttributeError:
pass # DB hasn't loaded yet

async def on_command(self, ctx):
self.total_commands_ran += 1
try:
self.commands_ran[ctx.command.qualified_name] += 1
except KeyError:
self.commands_ran[ctx.command.qualified_name] = 1

@async_cache(maxsize=0)
async def on_slash_command(self, inter: ApplicationCommandInteraction):
COMMAND_STRUCT = [inter.data]
Expand Down Expand Up @@ -84,11 +78,19 @@ async def on_slash_command(self, inter: ApplicationCommandInteraction):
break

COMMAND_NAME = " ".join([command.name for command in COMMAND_STRUCT])
self.total_commands_ran += 1

try:
self.total_commands_ran[inter.guild.id] += 1
except KeyError:
self.total_commands_ran[inter.guild.id] = 1

if self.commands_ran.get(inter.guild.id) is None:
self.commands_ran[inter.guild.id] = {}

try:
self.commands_ran[COMMAND_NAME] += 1
self.commands_ran[inter.guild.id][COMMAND_NAME] += 1
except KeyError:
self.commands_ran[COMMAND_NAME] = 1
self.commands_ran[inter.guild.id][COMMAND_NAME] = 1

async def on_ready(self):
if not self._ready_:
Expand Down Expand Up @@ -117,8 +119,8 @@ async def on_ready(self):
print("Bot reconnected")

async def _setup(self):
for command in self.application_commands:
self.commands_ran[f"{command.qualified_name}"] = 0
# for command in self.application_commands:
# self.commands_ran[f"{command.qualified_name}"] = 0
self.blacklist: BlacklistHandler = BlacklistHandler(self, self.db)
await self.blacklist.startup()

Expand Down