Add ThreadABC helper, that'll contain functions that threads can call
This commit is contained in:
@@ -14,7 +14,7 @@ from . import _core, _util
|
||||
from ._core import Image
|
||||
from ._exception import FBchatException, FBchatFacebookError
|
||||
from ._session import Session
|
||||
from ._thread import ThreadType, ThreadLocation, ThreadColor, Thread
|
||||
from ._thread import ThreadType, ThreadLocation, ThreadColor, ThreadABC, Thread
|
||||
from ._user import TypingStatus, User, ActiveStatus
|
||||
from ._group import Group
|
||||
from ._page import Page
|
||||
|
@@ -108,11 +108,6 @@ class Client:
|
||||
FETCH METHODS
|
||||
"""
|
||||
|
||||
def _forced_fetch(self, thread_id, mid):
|
||||
params = {"thread_and_message_id": {"thread_id": thread_id, "message_id": mid}}
|
||||
(j,) = self.graphql_requests(_graphql.from_doc_id("1768656253222505", params))
|
||||
return j
|
||||
|
||||
def fetch_threads(self, thread_location, before=None, after=None, limit=None):
|
||||
"""Fetch all threads in ``thread_location``.
|
||||
|
||||
@@ -1820,7 +1815,8 @@ class Client:
|
||||
self.on_unknown_messsage_type(msg=m)
|
||||
else:
|
||||
thread_id = str(delta["threadKey"]["threadFbId"])
|
||||
fetch_info = self._forced_fetch(thread_id, mid)
|
||||
thread = Thread(session=self.session, id=thread_id)
|
||||
fetch_info = thread._forced_fetch(mid)
|
||||
fetch_data = fetch_info["message"]
|
||||
author_id = fetch_data["message_sender"]["id"]
|
||||
at = _util.millis_to_datetime(int(fetch_data["timestamp_precise"]))
|
||||
|
@@ -1,13 +1,12 @@
|
||||
import attr
|
||||
from ._core import attrs_default, Image
|
||||
from . import _util, _session, _plan
|
||||
from ._thread import Thread
|
||||
from . import _util, _session, _plan, _thread
|
||||
from typing import Iterable
|
||||
|
||||
|
||||
@attrs_default
|
||||
class Group(Thread):
|
||||
"""Represents a Facebook group. Inherits `Thread`."""
|
||||
class Group(_thread.ThreadABC):
|
||||
"""Represents a Facebook group. Implements `ThreadABC`."""
|
||||
|
||||
#: The session to use when making requests.
|
||||
session = attr.ib(type=_session.Session)
|
||||
|
@@ -1,12 +1,11 @@
|
||||
import attr
|
||||
from ._core import attrs_default, Image
|
||||
from . import _session, _plan
|
||||
from ._thread import Thread
|
||||
from . import _session, _plan, _thread
|
||||
|
||||
|
||||
@attrs_default
|
||||
class Page(Thread):
|
||||
"""Represents a Facebook page. Inherits `Thread`."""
|
||||
class Page(_thread.ThreadABC):
|
||||
"""Represents a Facebook page. Implements `ThreadABC`."""
|
||||
|
||||
#: The session to use when making requests.
|
||||
session = attr.ib(type=_session.Session)
|
||||
@@ -33,6 +32,9 @@ class Page(Thread):
|
||||
#: The page's category
|
||||
category = attr.ib(None)
|
||||
|
||||
def _to_send_data(self):
|
||||
return {"other_user_fbid": self.id}
|
||||
|
||||
@classmethod
|
||||
def _from_graphql(cls, session, data):
|
||||
if data.get("profile_picture") is None:
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import abc
|
||||
import attr
|
||||
from ._core import attrs_default, Enum, Image
|
||||
from . import _session
|
||||
from typing import MutableMapping, Any
|
||||
|
||||
|
||||
class ThreadType(Enum):
|
||||
@@ -68,17 +70,39 @@ class ThreadColor(Enum):
|
||||
return cls._extend_if_invalid(value)
|
||||
|
||||
|
||||
@attrs_default
|
||||
class Thread:
|
||||
"""Represents a Facebook thread."""
|
||||
class ThreadABC(metaclass=abc.ABCMeta):
|
||||
"""Implemented by thread-like classes.
|
||||
|
||||
#: The session to use when making requests.
|
||||
session = attr.ib(type=_session.Session)
|
||||
#: The unique identifier of the thread.
|
||||
id = attr.ib(converter=str)
|
||||
This is private to implement.
|
||||
"""
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def session(self) -> _session.Session:
|
||||
"""The session to use when making requests."""
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def id(self) -> str:
|
||||
"""The unique identifier of the thread."""
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def _to_send_data(self) -> MutableMapping[str, str]:
|
||||
raise NotImplementedError
|
||||
|
||||
def _forced_fetch(self, message_id: str) -> dict:
|
||||
params = {
|
||||
"thread_and_message_id": {"thread_id": self.id, "message_id": message_id}
|
||||
}
|
||||
(j,) = self.session._graphql_requests(
|
||||
_graphql.from_doc_id("1768656253222505", params)
|
||||
)
|
||||
return j
|
||||
|
||||
@staticmethod
|
||||
def _parse_customization_info(data):
|
||||
def _parse_customization_info(data: Any) -> MutableMapping[str, Any]:
|
||||
if data is None or data.get("customization_info") is None:
|
||||
return {}
|
||||
info = data["customization_info"]
|
||||
@@ -110,6 +134,24 @@ class Thread:
|
||||
rtn["own_nickname"] = pc[1].get("nickname")
|
||||
return rtn
|
||||
|
||||
|
||||
@attrs_default
|
||||
class Thread(ThreadABC):
|
||||
"""Represents a Facebook thread, where the actual type is unknown.
|
||||
|
||||
Implements parts of `ThreadABC`, call the method to figure out if your use case is
|
||||
supported. Otherwise, you'll have to use an `User`/`Group`/`Page` object.
|
||||
|
||||
Note: This list may change in minor versions!
|
||||
"""
|
||||
|
||||
#: The session to use when making requests.
|
||||
session = attr.ib(type=_session.Session)
|
||||
#: The unique identifier of the thread.
|
||||
id = attr.ib(converter=str)
|
||||
|
||||
def _to_send_data(self):
|
||||
# TODO: Only implement this in subclasses
|
||||
return {"other_user_fbid": self.id}
|
||||
raise NotImplementedError(
|
||||
"The method you called is not supported on raw Thread objects."
|
||||
" Please use an appropriate User/Group/Page object instead!"
|
||||
)
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import attr
|
||||
from ._core import attrs_default, Enum, Image
|
||||
from . import _util, _session, _plan
|
||||
from ._thread import Thread
|
||||
from . import _util, _session, _plan, _thread
|
||||
|
||||
|
||||
GENDERS = {
|
||||
@@ -42,8 +41,8 @@ class TypingStatus(Enum):
|
||||
|
||||
|
||||
@attrs_default
|
||||
class User(Thread):
|
||||
"""Represents a Facebook user. Inherits `Thread`."""
|
||||
class User(_thread.ThreadABC):
|
||||
"""Represents a Facebook user. Implements `ThreadABC`."""
|
||||
|
||||
#: The session to use when making requests.
|
||||
session = attr.ib(type=_session.Session)
|
||||
@@ -80,6 +79,9 @@ class User(Thread):
|
||||
#: The default emoji
|
||||
emoji = attr.ib(None)
|
||||
|
||||
def _to_send_data(self):
|
||||
return {"other_user_fbid": self.id}
|
||||
|
||||
def confirm_friend_request(self):
|
||||
"""Confirm a friend request, adding the user to your friend list."""
|
||||
data = {"to_friend": self.id, "action": "confirm"}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
import fbchat
|
||||
from fbchat._thread import ThreadType, ThreadColor, Thread
|
||||
from fbchat import ThreadType, ThreadColor, ThreadABC, Thread
|
||||
|
||||
|
||||
def test_thread_type_to_class():
|
||||
@@ -19,8 +19,8 @@ def test_thread_color_from_graphql():
|
||||
|
||||
|
||||
def test_thread_parse_customization_info_empty():
|
||||
assert {} == Thread._parse_customization_info(None)
|
||||
assert {} == Thread._parse_customization_info({"customization_info": None})
|
||||
assert {} == ThreadABC._parse_customization_info(None)
|
||||
assert {} == ThreadABC._parse_customization_info({"customization_info": None})
|
||||
|
||||
|
||||
def test_thread_parse_customization_info_group():
|
||||
@@ -43,7 +43,7 @@ def test_thread_parse_customization_info_group():
|
||||
"color": ThreadColor.BRILLIANT_ROSE,
|
||||
"nicknames": {"123456789": "A", "987654321": "B"},
|
||||
}
|
||||
assert expected == Thread._parse_customization_info(data)
|
||||
assert expected == ThreadABC._parse_customization_info(data)
|
||||
|
||||
|
||||
def test_thread_parse_customization_info_user():
|
||||
@@ -62,4 +62,9 @@ def test_thread_parse_customization_info_user():
|
||||
# ... Other irrelevant fields
|
||||
}
|
||||
expected = {"emoji": None, "color": None, "own_nickname": "A", "nickname": "B"}
|
||||
assert expected == Thread._parse_customization_info(data)
|
||||
assert expected == ThreadABC._parse_customization_info(data)
|
||||
|
||||
|
||||
def test_thread_create_and_implements_thread_abc(session):
|
||||
thread = Thread(session=session, id="123")
|
||||
assert thread._parse_customization_info
|
||||
|
Reference in New Issue
Block a user