Source code for modules.users

from bson import ObjectId
from modules.database import DB as db
from modules.utils.generals import creation_date, encode_password
from modules.utils.token import Token
from typing import Any, Dict, List, Optional

[docs] class User_lite: """Initialize a lite user's version.""" def __init__(self, data: Optional[Dict[str, Any]] = None) -> None: """ Initialize a lite user's version. Args: data (Optional[Dict[str, Any]], optional): The user lite data. Defaults to None. - _id (ObjectId): The user's ID. - username (str): The user's username. Raises: ValueError: If the data types don't match. """ try: self.valid: bool = True #if not data: if not data or any(field is None for field in [data.get("_id") or data.get("ID"), data.get("username")]): self.valid = False self.ID: Optional[ObjectId] = None self.username: Optional[str] = None else: self.ID = ObjectId(data.get("_id", data.get("ID"))) if not self.ID: raise Exception("No hay ID") self.username = str(data["username"]) except Exception as e: raise ValueError(f"Error initializing the User_lite: {e}.") def __bool__(self) -> bool: """ The validity of the user. Returns: bool: True if is valid, else False. """ return self.valid def __eq__(self, other: object) -> bool: """ Compare two objects and give if they are the same Args: other (object): Other User to compare. Returns: bool: True if is the same, else False. """ if not isinstance(other, (User, User_lite)): return False return self.ID == other.ID
[docs] def json(self) -> Dict[str, Any]: """ Parse the user to JSON format. Returns: Dict[str, Any]: User data in JSON. """ if not self: raise ValueError("Error parsing the user: User not valid.") try: return { "ID": self.ID, "username": self.username } except Exception as e: raise ValueError(f"Error parsing the user: {e}")
[docs] def token(self) -> str: """ Creates a JWT with the user data. Raises: RuntimeError: Error creating the token. Returns: str: The JWT created. """ if not self: raise ValueError("Error creating the token: User not valid.") try: return Token.encode(self.ID, self.username) except Exception as e: raise RuntimeError(f"Error creating the token: {e}") from e
[docs] class User(User_lite): """Initialize an user.""" def __init__(self, data: Optional[Dict[str, Any]] = None) -> None: """ Initialize an user. Args: data (Optional[Dict[str, Any]], optional): The user data. Defaults to None. - _id (ObjectId, optional): The User ID, if isn't given create a new ID. - username (str): User's username. - email (str): User's email. - password (str): User's password. - posts (List[ObjectId], optional): User'posts. - followers (List[ObjectId], optional): User's followers. - following (List[ObjectId], optional): User's following. - createdAt (str, optional): Creation date, if isn't given create a new one. Raises: ValueError: If the data types don't match. """ try: self.valid: bool = True #if nor data or any(field is None for field in [data.get("username"), data.get("email"), data.get("password")]) if not data: self.valid = False else: self.ID: ObjectId = ObjectId(data.get("_id", ObjectId())) self.username: str = str(data["username"]) self.email: str = str(data["email"]) self.password: str = str(data["password"]) self.posts: List[ObjectId] = data.get("posts", []) self.followers: List[ObjectId] = data.get("followers", []) self.following: List[ObjectId] = data.get("following", []) self.createdAt: str = str(data.get("createdAt", creation_date())) except Exception as e: raise ValueError(f"Error initializing the User: {e}.")
[docs] def json(self) -> Dict[str, Any]: """ Parse the user to JSON format. Returns: Dict[str, Any]: User data in JSON. """ try: if not self: raise ValueError(f"Error al parsear el User: No se proporcionaron datos") return { "_id": self.ID, "username": self.username, "email": self.email, "password": self.password, "posts": self.posts, "followers": self.followers, "following": self.following, "createdAt": self.createdAt } except Exception as e: raise RuntimeError(f"Error parsing the user: {e}")
[docs] def filter(self, request_user: User_lite = User_lite()) -> Dict[str, Any]: """ Filter a user with this params: - Returns the "username". - Returns the posts. - Returns the count of followers. - Returns "isFollowing" as True of False, if is self don't have this key. Args: request_user (User_lite, optional): The user that fetch the post. Defaults to User_lite(). Raises: RuntimeError: Error filtering the user. Returns: Dict[str, Any]: The user filtered. """ from modules.posts import Posts try: if not self: raise ValueError(f"Error parsing the user: No data was provided") returned_user: Dict[str, Any] = { "username": self.username, "posts": Posts.get_user_posts(self.posts), "followers": len(self.followers), } following: bool | None = None if request_user == self else request_user.ID in self.followers if following is not None: returned_user["isFollowing"] = following return returned_user except Exception as e: raise RuntimeError(f"Error filtering the user: {e}")
[docs] def lite(self) -> User_lite: """ Make a lite user's version. Raises: RuntimeError: Error liting de user. Returns: User_lite: The lite user's version. """ try: if not self: raise ValueError(f"Error parsing the user: No data was provided") return User_lite({ "ID": self.ID, "username": self.username }) except Exception as e: raise RuntimeError(f"Error liting the user: {e}")
[docs] class Users: """Manage all users in the app."""
[docs] @classmethod def get_user(self, value: Any, field: str = "_id") -> User: """ Fetch a user. Args: value (Any): The value of the field to search. field (str, optional): The field to search. Defaults to "_id". Raises: RuntimeError: Error fetching the user. Returns: Dict[str, Any]: The user. """ try: user: Dict[str, Any] = db.get_user(value, field) return User(user) except Exception as e: raise RuntimeError(f"Error fetching the user: {e}") from e
[docs] @classmethod def create_user(self, username: str, email: str, password: str) -> User: """ Creates a new user. Args: username (str): The username. email (str): The email. password (str): The password Raises: RuntimeError: Error creating the user. Returns: User: The new user if was created. """ try: new_user: User = User({ "username": username, "email": email, "password": encode_password(password) }) return new_user if db.add_user(new_user.json()) else User() except Exception as e: raise RuntimeError(f"Error creating the user: {e}") from e
[docs] @classmethod def follow(self, follower: User_lite, following: User_lite) -> bool: """ Make a follow. Args: follower (User_lite): User that wants to follow. following (User_lite): User that will be followed. Raises: RuntimeError: Error following. Returns: bool: True if the operation was successfull. """ try: return db.follow(follower.ID, following.ID) except Exception as e: raise RuntimeError(f"Error following the user: {e}") from e
[docs] @classmethod def unfollow(self, follower: User_lite, following: User_lite) -> bool: """ Make a unfollow. Args: follower (User_lite): User that wants to unfollow. following (User_lite): User that will be unfollowed. Raises: RuntimeError: Error unfollowing. Returns: bool: True if the operation was successfull. """ try: return db.unfollow(follower.ID, following.ID) except Exception as e: raise RuntimeError(f"Error unfollowing the user: {e}") from e