Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -33,7 +33,6 @@ def normalize(v, default=""):
|
|
| 33 |
return str(v).strip()
|
| 34 |
|
| 35 |
def safe_text(text):
|
| 36 |
-
# Hanya izinkan ASCII 32β126 (FPDF tidak support Unicode)
|
| 37 |
return ''.join(c if 32 <= ord(c) <= 126 else ' ' for c in text)
|
| 38 |
|
| 39 |
def now_iso():
|
|
@@ -104,6 +103,7 @@ def build_ebook_pdf_with_images(username, goal, genre, tone, style, length,
|
|
| 104 |
|
| 105 |
ensure_outputs_dir()
|
| 106 |
pdf = EbookPDF(format="A4")
|
|
|
|
| 107 |
|
| 108 |
# COVER IMAGE
|
| 109 |
cover_prompt = f"{cover_brief} | {goal} | {genre} | {style} | pastel, kid-friendly, Islamic"
|
|
@@ -111,8 +111,6 @@ def build_ebook_pdf_with_images(username, goal, genre, tone, style, length,
|
|
| 111 |
cover_path = download_image(cover_url, f"cover_{uuid.uuid4().hex}.png")
|
| 112 |
|
| 113 |
pdf.add_page()
|
| 114 |
-
|
| 115 |
-
# MATIKAN AUTO PAGE BREAK SAAT COVER
|
| 116 |
pdf.set_auto_page_break(False)
|
| 117 |
|
| 118 |
if cover_path:
|
|
@@ -123,19 +121,16 @@ def build_ebook_pdf_with_images(username, goal, genre, tone, style, length,
|
|
| 123 |
pdf.rect(0, 0, 210, 297, "F")
|
| 124 |
pdf.set_y(50)
|
| 125 |
|
| 126 |
-
# AKTIFKAN KEMBALI AUTO PAGE BREAK
|
| 127 |
pdf.set_auto_page_break(True, margin=15)
|
| 128 |
-
|
| 129 |
-
# PAKSA Y AMAN
|
| 130 |
pdf.set_y(max(pdf.get_y(), 50))
|
| 131 |
|
| 132 |
# COVER TEXT
|
| 133 |
pdf.set_font("Helvetica", "B", 20)
|
| 134 |
-
pdf.multi_cell(
|
| 135 |
|
| 136 |
pdf.set_font("Helvetica", "", 12)
|
| 137 |
-
pdf.multi_cell(
|
| 138 |
-
pdf.multi_cell(
|
| 139 |
|
| 140 |
# TABLE OF CONTENTS
|
| 141 |
pdf.add_page()
|
|
@@ -164,7 +159,6 @@ def build_ebook_pdf_with_images(username, goal, genre, tone, style, length,
|
|
| 164 |
pdf.cell(0, 10, safe_text(ch), 0, 1)
|
| 165 |
pdf.ln(4)
|
| 166 |
|
| 167 |
-
# ILLUSTRATION
|
| 168 |
illus_prompt = (
|
| 169 |
f"Illustration for chapter {idx} of an Islamic children's story about {goal}. "
|
| 170 |
f"Scene: {ch}. Style: {style}, tone {tone}, pastel colors."
|
|
@@ -179,7 +173,7 @@ def build_ebook_pdf_with_images(username, goal, genre, tone, style, length,
|
|
| 179 |
|
| 180 |
pdf.set_font("Helvetica", "", 12)
|
| 181 |
for _ in range(5):
|
| 182 |
-
pdf.multi_cell(
|
| 183 |
pdf.ln(2)
|
| 184 |
|
| 185 |
filename = os.path.join("outputs", f"ebook_{uuid.uuid4().hex}.pdf")
|
|
@@ -242,25 +236,19 @@ with gr.Blocks() as demo:
|
|
| 242 |
login_user = gr.State("")
|
| 243 |
login_tier = gr.State("free")
|
| 244 |
|
| 245 |
-
# LOGIN UI
|
| 246 |
with gr.Group(visible=True) as login_ui:
|
| 247 |
gr.Markdown("# π Login untuk Menggunakan AIPromptLab")
|
| 248 |
-
|
| 249 |
username = gr.Textbox(label="Username")
|
| 250 |
password = gr.Textbox(label="Password", type="password")
|
| 251 |
login_btn = gr.Button("Login")
|
| 252 |
login_msg = gr.Markdown("")
|
| 253 |
|
| 254 |
-
# MAIN UI
|
| 255 |
with gr.Group(visible=False) as main_ui:
|
| 256 |
|
| 257 |
gr.Markdown("# π AIPromptLab β JSON & PDF E-Book Generator (Replicate FREE Models)")
|
| 258 |
|
| 259 |
with gr.Tabs():
|
| 260 |
|
| 261 |
-
# ============================
|
| 262 |
-
# TAB 1: E-BOOK
|
| 263 |
-
# ============================
|
| 264 |
with gr.Tab("E-Book Prompt & PDF"):
|
| 265 |
|
| 266 |
ebook_goal = gr.Textbox(label="Goal / Ide E-book")
|
|
@@ -336,15 +324,11 @@ with gr.Blocks() as demo:
|
|
| 336 |
|
| 337 |
ebook_generate_btn = gr.Button("π Generate E-book JSON")
|
| 338 |
ebook_output = gr.Textbox(label="E-book JSON Output", lines=18)
|
| 339 |
-
ebook_copy_btn = gr.Button("Copy E-book JSON")
|
| 340 |
|
| 341 |
gr.Markdown("### π Generate PDF E-book (A4 + Cover + Ilustrasi Bab)")
|
| 342 |
ebook_pdf_btn = gr.Button("Generate PDF E-book")
|
| 343 |
ebook_pdf_file = gr.File(label="Download E-book PDF")
|
| 344 |
|
| 345 |
-
# ============================
|
| 346 |
-
# LOGIN HANDLER
|
| 347 |
-
# ============================
|
| 348 |
def handle_login(username, password):
|
| 349 |
ok, tier, msg = login(username, password)
|
| 350 |
return (
|
|
@@ -362,9 +346,6 @@ with gr.Blocks() as demo:
|
|
| 362 |
[login_msg, login_ui, main_ui, login_status, login_user, login_tier]
|
| 363 |
)
|
| 364 |
|
| 365 |
-
# ============================
|
| 366 |
-
# E-BOOK GENERATE JSON
|
| 367 |
-
# ============================
|
| 368 |
def handle_ebook_generate(login_status, login_user, login_tier,
|
| 369 |
goal, genre, tone, style, platform, length, chapters):
|
| 370 |
if not login_status:
|
|
@@ -386,9 +367,6 @@ with gr.Blocks() as demo:
|
|
| 386 |
ebook_output
|
| 387 |
)
|
| 388 |
|
| 389 |
-
# ============================
|
| 390 |
-
# E-BOOK GENERATE PDF
|
| 391 |
-
# ============================
|
| 392 |
def handle_ebook_pdf(login_status, login_user,
|
| 393 |
goal, genre, tone, style, length, cover_brief, chapters):
|
| 394 |
if not login_status:
|
|
@@ -417,9 +395,6 @@ with gr.Blocks() as demo:
|
|
| 417 |
ebook_pdf_file
|
| 418 |
)
|
| 419 |
|
| 420 |
-
# ============================
|
| 421 |
-
# LAUNCH APP
|
| 422 |
-
# ============================
|
| 423 |
demo.launch(
|
| 424 |
server_name="0.0.0.0",
|
| 425 |
server_port=7860,
|
|
|
|
| 33 |
return str(v).strip()
|
| 34 |
|
| 35 |
def safe_text(text):
|
|
|
|
| 36 |
return ''.join(c if 32 <= ord(c) <= 126 else ' ' for c in text)
|
| 37 |
|
| 38 |
def now_iso():
|
|
|
|
| 103 |
|
| 104 |
ensure_outputs_dir()
|
| 105 |
pdf = EbookPDF(format="A4")
|
| 106 |
+
pdf.set_margins(15, 15, 15)
|
| 107 |
|
| 108 |
# COVER IMAGE
|
| 109 |
cover_prompt = f"{cover_brief} | {goal} | {genre} | {style} | pastel, kid-friendly, Islamic"
|
|
|
|
| 111 |
cover_path = download_image(cover_url, f"cover_{uuid.uuid4().hex}.png")
|
| 112 |
|
| 113 |
pdf.add_page()
|
|
|
|
|
|
|
| 114 |
pdf.set_auto_page_break(False)
|
| 115 |
|
| 116 |
if cover_path:
|
|
|
|
| 121 |
pdf.rect(0, 0, 210, 297, "F")
|
| 122 |
pdf.set_y(50)
|
| 123 |
|
|
|
|
| 124 |
pdf.set_auto_page_break(True, margin=15)
|
|
|
|
|
|
|
| 125 |
pdf.set_y(max(pdf.get_y(), 50))
|
| 126 |
|
| 127 |
# COVER TEXT
|
| 128 |
pdf.set_font("Helvetica", "B", 20)
|
| 129 |
+
pdf.multi_cell(180, 10, safe_text(goal), 0)
|
| 130 |
|
| 131 |
pdf.set_font("Helvetica", "", 12)
|
| 132 |
+
pdf.multi_cell(180, 7, safe_text(f"Genre: {genre}"), 0)
|
| 133 |
+
pdf.multi_cell(180, 7, safe_text(f"Tone: {tone} | Style: {style}"), 0)
|
| 134 |
|
| 135 |
# TABLE OF CONTENTS
|
| 136 |
pdf.add_page()
|
|
|
|
| 159 |
pdf.cell(0, 10, safe_text(ch), 0, 1)
|
| 160 |
pdf.ln(4)
|
| 161 |
|
|
|
|
| 162 |
illus_prompt = (
|
| 163 |
f"Illustration for chapter {idx} of an Islamic children's story about {goal}. "
|
| 164 |
f"Scene: {ch}. Style: {style}, tone {tone}, pastel colors."
|
|
|
|
| 173 |
|
| 174 |
pdf.set_font("Helvetica", "", 12)
|
| 175 |
for _ in range(5):
|
| 176 |
+
pdf.multi_cell(180, 7, safe_text(body_paragraph), 0)
|
| 177 |
pdf.ln(2)
|
| 178 |
|
| 179 |
filename = os.path.join("outputs", f"ebook_{uuid.uuid4().hex}.pdf")
|
|
|
|
| 236 |
login_user = gr.State("")
|
| 237 |
login_tier = gr.State("free")
|
| 238 |
|
|
|
|
| 239 |
with gr.Group(visible=True) as login_ui:
|
| 240 |
gr.Markdown("# π Login untuk Menggunakan AIPromptLab")
|
|
|
|
| 241 |
username = gr.Textbox(label="Username")
|
| 242 |
password = gr.Textbox(label="Password", type="password")
|
| 243 |
login_btn = gr.Button("Login")
|
| 244 |
login_msg = gr.Markdown("")
|
| 245 |
|
|
|
|
| 246 |
with gr.Group(visible=False) as main_ui:
|
| 247 |
|
| 248 |
gr.Markdown("# π AIPromptLab β JSON & PDF E-Book Generator (Replicate FREE Models)")
|
| 249 |
|
| 250 |
with gr.Tabs():
|
| 251 |
|
|
|
|
|
|
|
|
|
|
| 252 |
with gr.Tab("E-Book Prompt & PDF"):
|
| 253 |
|
| 254 |
ebook_goal = gr.Textbox(label="Goal / Ide E-book")
|
|
|
|
| 324 |
|
| 325 |
ebook_generate_btn = gr.Button("π Generate E-book JSON")
|
| 326 |
ebook_output = gr.Textbox(label="E-book JSON Output", lines=18)
|
|
|
|
| 327 |
|
| 328 |
gr.Markdown("### π Generate PDF E-book (A4 + Cover + Ilustrasi Bab)")
|
| 329 |
ebook_pdf_btn = gr.Button("Generate PDF E-book")
|
| 330 |
ebook_pdf_file = gr.File(label="Download E-book PDF")
|
| 331 |
|
|
|
|
|
|
|
|
|
|
| 332 |
def handle_login(username, password):
|
| 333 |
ok, tier, msg = login(username, password)
|
| 334 |
return (
|
|
|
|
| 346 |
[login_msg, login_ui, main_ui, login_status, login_user, login_tier]
|
| 347 |
)
|
| 348 |
|
|
|
|
|
|
|
|
|
|
| 349 |
def handle_ebook_generate(login_status, login_user, login_tier,
|
| 350 |
goal, genre, tone, style, platform, length, chapters):
|
| 351 |
if not login_status:
|
|
|
|
| 367 |
ebook_output
|
| 368 |
)
|
| 369 |
|
|
|
|
|
|
|
|
|
|
| 370 |
def handle_ebook_pdf(login_status, login_user,
|
| 371 |
goal, genre, tone, style, length, cover_brief, chapters):
|
| 372 |
if not login_status:
|
|
|
|
| 395 |
ebook_pdf_file
|
| 396 |
)
|
| 397 |
|
|
|
|
|
|
|
|
|
|
| 398 |
demo.launch(
|
| 399 |
server_name="0.0.0.0",
|
| 400 |
server_port=7860,
|