async def auth(self, initialize=False): # https://docs.microsoft.com/zh-cn/azure/active-directory/develop/v2-oauth2-auth-code-flow url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token' data = { 'client_id': OD_CLIENT, 'client_secret': OD_SECRET, 'refresh_token': self.refresh_token, 'grant_type': 'refresh_token' } async with Request() as request: async with request.post(url, data=data) as response: response = await response.json() self.access_token = response['access_token'] self.refresh_token = response['refresh_token'] self.expires_at = time.time() + response['expires_in'] credentials = { 'access_token': response['access_token'], 'refresh_token': response['refresh_token'], 'expires_at': self.expires_at } if initialize: await self.collection.insert(OD_DOCUMENT, credentials) logger.info('OneDrive logged in') else: await self.document.update(credentials) logger.info('OneDrive access token updated')
async def getPost(self, post_id: int): url = 'https://' + self.url + '/post/show/' + str(post_id) async with Request() as request: async with request.get(url) as response: try: response.raise_for_status() except ClientResponseError as err: raise NazurinError(err) from None response = await response.text() soup = BeautifulSoup(response, 'html.parser') tag = soup.find(id="post-view").find(recursive=False) if tag.name == 'script': content = str.strip(tag.string) elif tag.name == 'div' and ('status-notice' in tag['class']): raise NazurinError(tag.get_text(strip=True)) else: logger.error(tag) raise NazurinError('Unknown error') info = content[19:-2] try: info = json.loads(info) post = info['posts'][0] tags = info['tags'] except json.decoder.JSONDecodeError as err: logger.error(err) return post, tags
async def download(self, **kwargs): async with Request(**kwargs) as session: tasks = [] for file in self.all_files: if not file.url: continue tasks.append(asyncio.create_task(file.download(session))) await asyncio.gather(*tasks)
async def getDynamic(self, dynamic_id: int): """Get dynamic data from API.""" api = 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id=' + str( dynamic_id) async with Request() as request: async with request.get(api) as response: source = await response.json() card = json.loads(source['data']['card']['card']) return card
async def getPost(self, post_id: str): """Fetch an post.""" api = f"https://www.artstation.com/projects/{post_id}.json" async with Request() as request: async with request.get(api) as response: if not response.status == 200: raise NazurinError('Post not found') post = await response.json() return post
async def getPost(self, post_id: str): """Fetch an post.""" api = f"https://m.weibo.cn/detail/{post_id}" async with Request() as request: async with request.get(api) as response: if not response.status == 200: raise NazurinError('Post not found') html = await response.text() post = self.parseHtml(html) return post
async def getPost(self, post_id: int): """Fetch an post.""" api = 'https://gelbooru.com/index.php?page=dapi&s=post&q=index&json=1&id=' + str( post_id) async with Request() as request: async with request.get(api) as response: response = await response.json() if 'post' not in response.keys(): raise NazurinError('Post not found') post = response['post'][0] return post
async def getTweet(self, status_id: int): """Get a tweet from API.""" # Old: 'https://syndication.twitter.com/tweets.json?ids='+ status_id +'&lang=en' api = 'https://cdn.syndication.twimg.com/tweet?id=' + str( status_id) + '&lang=en' async with Request() as request: async with request.get(api) as response: if response.status == 404: raise NazurinError('Tweet not found or unavailable.') tweet = await response.json() return tweet
async def size(self) -> int: self._size = self._size or await super().size() if self._size: return self._size async with Request( headers={'Referer': 'https://www.pixiv.net/'}) as request: async with request.head(self.url) as response: headers = response.headers if 'Content-Length' in headers.keys(): self._size = int(headers['Content-Length']) logger.info('Got image size: %s', self._size) else: logger.info('Failed to get image size') return self._size
async def _request(self, method, url, headers=None, **kwargs): # make a request with access token _headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' + self.access_token, } if headers: _headers.update(headers) if 'data' not in kwargs: _headers['Content-Type'] = 'application/json' async with Request(headers=_headers) as session: async with session.request(method, url, **kwargs) as response: response.raise_for_status() if 'application/json' in response.headers['Content-Type']: return await response.json() return await response.text()
async def viewUgoira(self, illust) -> Ugoira: """Download ugoira zip file, store animation data and convert ugoira to mp4.""" metadata = await Pixiv.ugoira_metadata(illust.id) frames = metadata.ugoira_metadata url = illust.meta_single_page.original_image_url zip_url = url.replace('/img-original/', '/img-zip-ugoira/') zip_url = zip_url.split('_ugoira0')[0] + '_ugoira1920x1080.zip' filename = str(illust.id) + '_ugoira1920x1080.zip' metafile = File(str(illust.id) + '_ugoira.json') gif_zip = File(filename, zip_url) files = [gif_zip, metafile] async with Request(headers=HEADERS) as session: await gif_zip.download(session) async with aiofiles.open(metafile.path, 'w') as f: await f.write(json.dumps(frames)) video = await self.ugoira2Mp4(gif_zip, frames) caption = self.buildCaption(illust) return Ugoira(video, caption, illust, files)
async def getPost(self, post_id: int): async with Request() as request: async with request.get('https://www.zerochan.net/' + str(post_id)) as response: try: response.raise_for_status() except ClientResponseError as err: raise NazurinError(err) from None # Override post_id if there's a redirection TODO: Check if response.history: post_id = response.url.path[1:] response = await response.text() soup = BeautifulSoup(response, 'html.parser') info = soup.find("script", {"type": "application/ld+json"}).contents info = json.loads(''.join(info).replace('\\\'', '\'')) name = info['name'].split(' #')[0] created_at = int( datetime.strptime(info['datePublished'], '%c').replace(tzinfo=timezone.utc).timestamp()) size = int(info['contentSize'][:-2]) * 1024 tags = dict() for tag in soup.find('ul', id='tags').find_all('li'): tag_name, tag_type = tag.contents tag_name = unquote(tag_name['href'][1:]).replace('+', '_') tag_type = tag_type[1:] tags[tag_name] = tag_type post = { 'id': int(post_id), 'name': name, 'created_at': created_at, 'image_width': info['width'][:-3], 'image_height': info['height'][:-3], 'tags': tags, 'file_ext': info['encodingFormat'], 'file_size': size, 'file_url': info['contentUrl'], 'preview_file_url': info['thumbnail'], 'uploader': info['author'] } return post