diff --git a/.github/workflows/nvidia_workflow.yml b/.github/workflows/nvidia_workflow.yml index 7852377d..5cf7c0a3 100644 --- a/.github/workflows/nvidia_workflow.yml +++ b/.github/workflows/nvidia_workflow.yml @@ -28,6 +28,8 @@ jobs: - name: Create input files shell: bash run: | + # install jq + apt update && apt install -y jq # Extract the payload content without printing it PAYLOAD=$(jq -r '.inputs.payload' $GITHUB_EVENT_PATH) diff --git a/src/discord-cluster-manager/cogs/admin_cog.py b/src/discord-cluster-manager/cogs/admin_cog.py index 8e39ee2f..179ebfb6 100644 --- a/src/discord-cluster-manager/cogs/admin_cog.py +++ b/src/discord-cluster-manager/cogs/admin_cog.py @@ -763,7 +763,9 @@ async def update_competition( @with_error_handling @discord.app_commands.describe(last_day_only="Only show stats for the last day") - async def show_bot_stats(self, interaction: discord.Interaction, last_day_only: bool): + @discord.app_commands.describe(leaderboard_name="Name of the leaderboard") + @app_commands.autocomplete(leaderboard_name=leaderboard_name_autocomplete) + async def show_bot_stats(self, interaction: discord.Interaction, last_day_only: bool, leaderboard_name: Optional[str] = None): is_admin = await self.admin_check(interaction) if not is_admin: await send_discord_message( @@ -774,7 +776,7 @@ async def show_bot_stats(self, interaction: discord.Interaction, last_day_only: return with self.bot.leaderboard_db as db: - stats = db.generate_stats(last_day_only) + stats = db.generate_stats(last_day_only, leaderboard_name) msg = """```""" for k, v in stats.items(): msg += f"\n{k} = {v}" diff --git a/src/discord-cluster-manager/leaderboard_db.py b/src/discord-cluster-manager/leaderboard_db.py index d48e8404..bd695993 100644 --- a/src/discord-cluster-manager/leaderboard_db.py +++ b/src/discord-cluster-manager/leaderboard_db.py @@ -530,32 +530,36 @@ def get_leaderboard_submissions( for submission in self.cursor.fetchall() ] - def generate_stats(self, last_day: bool): + def generate_stats(self, last_day: bool, leaderboard_name: Optional[str] = None): try: - return self._generate_stats(last_day) + return self._generate_stats(last_day, leaderboard_name) except Exception as e: logging.exception("error generating stats", exc_info=e) raise - def _generate_runner_stats(self, last_day: bool = False): + def _generate_runner_stats(self, last_day: bool = False, leaderboard_name: Optional[str] = None): select_expr = "WHERE NOW() - s.submission_time <= interval '24 hours'" if last_day else "" + if leaderboard_name: + select_expr += f"AND s.leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = '{leaderboard_name}')" + if not last_day: + select_expr = select_expr.replace("AND", "WHERE") # per-runner stats self.cursor.execute( - f""" - SELECT - runner, - COUNT(*), - COUNT(*) FILTER (WHERE passed), - COUNT(score), - COUNT(*) FILTER (WHERE secret), - MAX(runs.start_time - s.submission_time), - AVG(runs.start_time - s.submission_time), - SUM(runs.end_time - runs.start_time) - FROM leaderboard.runs JOIN leaderboard.submission s ON submission_id = s.id - {select_expr} - GROUP BY runner; - """ - ) + f""" + SELECT + runner, + COUNT(*), + COUNT(*) FILTER (WHERE passed), + COUNT(score), + COUNT(*) FILTER (WHERE secret), + MAX(runs.start_time - s.submission_time), + AVG(runs.start_time - s.submission_time), + SUM(runs.end_time - runs.start_time) + FROM leaderboard.runs JOIN leaderboard.submission s ON submission_id = s.id + {select_expr} + GROUP BY runner; + """ + ) result = {} for row in self.cursor.fetchall(): @@ -569,19 +573,25 @@ def _generate_runner_stats(self, last_day: bool = False): return result - def _generate_submission_stats(self, last_day: bool = False): - select_expr = "WHERE NOW() - submission_time <= interval '24 hours'" if last_day else "" + def _generate_submission_stats(self, last_day: bool = False, leaderboard_name: Optional[str] = None): + select_expr = "WHERE NOW() - s.submission_time <= interval '24 hours'" if last_day else "" + leaderboard_filter = "" + if leaderboard_name: + leaderboard_filter = f"WHERE leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = '{leaderboard_name}')" + if last_day: + leaderboard_filter = leaderboard_filter.replace("WHERE", "AND", 1) + select_expr += leaderboard_filter self.cursor.execute( - f""" - SELECT - COUNT(*), - COUNT(*) FILTER (WHERE NOT done), - COUNT(DISTINCT user_id) - FROM leaderboard.submission - {select_expr} - ; - """ - ) + f""" + SELECT + COUNT(*), + COUNT(*) FILTER (WHERE NOT done), + COUNT(DISTINCT user_id) + FROM leaderboard.submission s + {select_expr} + ; + """, + ) num_sub, num_sub_wait, num_users = self.cursor.fetchone() return { "num_submissions": num_sub, @@ -589,30 +599,45 @@ def _generate_submission_stats(self, last_day: bool = False): "num_users": num_users, } - def _generate_stats(self, last_day: bool = False): - result = self._generate_submission_stats(last_day) - result.update(self._generate_runner_stats(last_day)) + def _generate_stats(self, last_day: bool = False, leaderboard_name: Optional[str] = None): + result = self._generate_submission_stats(last_day, leaderboard_name) + result.update(self._generate_runner_stats(last_day, leaderboard_name)) # code-level stats if not last_day: - self.cursor.execute( + leaderboard_filter = "" + if leaderboard_name: + leaderboard_filter = f""" + WHERE id IN ( + SELECT code_id FROM leaderboard.submission s + JOIN leaderboard.leaderboard l ON s.leaderboard_id = l.id + WHERE l.name = '{leaderboard_name}' + ) """ - SELECT COUNT(*) FROM leaderboard.code_files; + self.cursor.execute( + f""" + SELECT COUNT(*) FROM leaderboard.code_files + {leaderboard_filter}; """ ) result["num_unique_codes"] = self.cursor.fetchone()[0] else: # calculate heavy hitters + leaderboard_filter = "" + if leaderboard_name: + leaderboard_filter = f"AND l.name = '{leaderboard_name}'" self.cursor.execute( - """ + f""" WITH run_durations AS ( SELECT s.user_id AS user_id, r.end_time - r.start_time AS duration FROM leaderboard.runs r JOIN leaderboard.submission s ON r.submission_id = s.id + JOIN leaderboard.leaderboard l ON s.leaderboard_id = l.id WHERE NOW() - s.submission_time <= interval '24 hours' + {leaderboard_filter} ) SELECT user_id,