class pixivComm: token = "" pixivClient = None def __init__(self, pixivCreds): self.pixivClient = Client() self.pixivClient.login(pixivCreds["user"], pixivCreds["pw"]) self.token = self.pixivClient.refresh_token def searchImage(self, tag): self.pixivClient.authenticate(self.token) searchStr = tag.replace('_', ' ') print(searchStr, tag) results = self.pixivClient.search_illustrations(searchStr) illustrations = results["illustrations"] randIllust = illustrations[randint(0,len(illustrations) - 1)] print(dir(randIllust)) while randIllust.type != enums.ContentType.ILLUSTRATION: randIllust = illustrations[randint(0,len(illustrations) - 1)] self.getImage(randIllust) imageURL = randIllust.image_urls[enums.Size.ORIGINAL] imageURL = glob.glob("./pixiv/" + str(randIllust.id) + "*")[0] return imageURL def getImage(self, illustration): illustration.download(pathlib.Path("./pixiv", size=enums.Size.ORIGINAL), filename = illustration.id) def testFetch(self): self.pixivClient.authenticate(self.token) illus = self.pixivClient.fetch_illustration(82417326) self.getImage(illus)
def login(client: Client, username, password): try: token = open('.token', 'r', encoding='utf-8').read() client.authenticate(token) except Exception: logging.info( "try token login failed, use username and password instead...") client.login(username, password) # save token with open('.token', 'w', encoding='utf-8') as f: f.write(cast(str, client.refresh_token)) logging.info("new token saved to ./.token")
class DowPixiv(): __page_data = "" __files = [] def __init__(self, download_dir, token): self.__download_dir = download_dir self.__token = token self.__client = Client() self.__client.authenticate(self.__token) pathlib.Path(self.__download_dir).mkdir(parents=True, exist_ok=True) self.__download_dir = pathlib.Path(self.__download_dir) def __load_page(self): if self.__page_data == "": self.__page_data = self.__client.fetch_user_bookmarks(self.__client.account.id) else: self.__page_data = self.__client.fetch_user_bookmarks(self.__client.account.id, max_bookmark_id=int (self.__page_data['next'])) self.__files = [] for ill in self.__page_data['illustrations']: tags = ill.user.name tags += " " + ill.user.account for tag in ill.tags: if tag['translated_name'] is not None: tags += " " + str (tag['translated_name']).replace(' ', '_').replace("'", "''") file_name = [] if ill.page_count == 1: ec = str (ill.image_urls[Size.ORIGINAL]).split('/')[-1].split(".")[-1] file_name.append(str (ill.image_urls[Size.ORIGINAL]).split('/')[-1].split("_")[0] + "." + ec) for p in ill.meta_pages: name = str (p[Size.ORIGINAL]).split('/')[-1] file_name.append(name) self.__files.append([ill, file_name, tags]) def __download_request(self, ill): ill.download(directory=self.__download_dir, size=Size.ORIGINAL) def GetFilesLen(self): return len(self.__files) def GetNextPage(self): self.__load_page() return self.__page_data['next'] is not None def DownloadFile(self, file): ill = file[0] print("Download File: %d" % ill.id) self.__download_request(ill) result = True for s in file[1]: dow_dir = pathlib.Path(self.__download_dir) if len (file[1]) > 1: dow_dir = dow_dir.joinpath(str (ill.id)) if not dow_dir.joinpath(s).exists(): result = False break return result def GetFile(self, index): # url, list of names, tags if index > len(self.__files): return None else: return self.__files[index] def GetShortFileName(self, file): return str (file[0].id)
class ThreadPixiv(Thread): def __init__(self, name): Thread.__init__(self, daemon=True) self.name = name self.client = Client(client_id=g.PixivClientID, client_secret=g.PixivClientSecret) self.allranking = [] self.artpath = Path('flask/images/pixiv/') self.start() def run(self): self.pixiv_init() def download_art(self, obj, size, filename): obj.download(directory=self.artpath, size=size, filename=filename) def random_pixiv_art(self): # download and set random pixiv art try: ranking = random.choice(self.allranking) fetchmode = random.random() # ranked or ranked related art 20/80 if fetchmode > 0.2: related_offset = 0 allrelated = [] for _ in range(4): related = self.client.fetch_illustration_related( ranking.id, offset=related_offset).get('illustrations') allrelated = u.sort_pixiv_arts(related, allrelated) related_offset += 30 illustration = random.choice(list(allrelated)) else: illustration = ranking print(f'art id: {illustration.id}') artid = illustration.id g.last_link = f'https://www.pixiv.net/en/artworks/{artid}' g.last_rand_img = f'{artid}.png' art = Path(f'flask/images/pixiv/{artid}.png') if not art.is_file(): self.download_art(illustration, g.pixiv_size, artid) if not art.is_file(): os.rename(f'flask/images/pixiv/{artid}.jpg', f'flask/images/pixiv/{artid}.png') set_image('pixiv/', f'{artid}.png') except BadApiResponse as pixiv_exception: # reconnect if 'Status code: 400' in str(pixiv_exception): self.pixiv_init() self.random_pixiv_art() except Exception as e: if 'RemoteDisconnected' in str(e): self.random_pixiv_art() def save_pixiv_art(self, namesave, owner, artid, folder='user/', setpic=False, save=False, save_msg=False): """ save pixiv art by art id :param save_msg: whether send <image saved> message :param save: whether save image :param setpic: whether set image :param namesave: filename :param owner: twitch username :param artid: pixiv art id :param folder: image save folder inside flask app static folder """ try: print(f'art id: {artid}') namesave = u.while_is_file(folder, namesave, '.png') namesave = u.while_is_file(folder, namesave, '_p0.png') savedart = self.client.fetch_illustration(int(artid)) self.download_art(savedart, g.pixiv_size, namesave) if os.path.isdir('flask/images/pixiv/' + namesave): mypath2 = 'flask/images/pixiv/' + namesave onlyfiles = [ f for f in listdir(mypath2) if isfile(join(mypath2, f)) ] for i in onlyfiles: os.rename(f'flask/images/pixiv/{namesave}/{i}', f'flask/images/{folder}{namesave}{i[8:-4]}.png') if save: db.add_link( f'https://www.pixiv.net/en/artworks/{artid}', f'{namesave}{i[8:-4]}.png') db.add_owner(f'{namesave}{i[8:-4]}.png', owner) if setpic: set_image(folder, f'{namesave}{i[8:-4]}.png') time.sleep(1.5) os.rmdir(f'flask/images/pixiv/{namesave}') if save_msg: u.send_message(f'{owner}, {namesave}.png saved') return art = Path(f'flask/images/pixiv/{namesave}.png') filepath = f'flask/images/pixiv/{namesave}.png' if not art.is_file(): filepath = f'flask/images/pixiv/{namesave}.jpg' os.rename(filepath, f'flask/images/{folder}{namesave}.png') if save: db.add_link(f'https://www.pixiv.net/en/artworks/{artid}', f'{namesave}.png') db.add_owner(f'{namesave}.png', owner) if setpic: set_image(folder, f'{namesave}.png') if save_msg: u.send_message(f'{owner}, {namesave}.png saved') except BadApiResponse as pixiv_exception: # reconnect print(f'badapiresponse - {pixiv_exception}') if 'Status code: 404' in str(pixiv_exception): u.send_message(f'{owner}, {artid} not found') return if 'Status code: 400' in str(pixiv_exception): self.pixiv_init() self.save_pixiv_art(namesave, owner, artid, folder, setpic, save, save_msg) except Exception as e: if 'RemoteDisconnected' in str(e): self.save_pixiv_art(namesave, owner, artid, folder, setpic, save, save_msg) def pixiv_init(self): try: self.allranking *= 0 self.client.authenticate(g.PixivToken) print('pixiv auth √') rank_offset = 30 ranking1 = self.client.fetch_illustrations_ranking( mode=RankingMode.DAY ).get('illustrations') # check 500 arts, filter by tags and ratio self.allranking = u.sort_pixiv_arts(ranking1, self.allranking) for i in range(16): print(f'\rpixiv load={int(i / 16 * 100) + 7}%', end='') ranking = self.client.fetch_illustrations_ranking( mode=RankingMode.DAY, offset=rank_offset).get('illustrations') self.allranking = u.sort_pixiv_arts(ranking, self.allranking) rank_offset += 30 print() except BadApiResponse: time.sleep(30) self.run()