2023-05-06 18:08:52 +03:00
|
|
|
import logging
|
2024-12-16 21:34:37 +02:00
|
|
|
from typing import Any, Union, Dict
|
2023-05-06 19:56:01 +03:00
|
|
|
|
2024-12-16 21:34:37 +02:00
|
|
|
from bson import ObjectId
|
|
|
|
from discord import User, Member
|
2024-12-16 00:36:48 +02:00
|
|
|
from libbot import config_get
|
2023-05-04 17:09:47 +03:00
|
|
|
|
2024-12-16 21:34:37 +02:00
|
|
|
from errors import UserNotFoundError
|
2024-12-16 17:25:35 +02:00
|
|
|
from modules.database import col_warnings, sync_col_users, sync_col_warnings, col_users
|
2023-05-04 17:09:47 +03:00
|
|
|
|
2023-05-06 18:08:52 +03:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2023-05-04 17:14:23 +03:00
|
|
|
|
|
|
|
class HoloUser:
|
2024-12-16 21:34:37 +02:00
|
|
|
def __init__(self, user: Union[User, Member, int]) -> None:
|
2023-05-04 17:09:47 +03:00
|
|
|
"""Get an object that has a proper binding between Discord ID and database
|
|
|
|
|
|
|
|
### Args:
|
2024-12-16 21:34:37 +02:00
|
|
|
* `user` (Union[User, Member, int]): Object from which ID can be extracted
|
2023-05-04 17:09:47 +03:00
|
|
|
|
|
|
|
### Raises:
|
|
|
|
* `UserNotFoundError`: User with such ID does not seem to exist in database
|
2023-05-04 17:14:23 +03:00
|
|
|
"""
|
2023-05-04 17:09:47 +03:00
|
|
|
|
2024-12-16 21:34:37 +02:00
|
|
|
self.id: int = user if not hasattr(user, "id") else user.id
|
2023-05-04 17:09:47 +03:00
|
|
|
|
2024-12-16 21:34:37 +02:00
|
|
|
jav_user: Union[Dict[str, Any], None] = sync_col_users.find_one(
|
|
|
|
{"user": self.id}
|
|
|
|
)
|
2023-05-04 17:09:47 +03:00
|
|
|
|
|
|
|
if jav_user is None:
|
|
|
|
raise UserNotFoundError(user=user, user_id=self.id)
|
|
|
|
|
2024-12-16 21:34:37 +02:00
|
|
|
self.db_id: ObjectId = jav_user["_id"]
|
2023-05-04 17:09:47 +03:00
|
|
|
|
2024-12-16 21:34:37 +02:00
|
|
|
self.customrole: Union[int, None] = jav_user["customrole"]
|
|
|
|
self.customchannel: Union[int, None] = jav_user["customchannel"]
|
|
|
|
self.warnings: int = self.warns()
|
2023-05-04 17:09:47 +03:00
|
|
|
|
|
|
|
def warns(self) -> int:
|
|
|
|
"""Get number of warnings user has
|
|
|
|
|
|
|
|
### Returns:
|
|
|
|
* `int`: Number of warnings
|
2023-05-04 17:14:23 +03:00
|
|
|
"""
|
2024-12-16 21:34:37 +02:00
|
|
|
warns: Union[Dict[str, Any], None] = sync_col_warnings.find_one(
|
|
|
|
{"user": self.id}
|
|
|
|
)
|
2024-12-16 00:36:48 +02:00
|
|
|
|
|
|
|
return 0 if warns is None else warns["warns"]
|
2023-05-04 17:09:47 +03:00
|
|
|
|
2024-12-16 17:25:35 +02:00
|
|
|
async def warn(self, count=1, reason: str = "Not provided") -> None:
|
2023-05-04 17:09:47 +03:00
|
|
|
"""Warn and add count to warns number
|
|
|
|
|
|
|
|
### Args:
|
|
|
|
* `count` (int, optional): Count of warnings to be added. Defaults to 1.
|
2023-05-04 17:14:23 +03:00
|
|
|
"""
|
2024-12-16 21:34:37 +02:00
|
|
|
warns: Union[Dict[str, Any], None] = await col_warnings.find_one(
|
|
|
|
{"user": self.id}
|
|
|
|
)
|
2024-12-16 00:36:48 +02:00
|
|
|
|
|
|
|
if warns is not None:
|
2024-12-16 17:25:35 +02:00
|
|
|
await col_warnings.update_one(
|
|
|
|
{"_id": self.db_id},
|
|
|
|
{"$set": {"warns": warns["warns"] + count}},
|
2023-05-04 17:14:23 +03:00
|
|
|
)
|
2023-05-04 17:09:47 +03:00
|
|
|
else:
|
2024-12-16 17:25:35 +02:00
|
|
|
await col_warnings.insert_one(document={"user": self.id, "warns": count})
|
2024-12-16 00:36:48 +02:00
|
|
|
|
2024-12-16 21:34:37 +02:00
|
|
|
logger.info("User %s was warned %s times due to: %s", self.id, count, reason)
|
2023-05-04 17:09:47 +03:00
|
|
|
|
2024-12-16 17:25:35 +02:00
|
|
|
async def set(self, key: str, value: Any) -> None:
|
2023-05-04 17:09:47 +03:00
|
|
|
"""Set attribute data and save it into database
|
|
|
|
|
|
|
|
### Args:
|
|
|
|
* `key` (str): Attribute to be changed
|
|
|
|
* `value` (Any): Value to set
|
2023-05-04 17:14:23 +03:00
|
|
|
"""
|
2023-05-04 17:09:47 +03:00
|
|
|
if not hasattr(self, key):
|
|
|
|
raise AttributeError()
|
2024-12-16 00:36:48 +02:00
|
|
|
|
2023-05-04 17:09:47 +03:00
|
|
|
setattr(self, key, value)
|
2024-12-16 17:25:35 +02:00
|
|
|
|
|
|
|
await col_users.update_one(
|
|
|
|
{"_id": self.db_id}, {"$set": {key: value}}, upsert=True
|
2023-05-04 17:14:23 +03:00
|
|
|
)
|
2024-12-16 00:36:48 +02:00
|
|
|
|
2024-12-16 21:34:37 +02:00
|
|
|
logger.info("Set attribute %s of user %s to %s", key, self.id, value)
|
2023-05-04 17:09:47 +03:00
|
|
|
|
2024-12-16 17:25:35 +02:00
|
|
|
@staticmethod
|
2024-12-16 21:34:37 +02:00
|
|
|
async def is_moderator(member: Union[User, Member]) -> bool:
|
2023-05-08 16:45:00 +03:00
|
|
|
"""Check if user is moderator or council member
|
|
|
|
|
|
|
|
### Args:
|
2024-12-16 21:34:37 +02:00
|
|
|
* `member` (Union[User, Member]): Member object
|
2023-05-08 16:45:00 +03:00
|
|
|
|
|
|
|
### Returns:
|
|
|
|
`bool`: `True` if member is a moderator or member of council and `False` if not
|
|
|
|
"""
|
2024-12-16 21:34:37 +02:00
|
|
|
if isinstance(member, User):
|
2023-05-08 16:45:00 +03:00
|
|
|
return False
|
2024-12-16 00:36:48 +02:00
|
|
|
|
2024-12-16 21:34:37 +02:00
|
|
|
moderator_role: Union[int, None] = await config_get("moderators", "roles")
|
|
|
|
council_role: Union[int, None] = await config_get("council", "roles")
|
2024-12-16 00:36:48 +02:00
|
|
|
|
2023-05-08 16:45:00 +03:00
|
|
|
for role in member.roles:
|
2024-12-16 21:34:37 +02:00
|
|
|
if role.id in (moderator_role, council_role):
|
2023-05-08 16:45:00 +03:00
|
|
|
return True
|
2024-12-16 00:36:48 +02:00
|
|
|
|
2023-05-08 16:45:00 +03:00
|
|
|
return False
|
|
|
|
|
2024-12-16 17:25:35 +02:00
|
|
|
@staticmethod
|
2024-12-16 21:34:37 +02:00
|
|
|
async def is_council(member: Union[User, Member]) -> bool:
|
2023-05-08 16:45:00 +03:00
|
|
|
"""Check if user is a member of council
|
|
|
|
|
|
|
|
### Args:
|
2024-12-16 21:34:37 +02:00
|
|
|
* `member` (Union[User, Member]): Member object
|
2023-05-08 16:45:00 +03:00
|
|
|
|
|
|
|
### Returns:
|
|
|
|
`bool`: `True` if member is a member of council and `False` if not
|
|
|
|
"""
|
2024-12-16 21:34:37 +02:00
|
|
|
if isinstance(member, User):
|
2023-05-08 16:45:00 +03:00
|
|
|
return False
|
2024-12-16 00:36:48 +02:00
|
|
|
|
2023-05-08 16:45:00 +03:00
|
|
|
council_role = await config_get("council", "roles")
|
2024-12-16 00:36:48 +02:00
|
|
|
|
2023-05-08 16:45:00 +03:00
|
|
|
for role in member.roles:
|
|
|
|
if role.id == council_role:
|
|
|
|
return True
|
2024-12-16 00:36:48 +02:00
|
|
|
|
2023-05-08 16:45:00 +03:00
|
|
|
return False
|
|
|
|
|
2023-05-06 18:08:52 +03:00
|
|
|
# def purge(self) -> None:
|
|
|
|
# """Completely remove data from database. Will not remove transactions logs and warnings."""
|
|
|
|
# col_users.delete_one(filter={"_id": self.db_id})
|
|
|
|
# self.unauthorize()
|