예제 #1
0
async def test1():
    client = PixivClient(env=True).start()
    api = AppPixivAPI(client=client)
    api.login(refresh_token=_TOKEN)
    # await api.login(_USERNAME, _PASSWORD)
    await client.close()
    print("test1 - finished")
예제 #2
0
async def get_by_ranking(mode="day", num=3):
    async with PixivClient(proxy=proxy, timeout=20) as client:
        aapi = AppPixivAPI(client=client, proxy=proxy)
        await aapi.login(refresh_token=pixiv_config.pixiv_token)
        illusts = await aapi.illust_ranking(mode)
        illusts = illusts["illusts"]
        random.shuffle(illusts)
        return illusts[0:num]
예제 #3
0
async def _test_async_illust_detail(num):
    async with PixivClient() as client:
        aapi = AppPixivAPI(client=client)
        papi = PixivAPI(client=client)
        await aapi.login(_USERNAME, _PASSWORD)
        await papi.login(_USERNAME, _PASSWORD)
        tasks = [asyncio.ensure_future(illust_detail(aapi, i)) for i in range(num)]
        await asyncio.wait(tasks)
예제 #4
0
async def _test_async_me_following_works(num):
    async with PixivClient() as client:
        aapi = AppPixivAPI(client=client)
        papi = PixivAPI(client=client)
        await aapi.login(_USERNAME, _PASSWORD)
        await papi.login(_USERNAME, _PASSWORD)
        tasks = [asyncio.ensure_future(me_following_works(papi, i)) for i in range(num)]
        await asyncio.wait(tasks)
예제 #5
0
 def __init__(self, client: NanoClient, pixiv_client: PixivClient()):
     self.name = "Pixiv"
     self.client = client
     self.aapi = AppPixivAPI(client=pixiv_client.start())
     self.day_pool = {}
     self.day_male_pool = {}
     self.day_female_pool = {}
     self.base_url = 'https://www.pixiv.net/en/artworks/'
     asyncio.ensure_future(self.load_pools_async())
예제 #6
0
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # forces reauth() to trigger if any method is called:
        self.last_auth = datetime.datetime.fromtimestamp(0)
        self.username = ""
        self.password = ""

        self.aapi = AppPixivAPI(**kwargs)
        self.papi = PixivAPI(**kwargs)
예제 #7
0
async def _test_async_ranking(num):
    async with PixivClient() as client:
        aapi = AppPixivAPI(client=client)
        papi = PixivAPI(client=client)
        await papi.login(refresh_token=_TOKEN)
        await aapi.login(refresh_token=_TOKEN)
        # await aapi.login(_USERNAME, _PASSWORD)
        # await papi.login(_USERNAME, _PASSWORD)
        tasks = [asyncio.ensure_future(ranking(papi, i)) for i in range(num)]
        await asyncio.wait(tasks)
class PixivParser:
    status = False
    aapi = AppPixivAPI()
    id_regex = r"[1-9]\d*"

    class Config(BaseConfig, config_file="push_config.json"):
        pixiv_refresh_token: str = str()

        @classmethod
        def _check(cls, _attr_name: str, _attr_value: Any) -> Tuple[str, Any]:
            if _attr_name == "pixiv_refresh_token" and _attr_value == "":
                logger.exception(f"非法的 refresh_token。如果您不知道这是什么,请查看文档")
            else:
                return _attr_name, _attr_value

    @classmethod
    def send(self, url: str, classification: str, bot: Bot, target):
        def origin_link_button(_id: int) -> InlineKeyboardMarkup:
            return InlineKeyboardMarkup([[
                InlineKeyboardButton(
                    text="原链接", url=f"https://www.pixiv.net/artworks/{_id}")
            ]])

        illust_id = int(re.search(pattern=self.id_regex, string=url).group(0))

        try:
            illust = Illust(illust_id, self.Config.pixiv_refresh_token)
        except IllustInitError:
            return

        illust.download()

        images = illust.get_downloaded_images()

        if len(images) > 1:
            bot.send_media_group(
                chat_id=target,
                media=[InputMediaPhoto(BytesIO(image)) for image in images])
            bot.send_message(text=str(illust),
                             chat_id=target,
                             reply_markup=origin_link_button(illust_id),
                             disable_web_page_preview=True,
                             parse_mode=ParseMode.HTML)
        else:
            print(str(illust))
            bot.send_photo(photo=BytesIO(images[0]),
                           chat_id=target,
                           caption=str(illust),
                           reply_markup=origin_link_button(illust_id),
                           parse_mode=ParseMode.HTML)

        logger.info(f"Pixiv: 成功推送 {illust.id}")
