Source code for flask_discord.models.user
from .. import configs
from .guild import Guild
from .. import exceptions
from .base import DiscordModelsBase
from .connections import UserConnection
from flask import current_app, session
[docs]class User(DiscordModelsBase):
"""Class representing Discord User.
Operations
----------
x == y
Checks if two user's are the same.
x != y
Checks if two user's are not the same.
str(x)
Returns the user's name with discriminator.
Attributes
----------
id : int
The discord ID of the user.
username : str
The discord username of the user.
discriminator : str
4 length string representing discord tag of the user.
avatar_hash : str
Hash of users avatar.
bot : bool
A boolean representing whether the user belongs to an OAuth2 application.
mfa_enabled : bool
A boolean representing whether the user has two factor enabled on their account.
locale : str
The user's chosen language option.
verified : bool
A boolean representing whether the email on this account has been verified.
email : str
User's email ID.
flags : int
An integer representing the
`user flags <https://discordapp.com/developers/docs/resources/user#user-object-user-flags>`_.
premium_type : int
An integer representing the
`type of nitro subscription <https://discordapp.com/developers/docs/resources/user#user-object-premium-types>`_.
connections : list
A list of :py:class:`flask_discord.UserConnection` instances. These are cached and this list might be empty.
"""
ROUTE = "/users/@me"
def __init__(self, payload):
super().__init__(payload)
self.id = int(self._payload["id"])
self.username = self._payload["username"]
self.discriminator = self._payload["discriminator"]
self.avatar_hash = self._payload.get("avatar", self.discriminator)
self.bot = self._payload.get("bot", False)
self.mfa_enabled = self._payload.get("mfa_enabled")
self.locale = self._payload.get("locale")
self.verified = self._payload.get("verified")
self.email = self._payload.get("email")
self.flags = self._payload.get("flags")
self.premium_type = self._payload.get("premium_type")
# Few properties which are intended to be cached.
self._guilds = None # Mapping of guild ID to flask_discord.models.Guild(...).
self.connections = None # List of flask_discord.models.UserConnection(...).
@property
def guilds(self):
"""A cached mapping of user's guild ID to :py:class:`flask_discord.Guild`. The guilds are cached when the first
API call for guilds is requested so it might be an empty dict.
"""
try:
return list(self._guilds.values())
except AttributeError:
pass
@guilds.setter
def guilds(self, value):
self._guilds = value
def __str__(self):
return f"{self.name}#{self.discriminator}"
def __eq__(self, user):
return isinstance(user, User) and user.id == self.id
def __ne__(self, user):
return not self.__eq__(user)
@property
def name(self):
"""An alias to the username attribute."""
return self.username
@property
def avatar_url(self):
"""A property returning direct URL to user's avatar."""
if not self.avatar_hash:
return
image_format = configs.DISCORD_ANIMATED_IMAGE_FORMAT \
if self.is_avatar_animated else configs.DISCORD_IMAGE_FORMAT
return configs.DISCORD_USER_AVATAR_BASE_URL.format(
user_id=self.id, avatar_hash=self.avatar_hash, format=image_format)
@property
def default_avatar_url(self):
"""A property which returns the default avatar URL as when user doesn't has any avatar set."""
return configs.DISCORD_DEFAULT_USER_AVATAR_BASE_URL.format(modulo5=int(self.discriminator) % 5)
@property
def is_avatar_animated(self):
"""A boolean representing if avatar of user is animated. Meaning user has GIF avatar."""
try:
return self.avatar_hash.startswith("a_")
except AttributeError:
return False
[docs] @classmethod
def fetch_from_api(cls, guilds=False, connections=False):
"""A class method which returns an instance of this model by implicitly making an
API call to Discord. The user returned from API will always be cached and update in internal cache.
Parameters
----------
guilds : bool
A boolean indicating if user's guilds should be cached or not. Defaults to ``False``. If chose to not
cache, user's guilds can always be obtained from :py:func:`flask_discord.Guilds.fetch_from_api()`.
connections : bool
A boolean indicating if user's connections should be cached or not. Defaults to ``False``. If chose to not
cache, user's connections can always be obtained from :py:func:`flask_discord.Connections.fetch_from_api()`.
Returns
-------
cls
An instance of this model itself.
[cls, ...]
List of instances of this model when many of these models exist."""
self = super().fetch_from_api()
current_app.discord.users_cache.update({self.id: self})
session["DISCORD_USER_ID"] = self.id
if guilds:
self.fetch_guilds()
if connections:
self.fetch_connections()
return self
[docs] @classmethod
def get_from_cache(cls):
"""A class method which returns an instance of this model if it exists in internal cache.
Returns
-------
flask_discord.User
An user instance if it exists in internal cache.
None
If the current doesn't exists in internal cache.
"""
return current_app.discord.users_cache.get(current_app.discord.user_id)
[docs] def add_to_guild(self, guild_id) -> dict:
"""Method to add user to the guild, provided OAuth2 session has already been created with ``guilds.join`` scope.
Parameters
----------
guild_id : int
The ID of the guild you want this user to be added.
Returns
-------
dict
A dict of guild member object. Returns an empty dict if user is already present in the guild.
Raises
------
flask_discord.Unauthorized
Raises :py:class:`flask_discord.Unauthorized` if current user is not authorized.
"""
try:
data = {"access_token": current_app.discord.get_authorization_token()["access_token"]}
except KeyError:
raise exceptions.Unauthorized
return self._bot_request(f"/guilds/{guild_id}/members/{self.id}", method="PUT", json=data) or dict()
[docs] def fetch_guilds(self) -> list:
"""A method which makes an API call to Discord to get user's guilds. It prepares the internal guilds cache
and returns list of all guilds the user is member of.
Returns
-------
list
List of :py:class:`flask_discord.Guilds` instances.
"""
self._guilds = {guild.id: guild for guild in Guild.fetch_from_api(cache=False)}
return self.guilds
[docs] def fetch_connections(self) -> list:
"""A method which makes an API call to Discord to get user's connections. It prepares the internal connection
cache and returns list of all connection instances.
Returns
-------
list
A list of :py:class:`flask_discord.UserConnection` instances.
"""
self.connections = UserConnection.fetch_from_api(cache=False)
return self.connections
[docs]class Bot(User):
"""Class representing the client user itself."""
# TODO: What is this?