Skip to content
Closed
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
16 changes: 16 additions & 0 deletions cogs/tasks.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -18,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):
Expand Down Expand Up @@ -69,5 +72,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))
68 changes: 57 additions & 11 deletions src/presence.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import discord
import json
import random
import time

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.

Expand Down Expand Up @@ -32,36 +35,79 @@ 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
if str(game_id) not in games:
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(),
"last_seen": time.time()
}

# 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
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_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})"))
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}')
logger.error(f'Error processing user {user}: {e}')
Loading