141 lines
5.2 KiB
Python
141 lines
5.2 KiB
Python
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)) |