Merge pull request #5 from TheOnlyWayUp/redesign

Update UI
This commit is contained in:
Dhanush R
2024-06-25 23:53:47 +05:30
committed by GitHub
6 changed files with 181 additions and 130 deletions
+3
View File
@@ -9,6 +9,8 @@ asttokens==2.4.1
async-timeout==4.0.3 async-timeout==4.0.3
attrs==23.1.0 attrs==23.1.0
backoff==2.2.1 backoff==2.2.1
beautifulsoup4==4.12.3
bs4==0.0.2
click==8.1.7 click==8.1.7
comm==0.2.0 comm==0.2.0
debugpy==1.8.0 debugpy==1.8.0
@@ -48,6 +50,7 @@ pyzmq==25.1.2
rich==13.7.0 rich==13.7.0
six==1.16.0 six==1.16.0
sniffio==1.3.0 sniffio==1.3.0
soupsieve==2.5
stack-data==0.6.3 stack-data==0.6.3
starlette==0.32.0.post1 starlette==0.32.0.post1
tornado==6.4 tornado==6.4
+22 -2
View File
@@ -6,6 +6,7 @@ import backoff
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 from aiohttp_client_cache import FileBackend
from bs4 import BeautifulSoup
headers = { headers = {
@@ -116,19 +117,38 @@ async def set_cover(book, data):
book.set_cover("cover.jpg", await fetch_cover(data["cover"])) book.set_cover("cover.jpg", await fetch_cover(data["cover"]))
async def add_chapters(book, data): async def add_chapters(book, data, download_images: bool = False):
chapters = [] chapters = []
for part in data["parts"]: for part in data["parts"]:
content = await fetch_part_content(part["id"]) content = await fetch_part_content(part["id"])
title = part["title"] title = part["title"]
clean_title = slugify(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
chapter = epub.EpubHtml( chapter = epub.EpubHtml(
title=title, title=title,
file_name=f"{slugify(title)}.xhtml", file_name=f"{clean_title}.xhtml",
lang=data["language"]["name"], lang=data["language"]["name"],
) )
if download_images:
soup = BeautifulSoup(content, "lxml")
async with CachedSession(cache=cache, headers=headers) as session:
for idx, image in enumerate(soup.find_all("img")):
if not image["src"]:
continue
async with session.get(image["src"]) as response:
img = epub.EpubImage(
media_type="image/jpeg",
content=await response.read(),
file_name=f"static/{clean_title}/{idx}.jpeg",
)
book.add_item(img)
content = content.replace(
str(image), f'<img src="static/{clean_title}/{idx}.jpeg"/>'
)
chapter.set_content(f"<h1>{title}</h1>" + content) chapter.set_content(f"<h1>{title}</h1>" + content)
chapters.append(chapter) chapters.append(chapter)
+19 -7
View File
@@ -1,6 +1,6 @@
from pathlib import Path from pathlib import Path
from fastapi import FastAPI from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse, StreamingResponse from fastapi.responses import FileResponse, HTMLResponse, StreamingResponse
from ebooklib import epub from ebooklib import epub
from create_book import retrieve_story, set_cover, set_metadata, add_chapters, slugify from create_book import retrieve_story, set_cover, set_metadata, add_chapters, slugify
import tempfile import tempfile
@@ -17,17 +17,29 @@ def home():
@app.get("/download/{story_id}") @app.get("/download/{story_id}")
async def download_book(story_id: int): async def download_book(story_id: int, download_images: bool = False):
data = await retrieve_story(story_id) data = await retrieve_story(story_id)
book = epub.EpubBook() book = epub.EpubBook()
# Metadata and Cover are updated # Metadata and Cover are updated
set_metadata(book, data) try:
set_metadata(book, data)
except KeyError:
# raise HTTPException(
# status_code=404,
# detail='Story not found. Check the ID - Support is available on the <a href="https://discord.gg/P9RHC4KCwd" target="_blank">Discord</a>',
# )
# return FileResponse(BUILD_PATH / "index.html", status_code=404)
return HTMLResponse(
status_code=404,
content='Story not found. Check the ID - Support is available on the <a href="https://discord.gg/P9RHC4KCwd" target="_blank">Discord</a>',
)
await set_cover(book, data) await set_cover(book, data)
# print("Metadata Downloaded") # print("Metadata Downloaded")
# Chapters are downloaded # Chapters are downloaded
async for title in add_chapters(book, data): async for title in add_chapters(book, data, download_images=download_images):
# print(f"Part ({title}) downloaded") # print(f"Part ({title}) downloaded")
... ...
@@ -46,7 +58,7 @@ async def download_book(story_id: int):
BytesIO(book_data), BytesIO(book_data),
media_type="application/epub+zip", media_type="application/epub+zip",
headers={ headers={
"Content-Disposition": f'attachment; filename="{slugify(data["title"])}_{story_id}.epub"' # Thanks https://stackoverflow.com/a/72729058 "Content-Disposition": f'attachment; filename="{slugify(data["title"])}_{story_id}_{"images" if download_images else ""}.epub"' # Thanks https://stackoverflow.com/a/72729058
}, },
) )
@@ -57,4 +69,4 @@ app.mount("/", StaticFiles(directory=BUILD_PATH), "static")
if __name__ == "__main__": if __name__ == "__main__":
import uvicorn import uvicorn
uvicorn.run(app, host="0.0.0.0", port=80) uvicorn.run(app, host="0.0.0.0", port=1112)
File diff suppressed because one or more lines are too long
+93 -120
View File
@@ -1,57 +1,105 @@
<script> <script>
let story_id = ""; let story_id = "";
let download_images = false;
let after_download_page = true;
</script> </script>
<div> <div>
<div class="hero min-h-screen bg-base-200"> <div class="hero min-h-screen">
<div class="hero-content flex-col lg:flex-row-reverse"> <div
<div class="text-center lg:text-left lg:p-10"> class="hero-content flex-col lg:flex-row-reverse glass p-16 rounded shadow-sm"
<h1 >
class="font-extrabold text-transparent text-5xl bg-clip-text bg-gradient-to-r to-pink-600 via-yellow-600 from-red-700" {#if !after_download_page}
> <div class="text-center lg:text-left lg:p-10">
Wattpad Downloader <h1
</h1> class="font-extrabold text-transparent text-5xl bg-clip-text bg-gradient-to-r to-pink-600 via-yellow-600 from-red-700"
<p class="py-6"> >
Download your favourite books as EPUBs with a single click! Wattpad Downloader
</p> </h1>
</div> <p class="pt-6 text-lg">
<div class="card shrink-0 w-full max-w-sm shadow-2xl bg-base-100"> Download your favourite books with a single click!
<form class="card-body"> </p>
<div class="form-control"> <ul class="pt-4 list list-inside text-xl">
<input <li>06/24 - 🎉 Image Downloading!</li>
type="number" </ul>
placeholder="Story ID" </div>
class="input input-bordered" <div class="card shrink-0 w-full max-w-sm shadow-2xl bg-base-100">
bind:value={story_id} <form class="card-body">
required <div class="form-control">
name="story_id" <input
/> type="number"
<label class="label" for="story_id"> placeholder="Story ID"
<button class="input input-bordered"
class="label-text link" bind:value={story_id}
onclick="StoryIDTutorialModal.showModal()" required
data-umami-event="StoryIDTutorialModal Open" name="story_id"
>How to get a Story ID</button />
<label class="label" for="story_id">
<button
class="label-text link"
onclick="StoryIDTutorialModal.showModal()"
data-umami-event="StoryIDTutorialModal Open"
>How to get a Story ID</button
>
</label>
</div>
<div class="form-control mt-6">
<a
class="btn btn-primary rounded-l-none"
class:btn-disabled={!story_id}
data-umami-event="Download"
href={`/download/${story_id}${download_images ? "?download_images=true" : ""}`}
on:click={() => (after_download_page = true)}>Download</a
> >
</label> <label class="cursor-pointer label">
</div> <span class="label-text"
>Include Images (<strong>Slower Download</strong>)</span
>
<input
type="checkbox"
class="checkbox checkbox-warning shadow-md"
bind:checked={download_images}
/>
</label>
</div>
</form>
<div class="form-control mt-6"> <button
<a data-feedback-fish
class="btn btn-primary rounded-l-none" class="link pb-4"
class:btn-disabled={!story_id} data-umami-event="Feedback">Feedback</button
href={`/download/${story_id}`} >
data-umami-event="Download" </div>
download {:else}
onclick="AfterDownloadModal.showModal()">Download</a <div class="text-center max-w-4xl">
<h1 class="font-bold text-3xl">
Your download has <span
class="text-transparent bg-clip-text bg-gradient-to-r to-pink-600 via-yellow-600 from-red-700"
>Started</span
> >
</h1>
<div class="py-4 space-y-2">
<p class="text-2xl">
If you found this site useful, please consider <a
href="https://github.com/TheOnlyWayUp/WattpadDownloader"
target="_blank"
class="link"
data-umami-event="Star">starring the project</a
> to support WattpadDownloader.
</p>
<p class="text-lg pt-2">
You can also join us on <a
href="https://discord.gg/P9RHC4KCwd"
target="_blank"
class="link"
data-umami-event="Discord">discord</a
>, where we release features early and discuss updates.
</p>
</div> </div>
</form> <a href="/" class="btn btn-outline btn-lg mt-10">Download More</a>
</div>
<button data-feedback-fish class="link pb-2" data-umami-event="Feedback" {/if}
>Feedback</button
>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -90,78 +138,3 @@
<button>close</button> <button>close</button>
</form> </form>
</dialog> </dialog>
<dialog id="AfterDownloadModal" class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">Your download has started</h3>
<div class="py-4 space-y-2">
<p class="text-xl">
Hi, thanks for using my site! If you found it useful, please consider <a
href="https://liberapay.com/TheOnlyWayUp/"
target="_blank"
class="link"
data-umami-event="Donate">donating</a
> to keep this project alive.
</p>
<p>
You can also join us on <a
href="https://discord.gg/P9RHC4KCwd"
target="_blank"
class="link"
data-umami-event="Discord">discord</a
>, where we discuss updates and features.
</p>
<p class="text-lg">
Please take a look at <a
href="https://rambhat.la"
class="link"
data-umami-event="My Work">my work</a
>!
</p>
</div>
<div class="pt-2">
<form method="dialog">
<!-- if there is a button in form, it will close the modal -->
<button
class="btn w-full btn-sm btn-ghost"
data-umami-event="AfterDownloadModal Close">Close</button
>
</form>
</div>
</div>
</dialog>
<footer
class="footer footer-center p-4 bg-base-300 text-base-content bottom-0 fixed"
>
<aside>
<div class="grid grid-cols-3 max-w-lg w-full">
<a
href="https://liberapay.com/TheOnlyWayUp/"
target="_blank"
class="link"
data-umami-event="Footer Donate">Donate</a
>
<a
href="https://rambhat.la"
target="_blank"
class="link"
data-umami-event="Footer AboutMe">About Me</a
>
<a
href="https://discord.gg/P9RHC4KCwd"
target="_blank"
class="link"
data-umami-event="Footer Discord">Discord</a
>
</div>
<p>
Copyright © 2024 - All rights reserved by <a
href="https://rambhat.la"
class="link"
target="_blank"
data-umami-event="CopyrightHolder">Dhanush R</a
>
</p>
</aside>
</footer>