2024-05-01 22:15:35 +03:00
|
|
|
import logging
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from typing import Literal, Union
|
|
|
|
|
|
|
|
from bson import ObjectId
|
|
|
|
from discord import Thread
|
|
|
|
|
|
|
|
from classes.enums import MemberStatus
|
2024-06-02 22:51:07 +03:00
|
|
|
from classes.errors import MemberAlreadyExistsError, MemberNotFoundError
|
|
|
|
from classes.pycord_check import PycordCheck
|
2024-05-01 22:15:35 +03:00
|
|
|
from modules.database import col_members
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class PycordMember:
|
|
|
|
"""Dataclass of DB entry of a member"""
|
|
|
|
|
|
|
|
__slots__ = ("_id", "id", "guild", "status")
|
|
|
|
|
|
|
|
_id: ObjectId
|
|
|
|
id: int
|
|
|
|
guild: ObjectId
|
|
|
|
status: Literal[
|
|
|
|
MemberStatus.VERIFIED,
|
|
|
|
MemberStatus.UNVERIFIED,
|
|
|
|
MemberStatus.FAILED,
|
|
|
|
MemberStatus.ADDITIONAL,
|
|
|
|
]
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
async def find(cls, id: Union[int, ObjectId], guild: ObjectId):
|
2024-06-02 22:51:07 +03:00
|
|
|
"""Find member in the database.
|
2024-05-01 22:15:35 +03:00
|
|
|
|
|
|
|
### Args:
|
|
|
|
* id (`Union[int, ObjectId]`): Member's Discord ID
|
|
|
|
* guild (`ObjectId`): Discord guild's database ID
|
|
|
|
|
|
|
|
### Raises:
|
2024-06-02 22:51:07 +03:00
|
|
|
* `MemberNotFoundError`: Raised when member entry could not be found.
|
2024-05-01 22:15:35 +03:00
|
|
|
|
|
|
|
### Returns:
|
|
|
|
* `PycordMember`: Member with its database data.
|
|
|
|
"""
|
|
|
|
db_entry = await col_members.find_one(
|
|
|
|
(
|
|
|
|
{"id": id, "guild": guild}
|
|
|
|
if isinstance(id, int)
|
|
|
|
else {"_id": id, "guild": guild}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2024-06-02 22:51:07 +03:00
|
|
|
if not db_entry:
|
2024-05-01 22:15:35 +03:00
|
|
|
raise MemberNotFoundError(id, guild)
|
|
|
|
|
|
|
|
return cls(**db_entry)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
async def create(
|
|
|
|
cls,
|
|
|
|
id: int,
|
|
|
|
guild: ObjectId,
|
|
|
|
status: Literal[
|
|
|
|
MemberStatus.VERIFIED,
|
|
|
|
MemberStatus.UNVERIFIED,
|
|
|
|
MemberStatus.FAILED,
|
|
|
|
MemberStatus.ADDITIONAL,
|
|
|
|
],
|
|
|
|
):
|
2024-06-02 22:51:07 +03:00
|
|
|
# Check whether member already exists
|
|
|
|
if await col_members.find_one({"id": True, "guild": guild}):
|
|
|
|
raise MemberAlreadyExistsError(id, guild)
|
2024-05-01 22:15:35 +03:00
|
|
|
|
2024-06-02 22:51:07 +03:00
|
|
|
# Create a member dict
|
|
|
|
check = {
|
|
|
|
"id": id,
|
|
|
|
"guild": guild,
|
|
|
|
"status": status.value,
|
|
|
|
}
|
|
|
|
|
|
|
|
# Insert the member into the database
|
|
|
|
inserted = await col_members.insert_one(check)
|
|
|
|
|
|
|
|
check["_id"] = inserted.inserted_id
|
|
|
|
|
|
|
|
return cls(**check)
|
|
|
|
|
|
|
|
async def new_check(self, thread_id: int) -> PycordCheck:
|
|
|
|
return await PycordCheck.create(self.guild, thread_id, self._id)
|
|
|
|
|
|
|
|
async def get_check(self) -> PycordCheck:
|
|
|
|
"""Get an ongoing check
|
|
|
|
|
|
|
|
### Returns:
|
|
|
|
* `PycordCheck`: An ongoing check
|
|
|
|
|
|
|
|
### Raises:
|
|
|
|
* `CheckNotFoundError`: Member does not have an ongoing check
|
|
|
|
"""
|
|
|
|
return await PycordCheck.find(self.guild, self._id)
|
2024-05-01 22:15:35 +03:00
|
|
|
|
|
|
|
async def set_status(
|
|
|
|
self,
|
|
|
|
status: Literal[
|
|
|
|
MemberStatus.VERIFIED,
|
|
|
|
MemberStatus.UNVERIFIED,
|
|
|
|
MemberStatus.FAILED,
|
|
|
|
MemberStatus.ADDITIONAL,
|
|
|
|
],
|
|
|
|
) -> Union[Thread, None]:
|
2024-06-02 22:51:07 +03:00
|
|
|
await col_members.update_one({"_id": self._id}, {"$set": {status.value}})
|
|
|
|
self.status = status
|