Spaces:
Runtime error
Runtime error
File size: 4,847 Bytes
62e45ba dbfb58e 62e45ba dbfb58e 62e45ba dbfb58e 62e45ba ee26b24 62e45ba ee26b24 62e45ba ee26b24 62e45ba ee26b24 62e45ba dbfb58e ee26b24 62e45ba dbfb58e 62e45ba dbfb58e 62e45ba ee26b24 62e45ba dbfb58e 62e45ba dbfb58e 62e45ba ee26b24 62e45ba dbfb58e 62e45ba dbfb58e 62e45ba | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | import os
from ebooklib import epub
from fpdf import FPDF
import markdown
class BookBuilder:
def __init__(self, title, author, description="", cover_image=None):
self.title = title
self.author = author
self.description = description
self.cover_image = cover_image
self.chapters = []
# Fetch Business Metadata from Environment
self.business_name = os.environ.get("BUSINESS_NAME", "Fair Dinkum Publishing")
self.abn = os.environ.get("BUSINESS_ABN", "63 590 716 023")
self.owner = os.environ.get("BUSINESS_OWNER", "BRETT SJOBERG")
def add_chapter(self, title, content):
self.chapters.append({"title": title, "content": content})
def generate_epub(self, output_path):
book = epub.EpubBook()
book.set_identifier(f"fdp-{abs(hash(self.title))}")
book.set_title(self.title)
book.set_language("en")
book.add_author(self.author)
book.add_metadata("DC", "publisher", self.business_name)
book.add_metadata("DC", "description", self.description)
book.add_metadata("DC", "rights", f"Copyright (c) 2026 {self.owner}. ABN: {self.abn}")
spine = ["nav"]
# Add Cover Image if provided
if self.cover_image and os.path.exists(self.cover_image):
with open(self.cover_image, 'rb') as img_file:
content = img_file.read()
img_ext = os.path.splitext(self.cover_image)[1][1:]
book.set_cover("cover.jpg", content)
# Add Copyright Page
copy_page = epub.EpubHtml(title="Copyright", file_name="copyright.xhtml", lang="en")
copy_page.content = f"""
<h1>Copyright</h1>
<p><strong>{self.title}</strong></p>
<p>Published by {self.business_name}</p>
<p>Owner: {self.owner}</p>
<p>ABN: {self.abn}</p>
<p>All rights reserved. No part of this publication may be reproduced without permission.</p>
"""
book.add_item(copy_page)
spine.append(copy_page)
for i, ch in enumerate(self.chapters):
chapter = epub.EpubHtml(title=ch["title"], file_name=f"chap_{i+1}.xhtml", lang="en")
# Convert Markdown to HTML
content_html = markdown.markdown(ch["content"])
chapter.content = f"<h1>{ch['title']}</h1>{content_html}"
book.add_item(chapter)
spine.append(chapter)
book.add_item(epub.EpubNav())
book.add_item(epub.EpubNcx())
book.spine = spine
epub.write_epub(output_path, book, {})
return output_path
def generate_pdf(self, output_path):
pdf = FPDF()
pdf.set_auto_page_break(auto=True, margin=15)
# Title Page
pdf.add_page()
if self.cover_image and os.path.exists(self.cover_image):
# Try to fit cover image on first page
pdf.image(self.cover_image, x=10, y=10, w=190)
pdf.add_page()
pdf.set_font("Arial", "B", 24)
pdf.cell(200, 40, self.title, ln=True, align="C")
pdf.set_font("Arial", "I", 16)
pdf.cell(200, 10, f"By {self.author}", ln=True, align="C")
pdf.ln(20)
# Copyright Info
pdf.set_font("Arial", "", 10)
pdf.cell(0, 10, f"Published by {self.business_name}", ln=True, align="C")
pdf.cell(0, 10, f"ABN: {self.abn}", ln=True, align="C")
pdf.ln(20)
# Chapters
for ch in self.chapters:
pdf.add_page()
pdf.set_font("Arial", "B", 18)
pdf.cell(0, 10, ch["title"], ln=True)
pdf.ln(10)
# Use write_html to handle basic markdown-to-html conversion for FPDF
# FPDF2 supports basic HTML tags with write_html
html_content = markdown.markdown(ch["content"])
pdf.set_font("Arial", "", 12)
pdf.write_html(html_content)
# Footer on every page
pdf.set_y(-15)
pdf.set_font("Arial", "I", 8)
pdf.cell(0, 10, f"{self.business_name} - ABN {self.abn} - Page {pdf.page_no()}", align="C")
pdf.output(output_path)
return output_path
def create_ebook_files(title, author, content_list, base_name="ebook", cover_image=None):
"""
Helper to create both formats.
content_list: List of dicts with 'title' and 'content'.
"""
builder = BookBuilder(title, author, cover_image=cover_image)
for item in content_list:
builder.add_chapter(item["title"], item["content"])
os.makedirs("exports", exist_ok=True)
epub_file = builder.generate_epub(f"exports/{base_name}.epub")
pdf_file = builder.generate_pdf(f"exports/{base_name}.pdf")
return epub_file, pdf_file
|