예제 #9
0
async def get_by_search(keyword, num=3):
    async with PixivClient(proxy=proxy, timeout=20) as client:
        aapi = AppPixivAPI(client=client, proxy=proxy)
        await aapi.login(refresh_token=pixiv_config.pixiv_token)
        illusts = await aapi.search_illust(keyword)
        illusts = illusts["illusts"]
        illusts = sorted(illusts,
                         key=lambda i: i["total_bookmarks"],
                         reverse=True)
        if len(illusts) > num * 3:
            illusts = illusts[0:int(len(illusts) / 2)]
        random.shuffle(illusts)
        return illusts[0:min(num, len(illusts))]
예제 #10
0
async def to_msg(illusts) -> Message:
    msg = Message()
    async with PixivClient(proxy=proxy, timeout=20) as client:
        aapi = AppPixivAPI(client=client, proxy=proxy)
        await aapi.login(refresh_token=pixiv_config.pixiv_token)
        for illust in illusts:
            try:
                url: str = illust["image_urls"]["large"]
                url = url.replace("_webp", "").replace("i.pximg.net",
                                                       "i.pixiv.re")
                async with httpx.AsyncClient() as client:
                    resp = await client.get(url, timeout=20)
                    result = resp.content
                if result:
                    msg.append("{} ({})".format(illust["title"], illust["id"]))
                    msg.append(MessageSegment.image(result))
            except Exception as e:
                logger.warning(f"Error downloading image: {e}")
        return msg
예제 #11
0
파일: test.py 프로젝트: madeyoga/Nano-Bot
async def test_pixivpy_async_app_api():
    client = PixivClient(env=True)
    aapi = AppPixivAPI(client=client.start())

    # conn = aiohttp.TCPConnector(limit_per_host=30)
    # session = aiohttp.ClientSession(
    #     connector=conn,
    #     timeout=aiohttp.ClientTimeout(total=10),
    #     trust_env=True,
    # )
    # client.client = session

    username, password = os.environ['PIXIV_USERNAME'], os.environ['PIXIV_PASS']
    
    # For App Pixiv API
    await aapi.login(username, password)

    res = await aapi.illust_ranking("day")
    illusts = res.get("illusts")
    print(len(illusts), illusts[0])

    await client.close()
예제 #12
0
async def get_by_id(work_id):
    async with PixivClient(proxy=proxy, timeout=20) as client:
        aapi = AppPixivAPI(client=client, proxy=proxy)
        await aapi.login(refresh_token=pixiv_config.pixiv_token)
        illust = await aapi.illust_detail(work_id)
        return illust
