base-discord-bot/cogs/activities.py

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))