151 lines
5.5 KiB
Python
151 lines
5.5 KiB
Python
from datetime import datetime
|
|
from logging import Logger
|
|
from pathlib import Path
|
|
from typing import Any, Dict, List
|
|
from zoneinfo import ZoneInfo
|
|
|
|
from bson import ObjectId
|
|
from bson.errors import InvalidId
|
|
from discord import Activity, ActivityType, Cog, File, Member, TextChannel
|
|
|
|
from classes import PycordEvent, PycordGuild, PycordUser
|
|
from classes.errors import GuildNotFoundError
|
|
from classes.pycord_bot import PycordBot
|
|
from modules.database import col_users
|
|
from modules.utils import get_logger, get_utc_now
|
|
|
|
logger: Logger = get_logger(__name__)
|
|
|
|
|
|
class CogUtility(Cog):
|
|
def __init__(self, bot: PycordBot):
|
|
self.bot: PycordBot = bot
|
|
|
|
@Cog.listener()
|
|
async def on_ready(self) -> None:
|
|
"""Listener for the event when bot connects to Discord and becomes "ready"."""
|
|
logger.info("Logged in as %s", self.bot.user)
|
|
|
|
activity_enabled: bool = self.bot.config["bot"]["status"]["enabled"]
|
|
activity_type: str = self.bot.config["bot"]["status"]["activity_type"]
|
|
activity_message: str = self.bot.config["bot"]["status"]["activity_text"]
|
|
|
|
if not activity_enabled:
|
|
return
|
|
|
|
if activity_type == "playing":
|
|
await self.bot.change_presence(
|
|
activity=Activity(type=ActivityType.playing, name=activity_message)
|
|
)
|
|
elif activity_type == "watching":
|
|
await self.bot.change_presence(
|
|
activity=Activity(type=ActivityType.watching, name=activity_message)
|
|
)
|
|
elif activity_type == "listening":
|
|
await self.bot.change_presence(
|
|
activity=Activity(type=ActivityType.listening, name=activity_message)
|
|
)
|
|
elif activity_type == "streaming":
|
|
await self.bot.change_presence(
|
|
activity=Activity(type=ActivityType.streaming, name=activity_message)
|
|
)
|
|
elif activity_type == "competing":
|
|
await self.bot.change_presence(
|
|
activity=Activity(type=ActivityType.competing, name=activity_message)
|
|
)
|
|
elif activity_type == "custom":
|
|
await self.bot.change_presence(
|
|
activity=Activity(type=ActivityType.custom, name=activity_message)
|
|
)
|
|
else:
|
|
return
|
|
|
|
logger.info("Set activity type to %s with message %s", activity_type, activity_message)
|
|
|
|
@Cog.listener("on_member_join")
|
|
async def on_member_join(self, member: Member) -> None:
|
|
try:
|
|
guild: PycordGuild = await self.bot.find_guild(member.guild.id)
|
|
except (InvalidId, GuildNotFoundError) as exc:
|
|
logger.error(
|
|
"Could not process member join event for %s in %s due to: %s",
|
|
member.id,
|
|
member.guild.id,
|
|
exc,
|
|
)
|
|
return
|
|
|
|
user: PycordUser = await self.bot.find_user(member.id, member.guild.id)
|
|
events: List[PycordEvent] = []
|
|
|
|
utc_now: datetime = get_utc_now()
|
|
|
|
pipeline: List[Dict[str, Any]] = [
|
|
{"$match": {"id": user.id}},
|
|
{
|
|
"$lookup": {
|
|
"from": "events",
|
|
"let": {"event_ids": "$registered_event_ids"},
|
|
"pipeline": [
|
|
{
|
|
"$match": {
|
|
"$expr": {
|
|
"$and": [
|
|
{"$in": ["$_id", "$$event_ids"]},
|
|
{"$eq": ["$ended", None]},
|
|
{"$gt": ["$ends", utc_now]},
|
|
{"$lt": ["$starts", utc_now]},
|
|
{"$eq": ["$is_cancelled", False]},
|
|
]
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"as": "registered_events",
|
|
}
|
|
},
|
|
{"$match": {"registered_events.0": {"$exists": True}}},
|
|
]
|
|
|
|
async with await col_users.aggregate(pipeline) as cursor:
|
|
async for result in cursor:
|
|
for registered_event in result["registered_events"]:
|
|
events.append(PycordEvent(**registered_event))
|
|
|
|
for event in events:
|
|
if user.current_event_id is not None and user.current_event_id != event._id:
|
|
continue
|
|
|
|
if user.current_event_id is None:
|
|
await user.set_event(event._id, cache=self.bot.cache)
|
|
|
|
channel: TextChannel | None = await user.fix_event_channel(
|
|
self.bot, member.guild, guild, event, cache=self.bot.cache
|
|
)
|
|
|
|
if channel is None:
|
|
continue
|
|
|
|
thumbnail: File | None = (
|
|
None
|
|
if event.thumbnail is None
|
|
else File(Path(f"data/{event.thumbnail['id']}"), event.thumbnail["filename"])
|
|
)
|
|
|
|
await channel.send(
|
|
self.bot._("notice_event_already_started", "messages").format(event_name=event.name),
|
|
file=thumbnail,
|
|
)
|
|
|
|
stage_id: ObjectId = (
|
|
event.stage_ids[0] if user.current_stage_id is None else user.current_stage_id
|
|
)
|
|
|
|
await user.set_event_stage(stage_id, cache=self.bot.cache)
|
|
|
|
await self.bot.send_stage_question(channel, event, await self.bot.find_event_stage(stage_id))
|
|
|
|
|
|
def setup(bot: PycordBot) -> None:
|
|
bot.add_cog(CogUtility(bot))
|