import datetime import discord from discord.ext import commands import logging import os import pathlib import sqlite3 import typing class Activities(commands.Cog): """A cog to track and gather statistics on user activities.""" <<<<<<< HEAD """Related commands.""" __slots__ = ("nerd", "nerds", [REDACTED], [REDACTED]) ======= __slots__ = ("nerd", "nerds", "fword", "fwords") >>>>>>> 669339f (Made player controls based on Discord actions.) def __init__(self, bot): self.bot = bot self.logger = logging.getLogger("activities") <<<<<<< HEAD self.db = database.Database("[REDACTED]_bot.db") ======= >>>>>>> 669339f (Made player controls based on Discord actions.) async def __local_check(self, ctx): """A local check which applies to all commands in this cog.""" if not ctx.guild: raise commands.NoPrivateMessage return True async def __error(self, ctx, error): """A local error handler for all errors arising from commands in this cog.""" if isinstance(error, commands.NoPrivateMessage): try: return await ctx.send( 'This command can not be used in private messages.') except discord.HTTPException: pass print('Ignoring exception in command {}:'.format(ctx.command), file=sys.stderr) traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr) @commands.Cog.listener() async def on_presence_update( self, before: discord.Member, after: discord.Member): # Log the activity or status change if after.activity: self.logger.info( f"User '{before.name}' changed activity to "\ f"'{after.activity.name}'") else: self.logger.info( f"User '{before.name}' changed status to '{after.status}'") self.bot.db.insert_activity_change(before, after) @commands.command(name='nerd', aliases=['nerdscale'], description="Find how nerdy a user is.") async def nerd_(self, ctx, member: typing.Union[discord.Member, int, None]): """Clowns on users who play League of Legends. This command receives a user, computes the amount of time they have spent playing League of Legends, and will make fun of them if they have any time in it at all. It optionally takes no argument, and will find the user in the guild with the most time in League of Legends and call them out. Args: member (discord.Member, int, None, optional): The member to check for League stats. """ # If member is not defined, find the user with the most time if not member: members = [member.id for member in ctx.guild.members] else: if isinstance(member, discord.Member): members = [member.id] else: members = [member] # Get League stats for every member in guild league_stats = {} for m in members: league_stats[m] = datetime.timedelta() stats = self.db.get_activity_stats(m) sus = True if stats == {} else False for key, value in stats.items(): if 'leagueoflegends' in key.lower().strip().replace(' ', ''): league_stats[m] += value # Sort all users by time in League league_stats = dict(sorted( league_stats.items(), key=lambda x: x[1], reverse=True )) # Get top user user_id, time = next(iter(league_stats.items())) time_val = None time_units = None if time.total_seconds() // 3600 > 0: time_val = int(time.total_seconds() // 3600) time_units = "hours" if time_val > 1 else "hour" else: time_val = int(time.total_seconds() // 60) time_units = "minutes" if time_val > 1 else "minute" # Send Discord message to clown on user response = "" if member: if time_val != 0: descriptor = "" if time_units in ["hour", "hours"]: descriptor = "a massive fucking nerd" elif time_units in ["minutes", "minute"]: descriptor = "a huge nerd" else: descriptor = "a nerd" response = f"<@{user_id}> has played League for {time_val} "\ f"{time_units} in the past month, making them "\ f"{descriptor}." else: if sus: response = f"<@{user_id}> doesn't have any activities at "\ f"all. They're definitely hiding something." else: response = f"<@{user_id}> doesn't have any time in "\ f"League. They're not a nerd." else: response = ( f"<@{user_id}> has played League for {time_val} {time_units} "\ f"in the past month, making them the biggest nerd." ) await ctx.send(response) async def setup(bot): await bot.add_cog(Activities(bot))