def main():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(_main(AppPixivAPI()))
예제 #14
0
class Illust:

    aapi = AppPixivAPI(env=True)

    def __init__(self, illust_id: int, refresh_token:str):
        async def init_appapi() -> bool:
            try:
                await self.aapi.login(refresh_token=refresh_token)
            except:
                return False
            self.aapi.set_accept_language("zh-CN")
            return True

        async def get_info() -> bool:
            try:
                json_result = await self.aapi.illust_detail(self.id)
            except:
                return False

            info = json_result.illust

            self.caption = str()
            if info.caption != "":
                soup = BeautifulSoup(info.caption, "html.parser")
                self.caption = "\n" + soup.get_text()

            self.title = info.title
            self.author = (info.user.name, info.user.id)

            self.tags = [(tag.name, tag.translated_name) for tag in info.tags]

            if info.page_count == 1:
                self.urls = [info.image_urls.large]
                self.original_urls = [info.meta_single_page.original_image_url]
            else:
                self.urls = [
                    page.image_urls.large for page in info.meta_pages]
                self.original_urls = [
                    page.image_urls.original for page in info.meta_pages]

            return True

        loop = asyncio.new_event_loop()
        login_result = loop.run_until_complete(init_appapi())
        loop.close()
        if not login_result:
            logger.exception("Pixiv 登录失败")
            raise LoginError
        logger.info("Pixiv 登录成功")

        self.id: int = illust_id

        self.__images: list = list()

        loop = asyncio.new_event_loop()
        get_info_result = loop.run_until_complete(get_info())
        loop.close()
        if not get_info_result:
            logger.exception("插画信息获取失败")
            raise GetInfoError

    def __str__(self):
        tags_text = str()
        for tag in self.tags:
            tags_text = tags_text + \
                f"<a href=\"https://www.pixiv.net/tags/{tag[0]}/artworks\">{tag[0]}</a>"
            if tag[1]:
                tags_text = tags_text + f" ({tag[1]})"
            tags_text = tags_text+", "

        return f"<b>标题:</b>{self.title}\n<b>作者:</b><a href=\"https://www.pixiv.net/users/{self.author[1]}\">{self.author[0]}</a>\n<b>简介:</b>{self.caption}\n<b>标签:</b>{tags_text}"

    async def __download_single_image(self, url: str, size_hint: str, page_hint: int):
        try:
            content, type = await self.aapi.down(url, "https://app-api.pixiv.net/")
        except:
            logger.exception(f"{self.id} {size_hint} 第 {page_hint} 张下载错误")
            raise DownloadError

        if type is not None and type.find("image") != -1:
            self.__images.append((page_hint, content))
        else:
            logger.exception(f"{self.id} {size_hint} 第 {page_hint} 张下载错误")
            raise DownloadError

        logger.info(f"成功下载 {self.id} {size_hint} 第 {page_hint} 张")

    def __download_images(self, original: bool = False):
        page = 0
        loop = asyncio.new_event_loop()

        if not original:
            urls = self.urls
            size_hint = "large"
        else:
            urls = self.original_urls
            size_hint = "original"

        tasks = list()
        for url in urls:
            tasks.append(self.__download_single_image(url, size_hint, page))
            page = page + 1

        try:
            loop.run_until_complete(asyncio.gather(*tasks, loop=loop))
        except DownloadError:
            pass
        finally:
            loop.close()

        logger.info(f"成功下载 {self.id} 全部 {size_hint} 图片")

    def download(self):
        self.__download_images()

    def download_original(self):
        self.__download_images(True)

    def get_downloaded_images(self):
        if not len(self.__images):
            return None

        self.__images.sort(key=lambda elem: elem[0])

        return [elem[1] for elem in self.__images[:9]]
