|
|
|
@ -1,4 +1,3 @@ |
|
|
|
|
#!/usr/bin/python3 |
|
|
|
|
""" |
|
|
|
|
Fbx Client |
|
|
|
|
""" |
|
|
|
@ -13,10 +12,7 @@ from . import api |
|
|
|
|
from . import utils |
|
|
|
|
from . import mdns |
|
|
|
|
|
|
|
|
|
__all__ = [ |
|
|
|
|
"FbxTransport", |
|
|
|
|
"Fbx", |
|
|
|
|
"FbxClass", ] |
|
|
|
|
__all__ = ["Transport", "Fbx", "FbxClass"] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FbxClass(): |
|
|
|
@ -28,7 +24,7 @@ class FbxClass(): |
|
|
|
|
self._trn = transport |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FbxTransport(): |
|
|
|
|
class Transport(): |
|
|
|
|
""" |
|
|
|
|
Transport abstraction and context handling for all methods |
|
|
|
|
""" |
|
|
|
@ -53,23 +49,27 @@ class FbxTransport(): |
|
|
|
|
else: |
|
|
|
|
self._url = url |
|
|
|
|
|
|
|
|
|
def set_session_header(self, session_token): |
|
|
|
|
def set_header(self, session_token): |
|
|
|
|
self._session.headers.update({'X-Fbx-App-Auth': session_token}) |
|
|
|
|
|
|
|
|
|
def api_exec(self, http_method, endpoint, post_data=None, **kwargs): |
|
|
|
|
req_response = self._session.request( |
|
|
|
|
http_method, |
|
|
|
|
self._url + "/" + endpoint.format(**kwargs), json=post_data) |
|
|
|
|
self.log.debug(">> Sent %s %s/%s Post: %s", http_method, self._url, |
|
|
|
|
endpoint.format(**kwargs), post_data) |
|
|
|
|
req_response.raise_for_status() |
|
|
|
|
try: |
|
|
|
|
self.log.debug(">> Sent %s %s/%s Post: %s", http_method, self._url, |
|
|
|
|
endpoint.format(**kwargs), post_data) |
|
|
|
|
req_response = self._session.request( |
|
|
|
|
http_method, |
|
|
|
|
self._url + "/" + endpoint.format(**kwargs), json=post_data) |
|
|
|
|
req_response.raise_for_status() |
|
|
|
|
except requests.exceptions.RequestException as exc: |
|
|
|
|
raise RequestError(exc) |
|
|
|
|
|
|
|
|
|
response = req_response.json() |
|
|
|
|
if response['success']: |
|
|
|
|
if 'result' in response: |
|
|
|
|
self.log.debug("<< Got {}".format(response['result'])) |
|
|
|
|
return response['result'] |
|
|
|
|
else: |
|
|
|
|
raise FbxErrorResponse(response['error_code'], response['msg']) |
|
|
|
|
raise ResponseError(response['error_code'], response['msg']) |
|
|
|
|
|
|
|
|
|
def local_base(self, url=api._DISC_HTTP_URL): |
|
|
|
|
response = self._session.get("{}/api_version".format(url)).json() |
|
|
|
@ -85,9 +85,9 @@ class Fbx(): |
|
|
|
|
|
|
|
|
|
def __init__(self, url=None, nomdns=False, session=None): |
|
|
|
|
self.log = logging.getLogger("pyfbx.fbx") |
|
|
|
|
self._trn = FbxTransport(url, nomdns=nomdns, session=session) |
|
|
|
|
self.app_id = None |
|
|
|
|
self.token = None |
|
|
|
|
self._trn = Transport(url, nomdns=nomdns, session=session) |
|
|
|
|
self._app_id = None |
|
|
|
|
self._token = None |
|
|
|
|
|
|
|
|
|
# Create on the fly attributes to classes |
|
|
|
|
_globals = globals() |
|
|
|
@ -100,10 +100,10 @@ class Fbx(): |
|
|
|
|
""" |
|
|
|
|
Register app |
|
|
|
|
""" |
|
|
|
|
self.app_id = app_id |
|
|
|
|
data = {"app_id": self.app_id, "app_name": app_name, "device_name": device} |
|
|
|
|
self._app_id = app_id |
|
|
|
|
data = {"app_id": self._app_id, "app_name": app_name, "device_name": device} |
|
|
|
|
res = self._trn.api_exec("POST", "login/authorize/", data) |
|
|
|
|
trackid, self.token = res["track_id"], res["app_token"] |
|
|
|
|
trackid, self._token = res["track_id"], res["app_token"] |
|
|
|
|
s = "pending" |
|
|
|
|
self.log.info("Press Ok on the freebox to register application") |
|
|
|
|
while s == "pending": |
|
|
|
@ -111,34 +111,41 @@ class Fbx(): |
|
|
|
|
if s == "pending": |
|
|
|
|
time.sleep(1) |
|
|
|
|
self.log.debug("Registration returned: {}".format(s)) |
|
|
|
|
return s == "granted" and self.token |
|
|
|
|
return s == "granted" and self._token |
|
|
|
|
|
|
|
|
|
def mksession(self, app_id=None, token=None): |
|
|
|
|
self.log.debug("Making session with token={}[{}], app_id={}[{}]".format( |
|
|
|
|
token, self.token, self.app_id, app_id)) |
|
|
|
|
token, self._token, app_id, self._app_id)) |
|
|
|
|
if token: # Don't overwrite previous token (used for refresh) |
|
|
|
|
self.token = token |
|
|
|
|
self._token = token |
|
|
|
|
if app_id: |
|
|
|
|
self.app_id = app_id |
|
|
|
|
elif not self.app_id: |
|
|
|
|
self._app_id = app_id |
|
|
|
|
elif not self._app_id: |
|
|
|
|
raise Exception("Missing app_id") |
|
|
|
|
login = self._trn.api_exec("GET", "login/") |
|
|
|
|
if not login['logged_in']: |
|
|
|
|
data = { |
|
|
|
|
"app_id": self.app_id, |
|
|
|
|
"password": hmac.new(bytes(self.token, "ascii"), |
|
|
|
|
"app_id": self._app_id, |
|
|
|
|
"password": hmac.new(bytes(self._token, "ascii"), |
|
|
|
|
bytes(login['challenge'], "ascii"), |
|
|
|
|
hashlib.sha1).hexdigest() |
|
|
|
|
} |
|
|
|
|
resp = self._trn.api_exec("POST", "login/session/", data) |
|
|
|
|
session_token = resp["session_token"] |
|
|
|
|
self.app_id = app_id |
|
|
|
|
self._trn.set_session_header(session_token) |
|
|
|
|
self.log.info("Authenticated. Storing token={}, app_id={}".format(self.token, self.app_id)) |
|
|
|
|
self._trn.set_header(session_token) |
|
|
|
|
self.log.info("Authenticated. Storing token={}, app_id={}".format(self._token, self._app_id)) |
|
|
|
|
return resp["permissions"] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FbxErrorResponse(Exception): |
|
|
|
|
class RequestError(Exception): |
|
|
|
|
def __init__(self, msg): |
|
|
|
|
self.msg = msg |
|
|
|
|
|
|
|
|
|
def __str__(self): |
|
|
|
|
return '{}'.format(self.msg) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ResponseError(Exception): |
|
|
|
|
def __init__(self, error_code, msg): |
|
|
|
|
self.error_code = error_code |
|
|
|
|
self.msg = msg |
|
|
|
|