Move user id handling to State
This commit is contained in:
@@ -174,16 +174,11 @@ class Client(object):
|
||||
"""
|
||||
try:
|
||||
# Load cookies into current session
|
||||
state = State.from_cookies(session_cookies, user_agent=user_agent)
|
||||
self._state = State.from_cookies(session_cookies, user_agent=user_agent)
|
||||
self._uid = self._state.user_id
|
||||
except Exception as e:
|
||||
log.exception("Failed loading session")
|
||||
return False
|
||||
uid = state.get_user_id()
|
||||
if uid is None:
|
||||
log.warning("Could not find c_user cookie")
|
||||
return False
|
||||
self._state = state
|
||||
self._uid = uid
|
||||
return True
|
||||
|
||||
def login(self, email, password, max_tries=5, user_agent=None):
|
||||
@@ -209,23 +204,19 @@ class Client(object):
|
||||
|
||||
for i in range(1, max_tries + 1):
|
||||
try:
|
||||
state = State.login(
|
||||
self._state = State.login(
|
||||
email,
|
||||
password,
|
||||
on_2fa_callback=self.on2FACode,
|
||||
user_agent=user_agent,
|
||||
)
|
||||
uid = state.get_user_id()
|
||||
if uid is None:
|
||||
raise FBchatException("Could not find user id")
|
||||
self._uid = self._state.user_id
|
||||
except Exception:
|
||||
if i >= max_tries:
|
||||
raise
|
||||
log.exception("Attempt #{} failed, retrying".format(i))
|
||||
time.sleep(1)
|
||||
else:
|
||||
self._state = state
|
||||
self._uid = uid
|
||||
self.onLoggedIn(email=email)
|
||||
break
|
||||
|
||||
|
@@ -12,6 +12,14 @@ from . import _graphql, _util, _exception
|
||||
FB_DTSG_REGEX = re.compile(r'name="fb_dtsg" value="(.*?)"')
|
||||
|
||||
|
||||
def get_user_id(session):
|
||||
# TODO: Optimize this `.get_dict()` call!
|
||||
rtn = session.cookies.get_dict().get("c_user")
|
||||
if rtn is None:
|
||||
raise _exception.FBchatException("Could not find user id")
|
||||
return str(rtn)
|
||||
|
||||
|
||||
def find_input_fields(html):
|
||||
return bs4.BeautifulSoup(html, "html.parser", parse_only=bs4.SoupStrainer("input"))
|
||||
|
||||
@@ -91,18 +99,13 @@ def _2fa_helper(session, code, r):
|
||||
class State(object):
|
||||
"""Stores and manages state required for most Facebook requests."""
|
||||
|
||||
user_id = attr.ib()
|
||||
fb_dtsg = attr.ib()
|
||||
_revision = attr.ib()
|
||||
_session = attr.ib(factory=session_factory)
|
||||
_counter = attr.ib(0)
|
||||
_logout_h = attr.ib(None)
|
||||
|
||||
def get_user_id(self):
|
||||
rtn = self.get_cookies().get("c_user")
|
||||
if rtn is None:
|
||||
return None
|
||||
return str(rtn)
|
||||
|
||||
def get_params(self):
|
||||
self._counter += 1 # TODO: Make this operation atomic / thread-safe
|
||||
return {
|
||||
@@ -163,6 +166,9 @@ class State(object):
|
||||
|
||||
@classmethod
|
||||
def from_session(cls, session):
|
||||
# TODO: Automatically set user_id when the cookie changes in the session
|
||||
user_id = get_user_id(session)
|
||||
|
||||
r = session.get(_util.prefix_url("/"))
|
||||
|
||||
soup = find_input_fields(r.text)
|
||||
@@ -180,7 +186,11 @@ class State(object):
|
||||
logout_h = logout_h_element["value"] if logout_h_element else None
|
||||
|
||||
return cls(
|
||||
fb_dtsg=fb_dtsg, revision=revision, session=session, logout_h=logout_h
|
||||
user_id=user_id,
|
||||
fb_dtsg=fb_dtsg,
|
||||
revision=revision,
|
||||
session=session,
|
||||
logout_h=logout_h,
|
||||
)
|
||||
|
||||
def get_cookies(self):
|
||||
@@ -197,6 +207,7 @@ class State(object):
|
||||
# It may be a bad idea to do this in an exception handler, if you have a better method, please suggest it!
|
||||
_util.log.warning("Refreshing state and resending request")
|
||||
new = State.from_session(session=self._session)
|
||||
self.user_id = new.user_id
|
||||
self.fb_dtsg = new.fb_dtsg
|
||||
self._revision = new._revision
|
||||
self._counter = new._counter
|
||||
|
Reference in New Issue
Block a user