Files
kwaylon/robopage.py

136 lines
4.7 KiB
Python

import json
import logging
import os
import re
from pathlib import Path
from typing import Union
import discord
from discord import RawReactionActionEvent, RawReactionClearEmojiEvent
from dotenv import load_dotenv
import data
import jokes
logging.basicConfig(level=logging.INFO)
LIL_STINKY_ID = 704043422276780072
LOGGER = logging.getLogger(__name__)
class RoboPage(discord.Client):
db_path: str = 'messages.db'
def __init__(self, *args, **kwargs):
super(RoboPage, self).__init__(*args, **kwargs)
attrs = filter(lambda n: n.endswith('Joke') and n not in ['Joke', 'GifJoke'], dir(jokes))
attrs = map(lambda n: getattr(jokes, n)(), attrs)
self.jokes = list(attrs)
self.most_regex = re.compile(
"^who is the most (?P<emoji>\w+)(?: in the past (?P<days>\d+) days)?\??$",
re.IGNORECASE
)
self.leaderboard_regex = re.compile(
'^most (?P<emoji>\w+)(?=(?:.+)?leaderboard)(?:.+(?P<days>\d+) days)?',
re.IGNORECASE
)
with Path('gifs.json').open('r') as file:
self.gifs = json.load(file)
def run(self):
return super().run(os.getenv('DISCORD_TOKEN'))
async def handle_ready(self):
async def alive():
channel: discord.TextChannel = discord.utils.get(self.get_all_channels(), name='robotics-facility')
await channel.send(f"I'm aliiiiiive {discord.utils.get(self.emojis, name='kaylon')}")
self.data: data.MsgData = await data.MsgData.create(
client=self,
# limit=5000,
limit=20,
# days=30,
)
self.data.to_sql('messages.db')
LOGGER.info(f'{self.data.msgs.shape[0]} messages total')
# await alive()
async def handle_message(self, message):
if message.author != self.user:
if hasattr(self, 'data'):
await self.data.add_msg(message)
if (m := self.leaderboard_regex.match(message.content)) is not None:
days = int(m.group('days')) or 14
emoji = m.group('emoji').lower()
try:
await message.reply(
await self.data.emoji_leaderboard(client=self, emoji_name=emoji, days=days)
)
except KeyError as e:
LOGGER.exception(e)
await message.reply(f"I couldn't find any {m.group('emoji')} reactions. Leave me alone!")
return
elif (m := self.most_regex.match(message.content)) is not None:
days = int(m.group('days')) or 14
emoji = m.group('emoji').lower()
try:
await message.reply(
await self.data.biggest_single(client=self, emoji=emoji, days=days))
except IndexError as e:
await message.reply('NObody')
return
for joke in self.jokes:
if (scan_res := joke.scan(message)):
LOGGER.info(f'{joke.__class__.__name__} detected: {message.content}, {scan_res.group()}')
await joke.respond(message, self, scan_res)
async def handle_raw_reaction(self, payload: Union[RawReactionActionEvent, RawReactionClearEmojiEvent]):
LOGGER.info(payload)
guild = await client.fetch_guild(payload.guild_id)
channel = await guild.fetch_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
if isinstance(payload, RawReactionActionEvent):
LOGGER.info(
f'{payload.member.display_name} added {payload.emoji} to\n{message.author.display_name}: {message.content}')
elif isinstance(payload, RawReactionClearEmojiEvent):
LOGGER.info(f'{payload.emoji} removed from\n{message.author.display_name}: {message.content}')
if hasattr(self, 'data'):
await self.data.update_reaction(msg=message)
if __name__ == '__main__':
load_dotenv()
client = RoboPage()
@client.event
async def on_ready():
# print(len(list(client.get_all_members())))
await client.handle_ready()
# print('\n'.join(client.data.reactions.index.get_level_values(1).drop_duplicates().sort_values()))
@client.event
async def on_message(message: discord.Message):
await client.handle_message(message)
@client.event
async def on_raw_reaction_add(payload: RawReactionActionEvent):
await client.handle_raw_reaction(payload)
@client.event
async def on_raw_reaction_remove(payload: RawReactionClearEmojiEvent):
await client.handle_raw_reaction(payload)
client.run()