From c11af09b64df4be77257207dfd147649489c776e Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Thu, 28 Jul 2016 22:34:04 +0200 Subject: [PATCH] [FEATURE] Api Wrapper to handle connection issues (#1459) * add an api wrapper managing (trying to) handle connections error, needs more testing * refine error testing * import fix * sleep less, lazy bum * change retry parameter as an optional argument --- pokemongo_bot/__init__.py | 7 ++--- pokemongo_bot/api_wrapper.py | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 pokemongo_bot/api_wrapper.py diff --git a/pokemongo_bot/__init__.py b/pokemongo_bot/__init__.py index 3a2068bf8c..0ae2188d98 100644 --- a/pokemongo_bot/__init__.py +++ b/pokemongo_bot/__init__.py @@ -21,6 +21,7 @@ from metrics import Metrics from spiral_navigator import SpiralNavigator from worker_result import WorkerResult +from api_wrapper import ApiWrapper class PokemonGoBot(object): @@ -205,9 +206,7 @@ def check_session(self, position): def login(self): logger.log('Attempting login to Pokemon Go.', 'white') - self.api._auth_token = None - self.api._auth_provider = None - self.api._api_endpoint = None + self.api.reset_auth() lat, lng = self.position[0:2] self.api.set_position(lat, lng, 0) @@ -223,7 +222,7 @@ def login(self): def _setup_api(self): # instantiate pgoapi - self.api = PGoApi() + self.api = ApiWrapper(PGoApi()) # provide player position on the earth self._set_starting_position() diff --git a/pokemongo_bot/api_wrapper.py b/pokemongo_bot/api_wrapper.py new file mode 100644 index 0000000000..630e76d9a2 --- /dev/null +++ b/pokemongo_bot/api_wrapper.py @@ -0,0 +1,55 @@ +# api_wrapper.py + +from pgoapi import PGoApi +from pgoapi.exceptions import NotLoggedInException +from human_behaviour import sleep +import logger + +class ApiWrapper(object): + def __init__(self, api): + self._api = api + self.reset_auth() + + def reset_auth(self): + self._api._auth_token = None + self._api._auth_provider = None + self._api._api_endpoint = None + + # wrap api methods + def _can_call(self): + if not self._api._req_method_list or len(self._api._req_method_list) == 0: + raise RuntimeError('Trying to call the api without setting any request') + if self._api._auth_provider is None or not self._api._auth_provider.is_login(): + logger.log('Not logged in!', 'red') + raise NotLoggedInException() + return True + + def call(self, max_retry=5): + if not self._can_call(): + return False + + api_req_method_list = self._api._req_method_list + result = None + try_cnt = 0 + while True: + self._api._req_method_list = [req_method for req_method in api_req_method_list] # api internally clear this field after a call + result = self._api.call() + if result is None: + try_cnt += 1 + logger.log('Server seems to be busy or offline - try again - {}/{}'.format(try_cnt, max_retry), 'red') + if try_cnt >= max_retry: + raise ServerBusyOrOfflineException() + sleep(1) + else: + break + return result + + def login(self, provider, username, password): + return self._api.login(provider, username, password) + + # fallback + def __getattr__(self, func): + return getattr(self._api, func) + + +