Compare commits

...

9 Commits

Author SHA1 Message Date
Michael Lehmann
1c111fd637 Remove unused imports 2025-10-06 23:27:40 +02:00
Michael Lehmann
777cff600c Ignore type error. 2025-10-06 23:21:29 +02:00
Michael Lehmann
be6bfb10cd Update 2025-10-06 23:14:56 +02:00
Michael Lehmann
ca76bdd564 Add generate epub function. 2025-10-05 15:58:46 +02:00
Michael Lehmann
52d03aa633 Add types-requests. 2025-10-05 14:45:34 +02:00
Michael Lehmann
2435bd7888 Work in progress. 2025-10-05 14:45:24 +02:00
Michael Lehmann
71e6c5dd48 Add Pip. 2025-10-05 14:43:04 +02:00
Michael Lehmann
827a2ae354 Add intial main.py file 2025-10-05 12:50:53 +02:00
Michael Lehmann
31e2a102bd Add additional Packages 2025-10-05 12:50:41 +02:00
3 changed files with 268 additions and 7 deletions

View File

@@ -1,15 +1,54 @@
# issuu2epub # Issuu to EPUB Converter
Download Documents from Issuu as EPUB Files. Ein Python-Skript zum Konvertieren von Issuu-Dokumenten in EPUB-Dateien,
optimiert für Kindle E-Reader.
## 📋 Übersicht
Dieses Tool lädt Dokumente von Issuu herunter und konvertiert sie in das
EPUB-Format. Das erste Bild wird als Cover verwendet, und alle Bilder werden für
optimale Darstellung auf E-Readern komprimiert.
## ✨ Features
- **Einfache Befehlszeilenschnittstelle** mit Click
- **Automatisches Cover** aus der ersten Seite
- **Kindle-optimierte** Bildkompression
- **Kein Inhaltsverzeichnis** für direkten Zugriff auf den Inhalt
- **Temporäre Verzeichnisse** für saubere Verarbeitung
- **Unterstützt große Dokumente** mit Stream-Download
## 🚀 Verwendung
### Einfache Verwendung
```bash
python issuu2epub.py
```
Das Skript fragt interaktiv nach allen benötigten Informationen:
1. Issuu URL: Die URL des Issuu-Dokuments
2. Document Title: Titel des Dokuments
3. Document Author: Autor des Dokuments
4. EPUB Output Filename: Name der Ausgabedatei (z.B. mein_dokument.epub)
### Direkte Befehlszeilenverwendung
```bash
python issuu2epub.py --url "https://issuu.com/bscyb1898/docs/yb_mag_nr._1_saison_2025_26" --title "YB Mag 2025 01" --author "BSC YB" --output "YB_Mag_2025_01.epub"
```
## Notes ## Notes
- Educational Use Only: These tools are intended for educational purposes. Dieses Tool ist für den persönlichen Gebrauch bestimmt. Stellen Sie sicher, dass
Always respect the terms of service of Issuu and other websites. Sie die Urheberrechte der Dokumente respektieren und nur Inhalte verwenden, für
- Responsibility: The repository author is not responsible for any misuse of die Sie die entsprechenden Rechte besitzen oder die unter einer freien Lizenz
these tools. stehen.
## Credits ## Credits
- AhmedOsamaMath/issuu-downloader - AhmedOsamaMath/issuu-downloader
```
```

View File

