Move request payload into State model
This commit is contained in:
@@ -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
23
fbchat/_state.py
Normal 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,
|
||||||
|
}
|
Reference in New Issue
Block a user