Akhmad123 commited on
Commit
650e153
Β·
verified Β·
1 Parent(s): 5f90c19

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -47
app.py CHANGED
@@ -5,6 +5,16 @@ from datetime import datetime
5
  from fpdf import FPDF
6
  import os
7
  import uuid
 
 
 
 
 
 
 
 
 
 
8
 
9
  # ============================
10
  # USER DATABASE (SIMPLE)
@@ -26,12 +36,60 @@ def normalize(v, default=""):
26
  def now_iso():
27
  return datetime.utcnow().isoformat() + "Z"
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  # ============================
30
  # E-BOOK JSON GENERATOR
31
  # ============================
32
  def generate_ebook_json(username, tier,
33
  goal, genre, tone, style,
34
- platform, length):
35
 
36
  goal = normalize(goal, "Islamic children's story about good manners.")
37
  genre = normalize(genre, "Islamic Children Story")
@@ -39,6 +97,13 @@ def generate_ebook_json(username, tier,
39
  style = normalize(style, "Storybook style")
40
  platform = normalize(platform, "KDP")
41
  length = normalize(length, "Medium (30–50 pages)")
 
 
 
 
 
 
 
42
 
43
  data = {
44
  "type": "ebook",
@@ -51,6 +116,7 @@ def generate_ebook_json(username, tier,
51
  "writing_style": style,
52
  "length": length,
53
  "goal": goal,
 
54
  "prompts": {
55
  "title_prompt": (
56
  f"Generate 10 title ideas for an {genre} ebook about '{goal}'. "
@@ -60,7 +126,7 @@ def generate_ebook_json(username, tier,
60
  "outline_prompt": (
61
  f"Create a detailed chapter outline for an {genre} ebook about '{goal}'. "
62
  f"Tone: {tone}. Style: {style}. Length: {length}. "
63
- "Include chapter titles and 2–3 bullet points per chapter."
64
  ),
65
  "chapter_prompt": (
66
  f"Write Chapter 1 of an {genre} ebook about '{goal}'. "
@@ -157,7 +223,7 @@ def generate_video_json(username, tier,
157
  return json.dumps(data, ensure_ascii=False, indent=2)
158
 
159
  # ============================
160
- # PDF E-BOOK GENERATOR (A4)
161
  # ============================
162
  class EbookPDF(FPDF):
163
  def header(self):
@@ -172,32 +238,34 @@ class EbookPDF(FPDF):
172
  self.set_font("Helvetica", "I", 9)
173
  self.cell(0, 10, f"Page {self.page_no()}", 0, 0, "C")
174
 
175
- def build_ebook_pdf(username, goal, genre, tone, style, length, cover_brief):
 
 
176
  pdf = EbookPDF(format="A4")
177
  pdf.set_auto_page_break(auto=True, margin=15)
178
 
179
- # COVER
180
- pdf.add_page()
181
- pdf.set_fill_color(230, 240, 255)
182
- pdf.rect(0, 0, 210, 297, "F")
183
 
184
- pdf.set_font("Helvetica", "B", 28)
185
- pdf.set_text_color(40, 40, 70)
186
- pdf.ln(60)
187
- pdf.multi_cell(0, 15, "E-Book", 0, "C")
188
- pdf.ln(5)
 
 
 
 
 
 
189
  pdf.set_font("Helvetica", "B", 20)
190
- pdf.multi_cell(0, 12, goal, 0, "C")
191
- pdf.ln(10)
192
  pdf.set_font("Helvetica", "", 12)
193
- pdf.multi_cell(0, 8, f"Genre: {genre}", 0, "C")
194
- pdf.multi_cell(0, 8, f"Tone: {tone} | Style: {style}", 0, "C")
195
- pdf.ln(15)
196
- pdf.set_font("Helvetica", "I", 11)
197
- pdf.multi_cell(0, 7, "Cover illustration idea:", 0, "C")
198
- pdf.ln(3)
199
- pdf.set_font("Helvetica", "", 11)
200
- pdf.multi_cell(0, 7, cover_brief, 0, "C")
201
 
202
  # TABLE OF CONTENTS
203
  pdf.add_page()
@@ -205,36 +273,44 @@ def build_ebook_pdf(username, goal, genre, tone, style, length, cover_brief):
205
  pdf.cell(0, 10, "Daftar Isi", 0, 1)
206
  pdf.ln(5)
207
  pdf.set_font("Helvetica", "", 12)
208
- chapters = [
209
- "Bab 1: Pembukaan",
210
- "Bab 2: Konflik Utama",
211
- "Bab 3: Perjalanan Tokoh",
212
- "Bab 4: Puncak Cerita",
213
- "Bab 5: Penutup & Hikmah"
214
- ]
215
  for i, ch in enumerate(chapters, start=1):
216
  pdf.cell(0, 8, f"{i}. {ch}", 0, 1)
217
 
218
- # CHAPTERS (SIMPLE GENERATED TEXT)
219
  body_paragraph = (
220
  f"Cerita ini mengisahkan tentang {goal.lower()}, disampaikan dengan gaya {style.lower()} "
221
  f"dan nuansa {tone.lower()}. Setiap bagian dirancang agar mudah dipahami anak-anak, "
222
  "mengandung nilai-nilai kebaikan, dan mengajak pembaca untuk merenungkan makna di balik setiap peristiwa."
223
  )
224
 
225
- for ch in chapters:
 
226
  pdf.add_page()
227
  pdf.set_font("Helvetica", "B", 16)
228
  pdf.cell(0, 10, ch, 0, 1)
229
  pdf.ln(4)
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  pdf.set_font("Helvetica", "", 12)
231
- for _ in range(6):
232
- pdf.multi_cell(0, 7, body_paragraph, 0, "J")
233
  pdf.ln(2)
234
 
235
- # SAVE TEMP FILE
236
- os.makedirs("outputs", exist_ok=True)
237
- filename = f"outputs/ebook_{uuid.uuid4().hex}.pdf"
238
  pdf.output(filename)
239
  return filename
240
 
@@ -267,7 +343,7 @@ with gr.Blocks() as demo:
267
  # MAIN UI (hidden first)
268
  with gr.Group(visible=False) as main_ui:
269
 
270
- gr.Markdown("# 🌟 AIPromptLab β€” Multi Output JSON & PDF E-Book Generator")
271
 
272
  with gr.Tabs():
273
 
@@ -334,8 +410,16 @@ with gr.Blocks() as demo:
334
  value="Medium (30–50 pages)"
335
  )
336
 
 
 
 
 
 
 
 
 
337
  ebook_cover_brief = gr.Textbox(
338
- label="Cover Illustration Brief (diambil dari konsep image design)",
339
  value="Cute pastel Islamic illustration of children reading together under warm light, soft colors, friendly style."
340
  )
341
 
@@ -343,7 +427,7 @@ with gr.Blocks() as demo:
343
  ebook_output = gr.Textbox(label="E-book JSON Output", lines=18, elem_id="ebook-json-output")
344
  ebook_copy_btn = gr.Button("Copy E-book JSON")
345
 
346
- gr.Markdown("### πŸ“„ Generate PDF E-book (A4)")
347
  ebook_pdf_btn = gr.Button("Generate PDF E-book")
348
  ebook_pdf_file = gr.File(label="Download E-book PDF")
349
 
@@ -476,21 +560,21 @@ with gr.Blocks() as demo:
476
 
477
  # E-BOOK GENERATE JSON
478
  def handle_ebook_generate(login_status, login_user, login_tier,
479
- goal, genre, tone, style, platform, length):
480
  if not login_status:
481
  return "❌ Anda belum login."
482
- return generate_ebook_json(login_user, login_tier, goal, genre, tone, style, platform, length)
483
 
484
  ebook_generate_btn.click(
485
  handle_ebook_generate,
486
  [login_status, login_user, login_tier,
487
- ebook_goal, ebook_genre, ebook_tone, ebook_style, ebook_platform, ebook_length],
488
  ebook_output
489
  )
490
 
491
  # E-BOOK GENERATE PDF
492
  def handle_ebook_pdf(login_status, login_user,
493
- goal, genre, tone, style, length, cover_brief):
494
  if not login_status:
495
  return None
496
  goal_ = normalize(goal, "Islamic children's story about good manners.")
@@ -499,13 +583,13 @@ with gr.Blocks() as demo:
499
  style_ = normalize(style, "Storybook style")
500
  length_ = normalize(length, "Medium (30–50 pages)")
501
  cover_ = normalize(cover_brief, "Pastel Islamic illustration of children reading together.")
502
- pdf_path = build_ebook_pdf(login_user, goal_, genre_, tone_, style_, length_, cover_)
503
  return pdf_path
504
 
505
  ebook_pdf_btn.click(
506
  handle_ebook_pdf,
507
  [login_status, login_user,
508
- ebook_goal, ebook_genre, ebook_tone, ebook_style, ebook_length, ebook_cover_brief],
509
  ebook_pdf_file
510
  )
511
 
@@ -564,5 +648,5 @@ demo.launch(
564
  server_name="0.0.0.0",
565
  server_port=7860,
566
  theme=gr.themes.Soft(),
567
- share=True
568
  )
 
5
  from fpdf import FPDF
6
  import os
7
  import uuid
8
+ import requests
9
+ import replicate
10
+
11
+ # ============================
12
+ # CONFIG
13
+ # ============================
14
+ REPLICATE_API_TOKEN = "ISI_API_KEY_REPLICATE_KAMU_DI_SINI"
15
+ os.environ["REPLICATE_API_TOKEN"] = REPLICATE_API_TOKEN
16
+
17
+ MAX_CHAPTERS = 10 # batas maksimal bab
18
 
19
  # ============================
20
  # USER DATABASE (SIMPLE)
 
36
  def now_iso():
37
  return datetime.utcnow().isoformat() + "Z"
38
 
39
+ def ensure_outputs_dir():
40
+ os.makedirs("outputs", exist_ok=True)
41
+
42
+ # ============================
43
+ # REPLICATE IMAGE HELPERS
44
+ # ============================
45
+ def generate_image_flux(prompt: str) -> str:
46
+ """
47
+ Generate image URL using Flux Schnell on Replicate (for cover).
48
+ """
49
+ output = replicate.run(
50
+ "black-forest-labs/flux-schnell",
51
+ input={"prompt": prompt}
52
+ )
53
+ # output biasanya list URL
54
+ if isinstance(output, list) and len(output) > 0:
55
+ return output[0]
56
+ return ""
57
+
58
+ def generate_image_sdxl(prompt: str) -> str:
59
+ """
60
+ Generate image URL using SDXL on Replicate (for chapter illustrations).
61
+ """
62
+ output = replicate.run(
63
+ "stability-ai/sdxl",
64
+ input={"prompt": prompt}
65
+ )
66
+ if isinstance(output, list) and len(output) > 0:
67
+ return output[0]
68
+ return ""
69
+
70
+ def download_image(url: str, filename: str) -> str:
71
+ """
72
+ Download image from URL to local file.
73
+ """
74
+ if not url:
75
+ return ""
76
+ ensure_outputs_dir()
77
+ path = os.path.join("outputs", filename)
78
+ try:
79
+ r = requests.get(url, timeout=60)
80
+ r.raise_for_status()
81
+ with open(path, "wb") as f:
82
+ f.write(r.content)
83
+ return path
84
+ except Exception:
85
+ return ""
86
+
87
  # ============================
88
  # E-BOOK JSON GENERATOR
89
  # ============================
90
  def generate_ebook_json(username, tier,
91
  goal, genre, tone, style,
92
+ platform, length, chapters):
93
 
94
  goal = normalize(goal, "Islamic children's story about good manners.")
95
  genre = normalize(genre, "Islamic Children Story")
 
97
  style = normalize(style, "Storybook style")
98
  platform = normalize(platform, "KDP")
99
  length = normalize(length, "Medium (30–50 pages)")
100
+ try:
101
+ chapters = int(chapters)
102
+ except Exception:
103
+ chapters = 5
104
+ chapters = max(1, min(MAX_CHAPTERS, chapters))
105
+
106
+ chapter_titles = [f"Bab {i}: Judul Bab {i}" for i in range(1, chapters + 1)]
107
 
108
  data = {
109
  "type": "ebook",
 
116
  "writing_style": style,
117
  "length": length,
118
  "goal": goal,
119
+ "chapters": chapter_titles,
120
  "prompts": {
121
  "title_prompt": (
122
  f"Generate 10 title ideas for an {genre} ebook about '{goal}'. "
 
126
  "outline_prompt": (
127
  f"Create a detailed chapter outline for an {genre} ebook about '{goal}'. "
128
  f"Tone: {tone}. Style: {style}. Length: {length}. "
129
+ f"Use {chapters} chapters. Include chapter titles and 2–3 bullet points per chapter."
130
  ),
131
  "chapter_prompt": (
132
  f"Write Chapter 1 of an {genre} ebook about '{goal}'. "
 
223
  return json.dumps(data, ensure_ascii=False, indent=2)
224
 
225
  # ============================
226
+ # PDF E-BOOK GENERATOR (A4) + IMAGES
227
  # ============================
228
  class EbookPDF(FPDF):
229
  def header(self):
 
238
  self.set_font("Helvetica", "I", 9)
239
  self.cell(0, 10, f"Page {self.page_no()}", 0, 0, "C")
240
 
241
+ def build_ebook_pdf_with_images(username, goal, genre, tone, style, length,
242
+ cover_brief, chapters_count):
243
+ ensure_outputs_dir()
244
  pdf = EbookPDF(format="A4")
245
  pdf.set_auto_page_break(auto=True, margin=15)
246
 
247
+ # ===== COVER IMAGE VIA FLUX =====
248
+ cover_prompt = f"{cover_brief} | {goal} | {genre} | {style} | pastel, kid-friendly, Islamic"
249
+ cover_url = generate_image_flux(cover_prompt)
250
+ cover_path = download_image(cover_url, f"cover_{uuid.uuid4().hex}.png")
251
 
252
+ # COVER PAGE
253
+ pdf.add_page()
254
+ if cover_path:
255
+ # full width cover
256
+ pdf.image(cover_path, x=0, y=0, w=210)
257
+ pdf.ln(200)
258
+ else:
259
+ pdf.set_fill_color(230, 240, 255)
260
+ pdf.rect(0, 0, 210, 297, "F")
261
+
262
+ pdf.set_y(220)
263
  pdf.set_font("Helvetica", "B", 20)
264
+ pdf.set_text_color(20, 20, 40)
265
+ pdf.multi_cell(0, 10, goal, 0, "L")
266
  pdf.set_font("Helvetica", "", 12)
267
+ pdf.multi_cell(0, 7, f"Genre: {genre}", 0, "L")
268
+ pdf.multi_cell(0, 7, f"Tone: {tone} | Style: {style}", 0, "L")
 
 
 
 
 
 
269
 
270
  # TABLE OF CONTENTS
271
  pdf.add_page()
 
273
  pdf.cell(0, 10, "Daftar Isi", 0, 1)
274
  pdf.ln(5)
275
  pdf.set_font("Helvetica", "", 12)
276
+
277
+ chapters_count = max(1, min(MAX_CHAPTERS, int(chapters_count)))
278
+ chapters = [f"Bab {i}: Peristiwa Penting {i}" for i in range(1, chapters_count + 1)]
 
 
 
 
279
  for i, ch in enumerate(chapters, start=1):
280
  pdf.cell(0, 8, f"{i}. {ch}", 0, 1)
281
 
282
+ # BODY TEXT TEMPLATE
283
  body_paragraph = (
284
  f"Cerita ini mengisahkan tentang {goal.lower()}, disampaikan dengan gaya {style.lower()} "
285
  f"dan nuansa {tone.lower()}. Setiap bagian dirancang agar mudah dipahami anak-anak, "
286
  "mengandung nilai-nilai kebaikan, dan mengajak pembaca untuk merenungkan makna di balik setiap peristiwa."
287
  )
288
 
289
+ # CHAPTERS WITH SDXL IMAGES
290
+ for idx, ch in enumerate(chapters, start=1):
291
  pdf.add_page()
292
  pdf.set_font("Helvetica", "B", 16)
293
  pdf.cell(0, 10, ch, 0, 1)
294
  pdf.ln(4)
295
+
296
+ # generate illustration for this chapter
297
+ illus_prompt = (
298
+ f"Illustration for chapter {idx} of an Islamic children's story about {goal}. "
299
+ f"Scene: {ch}. Style: {style}, tone {tone}, pastel colors, kid-friendly, Islamic."
300
+ )
301
+ illus_url = generate_image_sdxl(illus_prompt)
302
+ illus_path = download_image(illus_url, f"chapter_{idx}_{uuid.uuid4().hex}.png")
303
+
304
+ if illus_path:
305
+ pdf.image(illus_path, x=20, y=pdf.get_y(), w=170)
306
+ pdf.ln(80)
307
+
308
  pdf.set_font("Helvetica", "", 12)
309
+ for _ in range(5):
310
+ pdf.multi_cell(0, 7, body_paragraph, 0, "L")
311
  pdf.ln(2)
312
 
313
+ filename = os.path.join("outputs", f"ebook_{uuid.uuid4().hex}.pdf")
 
 
314
  pdf.output(filename)
315
  return filename
316
 
 
343
  # MAIN UI (hidden first)
344
  with gr.Group(visible=False) as main_ui:
345
 
346
+ gr.Markdown("# 🌟 AIPromptLab β€” JSON & PDF E-Book Generator (Replicate + Flux + SDXL)")
347
 
348
  with gr.Tabs():
349
 
 
410
  value="Medium (30–50 pages)"
411
  )
412
 
413
+ ebook_chapters = gr.Slider(
414
+ label="Jumlah Bab (dengan ilustrasi)",
415
+ minimum=1,
416
+ maximum=MAX_CHAPTERS,
417
+ step=1,
418
+ value=5
419
+ )
420
+
421
  ebook_cover_brief = gr.Textbox(
422
+ label="Cover Illustration Brief",
423
  value="Cute pastel Islamic illustration of children reading together under warm light, soft colors, friendly style."
424
  )
425
 
 
427
  ebook_output = gr.Textbox(label="E-book JSON Output", lines=18, elem_id="ebook-json-output")
428
  ebook_copy_btn = gr.Button("Copy E-book JSON")
429
 
430
+ gr.Markdown("### πŸ“„ Generate PDF E-book (A4 + Cover + Ilustrasi Bab)")
431
  ebook_pdf_btn = gr.Button("Generate PDF E-book")
432
  ebook_pdf_file = gr.File(label="Download E-book PDF")
433
 
 
560
 
561
  # E-BOOK GENERATE JSON
562
  def handle_ebook_generate(login_status, login_user, login_tier,
563
+ goal, genre, tone, style, platform, length, chapters):
564
  if not login_status:
565
  return "❌ Anda belum login."
566
+ return generate_ebook_json(login_user, login_tier, goal, genre, tone, style, platform, length, chapters)
567
 
568
  ebook_generate_btn.click(
569
  handle_ebook_generate,
570
  [login_status, login_user, login_tier,
571
+ ebook_goal, ebook_genre, ebook_tone, ebook_style, ebook_platform, ebook_length, ebook_chapters],
572
  ebook_output
573
  )
574
 
575
  # E-BOOK GENERATE PDF
576
  def handle_ebook_pdf(login_status, login_user,
577
+ goal, genre, tone, style, length, cover_brief, chapters):
578
  if not login_status:
579
  return None
580
  goal_ = normalize(goal, "Islamic children's story about good manners.")
 
583
  style_ = normalize(style, "Storybook style")
584
  length_ = normalize(length, "Medium (30–50 pages)")
585
  cover_ = normalize(cover_brief, "Pastel Islamic illustration of children reading together.")
586
+ pdf_path = build_ebook_pdf_with_images(login_user, goal_, genre_, tone_, style_, length_, cover_, chapters)
587
  return pdf_path
588
 
589
  ebook_pdf_btn.click(
590
  handle_ebook_pdf,
591
  [login_status, login_user,
592
+ ebook_goal, ebook_genre, ebook_tone, ebook_style, ebook_length, ebook_cover_brief, ebook_chapters],
593
  ebook_pdf_file
594
  )
595
 
 
648
  server_name="0.0.0.0",
649
  server_port=7860,
650
  theme=gr.themes.Soft(),
651
+ ssr_mode=True
652
  )