@@ -6,7 +6,14 @@
}; };
}; };
packages = []; packages = [
pkgs.python313Packages.click
pkgs.python313Packages.ebooklib
pkgs.python313Packages.requests
pkgs.python313Packages.pip
pkgs.python313Packages.pillow
pkgs.python313Packages.types-requests
];
git-hooks = { git-hooks = {
enable = true; enable = true;

215
issuu2epub.py Normal file
View File

@@ -0,0 +1,215 @@
import io
import re
import secrets
import tempfile
from pathlib import Path
import click
from ebooklib import epub # type: ignore
from PIL import Image
from requests import HTTPError, request
def parse_issuu_url(url: str) -> tuple[str, str]:
"""Get Username and document_id from issuu url.
returns:
username: str
document_id: str
"""
issuu_url_pattern = re.compile(r"https://issuu.com/([^\/]*)/docs/(.*)$")
if mtc := issuu_url_pattern.match(url):
username = mtc.group(1)
document_id = mtc.group(2)
else:
raise ValueError("Issuu URL not Valid!")
return username, document_id
def create_working_dir() -> Path:
"""create a working directory.
returns:
Path() to a temporary directory.
"""
working_dir = tempfile.mkdtemp(prefix="issuu2epub_")
return Path(working_dir)
def get_page_urls(username: str, document_id: str) -> list[str]:
"""get a list of all pages."""
json_url = f"https://reader3.isu.pub/{username}/{document_id}/reader3_4.json"
r = request("GET", json_url, timeout=(5, 5))
if not r.ok:
raise HTTPError("Failed to download document information")
document_data = r.json()
return [
f"https://{page['imageUri']}" for page in document_data["document"]["pages"]
]
def download_pages(page_urls: list[str], working_dir: Path) -> list[Path]:
"""download all page images and return file paths."""
page_paths = []
for url in page_urls:
filename = url.split("/")[-1]
path = Path(working_dir / filename)
page_paths.append(path)
with request("GET", url=url, stream=True, timeout=(10, 10)) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
return page_paths
def convert_image(image_path: Path) -> io.BytesIO:
"""convert image and return bytes array."""
max_image_size = (1000, 1400)
target_quality = 50
with Image.open(image_path.as_posix()) as img:
if img.mode in ("RGBA", "P"):
img = img.convert("RGB")
img.thumbnail(max_image_size, Image.Resampling.LANCZOS)
img_byte_arr = io.BytesIO()
img.save(img_byte_arr, format="JPEG", optimize=True, quality=target_quality)
img_byte_arr = img_byte_arr.getvalue() # type: ignore[assignment]
return img_byte_arr # type: ignore[return-value]
def generate_epub(
pages: list[Path], output_file: Path, title: str, author: str
) -> None:
"""generate epub file."""
book = epub.EpubBook()
book.set_identifier(secrets.token_urlsafe(10))
book.set_title(title=title)
book.set_language("de")
book.add_author(author=author)
chapters = []
# Use first image as Cover
title_page = epub.EpubHtml(title=title, file_name="title_page.xhtml", lang="de")
cover_image = epub.EpubImage()
cover_image.file_name = f"images/cover.jpg"
cover_image.media_type = "image/jpeg"
cover_image.content = convert_image(pages[0])
book.add_item(cover_image)
title_page.content = f"""
<html>
<head>
<title>{title}</title>
<style>
body {{
margin: 0;
padding: 20px;
text-align: center;
}}
img {{
max-width: 100%;
height: auto;
max-height: 90vh;
}}
</style>
</head>
<body>
<img src="{cover_image.file_name}" alt="Cover"/>
</body>
</html>
"""
book.add_item(title_page)
chapters.append(title_page)
# Add Pages.
for i, page in enumerate(pages[1:], start=1):
page_title = f"Page {i}"
image_item = epub.EpubImage()
image_item.file_name = f"images/page_{i:03d}.jpg"
image_item.media_type = "image/jpeg"
image_item.content = convert_image(page)
book.add_item(image_item)
chapter = epub.EpubHtml(
title=page_title, file_name=f"page_{i}.xhtml", lang="de"
)
chapter.content = f"""
<html>
<head>
<title>{page_title}</title>
<style>
body {{
margin: 0;
padding: 20px;
text-align: center;
}}
img {{
max-width: 100%;
height: auto;
max-height: 90vh;
}}
</style>
</head>
<body>
<img src="{image_item.file_name}" alt="Page {i}"/>
</body>
</html>
"""
book.add_item(chapter)
chapters.append(chapter)
book.spine = ["nav"] + chapters
epub.write_epub(output_file, book, {})
print(f"✅ Kindle-optimiertes EPUB erstellt: {output_file}")
@click.command()
@click.option("--url", prompt="Issuu URL", help="Issuu URL to convert to EPUB")
@click.option("--title", prompt="Document Title", help="Document Title")
@click.option("--author", prompt="Document Author", help="Document Author")
@click.option(
"--output",
prompt="EPUB Output Filename",
help="EPUB Output File",
)
def main(url: str, title: str, author: str, output: str) -> None:
"""main function."""
cwd = create_working_dir()
username, document_id = parse_issuu_url(url=url)
urls = get_page_urls(username, document_id)
pages = download_pages(urls, cwd)
generate_epub(
pages=pages,
output_file=Path(output),
title=title,
author=author,
)
if __name__ == "__main__":
main()