import aiohttp from aiohttp import ClientResponse from attrs import define HTTP_HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36", "Content-Language": "en-US", "Cache-Control": "max-age=0", "Accept": "*/*", "Accept-Charset": "utf-8,ISO-8859-1;q=0.7,*;q=0.3", "Accept-Language": "en-US,en;q=0.9,en-US;q=0.8,en;q=0.7", "Connection": 'keep-alive' } @define class DeezerEngine: cookies: dict arl: str = None token: str = None @classmethod async def from_arl(cls, arl: str): cookies = {'arl': arl} data, cookies = await cls(cookies).call_api( 'deezer.getUserData', get_cookies=True ) data = data['results'] token = data['checkForm'] return cls( cookies=cookies, arl=arl, token=token ) async def call_legacy_api( self, request_point: str, params: dict = None ): async with aiohttp.ClientSession(cookies=self.cookies) as session: async with session.get( f"https://api.deezer.com/{request_point}", params=params, headers=HTTP_HEADERS ) as r: return await r.json() @staticmethod async def _iter_exact_chunks(response: ClientResponse, chunk_size: int = 2048): buffer = b"" async for chunk in response.content.iter_any(): buffer += chunk while len(buffer) >= chunk_size: yield buffer[:chunk_size] buffer = buffer[chunk_size:] if buffer: yield buffer async def get_data_iter(self, url: str): async with aiohttp.ClientSession( cookies=self.cookies, headers=HTTP_HEADERS ) as session: r = await session.get( url, allow_redirects=True ) async for chunk in self._iter_exact_chunks(r): yield chunk async def call_api( self, method: str, params: dict = None, get_cookies: bool = False ): async with aiohttp.ClientSession(cookies=self.cookies) as session: async with session.post( f"https://www.deezer.com/ajax/gw-light.php", params={ 'method': method, 'api_version': '1.0', 'input': '3', 'api_token': self.token or 'null', }, headers=HTTP_HEADERS, json=params ) as r: if not get_cookies: return await r.json() else: return await r.json(), r.cookies