예제 #15
0
class PixivParser:
    status = False
    aapi = AppPixivAPI()
    id_regex = r"[1-9]\d*"

    class Config(BaseConfig, config_file="push_config.json"):
        pixiv_username: str = str()
        pixiv_password: str = str()
        download_path: Optional[str] = str()

        @classmethod
        def _check(cls, _attr_name: str, _attr_value: Any) -> Tuple[str, Any]:
            if _attr_name == "download_path" and _attr_value == "":
                logger.info(f"未提供下载路径, 使用 {os.path.dirname(__file__)}/PixivDownload")
                try:
                    os.mkdir(f"{os.path.dirname(__file__)}/PixivDownload")
                except FileExistsError:
                    pass
                except BaseException as exc:
                    logger.exception("下载路径不可用")
                    #sys.exit(1)
                    raise exc
                return _attr_name, os.path.dirname(__file__) + "/PixivDownload"
            else:
                return _attr_name, _attr_value

    @classmethod
    @run_async
    def send(self, url: str, classification: str, bot: Bot, target):
        async def init_appapi(aapi: AppPixivAPI):
            try:
                await aapi.login(username=self.Config.pixiv_username, password=self.Config.pixiv_password)
            except:
                logger.exception("Pixiv 登陆失败")
                return False
            logger.info("成功登录 Pixiv")
            aapi.set_accept_language("zh-CN")
            return True

        def origin_link(_id: int):
            return InlineKeyboardMarkup([[InlineKeyboardButton(text="原链接", url=f"https://www.pixiv.net/artworks/{_id}")]])

        def parse_tags_text(tags: list) -> str:
            text = str()
            for tag in tags:
                if tag.translated_name:
                    translated_name = f"({tag.translated_name})"
                else:
                    translated_name = ""
                text = text + \
                    f"<a href=\"https://www.pixiv.net/tags/{tag.name}/artworks\">{tag.name}{translated_name}</a> "
            return text

        async def download_single_pic(url: str, _id: int, size: str, page: int, aapi: AppPixivAPI):
            url_basename = os.path.basename(url)
            extension = os.path.splitext(url_basename)[1]
            name = f"{_id}_p{page}_{size}{extension}"
            try:
                os.mkdir(f"{self.Config.download_path}/{_id}")
            except FileExistsError:
                pass
            await aapi.download(url, path=self.Config.download_path + "/" + str(_id), name=name)
            logger.info(f"成功下载 {name}")

        def download_pic(urls: list, _id: int, size: str, aapi: AppPixivAPI):
            page = 0
            loop = asyncio.new_event_loop()
            tasks = list()
            for url in urls:
                tasks.append(download_single_pic(url, _id, size, page, aapi))
                # download_single_pic(url, _id, size, page, aapi)
                page = page + 1
            loop.run_until_complete(asyncio.gather(*tasks, loop=loop))
            loop.close()
            logger.info(f"成功下载 {_id} 全部图片")

        async def parse_illust_info_msg(illust_id: int, aapi: AppPixivAPI):
            json_result = await aapi.illust_detail(illust_id)
            info = json_result.illust
            caption = str()
            if info.caption != "":
                soup = BeautifulSoup(info.caption, "html.parser")
                caption = "\n" + soup.get_text()
            msg_text = f"<b>标题:</b>{info.title}\n<b>作者:</b><a href=\"https://www.pixiv.net/users/{info.user.id}\">{info.user.name}</a>{caption}\n<b>标签:</b>{parse_tags_text(info.tags)}{classification}"
            logger.info(msg_text)

            if info.page_count == 1:
                illust_urls = [info.image_urls.large]
            else:
                illust_urls = [page.image_urls.large for page in info.meta_pages]
            return illust_urls, illust_id, msg_text

        loop = asyncio.new_event_loop()
        login_result = loop.run_until_complete(init_appapi(self.aapi))
        loop.close()
        if not login_result:
            return

        illust_id = int(re.search(pattern=self.id_regex, string=url).group(0))

        loop = asyncio.new_event_loop()
        illust_urls, illust_id, msg_text = loop.run_until_complete(
            parse_illust_info_msg(illust_id, self.aapi))
        loop.close()
        download_pic(illust_urls, illust_id, "large", self.aapi)
        file_dirs = [self.Config.download_path+f"/{illust_id}/" +
                     filename for filename in os.listdir(self.Config.download_path+f"/{illust_id}")]
        if len(file_dirs) == 1:
            bot.send_photo(chat_id=target,
                           photo=open(file_dirs[0], 'rb'),
                           caption=msg_text,
                           reply_markup=origin_link(illust_id),
                           parse_mode=ParseMode.HTML)
        else:
            tmp_sub_file_group = list()
            tmp_size = 0
            sub_file_groups = list()
            for file_dir in file_dirs:
                if tmp_size + os.path.getsize(file_dir) <= 5242880 and len(tmp_sub_file_group) + 1 <= 10:
                    tmp_sub_file_group.append(InputMediaPhoto(media=open(file_dir, 'rb'),
                                                              caption=msg_text,
                                                              parse_mode=ParseMode.HTML))
                else:
                    sub_file_groups.append(tmp_sub_file_group)
                    tmp_sub_file_group = [InputMediaPhoto(media=open(file_dir, 'rb'),
                                                          caption=msg_text,
                                                          parse_mode=ParseMode.HTML)]
                    tmp_size = os.path.getsize(file_dir)
            sub_file_groups.append(tmp_sub_file_group)
            for sub_file_group in sub_file_groups:
                bot.send_media_group(chat_id=target, media=sub_file_group)
            bot.send_message(chat_id=target,
                          text=msg_text,
                          reply_markup=origin_link(illust_id),
                          disable_web_page_preview=True,
                          parse_mode=ParseMode.HTML)