Fix type specifiers in models
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import attr
|
||||
import requests
|
||||
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
|
||||
# Not frozen, since that doesn't work in PyPy
|
||||
@attr.s(slots=True, auto_exc=True)
|
||||
@@ -20,7 +20,7 @@ class HTTPError(FacebookError):
|
||||
"""Base class for errors with the HTTP(s) connection to Facebook."""
|
||||
|
||||
#: The returned HTTP status code, if relevant
|
||||
status_code = attr.ib(None, type=int)
|
||||
status_code = attr.ib(None, type=Optional[int])
|
||||
|
||||
def __str__(self):
|
||||
if not self.status_code:
|
||||
@@ -58,7 +58,7 @@ class ExternalError(FacebookError):
|
||||
#: The error message that Facebook returned (Possibly in the user's own language)
|
||||
description = attr.ib(type=str)
|
||||
#: The error code that Facebook returned
|
||||
code = attr.ib(None, type=int)
|
||||
code = attr.ib(None, type=Optional[int])
|
||||
|
||||
def __str__(self):
|
||||
if self.code:
|
||||
@@ -73,7 +73,7 @@ class GraphQLError(ExternalError):
|
||||
# TODO: Handle multiple errors
|
||||
|
||||
#: Query debug information
|
||||
debug_info = attr.ib(None, type=str)
|
||||
debug_info = attr.ib(None, type=Optional[str])
|
||||
|
||||
def __str__(self):
|
||||
if self.debug_info:
|
||||
|
@@ -5,7 +5,7 @@ import requests
|
||||
from ._common import log, kw_only
|
||||
from . import _util, _exception, _session, _graphql, _events
|
||||
|
||||
from typing import Iterable, Optional, Mapping
|
||||
from typing import Iterable, Optional, Mapping, List
|
||||
|
||||
|
||||
HOST = "edge-chat.facebook.com"
|
||||
@@ -118,7 +118,7 @@ class Listener:
|
||||
_mqtt = attr.ib(factory=mqtt_factory, type=paho.mqtt.client.Client)
|
||||
_sync_token = attr.ib(None, type=Optional[str])
|
||||
_sequence_id = attr.ib(None, type=Optional[int])
|
||||
_tmp_events = attr.ib(factory=list, type=Iterable[_events.Event])
|
||||
_tmp_events = attr.ib(factory=list, type=List[_events.Event])
|
||||
|
||||
def __attrs_post_init__(self):
|
||||
# Configure callbacks
|
||||
|
@@ -3,7 +3,7 @@ from . import Image
|
||||
from .._common import attrs_default
|
||||
from .. import _util
|
||||
|
||||
from typing import Sequence
|
||||
from typing import Optional, Sequence
|
||||
|
||||
|
||||
@attrs_default
|
||||
@@ -11,7 +11,7 @@ class Attachment:
|
||||
"""Represents a Facebook attachment."""
|
||||
|
||||
#: The attachment ID
|
||||
id = attr.ib(None, type=str)
|
||||
id = attr.ib(None, type=Optional[str])
|
||||
|
||||
|
||||
@attrs_default
|
||||
@@ -24,21 +24,21 @@ class ShareAttachment(Attachment):
|
||||
"""Represents a shared item (e.g. URL) attachment."""
|
||||
|
||||
#: ID of the author of the shared post
|
||||
author = attr.ib(None, type=str)
|
||||
author = attr.ib(None, type=Optional[str])
|
||||
#: Target URL
|
||||
url = attr.ib(None, type=str)
|
||||
url = attr.ib(None, type=Optional[str])
|
||||
#: Original URL if Facebook redirects the URL
|
||||
original_url = attr.ib(None, type=str)
|
||||
original_url = attr.ib(None, type=Optional[str])
|
||||
#: Title of the attachment
|
||||
title = attr.ib(None, type=str)
|
||||
title = attr.ib(None, type=Optional[str])
|
||||
#: Description of the attachment
|
||||
description = attr.ib(None, type=str)
|
||||
description = attr.ib(None, type=Optional[str])
|
||||
#: Name of the source
|
||||
source = attr.ib(None, type=str)
|
||||
source = attr.ib(None, type=Optional[str])
|
||||
#: The attached image
|
||||
image = attr.ib(None, type=Image)
|
||||
image = attr.ib(None, type=Optional[Image])
|
||||
#: URL of the original image if Facebook uses ``safe_image``
|
||||
original_image_url = attr.ib(None, type=str)
|
||||
original_image_url = attr.ib(None, type=Optional[str])
|
||||
#: List of additional attachments
|
||||
attachments = attr.ib(factory=list, type=Sequence[Attachment])
|
||||
|
||||
|
@@ -4,6 +4,8 @@ import enum
|
||||
from .._common import attrs_default
|
||||
from .. import _util
|
||||
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class ThreadLocation(enum.Enum):
|
||||
"""Used to specify where a thread is located (inbox, pending, archived, other)."""
|
||||
@@ -21,11 +23,11 @@ class ThreadLocation(enum.Enum):
|
||||
@attrs_default
|
||||
class ActiveStatus:
|
||||
#: Whether the user is active now
|
||||
active = attr.ib(None, type=bool)
|
||||
active = attr.ib(type=bool)
|
||||
#: Datetime when the user was last active
|
||||
last_active = attr.ib(None, type=datetime.datetime)
|
||||
last_active = attr.ib(None, type=Optional[datetime.datetime])
|
||||
#: Whether the user is playing Messenger game now
|
||||
in_game = attr.ib(None, type=bool)
|
||||
in_game = attr.ib(None, type=Optional[bool])
|
||||
|
||||
@classmethod
|
||||
def _from_orca_presence(cls, data):
|
||||
@@ -42,9 +44,9 @@ class Image:
|
||||
#: URL to the image
|
||||
url = attr.ib(type=str)
|
||||
#: Width of the image
|
||||
width = attr.ib(None, type=int)
|
||||
width = attr.ib(None, type=Optional[int])
|
||||
#: Height of the image
|
||||
height = attr.ib(None, type=int)
|
||||
height = attr.ib(None, type=Optional[int])
|
||||
|
||||
@classmethod
|
||||
def _from_uri(cls, data):
|
||||
|
@@ -4,7 +4,7 @@ from . import Image, Attachment
|
||||
from .._common import attrs_default
|
||||
from .. import _util
|
||||
|
||||
from typing import Set
|
||||
from typing import Set, Optional
|
||||
|
||||
|
||||
@attrs_default
|
||||
@@ -12,13 +12,13 @@ class FileAttachment(Attachment):
|
||||
"""Represents a file that has been sent as a Facebook attachment."""
|
||||
|
||||
#: URL where you can download the file
|
||||
url = attr.ib(None, type=str)
|
||||
url = attr.ib(None, type=Optional[str])
|
||||
#: Size of the file in bytes
|
||||
size = attr.ib(None, type=int)
|
||||
size = attr.ib(None, type=Optional[int])
|
||||
#: Name of the file
|
||||
name = attr.ib(None, type=str)
|
||||
name = attr.ib(None, type=Optional[str])
|
||||
#: Whether Facebook determines that this file may be harmful
|
||||
is_malicious = attr.ib(None, type=bool)
|
||||
is_malicious = attr.ib(None, type=Optional[bool])
|
||||
|
||||
@classmethod
|
||||
def _from_graphql(cls, data, size=None):
|
||||
@@ -36,13 +36,13 @@ class AudioAttachment(Attachment):
|
||||
"""Represents an audio file that has been sent as a Facebook attachment."""
|
||||
|
||||
#: Name of the file
|
||||
filename = attr.ib(None, type=str)
|
||||
filename = attr.ib(None, type=Optional[str])
|
||||
#: URL of the audio file
|
||||
url = attr.ib(None, type=str)
|
||||
url = attr.ib(None, type=Optional[str])
|
||||
#: Duration of the audio clip as a timedelta
|
||||
duration = attr.ib(None, type=datetime.timedelta)
|
||||
duration = attr.ib(None, type=Optional[datetime.timedelta])
|
||||
#: Audio type
|
||||
audio_type = attr.ib(None, type=str)
|
||||
audio_type = attr.ib(None, type=Optional[str])
|
||||
|
||||
@classmethod
|
||||
def _from_graphql(cls, data):
|
||||
@@ -63,13 +63,13 @@ class ImageAttachment(Attachment):
|
||||
"""
|
||||
|
||||
#: The extension of the original image (e.g. ``png``)
|
||||
original_extension = attr.ib(None, type=str)
|
||||
original_extension = attr.ib(None, type=Optional[str])
|
||||
#: Width of original image
|
||||
width = attr.ib(None, converter=lambda x: None if x is None else int(x), type=int)
|
||||
width = attr.ib(None, converter=_util.int_or_none, type=Optional[int])
|
||||
#: Height of original image
|
||||
height = attr.ib(None, converter=lambda x: None if x is None else int(x), type=int)
|
||||
height = attr.ib(None, converter=_util.int_or_none, type=Optional[int])
|
||||
#: Whether the image is animated
|
||||
is_animated = attr.ib(None, type=bool)
|
||||
is_animated = attr.ib(None, type=Optional[bool])
|
||||
#: A set, containing variously sized / various types of previews of the image
|
||||
previews = attr.ib(factory=set, type=Set[Image])
|
||||
|
||||
@@ -113,15 +113,15 @@ class VideoAttachment(Attachment):
|
||||
"""Represents a video that has been sent as a Facebook attachment."""
|
||||
|
||||
#: Size of the original video in bytes
|
||||
size = attr.ib(None, type=int)
|
||||
size = attr.ib(None, type=Optional[int])
|
||||
#: Width of original video
|
||||
width = attr.ib(None, type=int)
|
||||
width = attr.ib(None, type=Optional[int])
|
||||
#: Height of original video
|
||||
height = attr.ib(None, type=int)
|
||||
height = attr.ib(None, type=Optional[int])
|
||||
#: Length of video as a timedelta
|
||||
duration = attr.ib(None, type=datetime.timedelta)
|
||||
duration = attr.ib(None, type=Optional[datetime.timedelta])
|
||||
#: URL to very compressed preview video
|
||||
preview_url = attr.ib(None, type=str)
|
||||
preview_url = attr.ib(None, type=Optional[str])
|
||||
#: A set, containing variously sized previews of the video
|
||||
previews = attr.ib(factory=set, type=Set[Image])
|
||||
|
||||
|
@@ -1,8 +1,11 @@
|
||||
import attr
|
||||
import datetime
|
||||
from . import Image, Attachment
|
||||
from .._common import attrs_default
|
||||
from .. import _util, _exception
|
||||
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@attrs_default
|
||||
class LocationAttachment(Attachment):
|
||||
@@ -12,15 +15,15 @@ class LocationAttachment(Attachment):
|
||||
"""
|
||||
|
||||
#: Latitude of the location
|
||||
latitude = attr.ib(None, type=float)
|
||||
latitude = attr.ib(None, type=Optional[float])
|
||||
#: Longitude of the location
|
||||
longitude = attr.ib(None, type=float)
|
||||
longitude = attr.ib(None, type=Optional[float])
|
||||
#: Image showing the map of the location
|
||||
image = attr.ib(None, type=Image)
|
||||
image = attr.ib(None, type=Optional[Image])
|
||||
#: URL to Bing maps with the location
|
||||
url = attr.ib(None, type=str)
|
||||
url = attr.ib(None, type=Optional[str])
|
||||
# Address of the location
|
||||
address = attr.ib(None, type=str)
|
||||
address = attr.ib(None, type=Optional[str])
|
||||
|
||||
@classmethod
|
||||
def _from_graphql(cls, data):
|
||||
@@ -51,11 +54,11 @@ class LiveLocationAttachment(LocationAttachment):
|
||||
"""Represents a live user location."""
|
||||
|
||||
#: Name of the location
|
||||
name = attr.ib(None)
|
||||
name = attr.ib(None, type=Optional[str])
|
||||
#: Datetime when live location expires
|
||||
expires_at = attr.ib(None)
|
||||
expires_at = attr.ib(None, type=Optional[datetime.datetime])
|
||||
#: True if live location is expired
|
||||
is_expired = attr.ib(None)
|
||||
is_expired = attr.ib(None, type=Optional[bool])
|
||||
|
||||
@classmethod
|
||||
def _from_pull(cls, data):
|
||||
|
@@ -255,31 +255,31 @@ class MessageData(Message):
|
||||
#: Datetime of when the message was sent
|
||||
created_at = attr.ib(type=datetime.datetime)
|
||||
#: The actual message
|
||||
text = attr.ib(None, type=str)
|
||||
text = attr.ib(None, type=Optional[str])
|
||||
#: A list of `Mention` objects
|
||||
mentions = attr.ib(factory=list, type=Sequence[Mention])
|
||||
#: Size of a sent emoji
|
||||
emoji_size = attr.ib(None, type=EmojiSize)
|
||||
emoji_size = attr.ib(None, type=Optional[EmojiSize])
|
||||
#: Whether the message is read
|
||||
is_read = attr.ib(None, type=bool)
|
||||
is_read = attr.ib(None, type=Optional[bool])
|
||||
#: A list of people IDs who read the message, works only with `Client.fetch_thread_messages`
|
||||
read_by = attr.ib(factory=list, type=bool)
|
||||
#: A dictionary with user's IDs as keys, and their reaction as values
|
||||
reactions = attr.ib(factory=dict, type=Mapping[str, str])
|
||||
#: A `Sticker`
|
||||
sticker = attr.ib(None, type=_sticker.Sticker)
|
||||
sticker = attr.ib(None, type=Optional[_sticker.Sticker])
|
||||
#: A list of attachments
|
||||
attachments = attr.ib(factory=list, type=Sequence[_attachment.Attachment])
|
||||
#: A list of `QuickReply`
|
||||
quick_replies = attr.ib(factory=list, type=Sequence[_quick_reply.QuickReply])
|
||||
#: Whether the message is unsent (deleted for everyone)
|
||||
unsent = attr.ib(False, type=bool)
|
||||
unsent = attr.ib(False, type=Optional[bool])
|
||||
#: Message ID you want to reply to
|
||||
reply_to_id = attr.ib(None, type=str)
|
||||
reply_to_id = attr.ib(None, type=Optional[str])
|
||||
#: Replied message
|
||||
replied_to = attr.ib(None, type="MessageData")
|
||||
replied_to = attr.ib(None, type=Optional["MessageData"])
|
||||
#: Whether the message was forwarded
|
||||
forwarded = attr.ib(False, type=bool)
|
||||
forwarded = attr.ib(False, type=Optional[bool])
|
||||
|
||||
@staticmethod
|
||||
def _get_forwarded_from_tags(tags):
|
||||
|
@@ -4,7 +4,7 @@ import enum
|
||||
from .._common import attrs_default
|
||||
from .. import _exception, _util, _session
|
||||
|
||||
from typing import Mapping, Sequence
|
||||
from typing import Mapping, Sequence, Optional
|
||||
|
||||
|
||||
class GuestStatus(enum.Enum):
|
||||
@@ -132,13 +132,13 @@ class PlanData(Plan):
|
||||
#: Plan title
|
||||
title = attr.ib(type=str)
|
||||
#: Plan location name
|
||||
location = attr.ib(None, converter=lambda x: x or "", type=str)
|
||||
location = attr.ib(None, converter=lambda x: x or "", type=Optional[str])
|
||||
#: Plan location ID
|
||||
location_id = attr.ib(None, converter=lambda x: x or "", type=str)
|
||||
location_id = attr.ib(None, converter=lambda x: x or "", type=Optional[str])
|
||||
#: ID of the plan creator
|
||||
author_id = attr.ib(None, type=str)
|
||||
author_id = attr.ib(None, type=Optional[str])
|
||||
#: `User` ids mapped to their `GuestStatus`
|
||||
guests = attr.ib(None, type=Mapping[str, GuestStatus])
|
||||
guests = attr.ib(None, type=Optional[Mapping[str, GuestStatus]])
|
||||
|
||||
@property
|
||||
def going(self) -> Sequence[str]:
|
||||
|
@@ -2,7 +2,7 @@ import attr
|
||||
from . import Attachment
|
||||
from .._common import attrs_default
|
||||
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
|
||||
|
||||
@attrs_default
|
||||
@@ -24,9 +24,9 @@ class QuickReplyText(QuickReply):
|
||||
"""Represents a text quick reply."""
|
||||
|
||||
#: Title of the quick reply
|
||||
title = attr.ib(None, type=str)
|
||||
#: URL of the quick reply image (optional)
|
||||
image_url = attr.ib(None, type=str)
|
||||
title = attr.ib(None, type=Optional[str])
|
||||
#: URL of the quick reply image
|
||||
image_url = attr.ib(None, type=Optional[str])
|
||||
#: Type of the quick reply
|
||||
_type = "text"
|
||||
|
||||
@@ -43,8 +43,8 @@ class QuickReplyLocation(QuickReply):
|
||||
class QuickReplyPhoneNumber(QuickReply):
|
||||
"""Represents a phone number quick reply (Doesn't work on mobile)."""
|
||||
|
||||
#: URL of the quick reply image (optional)
|
||||
image_url = attr.ib(None, type=str)
|
||||
#: URL of the quick reply image
|
||||
image_url = attr.ib(None, type=Optional[str])
|
||||
#: Type of the quick reply
|
||||
_type = "user_phone_number"
|
||||
|
||||
@@ -53,8 +53,8 @@ class QuickReplyPhoneNumber(QuickReply):
|
||||
class QuickReplyEmail(QuickReply):
|
||||
"""Represents an email quick reply (Doesn't work on mobile)."""
|
||||
|
||||
#: URL of the quick reply image (optional)
|
||||
image_url = attr.ib(None, type=str)
|
||||
#: URL of the quick reply image
|
||||
image_url = attr.ib(None, type=Optional[str])
|
||||
#: Type of the quick reply
|
||||
_type = "user_email"
|
||||
|
||||
|
@@ -2,34 +2,36 @@ import attr
|
||||
from . import Image, Attachment
|
||||
from .._common import attrs_default
|
||||
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@attrs_default
|
||||
class Sticker(Attachment):
|
||||
"""Represents a Facebook sticker that has been sent to a thread as an attachment."""
|
||||
|
||||
#: The sticker-pack's ID
|
||||
pack = attr.ib(None, type=str)
|
||||
pack = attr.ib(None, type=Optional[str])
|
||||
#: Whether the sticker is animated
|
||||
is_animated = attr.ib(False, type=bool)
|
||||
|
||||
# If the sticker is animated, the following should be present
|
||||
#: URL to a medium spritemap
|
||||
medium_sprite_image = attr.ib(None, type=str)
|
||||
medium_sprite_image = attr.ib(None, type=Optional[str])
|
||||
#: URL to a large spritemap
|
||||
large_sprite_image = attr.ib(None, type=str)
|
||||
large_sprite_image = attr.ib(None, type=Optional[str])
|
||||
#: The amount of frames present in the spritemap pr. row
|
||||
frames_per_row = attr.ib(None, type=int)
|
||||
frames_per_row = attr.ib(None, type=Optional[int])
|
||||
#: The amount of frames present in the spritemap pr. column
|
||||
frames_per_col = attr.ib(None, type=int)
|
||||
frames_per_col = attr.ib(None, type=Optional[int])
|
||||
#: The total amount of frames in the spritemap
|
||||
frame_count = attr.ib(None, type=int)
|
||||
frame_count = attr.ib(None, type=Optional[int])
|
||||
#: The frame rate the spritemap is intended to be played in
|
||||
frame_rate = attr.ib(None, type=int)
|
||||
frame_rate = attr.ib(None, type=Optional[int])
|
||||
|
||||
#: The sticker's image
|
||||
image = attr.ib(None, type=Image)
|
||||
image = attr.ib(None, type=Optional[Image])
|
||||
#: The sticker's label/name
|
||||
label = attr.ib(None, type=str)
|
||||
label = attr.ib(None, type=Optional[str])
|
||||
|
||||
@classmethod
|
||||
def _from_graphql(cls, data):
|
||||
|
@@ -157,7 +157,7 @@ class Session:
|
||||
_session = attr.ib(factory=session_factory, type=requests.Session)
|
||||
_counter = attr.ib(0, type=int)
|
||||
_client_id = attr.ib(factory=client_id_factory, type=str)
|
||||
_logout_h = attr.ib(None, type=str)
|
||||
_logout_h = attr.ib(None, type=Optional[str])
|
||||
|
||||
@property
|
||||
def user(self):
|
||||
|
@@ -4,7 +4,8 @@ from ._abc import ThreadABC
|
||||
from . import _user
|
||||
from .._common import attrs_default
|
||||
from .. import _util, _session, _graphql, _models
|
||||
from typing import Sequence, Iterable, Set, Mapping
|
||||
|
||||
from typing import Sequence, Iterable, Set, Mapping, Optional
|
||||
|
||||
|
||||
@attrs_default
|
||||
@@ -179,31 +180,31 @@ class GroupData(Group):
|
||||
"""
|
||||
|
||||
#: The group's picture
|
||||
photo = attr.ib(None, type="_models.Image")
|
||||
photo = attr.ib(None, type=Optional["_models.Image"])
|
||||
#: The name of the group
|
||||
name = attr.ib(None, type=str)
|
||||
name = attr.ib(None, type=Optional[str])
|
||||
#: When the group was last active / when the last message was sent
|
||||
last_active = attr.ib(None, type=datetime.datetime)
|
||||
last_active = attr.ib(None, type=Optional[datetime.datetime])
|
||||
#: Number of messages in the group
|
||||
message_count = attr.ib(None, type=int)
|
||||
message_count = attr.ib(None, type=Optional[int])
|
||||
#: Set `Plan`
|
||||
plan = attr.ib(None, type="_models.PlanData")
|
||||
plan = attr.ib(None, type=Optional["_models.PlanData"])
|
||||
#: The group thread's participant user ids
|
||||
participants = attr.ib(factory=set, type=Set[str])
|
||||
#: A dictionary, containing user nicknames mapped to their IDs
|
||||
nicknames = attr.ib(factory=dict, type=Mapping[str, str])
|
||||
#: The groups's message color
|
||||
color = attr.ib(None, type=str)
|
||||
color = attr.ib(None, type=Optional[str])
|
||||
#: The groups's default emoji
|
||||
emoji = attr.ib(None, type=str)
|
||||
emoji = attr.ib(None, type=Optional[str])
|
||||
# User ids of thread admins
|
||||
admins = attr.ib(factory=set, type=Set[str])
|
||||
# True if users need approval to join
|
||||
approval_mode = attr.ib(None, type=bool)
|
||||
approval_mode = attr.ib(None, type=Optional[bool])
|
||||
# Set containing user IDs requesting to join
|
||||
approval_requests = attr.ib(factory=set, type=Set[str])
|
||||
# Link for joining group
|
||||
join_link = attr.ib(None, type=str)
|
||||
join_link = attr.ib(None, type=Optional[str])
|
||||
|
||||
@classmethod
|
||||
def _from_graphql(cls, session, data):
|
||||
|
@@ -4,6 +4,8 @@ from ._abc import ThreadABC
|
||||
from .._common import attrs_default
|
||||
from .. import _session, _models
|
||||
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@attrs_default
|
||||
class Page(ThreadABC):
|
||||
@@ -39,21 +41,21 @@ class PageData(Page):
|
||||
#: The name of the page
|
||||
name = attr.ib(type=str)
|
||||
#: When the thread was last active / when the last message was sent
|
||||
last_active = attr.ib(None, type=datetime.datetime)
|
||||
last_active = attr.ib(None, type=Optional[datetime.datetime])
|
||||
#: Number of messages in the thread
|
||||
message_count = attr.ib(None, type=int)
|
||||
message_count = attr.ib(None, type=Optional[int])
|
||||
#: Set `Plan`
|
||||
plan = attr.ib(None, type="_models.PlanData")
|
||||
plan = attr.ib(None, type=Optional["_models.PlanData"])
|
||||
#: The page's custom URL
|
||||
url = attr.ib(None, type=str)
|
||||
url = attr.ib(None, type=Optional[str])
|
||||
#: The name of the page's location city
|
||||
city = attr.ib(None, type=str)
|
||||
city = attr.ib(None, type=Optional[str])
|
||||
#: Amount of likes the page has
|
||||
likes = attr.ib(None, type=int)
|
||||
likes = attr.ib(None, type=Optional[int])
|
||||
#: Some extra information about the page
|
||||
sub_title = attr.ib(None, type=str)
|
||||
sub_title = attr.ib(None, type=Optional[str])
|
||||
#: The page's category
|
||||
category = attr.ib(None, type=str)
|
||||
category = attr.ib(None, type=Optional[str])
|
||||
|
||||
@classmethod
|
||||
def _from_graphql(cls, session, data):
|
||||
|
@@ -4,6 +4,8 @@ from ._abc import ThreadABC
|
||||
from .._common import log, attrs_default
|
||||
from .. import _util, _session, _models
|
||||
|
||||
from typing import Optional
|
||||
|
||||
|
||||
GENDERS = {
|
||||
# For standard requests
|
||||
@@ -111,27 +113,27 @@ class UserData(User):
|
||||
#: The users first name
|
||||
first_name = attr.ib(type=str)
|
||||
#: The users last name
|
||||
last_name = attr.ib(None, type=str)
|
||||
last_name = attr.ib(None, type=Optional[str])
|
||||
#: Datetime when the thread was last active / when the last message was sent
|
||||
last_active = attr.ib(None, type=datetime.datetime)
|
||||
last_active = attr.ib(None, type=Optional[datetime.datetime])
|
||||
#: Number of messages in the thread
|
||||
message_count = attr.ib(None, type=int)
|
||||
message_count = attr.ib(None, type=Optional[int])
|
||||
#: Set `Plan`
|
||||
plan = attr.ib(None, type="_models.PlanData")
|
||||
plan = attr.ib(None, type=Optional["_models.PlanData"])
|
||||
#: The profile URL. ``None`` for Messenger-only users
|
||||
url = attr.ib(None, type=str)
|
||||
url = attr.ib(None, type=Optional[str])
|
||||
#: The user's gender
|
||||
gender = attr.ib(None, type=str)
|
||||
gender = attr.ib(None, type=Optional[str])
|
||||
#: From 0 to 1. How close the client is to the user
|
||||
affinity = attr.ib(None, type=float)
|
||||
affinity = attr.ib(None, type=Optional[float])
|
||||
#: The user's nickname
|
||||
nickname = attr.ib(None, type=str)
|
||||
nickname = attr.ib(None, type=Optional[str])
|
||||
#: The clients nickname, as seen by the user
|
||||
own_nickname = attr.ib(None, type=str)
|
||||
own_nickname = attr.ib(None, type=Optional[str])
|
||||
#: The message color
|
||||
color = attr.ib(None, type=str)
|
||||
color = attr.ib(None, type=Optional[str])
|
||||
#: The default emoji
|
||||
emoji = attr.ib(None, type=str)
|
||||
emoji = attr.ib(None, type=Optional[str])
|
||||
|
||||
@staticmethod
|
||||
def _get_other_user(data):
|
||||
|
@@ -20,6 +20,13 @@ USER_AGENTS = [
|
||||
]
|
||||
|
||||
|
||||
def int_or_none(inp: Any) -> Optional[int]:
|
||||
try:
|
||||
return int(inp)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def get_limits(limit: Optional[int], max_limit: int) -> Iterable[int]:
|
||||
"""Helper that generates limits based on a max limit."""
|
||||
if limit is None:
|
||||
|
Reference in New Issue
Block a user