From 69e670ec8c99a5d3b297619fefe392d9c109aea7 Mon Sep 17 00:00:00 2001 From: deb Date: Sun, 8 Feb 2026 00:52:09 -0500 Subject: [PATCH 1/4] - Add username to JSON file to bot and presence object - add task to clear games Json folder periodically to improve stale game presence --- cogs/tasks.py | 15 +++++++++++++++ src/presence.py | 13 ++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/cogs/tasks.py b/cogs/tasks.py index 0058c4e..ed7b90a 100644 --- a/cogs/tasks.py +++ b/cogs/tasks.py @@ -1,4 +1,6 @@ import asyncio +import json + from discord.ext import tasks, commands from src.achievements import process_achievements from src.daily_overview import process_daily_overview @@ -69,5 +71,18 @@ async def before_process_presence(self): logger.info(f'Waiting {delay} seconds for Presence task to start') await asyncio.sleep(delay) # Wait for the specified delay + @tasks.loop(hours=72) # Clear games.json every 3 days + async def clear_games_json(self): + try: + with open('games.json', 'w') as f: + json.dump({}, f) + logger.info('Cleared games.json file.') + except Exception as e: + logger.error(f'Error clearing games.json: {e}') + + @clear_games_json.before_loop + async def before_clear_games_json(self): + await self.bot.wait_until_ready() + async def setup(bot): await bot.add_cog(TasksCog(bot, start_delay=TASK_START_DELAY)) \ No newline at end of file diff --git a/src/presence.py b/src/presence.py index 829b86e..8772f08 100644 --- a/src/presence.py +++ b/src/presence.py @@ -4,6 +4,7 @@ from services.api import UserProfile, GameDetails from utils.custom_logger import logger + async def process_presence(bot, user, api_username, api_key): """Process the presence of a user in Discord by randomly setting their rich presence from games.json or adding new games. @@ -40,14 +41,14 @@ def get_or_fetch_game(game_id): logger.info(f"Fetching game ID {game_id} from API.") game_details = GameDetails(game_id, api_username, api_key) game = game_details.get_game() - games[str(game_id)] = {"title": game.title, "platform": game.remap_console_name()} - + games[str(game_id)] = {"user": user_profile, "title": game.title, "platform": game.remap_console_name()} + # Save the new game to games.json with open('games.json', 'w') as f: json.dump(games, f, indent=4) else: logger.info(f"Game ID {game_id} found in JSON.") - + return games # Fetch or add the last played game to games.json @@ -55,13 +56,15 @@ def get_or_fetch_game(game_id): # Pick a random game from the updated games.json random_game_id = random.choice(list(games.keys())) + game_user = games[user] game_data = games[random_game_id] game_title = game_data["title"] game_platform = game_data["platform"] # Set rich presence to a randomly selected game - await bot.change_presence(activity=discord.Game(name=f"{game_title} ({game_platform})")) + await bot.change_presence(activity=discord.Game(name=f"{game_title} ({game_platform})\nUser: {game_user}")) logger.info(f"Setting rich presence for {user} to {game_title} ({game_platform})") - + + except Exception as e: logger.error(f'Error processing user {user}: {e}') \ No newline at end of file From 230f02b8b3f8c1fe45d791619165a2af017a2fa4 Mon Sep 17 00:00:00 2001 From: Edward Gaborko <35812870+gorbster37@users.noreply.github.com> Date: Mon, 9 Feb 2026 22:11:19 -0500 Subject: [PATCH 2/4] Presence Tweaks (#1) * - Add username to JSON file to bot and presence object - add task to clear games Json folder periodically to improve stale game presence * small formatting fic * small fix * Fix games.json file * update newline to single line, discord does not support new lines * Update presence.py formatting --------- Co-authored-by: deb --- cogs/tasks.py | 15 +++++++++++++++ src/presence.py | 16 +++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/cogs/tasks.py b/cogs/tasks.py index 0058c4e..ed7b90a 100644 --- a/cogs/tasks.py +++ b/cogs/tasks.py @@ -1,4 +1,6 @@ import asyncio +import json + from discord.ext import tasks, commands from src.achievements import process_achievements from src.daily_overview import process_daily_overview @@ -69,5 +71,18 @@ async def before_process_presence(self): logger.info(f'Waiting {delay} seconds for Presence task to start') await asyncio.sleep(delay) # Wait for the specified delay + @tasks.loop(hours=72) # Clear games.json every 3 days + async def clear_games_json(self): + try: + with open('games.json', 'w') as f: + json.dump({}, f) + logger.info('Cleared games.json file.') + except Exception as e: + logger.error(f'Error clearing games.json: {e}') + + @clear_games_json.before_loop + async def before_clear_games_json(self): + await self.bot.wait_until_ready() + async def setup(bot): await bot.add_cog(TasksCog(bot, start_delay=TASK_START_DELAY)) \ No newline at end of file diff --git a/src/presence.py b/src/presence.py index 829b86e..a192113 100644 --- a/src/presence.py +++ b/src/presence.py @@ -4,6 +4,7 @@ from services.api import UserProfile, GameDetails from utils.custom_logger import logger + async def process_presence(bot, user, api_username, api_key): """Process the presence of a user in Discord by randomly setting their rich presence from games.json or adding new games. @@ -32,7 +33,8 @@ def get_or_fetch_game(game_id): try: with open('games.json', 'r') as f: games = json.load(f) - except FileNotFoundError: + except (FileNotFoundError, json.JSONDecodeError): + logger.warning("games.json not found or corrupted, starting fresh.") games = {} # If the game is not in games.json, fetch and add it @@ -40,14 +42,13 @@ def get_or_fetch_game(game_id): logger.info(f"Fetching game ID {game_id} from API.") game_details = GameDetails(game_id, api_username, api_key) game = game_details.get_game() - games[str(game_id)] = {"title": game.title, "platform": game.remap_console_name()} - + games[str(game_id)] = {"user": user, "title": game.title, "platform": game.remap_console_name()} + # Save the new game to games.json with open('games.json', 'w') as f: json.dump(games, f, indent=4) else: logger.info(f"Game ID {game_id} found in JSON.") - return games # Fetch or add the last played game to games.json @@ -56,12 +57,13 @@ def get_or_fetch_game(game_id): # Pick a random game from the updated games.json random_game_id = random.choice(list(games.keys())) game_data = games[random_game_id] + game_user = game_data["user"] game_title = game_data["title"] game_platform = game_data["platform"] # Set rich presence to a randomly selected game - await bot.change_presence(activity=discord.Game(name=f"{game_title} ({game_platform})")) + await bot.change_presence(activity=discord.Game(name=f"{game_title} ({game_platform}) | User: {game_user}")) logger.info(f"Setting rich presence for {user} to {game_title} ({game_platform})") - + except Exception as e: - logger.error(f'Error processing user {user}: {e}') \ No newline at end of file + logger.error(f'Error processing user {user}: {e}') From ab286b6ddfbc16456792cdfb9d6fa91b837a1d04 Mon Sep 17 00:00:00 2001 From: deb Date: Mon, 13 Apr 2026 18:27:27 -0400 Subject: [PATCH 3/4] start task --- cogs/tasks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/tasks.py b/cogs/tasks.py index ed7b90a..bc02fda 100644 --- a/cogs/tasks.py +++ b/cogs/tasks.py @@ -20,6 +20,7 @@ def __init__(self, bot: commands.Bot, start_delay: dict = None) -> None: self.users = users self.current_user_index = 0 self.process_presence.start() + self.clear_games_json.start() @tasks.loop(minutes=RETROACHIEVEMENTS_INTERVAL) async def process_achievements(self): From 97efda94b23e2cda43d5a2b115beb42539ab5325 Mon Sep 17 00:00:00 2001 From: deb Date: Mon, 13 Apr 2026 18:45:57 -0400 Subject: [PATCH 4/4] Presence selection changes --- src/presence.py | 56 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/presence.py b/src/presence.py index a192113..acf4006 100644 --- a/src/presence.py +++ b/src/presence.py @@ -1,6 +1,8 @@ import discord import json import random +import time + from services.api import UserProfile, GameDetails from utils.custom_logger import logger @@ -42,7 +44,12 @@ def get_or_fetch_game(game_id): logger.info(f"Fetching game ID {game_id} from API.") game_details = GameDetails(game_id, api_username, api_key) game = game_details.get_game() - games[str(game_id)] = {"user": user, "title": game.title, "platform": game.remap_console_name()} + games[str(game_id)] = { + "user": user, + "title": game.title, + "platform": game.remap_console_name(), + "last_seen": time.time() + } # Save the new game to games.json with open('games.json', 'w') as f: @@ -55,11 +62,48 @@ def get_or_fetch_game(game_id): games = get_or_fetch_game(last_game_id) # Pick a random game from the updated games.json - random_game_id = random.choice(list(games.keys())) - game_data = games[random_game_id] - game_user = game_data["user"] - game_title = game_data["title"] - game_platform = game_data["platform"] + # Sort games by most recent activity + sorted_games = sorted( + games.items(), + key=lambda item: item[1].get("last_seen", 0), + reverse=True + ) + + # Take only the last 5 most recent games + recent_games = sorted_games[:5] + + # Safety fallback (if games.json is empty) + if not recent_games: + return + + # Remove same user as last presence (no back-to-back users) + if process_presence.last_presence_user is not None: + filtered_games = [ + g for g in recent_games + if g[1].get("user") != process_presence.last_presence_user + ] + + # If filtering removes everything, fall back to original list + if filtered_games: + recent_games = filtered_games + + # Pick randomly from recent pool + random_game_id, game_data = random.choice(recent_games) + + # Extract selected game info + game_title = game_data.get("title") + game_platform = game_data.get("platform") + game_user = game_data.get("user") + + # Store last user to prevent repeats + process_presence.last_presence_user = game_user + + # Update last_seen for selected game + games[random_game_id]["last_seen"] = time.time() + + # Save updated games.json + with open('games.json', 'w') as f: + json.dump(games, f, indent=4) # Set rich presence to a randomly selected game await bot.change_presence(activity=discord.Game(name=f"{game_title} ({game_platform}) | User: {game_user}"))