feat(api): Download parts as .zip
This commit is contained in:
@@ -17,6 +17,8 @@ from pydantic_settings import BaseSettings
|
|||||||
from aiohttp import ClientResponseError
|
from aiohttp import ClientResponseError
|
||||||
from aiohttp_client_cache.session import CachedSession
|
from aiohttp_client_cache.session import CachedSession
|
||||||
from aiohttp_client_cache import FileBackend, RedisBackend
|
from aiohttp_client_cache import FileBackend, RedisBackend
|
||||||
|
from io import BytesIO
|
||||||
|
from zipfile import ZipFile
|
||||||
|
|
||||||
load_dotenv(override=True)
|
load_dotenv(override=True)
|
||||||
|
|
||||||
@@ -251,6 +253,26 @@ async def fetch_part_content(part_id: int, cookies: Optional[dict] = None) -> st
|
|||||||
return body
|
return body
|
||||||
|
|
||||||
|
|
||||||
|
@backoff.on_exception(backoff.expo, ClientResponseError, max_time=15)
|
||||||
|
async def fetch_story_zip(story_id: int, cookies: Optional[dict] = None) -> BytesIO:
|
||||||
|
"""Return a BytesIO stream of a .zip file containing each part's HTML content."""
|
||||||
|
with start_action(action_type="api_fetch_storyZip", story_id=story_id):
|
||||||
|
async with CachedSession(
|
||||||
|
headers=headers,
|
||||||
|
cookies=cookies,
|
||||||
|
cache=None if cookies else cache,
|
||||||
|
) as session:
|
||||||
|
async with session.get(
|
||||||
|
f"https://www.wattpad.com/apiv2/?m=storytext&group_id={story_id}&output=zip"
|
||||||
|
) as response:
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
bytes_object = await response.read()
|
||||||
|
bytes_stream = BytesIO(bytes_object)
|
||||||
|
|
||||||
|
return bytes_stream
|
||||||
|
|
||||||
|
|
||||||
@backoff.on_exception(backoff.expo, ClientResponseError, max_time=15)
|
@backoff.on_exception(backoff.expo, ClientResponseError, max_time=15)
|
||||||
async def fetch_cover(url: str) -> bytes:
|
async def fetch_cover(url: str) -> bytes:
|
||||||
"""Fetch cover image bytes."""
|
"""Fetch cover image bytes."""
|
||||||
@@ -307,8 +329,11 @@ async def add_chapters(
|
|||||||
):
|
):
|
||||||
chapters = []
|
chapters = []
|
||||||
|
|
||||||
|
story_zip = await fetch_story_zip(data["id"], cookies)
|
||||||
|
archive = ZipFile(story_zip, "r")
|
||||||
|
|
||||||
for cidx, part in enumerate(data["parts"]):
|
for cidx, part in enumerate(data["parts"]):
|
||||||
content = await fetch_part_content(part["id"], cookies=cookies)
|
content = archive.read(str(part["id"])).decode("utf-8")
|
||||||
title = part["title"]
|
title = part["title"]
|
||||||
|
|
||||||
# Thanks https://eu17.proxysite.com/process.php?d=5VyWYcoQl%2BVF0BYOuOavtvjOloFUZz2BJ%2Fepiusk6Nz7PV%2B9i8rs7cFviGftrBNll%2B0a3qO7UiDkTt4qwCa0fDES&b=1
|
# Thanks https://eu17.proxysite.com/process.php?d=5VyWYcoQl%2BVF0BYOuOavtvjOloFUZz2BJ%2Fepiusk6Nz7PV%2B9i8rs7cFviGftrBNll%2B0a3qO7UiDkTt4qwCa0fDES&b=1
|
||||||
|
|||||||
Reference in New Issue
Block a user