async def update_manifest(self, language): """Download the latest manifest file for the given language if necessary Args: language: The language corresponding to the manifest to update Raises: PydestException """ if language not in self.manifest_files.keys(): raise pydest.PydestException("Unsupported language: {}".format(language)) json = await self.api.get_destiny_manifest() if json['ErrorCode'] != 1: raise pydest.PydestException("Could not retrieve Manifest from Bungie.net") manifest_url = 'https://www.bungie.net' + json['Response']['mobileWorldContentPaths'][language] manifest_file_name = manifest_url.split('/')[-1] if not os.path.isfile(manifest_file_name): # Manifest doesn't exist, or isn't up to date # Download and extract the current manifest # Remove the zip file once finished filename = await self._download_file(manifest_url, MANIFEST_ZIP) if os.path.isfile('./{}'.format(MANIFEST_ZIP)): zip_ref = zipfile.ZipFile('./{}'.format(MANIFEST_ZIP), 'r') zip_ref.extractall('./') zip_ref.close() os.remove(MANIFEST_ZIP) else: raise pydest.PydestException("Could not retrieve Manifest from Bungie.net") self.manifest_files[language] = manifest_file_name
async def decode_hash(self, hash_id, definition, language): """Get the corresponding static info for an item given it's hash value Args: hash_id: The unique identifier of the entity to decode definition: The type of entity to be decoded (ex. 'DestinyClassDefinition') Returns: dict: json corresponding to the given hash_id and definition Raises: PydestException """ if language not in self.manifest_files.keys(): raise pydest.PydestException( "Unsupported language: {}".format(language)) if self.manifest_files.get(language) == '': await self.update_manifest(language) with DBase(self.manifest_files.get(language)) as db: try: res = db.query(hash_id, definition) except sqlite3.OperationalError as e: if e.args[0].startswith('no such table'): raise pydest.PydestException( "Invalid definition: {}".format(definition)) if len(res) > 0: return json.loads(res[0][0]) else: raise pydest.PydestException( "No entry found with id: {}".format(hash_id))
async def _request(self, req_type, url, access_token=None, params=None, data=None): """Make an async HTTP request and attempt to return json (dict)""" headers = {} if access_token: headers.update({'Authorization': f"Bearer {access_token}"}) encoded_url = urllib.parse.quote(url, safe=':/?&=,.') try: async with self.session.request(req_type, encoded_url, headers=headers, params=params, json=data) as r: if r.status == 401: raise pydest.PydestTokenException( "Access token has expired, refresh needed") else: json_res = await r.json() except aiohttp.ClientResponseError: raise pydest.PydestException("Could not connect to Bungie.net") return json_res
async def _get_request(self, url): """Make an async GET request and attempt to return json (dict)""" headers = {'X-API-KEY':'{}'.format(self.api_key)} async with self.session.get(url, headers=headers) as r: try: json = await r.json() except aiohttp.client_exceptions.ClientResponseError as e: raise pydest.PydestException("Could not connect to Bungie.net") return json
async def _get_request(self, url): """Make an async GET request and attempt to return json (dict)""" headers = {'X-API-KEY':'{}'.format(self.api_key)} encoded_url = urllib.parse.quote(url, safe=':/?&=,.') try: async with self.session.get(encoded_url, headers=headers) as r: json_res = await r.json() except aiohttp.client_exceptions.ClientResponseError as e: raise pydest.PydestException("Could not connect to Bungie.net") return json_res
async def refresh_oauth_token(self, refresh_token): data = { 'client_id': self.client_id, 'client_secret': self.client_secret, 'grant_type': 'refresh_token', 'refresh_token': refresh_token } try: async with self.session.post(f'{APP_URL}/oauth/token/', headers=None, data=data) as r: json_res = await r.json() except aiohttp.ClientResponseError: raise pydest.PydestException("Could not connect to Bungie.net") return json_res