Move request payload into State model

This commit is contained in:
Mads Marquart
2019-07-01 13:30:22 +02:00
parent 78c307780b
commit f07122d446
2 changed files with 32 additions and 21 deletions

View File

@@ -11,6 +11,7 @@ from collections import OrderedDict
from ._util import * from ._util import *
from .models import * from .models import *
from ._graphql import graphql_queries_to_json, graphql_response_to_json, GraphQL from ._graphql import graphql_queries_to_json, graphql_response_to_json, GraphQL
from ._state import State
import time import time
import json import json
@@ -69,11 +70,7 @@ class Client(object):
:raises: FBchatException on failed login :raises: FBchatException on failed login
""" """
self._sticky, self._pool = (None, None) self._sticky, self._pool = (None, None)
self._session = requests.session() self._resetValues()
self._req_counter = 1
self._seq = "0"
# See `createPoll` for the reason for using `OrderedDict` here
self._payload_default = OrderedDict()
self._default_thread_id = None self._default_thread_id = None
self._default_thread_type = None self._default_thread_type = None
self._pull_channel = 0 self._pull_channel = 0
@@ -106,14 +103,11 @@ class Client(object):
""" """
def _generatePayload(self, query): def _generatePayload(self, query):
"""Adds the following defaults to the payload:
__rev, __user, __a, ttstamp, fb_dtsg, __req
"""
if not query: if not query:
query = {} query = {}
query.update(self._payload_default)
query["__req"] = str_base(self._req_counter, 36) query["__req"] = str_base(self._req_counter, 36)
self._req_counter += 1 self._req_counter += 1
query.update(self._state.get_params())
return query return query
def _fix_fb_errors(self, error_code): def _fix_fb_errors(self, error_code):
@@ -271,14 +265,14 @@ class Client(object):
""" """
def _resetValues(self): def _resetValues(self):
self._payload_default = OrderedDict() self._state = State()
self._session = requests.session() self._session = requests.session()
self._req_counter = 1 self._req_counter = 1
self._seq = "0" self._seq = "0"
self._uid = None self._uid = None
def _postLogin(self): def _postLogin(self):
self._payload_default = OrderedDict() self._state = State()
self._client_id = hex(int(random() * 2147483648))[2:] self._client_id = hex(int(random() * 2147483648))[2:]
self._uid = self._session.cookies.get_dict().get("c_user") self._uid = self._session.cookies.get_dict().get("c_user")
if self._uid is None: if self._uid is None:
@@ -298,12 +292,9 @@ class Client(object):
if fb_h_element: if fb_h_element:
self._fb_h = fb_h_element["value"] self._fb_h = fb_h_element["value"]
# Set default payload revision = int(r.text.split('"client_revision":', 1)[1].split(",", 1)[0])
self._payload_default["__rev"] = int(
r.text.split('"client_revision":', 1)[1].split(",", 1)[0] self._state = State(fb_dtsg=fb_dtsg, revision=revision)
)
self._payload_default["__a"] = "1"
self._payload_default["fb_dtsg"] = fb_dtsg
def _login(self, email, password): def _login(self, email, password):
soup = bs(self._get("https://m.facebook.com/").text, "html.parser") soup = bs(self._get("https://m.facebook.com/").text, "html.parser")
@@ -1299,7 +1290,7 @@ class Client(object):
# update JS token if received in response # update JS token if received in response
fb_dtsg = get_jsmods_require(j, 2) fb_dtsg = get_jsmods_require(j, 2)
if fb_dtsg is not None: if fb_dtsg is not None:
self._payload_default["fb_dtsg"] = fb_dtsg self._state.fb_dtsg = fb_dtsg
try: try:
message_ids = [ message_ids = [
@@ -2092,9 +2083,6 @@ class Client(object):
# We're using ordered dicts, because the Facebook endpoint that parses the POST # We're using ordered dicts, because the Facebook endpoint that parses the POST
# parameters is badly implemented, and deals with ordering the options wrongly. # parameters is badly implemented, and deals with ordering the options wrongly.
# This also means we had to change `client._payload_default` to an ordered dict,
# since that's being copied in between this point and the `requests` call
#
# If you can find a way to fix this for the endpoint, or if you find another # If you can find a way to fix this for the endpoint, or if you find another
# endpoint, please do suggest it ;) # endpoint, please do suggest it ;)
data = OrderedDict([("question_text", poll.title), ("target_id", thread_id)]) data = OrderedDict([("question_text", poll.title), ("target_id", thread_id)])

23
fbchat/_state.py Normal file
View File

@@ -0,0 +1,23 @@
# -*- coding: UTF-8 -*-
from __future__ import unicode_literals
import attr
from . import _util
@attr.s(slots=True, kw_only=True)
class State(object):
"""Stores and manages state required for most Facebook requests."""
fb_dtsg = attr.ib(None)
_revision = attr.ib(None)
def get_params(self):
if self.fb_dtsg is None:
return {}
return {
"__a": 1,
"__rev": self._revision,
"fb_dtsg": self.fb_dtsg,
}