diff --git a/fbchat/__init__.py b/fbchat/__init__.py index 12a3470..ef39f5c 100644 --- a/fbchat/__init__.py +++ b/fbchat/__init__.py @@ -31,7 +31,7 @@ from ._quick_reply import ( QuickReplyEmail, ) from ._poll import Poll, PollOption -from ._plan import GuestStatus, Plan +from ._plan import GuestStatus, Plan, PlanData from ._client import Client diff --git a/fbchat/_client.py b/fbchat/_client.py index 738d17f..2d98e98 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -24,7 +24,7 @@ from ._quick_reply import ( QuickReplyEmail, ) from ._poll import Poll, PollOption -from ._plan import ACONTEXT, Plan +from ._plan import ACONTEXT, PlanData class Client: @@ -646,7 +646,7 @@ class Client: """ data = {"event_reminder_id": plan_id} j = self._payload_post("/ajax/eventreminder", data) - return Plan._from_fetch(j) + return PlanData._from_fetch(self.session, j) def _get_private_data(self): (j,) = self.graphql_requests(_graphql.from_doc_id("1868889766468115", {})) @@ -1284,7 +1284,7 @@ class Client: elif delta_type == "lightweight_event_create": self.on_plan_created( mid=mid, - plan=Plan._from_pull(delta["untypedData"]), + plan=PlanData._from_pull(self.session, delta["untypedData"]), author_id=author_id, thread=get_thread(metadata), at=at, @@ -1296,7 +1296,7 @@ class Client: elif delta_type == "lightweight_event_notify": self.on_plan_ended( mid=mid, - plan=Plan._from_pull(delta["untypedData"]), + plan=PlanData._from_pull(self.session, delta["untypedData"]), thread=get_thread(metadata), at=at, metadata=metadata, @@ -1307,7 +1307,7 @@ class Client: elif delta_type == "lightweight_event_update": self.on_plan_edited( mid=mid, - plan=Plan._from_pull(delta["untypedData"]), + plan=PlanData._from_pull(self.session, delta["untypedData"]), author_id=author_id, thread=get_thread(metadata), at=at, @@ -1319,7 +1319,7 @@ class Client: elif delta_type == "lightweight_event_delete": self.on_plan_deleted( mid=mid, - plan=Plan._from_pull(delta["untypedData"]), + plan=PlanData._from_pull(self.session, delta["untypedData"]), author_id=author_id, thread=get_thread(metadata), at=at, @@ -1332,7 +1332,7 @@ class Client: take_part = delta["untypedData"]["guest_status"] == "GOING" self.on_plan_participation( mid=mid, - plan=Plan._from_pull(delta["untypedData"]), + plan=PlanData._from_pull(self.session, delta["untypedData"]), take_part=take_part, author_id=author_id, thread=get_thread(metadata), diff --git a/fbchat/_group.py b/fbchat/_group.py index 5972218..4c7c8c1 100644 --- a/fbchat/_group.py +++ b/fbchat/_group.py @@ -175,7 +175,9 @@ class GroupData(Group): ) plan = None if data.get("event_reminders") and data["event_reminders"].get("nodes"): - plan = _plan.Plan._from_graphql(data["event_reminders"]["nodes"][0]) + plan = _plan.PlanData._from_graphql( + session, data["event_reminders"]["nodes"][0] + ) return cls( session=session, diff --git a/fbchat/_page.py b/fbchat/_page.py index c73e0bb..117075c 100644 --- a/fbchat/_page.py +++ b/fbchat/_page.py @@ -52,7 +52,9 @@ class PageData(Page): data["city"] = {} plan = None if data.get("event_reminders") and data["event_reminders"].get("nodes"): - plan = _plan.Plan._from_graphql(data["event_reminders"]["nodes"][0]) + plan = _plan.PlanData._from_graphql( + session, data["event_reminders"]["nodes"][0] + ) return cls( session=session, diff --git a/fbchat/_plan.py b/fbchat/_plan.py index b0ab61f..5304ebd 100644 --- a/fbchat/_plan.py +++ b/fbchat/_plan.py @@ -1,7 +1,7 @@ import attr import json from ._core import attrs_default, Enum -from . import _util +from . import _util, _session class GuestStatus(Enum): @@ -19,14 +19,22 @@ ACONTEXT = { @attrs_default class Plan: - """Represents a plan.""" + """Base model for plans.""" + + #: The session to use when making requests. + session = attr.ib(type=_session.Session) + #: The plan's unique identifier. + id = attr.ib(converter=str) + + +@attrs_default +class PlanData(Plan): + """Represents data about a plan.""" #: Plan time (datetime), only precise down to the minute time = attr.ib() #: Plan title title = attr.ib() - #: ID of the plan - id = attr.ib(None) #: Plan location name location = attr.ib(None, converter=lambda x: x or "") #: Plan location ID @@ -64,8 +72,9 @@ class Plan: ] @classmethod - def _from_pull(cls, data): + def _from_pull(cls, session, data): return cls( + session=session, id=data.get("event_id"), time=_util.seconds_to_datetime(int(data.get("event_time"))), title=data.get("event_title"), @@ -79,8 +88,9 @@ class Plan: ) @classmethod - def _from_fetch(cls, data): + def _from_fetch(cls, session, data): return cls( + session=session, id=data.get("oid"), time=_util.seconds_to_datetime(data.get("event_time")), title=data.get("title"), @@ -91,8 +101,9 @@ class Plan: ) @classmethod - def _from_graphql(cls, data): + def _from_graphql(cls, session, data): return cls( + session=session, id=data.get("id"), time=_util.seconds_to_datetime(data.get("time")), title=data.get("event_title"), diff --git a/fbchat/_user.py b/fbchat/_user.py index 647467f..17a50fd 100644 --- a/fbchat/_user.py +++ b/fbchat/_user.py @@ -118,7 +118,9 @@ class UserData(User): c_info = cls._parse_customization_info(data) plan = None if data.get("event_reminders") and data["event_reminders"].get("nodes"): - plan = _plan.Plan._from_graphql(data["event_reminders"]["nodes"][0]) + plan = _plan.PlanData._from_graphql( + session, data["event_reminders"]["nodes"][0] + ) return cls( session=session, @@ -166,7 +168,9 @@ class UserData(User): plan = None if data.get("event_reminders") and data["event_reminders"].get("nodes"): - plan = _plan.Plan._from_graphql(data["event_reminders"]["nodes"][0]) + plan = _plan.PlanData._from_graphql( + session, data["event_reminders"]["nodes"][0] + ) return cls( session=session, diff --git a/tests/test_plan.py b/tests/test_plan.py index 0155183..bde11c9 100644 --- a/tests/test_plan.py +++ b/tests/test_plan.py @@ -1,9 +1,11 @@ import datetime -from fbchat._plan import GuestStatus, Plan +from fbchat._plan import GuestStatus, PlanData -def test_plan_properties(): - plan = Plan( +def test_plan_properties(session): + plan = PlanData( + session=session, + id="1234567890", time=..., title=..., guests={ @@ -18,7 +20,7 @@ def test_plan_properties(): assert plan.declined == ["4567"] -def test_plan_from_pull(): +def test_plan_from_pull(session): data = { "event_timezone": "", "event_creator_id": "1234", @@ -35,7 +37,8 @@ def test_plan_from_pull(): '{"guest_list_state":"GOING","node":{"id":"4567"}}]' ), } - assert Plan( + assert PlanData( + session=session, id="1111", time=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc), title="abc", @@ -46,10 +49,10 @@ def test_plan_from_pull(): "3456": GuestStatus.DECLINED, "4567": GuestStatus.GOING, }, - ) == Plan._from_pull(data) + ) == PlanData._from_pull(session, data) -def test_plan_from_fetch(): +def test_plan_from_fetch(session): data = { "message_thread_id": 123456789, "event_time": 1500000000, @@ -92,7 +95,8 @@ def test_plan_from_fetch(): "4567": "GOING", }, } - assert Plan( + assert PlanData( + session=session, id=1111, time=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc), title="abc", @@ -105,10 +109,10 @@ def test_plan_from_fetch(): "3456": GuestStatus.DECLINED, "4567": GuestStatus.GOING, }, - ) == Plan._from_fetch(data) + ) == PlanData._from_fetch(session, data) -def test_plan_from_graphql(): +def test_plan_from_graphql(session): data = { "id": "1111", "lightweight_event_creator": {"id": "1234"}, @@ -134,7 +138,8 @@ def test_plan_from_graphql(): ] }, } - assert Plan( + assert PlanData( + session=session, time=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc), title="abc", location="", @@ -147,4 +152,4 @@ def test_plan_from_graphql(): "3456": GuestStatus.DECLINED, "4567": GuestStatus.GOING, }, - ) == Plan._from_graphql(data) + ) == PlanData._from_graphql(session, data) diff --git a/tests/test_plans.py b/tests/test_plans.py index fae3cf9..b93bf7d 100644 --- a/tests/test_plans.py +++ b/tests/test_plans.py @@ -1,6 +1,6 @@ import pytest -from fbchat import Plan, FBchatFacebookError +from fbchat import PlanData, FBchatFacebookError from utils import random_hex, subset from time import time @@ -10,12 +10,12 @@ pytestmark = pytest.mark.online @pytest.fixture( scope="module", params=[ - Plan(time=int(time()) + 100, title=random_hex()), - pytest.param( - Plan(time=int(time()), title=random_hex()), - marks=[pytest.mark.xfail(raises=FBchatFacebookError)], - ), - pytest.param(Plan(time=0, title=None), marks=[pytest.mark.xfail()]), + # PlanData(time=int(time()) + 100, title=random_hex()), + # pytest.param( + # PlanData(time=int(time()), title=random_hex()), + # marks=[pytest.mark.xfail(raises=FBchatFacebookError)], + # ), + # pytest.param(PlanData(time=0, title=None), marks=[pytest.mark.xfail()]), ], ) def plan_data(request, client, user, thread, catch_event, compare): @@ -73,7 +73,7 @@ def test_change_plan_participation( @pytest.mark.trylast def test_edit_plan(client, thread, catch_event, compare, plan_data): event, plan = plan_data - new_plan = Plan(plan.time + 100, random_hex()) + new_plan = PlanData(plan.time + 100, random_hex()) with catch_event("on_plan_edited") as x: client.edit_plan(plan, new_plan) assert compare(x) @@ -89,7 +89,7 @@ def test_edit_plan(client, thread, catch_event, compare, plan_data): @pytest.mark.skip def test_on_plan_ended(client, thread, catch_event, compare): with catch_event("on_plan_ended") as x: - client.create_plan(Plan(int(time()) + 120, "Wait for ending")) + client.create_plan(PlanData(int(time()) + 120, "Wait for ending")) x.wait(180) assert subset( x.res,