class PGoApi: API_ENTRY = 'https://pgorelease.nianticlabs.com/plfe/rpc' def __init__(self): self.log = logging.getLogger(__name__) self._auth_provider = None self._api_endpoint = None self._position_lat = 0 self._position_lng = 0 self._position_alt = 0 self._req_method_list = [] def call(self): if not self._req_method_list: return False if self._auth_provider is None or not self._auth_provider.is_login(): self.log.info('Not logged in') return False player_position = self.get_position() request = RpcApi(self._auth_provider) if self._api_endpoint: api_endpoint = self._api_endpoint else: api_endpoint = self.API_ENTRY self.log.info('Execution of RPC') response = None try: response = request.request(api_endpoint, self._req_method_list, player_position) except ServerBusyOrOfflineException as e: self.log.info('Server seems to be busy or offline - try again!') # cleanup after call execution self.log.info('Cleanup of request!') self._req_method_list = [] return response def list_curr_methods(self): for i in self._req_method_list: print("{} ({})".format(RequestType.Name(i),i)) def set_logger(self, logger): self._ = logger or logging.getLogger(__name__) def get_position(self): return (self._position_lat, self._position_lng, self._position_alt) def set_position(self, lat, lng, alt): self.log.debug('Set Position - Lat: %s Long: %s Alt: %s', lat, lng, alt) self._position_lat = lat self._position_lng = lng self._position_alt = alt def __getattr__(self, func): def function(**kwargs): if not self._req_method_list: self.log.info('Create new request...') name = func.upper() if kwargs: self._req_method_list.append( { RequestType.Value(name): kwargs } ) self.log.info("Adding '%s' to RPC request including arguments", name) self.log.debug("Arguments of '%s': \n\r%s", name, kwargs) else: self._req_method_list.append( RequestType.Value(name) ) self.log.info("Adding '%s' to RPC request", name) return self if func.upper() in RequestType.keys(): return function else: raise AttributeError def login(self, provider, username, password, auth_token=None): if not isinstance(username, six.string_types) or not isinstance(password, six.string_types): raise AuthException("Username/password not correctly specified") if provider == 'ptc': self._auth_provider = AuthPtc() elif provider == 'google': self._auth_provider = AuthGoogle() else: raise AuthException("Invalid authentication provider - only ptc/google available.") self.log.debug('Auth provider: %s', provider) if auth_token is None: if not self._auth_provider.login(username, password): self.log.info('Login process failed') return False with open("token.txt", "w") as f: f.write(self._auth_provider.get_token()) self.log.info('Token saved') else: self.log.info('Reuse token') self._auth_provider._login = True self._auth_provider.set_token(auth_token) self.log.info('Starting RPC login sequence (app simulation)') # making a standard call, like it is also done by the client self.get_player() self.get_hatched_eggs() self.get_inventory() self.check_awarded_badges() self.download_settings(hash="05daf51635c82611d1aac95c0b051d3ec088a930") response = self.call() if not response: self.log.info('Login failed!') return False if 'api_url' in response: self._api_endpoint = ('https://{}/rpc'.format(response['api_url'])) self.log.debug('Setting API endpoint to: %s', self._api_endpoint) else: self.log.error('Login failed - unexpected server response!') return False if 'auth_ticket' in response: self._auth_provider.set_ticket(response['auth_ticket'].values()) self.log.info('Finished RPC login sequence (app simulation)') self.log.info('Login process completed') return True
class PGoApi: def __init__(self): self.set_logger() self._auth_provider = None self._api_endpoint = 'https://pgorelease.nianticlabs.com/plfe/rpc' self._position_lat = None self._position_lng = None self._position_alt = None self.log.info('%s v%s - %s', __title__, __version__, __copyright__ ) def set_logger(self, logger = None): self.log = logger or logging.getLogger(__name__) def get_api_endpoint(self): return self._api_endpoint def get_position(self): return (self._position_lat, self._position_lng, self._position_alt) def set_position(self, lat, lng, alt): self.log.debug('Set Position - Lat: %s Long: %s Alt: %s', lat, lng, alt) self._position_lat = lat self._position_lng = lng self._position_alt = alt def create_request(self): request = PGoApiRequest(self._api_endpoint, self._auth_provider, self._position_lat, self._position_lng, self._position_alt) return request def __getattr__(self, func): def function(**kwargs): request = self.create_request() getattr(request, func)( _call_direct = True, **kwargs ) return request.call() if func.upper() in RequestType.keys(): return function else: raise AttributeError def login(self, provider, username, password, lat = None, lng = None, alt = None, app_simulation = True, token = None): if lat and lng and alt: self._position_lat = lat self._position_lng = lng self._position_alt = alt if not isinstance(username, six.string_types) or not isinstance(password, six.string_types): raise AuthException("Username/password not correctly specified") if provider == 'ptc': self._auth_provider = AuthPtc() elif provider == 'google': self._auth_provider = AuthGoogle() else: raise AuthException("Invalid authentication provider - only ptc/google available.") self.log.debug('Auth provider: %s', provider) if token == None: if not self._auth_provider.login(username, password): self.log.info('Login process failed') return False else: self._auth_provider._login = True self._auth_provider.set_token(token) if app_simulation: self.log.info('Starting RPC login sequence (app simulation)') # making a standard call, like it is also done by the client request = self.create_request() request.get_player() request.get_hatched_eggs() request.get_inventory() request.check_awarded_badges() request.download_settings(hash="05daf51635c82611d1aac95c0b051d3ec088a930") response = request.call() else: self.log.info('Starting minimal RPC login sequence') response = self.get_player() if not response: self.log.info('Login failed!') return False if 'api_url' in response: self._api_endpoint = ('https://{}/rpc'.format(response['api_url'])) self.log.debug('Setting API endpoint to: %s', self._api_endpoint) else: self.log.error('Login failed - unexpected server response!') return False if app_simulation: self.log.info('Finished RPC login sequence (app simulation)') else: self.log.info('Finished minimal RPC login sequence') self.log.info('Login process completed') return True