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