base-discord-bot/cogs/activities.py

119 lines
4.4 KiB
Python

import datetime
import discord
from discord.ext import commands
import logging
import os
import pathlib
import sqlite3
import typing
import database
class Activities(commands.Cog):
"""Related commands."""
__slots__ = ("nerd", "nerds", "fword", "fwords")
def __init__(self, bot):
self.bot = bot
self.logger = logging.getLogger("activities")
self.db = database.Database("boywife_bot.db")
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
self.logger.info("Received activity change; logging")
self.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]):
"""Checks the play history of all users in the Discord server, and
based on how many hours they have in League of Legends compared to
other users, declare how nerdy they are."""
# 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))