from __future__ import annotations import asyncio import contextlib import logging import random import re from logging.handlers import RotatingFileHandler from typing import TYPE_CHECKING import discord from discord.ext import commands from utils import config from utils.constants import RIP_EMOJIS, TEEHEE_EMOJIS if TYPE_CHECKING: from bot import Artemis log = logging.getLogger("artemis") cmd_log = logging.getLogger("commands") cmd_log.propagate = False cmd_log.setLevel(logging.DEBUG) ch = RotatingFileHandler("data/commands.log", "a", 10 * 1024**2, encoding="utf-8") ch.setLevel(logging.DEBUG) ch.setFormatter(logging.Formatter("[{asctime}] {message}", "%Y-%m-%d %H:%M:%S", style="{")) cmd_log.addHandler(ch) TIKTOK_RE = re.compile( r"https://vm\.tiktok\.com/(\w+)|https://(?:www\.)?tiktok\.com/(@.+?/video/\d+)" ) PIXIV_RE = re.compile(r"https:\/\/(?:www\.)?pixiv\.net(?:\/\w+)?\/artworks\/(?P\d+)\/?") REDDIT_RE = re.compile( r"https?:\/\/(?:www\.)?(?:old\.)?reddit\.com\/r\/\w+\/comments\/(?P[a-zA-Z0-9]+)(?:\/)?(?:[^\s]*)?" ) class Events(commands.Cog): def __init__(self, bot: Artemis): self.bot: Artemis = bot def suppress_embeds(self, message: discord.Message, delay: float | int = 0): async def _suppress(): await asyncio.sleep(delay) with contextlib.suppress(Exception): await message.edit(suppress=True) asyncio.create_task(_suppress()) async def handle_triggers(self, message: discord.Message, content: str): if content == "good bot": emoji = random.choice(TEEHEE_EMOJIS) await message.channel.send(emoji) elif content == "bad bot": emoji = random.choice(RIP_EMOJIS) await message.channel.send(emoji) async def handle_links(self, message: discord.Message, content: str): if message.guild and message.guild.id not in ( config.main_guild_id, config.dev_guild_id, ): return tiktok_url = TIKTOK_RE.search(content) if tiktok_url: vid = tiktok_url.group(1) or tiktok_url.group(2) self.suppress_embeds(message, 0.1) return await message.reply(f"https://vm.dstn.to/{vid}") pixiv_url = PIXIV_RE.search(content) if pixiv_url: pid = pixiv_url.group("pid") self.suppress_embeds(message, 0.1) return await message.reply(f"{config.api_base_url}/pixiv/{pid}") reddit_url = REDDIT_RE.search(content) if reddit_url: pid = reddit_url.group("id") reddit_post = await self.bot.reddit.post(pid=pid) if reddit_post: self.suppress_embeds(message, 0.1) embeds = await reddit_post.to_embed(message) return await message.reply(embeds=embeds) log.warn(f"Invalid Reddit post URL/ID: {reddit_url.group(0)}") @commands.Cog.listener() async def on_message(self, message: discord.Message): if message.author.bot: return content = message.content.lower() if content.startswith(("$")) and "$jsk" not in content: cmd_log.debug(f"{message.author.id}: {message.content}") await self.handle_triggers(message, content) await self.handle_links(message, content) @commands.Cog.listener() async def on_message_edit(self, before: discord.Message, after: discord.Message): if after.author.id != self.bot.owner_id: return if before.content == after.content: return await self.bot.process_commands(after) @commands.Cog.listener() async def on_thread_create(self, thread: discord.Thread): try: await thread.join() except Exception: pass async def setup(bot: Artemis): await bot.add_cog(Events(bot))