from __future__ import annotations
from datetime import datetime
from typing import TYPE_CHECKING, Literal
from .utils import timestamp_to_datetime
if TYPE_CHECKING:
from httpx import Response
from .client import Client
from .message import Message
from .tweet import Tweet
from .utils import Result
[docs]
class User:
"""
Attributes
----------
id : :class:`str`
The unique identifier of the user.
created_at : :class:`str`
The date and time when the user account was created.
name : :class:`str`
The user's name.
screen_name : :class:`str`
The user's screen name.
profile_image_url : :class:`str`
The URL of the user's profile image (HTTPS version).
profile_banner_url : :class:`str`
The URL of the user's profile banner.
url : :class:`str`
The user's URL.
location : :class:`str`
The user's location information.
description : :class:`str`
The user's profile description.
description_urls : :class:`list`
URLs found in the user's profile description.
urls : :class:`list`
URLs associated with the user.
pinned_tweet_ids : :class:`str`
The IDs of tweets that the user has pinned to their profile.
is_blue_verified : :class:`bool`
Indicates if the user is verified with a blue checkmark.
verified : :class:`bool`
Indicates if the user is verified.
possibly_sensitive : :class:`bool`
Indicates if the user's content may be sensitive.
can_dm : :class:`bool`
Indicates whether the user can receive direct messages.
can_media_tag : :class:`bool`
Indicates whether the user can be tagged in media.
want_retweets : :class:`bool`
Indicates if the user wants retweets.
default_profile : :class:`bool`
Indicates if the user has the default profile.
default_profile_image : :class:`bool`
Indicates if the user has the default profile image.
has_custom_timelines : :class:`bool`
Indicates if the user has custom timelines.
followers_count : :class:`int`
The count of followers.
fast_followers_count : :class:`int`
The count of fast followers.
normal_followers_count : :class:`int`
The count of normal followers.
following_count : :class:`int`
The count of users the user is following.
favourites_count : :class:`int`
The count of favorites or likes.
listed_count : :class:`int`
The count of lists the user is a member of.
media_count : :class:`int`
The count of media items associated with the user.
statuses_count : :class:`int`
The count of tweets.
is_translator : :class:`bool`
Indicates if the user is a translator.
translator_type : :class:`str`
The type of translator.
profile_interstitial_type : :class:`str`
The type of profile interstitial.
withheld_in_countries : list[:class:`str`]
Countries where the user's content is withheld.
"""
def __init__(self, client: Client, data: dict) -> None:
self._client = client
legacy = data['legacy']
self.id: str = data['rest_id']
self.created_at: str = legacy['created_at']
self.name: str = legacy['name']
self.screen_name: str = legacy['screen_name']
self.profile_image_url: str = legacy['profile_image_url_https']
self.profile_banner_url: str = legacy.get('profile_banner_url')
self.url: str = legacy.get('url')
self.location: str = legacy['location']
self.description: str = legacy['description']
self.description_urls: list = legacy['entities']['description']['urls']
self.urls: list = legacy['entities'].get('url', {}).get('urls')
self.pinned_tweet_ids: list[str] = legacy['pinned_tweet_ids_str']
self.is_blue_verified: bool = data['is_blue_verified']
self.verified: bool = legacy['verified']
self.possibly_sensitive: bool = legacy['possibly_sensitive']
self.can_dm: bool = legacy['can_dm']
self.can_media_tag: bool = legacy['can_media_tag']
self.want_retweets: bool = legacy['want_retweets']
self.default_profile: bool = legacy['default_profile']
self.default_profile_image: bool = legacy['default_profile_image']
self.has_custom_timelines: bool = legacy['has_custom_timelines']
self.followers_count: int = legacy['followers_count']
self.fast_followers_count: int = legacy['fast_followers_count']
self.normal_followers_count: int = legacy['normal_followers_count']
self.following_count: int = legacy['friends_count']
self.favourites_count: int = legacy['favourites_count']
self.listed_count: int = legacy['listed_count']
self.media_count = legacy['media_count']
self.statuses_count: int = legacy['statuses_count']
self.is_translator: bool = legacy['is_translator']
self.translator_type: str = legacy['translator_type']
self.withheld_in_countries: list[str] = legacy['withheld_in_countries']
self.protected: bool = legacy.get('protected', False)
@property
def created_at_datetime(self) -> datetime:
return timestamp_to_datetime(self.created_at)
[docs]
def follow(self) -> Response:
"""
Follows the user.
Returns
-------
:class:`httpx.Response`
Response returned from twitter api.
See Also
--------
Client.follow_user
"""
return self._client.follow_user(self.id)
[docs]
def unfollow(self) -> Response:
"""
Unfollows the user.
Returns
-------
:class:`httpx.Response`
Response returned from twitter api.
See Also
--------
Client.unfollow_user
"""
return self._client.unfollow_user(self.id)
[docs]
def block(self) -> Response:
"""
Blocks a user.
Parameters
----------
user_id : :class:`str`
The ID of the user to block.
Returns
-------
:class:`httpx.Response`
Response returned from twitter api.
See Also
--------
.unblock
"""
return self._client.block_user(self.id)
[docs]
def unblock(self) -> Response:
"""
Unblocks a user.
Parameters
----------
user_id : :class:`str`
The ID of the user to unblock.
Returns
-------
:class:`httpx.Response`
Response returned from twitter api.
See Also
--------
.block
"""
return self._client.unblock_user(self.id)
[docs]
def mute(self) -> Response:
"""
Mutes a user.
Parameters
----------
user_id : :class:`str`
The ID of the user to mute.
Returns
-------
:class:`httpx.Response`
Response returned from twitter api.
See Also
--------
.unmute
"""
return self._client.mute_user(self.id)
[docs]
def unmute(self) -> Response:
"""
Unmutes a user.
Parameters
----------
user_id : :class:`str`
The ID of the user to unmute.
Returns
-------
:class:`httpx.Response`
Response returned from twitter api.
See Also
--------
.mute
"""
return self._client.unmute_user(self.id)
[docs]
def get_followers(self, count: int = 20) -> Result[User]:
"""
Retrieves a list of followers for the user.
Parameters
----------
count : :class:`int`, default=20
The number of followers to retrieve.
Returns
-------
Result[:class:`User`]
A list of User objects representing the followers.
See Also
--------
Client.get_user_followers
"""
return self._client.get_user_followers(self.id, count)
[docs]
def get_verified_followers(self, count: int = 20) -> Result[User]:
"""
Retrieves a list of verified followers for the user.
Parameters
----------
count : :class:`int`, default=20
The number of verified followers to retrieve.
Returns
-------
Result[:class:`User`]
A list of User objects representing the verified followers.
See Also
--------
Client.get_user_verified_followers
"""
return self._client.get_user_verified_followers(self.id, count)
[docs]
def get_followers_you_know(self, count: int = 20) -> Result[User]:
"""
Retrieves a list of followers whom the user might know.
Parameters
----------
count : :class:`int`, default=20
The number of followers you might know to retrieve.
Returns
-------
Result[:class:`User`]
A list of User objects representing the followers you might know.
See Also
--------
Client.get_user_followers_you_know
"""
return self._client.get_user_followers_you_know(self.id, count)
[docs]
def get_following(self, count: int = 20) -> Result[User]:
"""
Retrieves a list of users whom the user is following.
Parameters
----------
count : :class:`int`, default=20
The number of following users to retrieve.
Returns
-------
Result[:class:`User`]
A list of User objects representing the users being followed.
See Also
--------
Client.get_user_following
"""
return self._client.get_user_following(self.id, count)
[docs]
def get_subscriptions(self, count: int = 20) -> Result[User]:
"""
Retrieves a list of users whom the user is subscribed to.
Parameters
----------
count : :class:`int`, default=20
The number of subscriptions to retrieve.
Returns
-------
Result[:class:`User`]
A list of User objects representing the subscribed users.
See Also
--------
Client.get_user_subscriptions
"""
return self._client.get_user_subscriptions(self.id, count)
[docs]
def send_dm(
self, text: str, media_id: str = None, reply_to = None
) -> Message:
"""
Send a direct message to the user.
Parameters
----------
text : :class:`str`
The text content of the direct message.
media_id : :class:`str`, default=None
The media ID associated with any media content
to be included in the message.
Media ID can be received by using the :func:`.upload_media` method.
reply_to : :class:`str`, default=None
Message ID to reply to.
Returns
-------
:class:`Message`
`Message` object containing information about the message sent.
Examples
--------
>>> # send DM with media
>>> media_id = client.upload_media('image.png')
>>> message = user.send_dm('text', media_id)
>>> print(message)
<Message id='...'>
See Also
--------
Client.upload_media
Client.send_dm
"""
return self._client.send_dm(self.id, text, media_id, reply_to)
[docs]
def get_dm_history(self, max_id: str = None) -> Result[Message]:
"""
Retrieves the DM conversation history with the user.
Parameters
----------
max_id : :class:`str`, default=None
If specified, retrieves messages older than the specified max_id.
Returns
-------
Result[:class:`Message`]
A Result object containing a list of Message objects representing
the DM conversation history.
Examples
--------
>>> messages = user.get_dm_history()
>>> for message in messages:
>>> print(message)
<Message id="...">
<Message id="...">
...
...
>>> more_messages = messages.next() # Retrieve more messages
>>> for message in more_messages:
>>> print(message)
<Message id="...">
<Message id="...">
...
...
"""
return self._client.get_dm_history(self.id, max_id)
[docs]
def update(self) -> None:
new = self._client.get_user_by_id(self.id)
self.__dict__.update(new.__dict__)
def __repr__(self) -> str:
return f'<User id="{self.id}">'
def __eq__(self, __value: object) -> bool:
return isinstance(__value, User) and self.id == __value.id
def __ne__(self, __value: object) -> bool:
return not self == __value