Small cleanup of event parsing
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import attr
|
||||
import datetime
|
||||
from ._common import attrs_event, Event, UnknownEvent, ThreadEvent
|
||||
from . import _client_payload, _delta_class, _delta_type
|
||||
from ._client_payload import *
|
||||
from ._delta_class import *
|
||||
from ._delta_type import *
|
||||
@@ -69,23 +68,6 @@ class Presence(Event):
|
||||
return cls(statuses=statuses, full=data["list_type"] == "full")
|
||||
|
||||
|
||||
def parse_delta(session, data):
|
||||
try:
|
||||
class_ = data["class"]
|
||||
if class_ == "ClientPayload":
|
||||
yield from _client_payload.parse_client_payloads(session, data)
|
||||
elif class_ == "AdminTextMessage":
|
||||
yield _delta_type.parse_delta(session, data)
|
||||
else:
|
||||
event = _delta_class.parse_delta(session, data)
|
||||
if event: # Skip `None`
|
||||
yield event
|
||||
except _exception.ParseError:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise _exception.ParseError("Error parsing delta", data=data) from e
|
||||
|
||||
|
||||
def parse_events(session, topic, data):
|
||||
# See Mqtt._configure_connect_options for information about these topics
|
||||
try:
|
||||
@@ -93,7 +75,19 @@ def parse_events(session, topic, data):
|
||||
# `deltas` will always be available, since we're filtering out the things
|
||||
# that don't have it earlier in the MQTT listener
|
||||
for delta in data["deltas"]:
|
||||
yield from parse_delta(session, delta)
|
||||
if delta["class"] == "ClientPayload":
|
||||
yield from parse_client_payloads(session, delta)
|
||||
continue
|
||||
try:
|
||||
event = parse_delta(session, delta)
|
||||
if event: # Skip `None`
|
||||
yield event
|
||||
except _exception.ParseError:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise _exception.ParseError(
|
||||
"Error parsing delta", data=delta
|
||||
) from e
|
||||
|
||||
elif topic == "/thread_typing":
|
||||
yield Typing._parse(session, data)
|
||||
|
@@ -18,6 +18,17 @@ class Event(metaclass=abc.ABCMeta):
|
||||
def _parse(cls, session, data):
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def _get_thread(session, data):
|
||||
# TODO: Handle pages? Is it even possible?
|
||||
key = data["threadKey"]
|
||||
|
||||
if "threadFbId" in key:
|
||||
return _threads.Group(session=session, id=str(key["threadFbId"]))
|
||||
elif "otherUserFbId" in key:
|
||||
return _threads.User(session=session, id=str(key["otherUserFbId"]))
|
||||
raise _exception.ParseError("Could not find thread data", data=data)
|
||||
|
||||
|
||||
@attrs_event
|
||||
class UnknownEvent(Event):
|
||||
@@ -42,21 +53,10 @@ class ThreadEvent(Event):
|
||||
#: Thread that the action was done in
|
||||
thread = attr.ib(type="_threads.ThreadABC")
|
||||
|
||||
@staticmethod
|
||||
def _get_thread(session, data):
|
||||
# TODO: Handle pages? Is it even possible?
|
||||
key = data["threadKey"]
|
||||
|
||||
if "threadFbId" in key:
|
||||
return _threads.Group(session=session, id=str(key["threadFbId"]))
|
||||
elif "otherUserFbId" in key:
|
||||
return _threads.User(session=session, id=str(key["otherUserFbId"]))
|
||||
raise _exception.ParseError("Could not find thread data", data=data)
|
||||
|
||||
@staticmethod
|
||||
def _parse_metadata(session, data):
|
||||
@classmethod
|
||||
def _parse_metadata(cls, session, data):
|
||||
metadata = data["messageMetadata"]
|
||||
author = _threads.User(session=session, id=metadata["actorFbId"])
|
||||
thread = ThreadEvent._get_thread(session, metadata)
|
||||
thread = cls._get_thread(session, metadata)
|
||||
at = _util.millis_to_datetime(int(metadata["timestamp"]))
|
||||
return author, thread, at
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import attr
|
||||
import datetime
|
||||
from ._common import attrs_event, Event, UnknownEvent, ThreadEvent
|
||||
from . import _delta_type
|
||||
from .. import _util, _threads, _models
|
||||
|
||||
from typing import Sequence, Optional
|
||||
@@ -83,7 +84,7 @@ class UnfetchedThreadEvent(Event):
|
||||
|
||||
@classmethod
|
||||
def _parse(cls, session, data):
|
||||
thread = ThreadEvent._get_thread(session, data)
|
||||
thread = cls._get_thread(session, data)
|
||||
message = None
|
||||
if "messageId" in data:
|
||||
message = _models.Message(thread=thread, id=data["messageId"])
|
||||
@@ -125,7 +126,7 @@ class ThreadsRead(Event):
|
||||
@classmethod
|
||||
def _parse_read_receipt(cls, session, data):
|
||||
author = _threads.User(session=session, id=data["actorFbId"])
|
||||
thread = ThreadEvent._get_thread(session, data)
|
||||
thread = cls._get_thread(session, data)
|
||||
at = _util.millis_to_datetime(int(data["actionTimestampMs"]))
|
||||
return cls(author=author, threads=[thread], at=at)
|
||||
|
||||
@@ -133,8 +134,7 @@ class ThreadsRead(Event):
|
||||
def _parse(cls, session, data):
|
||||
author = _threads.User(session=session, id=session.user_id)
|
||||
threads = [
|
||||
ThreadEvent._get_thread(session, {"threadKey": x})
|
||||
for x in data["threadKeys"]
|
||||
cls._get_thread(session, {"threadKey": x}) for x in data["threadKeys"]
|
||||
]
|
||||
at = _util.millis_to_datetime(int(data["actionTimestamp"]))
|
||||
return cls(author=author, threads=threads, at=at)
|
||||
@@ -175,14 +175,16 @@ class ThreadFolder(Event):
|
||||
|
||||
@classmethod
|
||||
def _parse(cls, session, data):
|
||||
thread = ThreadEvent._get_thread(session, data)
|
||||
thread = cls._get_thread(session, data)
|
||||
folder = _threads.ThreadLocation._parse(data["folder"])
|
||||
return cls(thread=thread, folder=folder)
|
||||
|
||||
|
||||
def parse_delta(session, data):
|
||||
class_ = data["class"]
|
||||
if class_ == "ParticipantsAddedToGroupThread":
|
||||
if class_ == "AdminTextMessage":
|
||||
return _delta_type.parse_admin_message(session, data)
|
||||
elif class_ == "ParticipantsAddedToGroupThread":
|
||||
return PeopleAdded._parse(session, data)
|
||||
elif class_ == "ParticipantLeftGroupThread":
|
||||
return PersonRemoved._parse(session, data)
|
||||
@@ -204,10 +206,10 @@ def parse_delta(session, data):
|
||||
elif class_ == "NoOp":
|
||||
# Skip "no operation" events
|
||||
return None
|
||||
elif class_ == "ClientPayload":
|
||||
return X._parse(session, data)
|
||||
elif class_ == "NewMessage":
|
||||
return MessageEvent._parse(session, data)
|
||||
elif class_ == "ThreadFolder":
|
||||
return ThreadFolder._parse(session, data)
|
||||
elif class_ == "ClientPayload":
|
||||
raise ValueError("This is implemented in `parse_events`")
|
||||
return UnknownEvent(source="Delta class", data=data)
|
||||
|
@@ -280,7 +280,7 @@ class PlanResponded(ThreadEvent):
|
||||
return cls(author=author, thread=thread, plan=plan, take_part=take_part, at=at)
|
||||
|
||||
|
||||
def parse_delta(session, data):
|
||||
def parse_admin_message(session, data):
|
||||
type_ = data["type"]
|
||||
if type_ == "change_thread_theme":
|
||||
return ColorSet._parse(session, data)
|
||||
|
@@ -13,7 +13,7 @@ from fbchat import (
|
||||
UnsendEvent,
|
||||
MessageReplyEvent,
|
||||
)
|
||||
from fbchat._events._client_payload import parse_client_delta, parse_client_payloads
|
||||
from fbchat._events import parse_client_delta, parse_client_payloads
|
||||
|
||||
|
||||
def test_reaction_event_added(session):
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import pytest
|
||||
import datetime
|
||||
from fbchat import Group, User, ParseError, ThreadEvent
|
||||
from fbchat import Group, User, ParseError, Event, ThreadEvent
|
||||
|
||||
|
||||
def test_thread_event_get_thread_group1(session):
|
||||
def test_event_get_thread_group1(session):
|
||||
data = {
|
||||
"threadKey": {"threadFbId": 1234},
|
||||
"messageId": "mid.$gAAT4Sw1WSGh14A3MOFvrsiDvr3Yc",
|
||||
@@ -18,10 +18,10 @@ def test_thread_event_get_thread_group1(session):
|
||||
"source:messenger:web",
|
||||
],
|
||||
}
|
||||
assert Group(session=session, id="1234") == ThreadEvent._get_thread(session, data)
|
||||
assert Group(session=session, id="1234") == Event._get_thread(session, data)
|
||||
|
||||
|
||||
def test_thread_event_get_thread_group2(session):
|
||||
def test_event_get_thread_group2(session):
|
||||
data = {
|
||||
"actorFbId": "4321",
|
||||
"folderId": {"systemFolderId": "INBOX"},
|
||||
@@ -33,10 +33,10 @@ def test_thread_event_get_thread_group2(session):
|
||||
"threadReadStateEffect": "KEEP_AS_IS",
|
||||
"timestamp": "1500000000000",
|
||||
}
|
||||
assert Group(session=session, id="1234") == ThreadEvent._get_thread(session, data)
|
||||
assert Group(session=session, id="1234") == Event._get_thread(session, data)
|
||||
|
||||
|
||||
def test_thread_event_get_thread_user(session):
|
||||
def test_event_get_thread_user(session):
|
||||
data = {
|
||||
"actorFbId": "4321",
|
||||
"folderId": {"systemFolderId": "INBOX"},
|
||||
@@ -49,13 +49,13 @@ def test_thread_event_get_thread_user(session):
|
||||
"threadReadStateEffect": "KEEP_AS_IS",
|
||||
"timestamp": "1500000000000",
|
||||
}
|
||||
assert User(session=session, id="1234") == ThreadEvent._get_thread(session, data)
|
||||
assert User(session=session, id="1234") == Event._get_thread(session, data)
|
||||
|
||||
|
||||
def test_thread_event_get_thread_unknown(session):
|
||||
def test_event_get_thread_unknown(session):
|
||||
data = {"threadKey": {"abc": "1234"}}
|
||||
with pytest.raises(ParseError, match="Could not find thread data"):
|
||||
ThreadEvent._get_thread(session, data)
|
||||
Event._get_thread(session, data)
|
||||
|
||||
|
||||
def test_thread_event_parse_metadata(session):
|
||||
|
@@ -17,7 +17,7 @@ from fbchat import (
|
||||
MessageEvent,
|
||||
ThreadFolder,
|
||||
)
|
||||
from fbchat._events._delta_class import parse_delta
|
||||
from fbchat._events import parse_delta
|
||||
|
||||
|
||||
def test_people_added(session):
|
||||
|
@@ -29,7 +29,7 @@ from fbchat import (
|
||||
PlanDeleted,
|
||||
PlanResponded,
|
||||
)
|
||||
from fbchat._events._delta_type import parse_delta
|
||||
from fbchat._events import parse_admin_message
|
||||
|
||||
|
||||
def test_color_set(session):
|
||||
@@ -65,7 +65,7 @@ def test_color_set(session):
|
||||
thread=Group(session=session, id="4321"),
|
||||
color="#ff7e29",
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_emoji_set(session):
|
||||
@@ -99,7 +99,7 @@ def test_emoji_set(session):
|
||||
thread=User(session=session, id="1234"),
|
||||
emoji="🌟",
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_nickname_set(session):
|
||||
@@ -132,7 +132,7 @@ def test_nickname_set(session):
|
||||
subject=User(session=session, id="2345"),
|
||||
nickname="abc",
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_nickname_clear(session):
|
||||
@@ -164,7 +164,7 @@ def test_nickname_clear(session):
|
||||
subject=User(session=session, id="1234"),
|
||||
nickname=None,
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_admins_added(session):
|
||||
@@ -201,7 +201,7 @@ def test_admins_added(session):
|
||||
thread=Group(session=session, id="4321"),
|
||||
added=[User(session=session, id="2345")],
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_admins_removed(session):
|
||||
@@ -238,7 +238,7 @@ def test_admins_removed(session):
|
||||
thread=Group(session=session, id="4321"),
|
||||
removed=[User(session=session, id="1234")],
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_approvalmode_set(session):
|
||||
@@ -270,7 +270,7 @@ def test_approvalmode_set(session):
|
||||
thread=Group(session=session, id="4321"),
|
||||
require_admin_approval=True,
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_approvalmode_unset(session):
|
||||
@@ -302,7 +302,7 @@ def test_approvalmode_unset(session):
|
||||
thread=Group(session=session, id="4321"),
|
||||
require_admin_approval=False,
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_call_started(session):
|
||||
@@ -360,7 +360,7 @@ def test_call_started(session):
|
||||
author=User(session=session, id="1234"),
|
||||
thread=Group(session=session, id="4321"),
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_group_call_ended(session):
|
||||
@@ -418,7 +418,7 @@ def test_group_call_ended(session):
|
||||
thread=Group(session=session, id="4321"),
|
||||
duration=datetime.timedelta(seconds=31),
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_user_call_ended(session):
|
||||
@@ -460,7 +460,7 @@ def test_user_call_ended(session):
|
||||
thread=User(session=session, id="1234"),
|
||||
duration=datetime.timedelta(seconds=3),
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_call_joined(session):
|
||||
@@ -495,7 +495,7 @@ def test_call_joined(session):
|
||||
author=User(session=session, id="1234"),
|
||||
thread=Group(session=session, id="4321"),
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_poll_created(session):
|
||||
@@ -572,7 +572,7 @@ def test_poll_created(session):
|
||||
options_count=2,
|
||||
),
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_poll_answered(session):
|
||||
@@ -665,7 +665,7 @@ def test_poll_answered(session):
|
||||
added_ids=["1002", "1003"],
|
||||
removed_ids=["1001"],
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_plan_created(session):
|
||||
@@ -725,7 +725,7 @@ def test_plan_created(session):
|
||||
},
|
||||
),
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Need to gather test data")
|
||||
@@ -749,7 +749,7 @@ def test_plan_ended(session):
|
||||
},
|
||||
),
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_plan_edited(session):
|
||||
@@ -815,7 +815,7 @@ def test_plan_edited(session):
|
||||
},
|
||||
),
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_plan_deleted(session):
|
||||
@@ -879,7 +879,7 @@ def test_plan_deleted(session):
|
||||
},
|
||||
),
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_plan_participation(session):
|
||||
@@ -948,9 +948,11 @@ def test_plan_participation(session):
|
||||
),
|
||||
take_part=False,
|
||||
at=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
|
||||
) == parse_delta(session, data)
|
||||
) == parse_admin_message(session, data)
|
||||
|
||||
|
||||
def test_parse_delta_unknown(session):
|
||||
def test_parse_admin_message_unknown(session):
|
||||
data = {"class": "AdminTextMessage", "type": "abc"}
|
||||
assert UnknownEvent(source="Delta type", data=data) == parse_delta(session, data)
|
||||
assert UnknownEvent(source="Delta type", data=data) == parse_admin_message(
|
||||
session, data
|
||||
)
|
||||
|
@@ -13,7 +13,7 @@ from fbchat import (
|
||||
UnfetchedThreadEvent,
|
||||
ActiveStatus,
|
||||
)
|
||||
from fbchat._events import parse_delta, parse_events
|
||||
from fbchat._events import parse_events
|
||||
|
||||
|
||||
def test_t_ms_full(session):
|
||||
|
Reference in New Issue
Block a user