Move user id handling to State
This commit is contained in:
@@ -174,16 +174,11 @@ class Client(object):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Load cookies into current session
|
# 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:
|
except Exception as e:
|
||||||
log.exception("Failed loading session")
|
log.exception("Failed loading session")
|
||||||
return False
|
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
|
return True
|
||||||
|
|
||||||
def login(self, email, password, max_tries=5, user_agent=None):
|
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):
|
for i in range(1, max_tries + 1):
|
||||||
try:
|
try:
|
||||||
state = State.login(
|
self._state = State.login(
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
on_2fa_callback=self.on2FACode,
|
on_2fa_callback=self.on2FACode,
|
||||||
user_agent=user_agent,
|
user_agent=user_agent,
|
||||||
)
|
)
|
||||||
uid = state.get_user_id()
|
self._uid = self._state.user_id
|
||||||
if uid is None:
|
|
||||||
raise FBchatException("Could not find user id")
|
|
||||||
except Exception:
|
except Exception:
|
||||||
if i >= max_tries:
|
if i >= max_tries:
|
||||||
raise
|
raise
|
||||||
log.exception("Attempt #{} failed, retrying".format(i))
|
log.exception("Attempt #{} failed, retrying".format(i))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
else:
|
else:
|
||||||
self._state = state
|
|
||||||
self._uid = uid
|
|
||||||
self.onLoggedIn(email=email)
|
self.onLoggedIn(email=email)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@@ -12,6 +12,14 @@ from . import _graphql, _util, _exception
|
|||||||
FB_DTSG_REGEX = re.compile(r'name="fb_dtsg" value="(.*?)"')
|
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):
|
def find_input_fields(html):
|
||||||
return bs4.BeautifulSoup(html, "html.parser", parse_only=bs4.SoupStrainer("input"))
|
return bs4.BeautifulSoup(html, "html.parser", parse_only=bs4.SoupStrainer("input"))
|
||||||
|
|
||||||
@@ -91,18 +99,13 @@ def _2fa_helper(session, code, r):
|
|||||||
class State(object):
|
class State(object):
|
||||||
"""Stores and manages state required for most Facebook requests."""
|
"""Stores and manages state required for most Facebook requests."""
|
||||||
|
|
||||||
|
user_id = attr.ib()
|
||||||
fb_dtsg = attr.ib()
|
fb_dtsg = attr.ib()
|
||||||
_revision = attr.ib()
|
_revision = attr.ib()
|
||||||
_session = attr.ib(factory=session_factory)
|
_session = attr.ib(factory=session_factory)
|
||||||
_counter = attr.ib(0)
|
_counter = attr.ib(0)
|
||||||
_logout_h = attr.ib(None)
|
_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):
|
def get_params(self):
|
||||||
self._counter += 1 # TODO: Make this operation atomic / thread-safe
|
self._counter += 1 # TODO: Make this operation atomic / thread-safe
|
||||||
return {
|
return {
|
||||||
@@ -163,6 +166,9 @@ class State(object):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_session(cls, session):
|
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("/"))
|
r = session.get(_util.prefix_url("/"))
|
||||||
|
|
||||||
soup = find_input_fields(r.text)
|
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
|
logout_h = logout_h_element["value"] if logout_h_element else None
|
||||||
|
|
||||||
return cls(
|
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):
|
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!
|
# 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")
|
_util.log.warning("Refreshing state and resending request")
|
||||||
new = State.from_session(session=self._session)
|
new = State.from_session(session=self._session)
|
||||||
|
self.user_id = new.user_id
|
||||||
self.fb_dtsg = new.fb_dtsg
|
self.fb_dtsg = new.fb_dtsg
|
||||||
self._revision = new._revision
|
self._revision = new._revision
|
||||||
self._counter = new._counter
|
self._counter = new._counter
|
||||||
|
Reference in New Issue
Block a user