Akhmad123 commited on
Commit
6f37e55
Β·
verified Β·
1 Parent(s): ed1266d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -77
app.py CHANGED
@@ -19,6 +19,7 @@ GROQ_API_KEY = "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"
19
  client = Groq(api_key=GROQ_API_KEY)
20
 
21
  MAX_CHAPTERS = 10
 
22
 
23
  # ============================
24
  # USER DB
@@ -47,30 +48,49 @@ def ensure_outputs_dir():
47
  os.makedirs("outputs", exist_ok=True)
48
 
49
  # ============================
50
- # AI TEXT GENERATOR (GROQ LLaMA‑3 70B)
51
  # ============================
52
  def ai_generate(prompt):
53
  try:
54
  response = client.chat.completions.create(
55
  model="llama-3.3-70b-versatile",
56
  messages=[{"role": "user", "content": prompt}],
57
- max_tokens=600
58
  )
59
  return response.choices[0].message.content
60
  except Exception as e:
61
  return f"AI gagal menghasilkan teks. Error: {str(e)}"
62
 
63
- def generate_chapter_text(goal, style, tone, chapter_title):
64
  prompt = f"""
65
- Buatkan 1 bab cerita anak Islami.
 
 
66
  Judul bab: {chapter_title}
67
  Tema utama: {goal}
68
  Gaya: {style}
69
  Tone: {tone}
70
- Panjang: 4 paragraf.
71
- Bahasa Indonesia.
 
 
 
 
 
 
 
 
 
72
  """
73
- return ai_generate(prompt)
 
 
 
 
 
 
 
 
74
 
75
  # ============================
76
  # REPLICATE IMAGE MODELS
@@ -114,14 +134,14 @@ def download_image(url, filename):
114
  return ""
115
 
116
  # ============================
117
- # PDF BUILDER
118
  # ============================
119
  class EbookPDF(FPDF):
120
  def header(self):
121
  if self.page_no() == 1:
122
  return
123
  self.set_font("Helvetica", "I", 9)
124
- self.cell(0, 8, "AIPromptLab E-Book", 0, 1, "R")
125
  self.ln(2)
126
 
127
  def footer(self):
@@ -136,8 +156,11 @@ def build_ebook_pdf_with_images(username, goal, genre, tone, style, length,
136
  pdf = EbookPDF(format="A4")
137
  pdf.set_margins(15, 15, 15)
138
 
139
- # COVER IMAGE
140
- cover_prompt = f"{cover_brief} | {goal} | {genre} | {style} | pastel, kid-friendly, Islamic"
 
 
 
141
  cover_url = generate_image_flux(cover_prompt)
142
  cover_path = download_image(cover_url, f"cover_{uuid.uuid4().hex}.png")
143
 
@@ -160,13 +183,13 @@ def build_ebook_pdf_with_images(username, goal, genre, tone, style, length,
160
  pdf.multi_cell(180, 10, safe_text(goal), 0)
161
 
162
  pdf.set_font("Helvetica", "", 12)
163
- pdf.multi_cell(180, 7, safe_text(f"Genre: {genre}"), 0)
164
  pdf.multi_cell(180, 7, safe_text(f"Tone: {tone} | Style: {style}"), 0)
165
 
166
  # TABLE OF CONTENTS
167
  pdf.add_page()
168
  pdf.set_font("Helvetica", "B", 18)
169
- pdf.cell(0, 10, "Daftar Isi", 0, 1)
170
  pdf.ln(5)
171
 
172
  pdf.set_font("Helvetica", "", 12)
@@ -176,48 +199,56 @@ def build_ebook_pdf_with_images(username, goal, genre, tone, style, length,
176
  for i, ch in enumerate(chapters, start=1):
177
  pdf.cell(0, 8, safe_text(f"{i}. {ch}"), 0, 1)
178
 
179
- # CHAPTERS (AI TEXT)
180
  for idx, ch in enumerate(chapters, start=1):
181
  pdf.add_page()
182
  pdf.set_font("Helvetica", "B", 16)
183
  pdf.cell(0, 10, safe_text(ch), 0, 1)
184
  pdf.ln(4)
185
 
186
- # ILLUSTRATION
187
- illus_prompt = (
188
- f"Illustration for chapter {idx} of an Islamic children's story about {goal}. "
189
- f"Scene: {ch}. Style: {style}, tone {tone}, pastel colors."
190
- )
191
- illus_url = generate_image_sdxl(illus_prompt)
192
- illus_path = download_image(illus_url, f"chapter_{idx}_{uuid.uuid4().hex}.png")
193
-
194
- if illus_path:
195
- y_start = pdf.get_y()
196
- pdf.image(illus_path, x=20, y=y_start, w=170)
197
- pdf.set_y(y_start + 80)
198
-
199
- # AI CHAPTER TEXT (GROQ)
200
- chapter_text = generate_chapter_text(goal, style, tone, ch)
201
-
202
- pdf.set_font("Helvetica", "", 12)
203
- pdf.multi_cell(180, 7, safe_text(chapter_text), 0)
204
- pdf.ln(2)
205
-
206
- filename = os.path.join("outputs", f"ebook_{uuid.uuid4().hex}.pdf")
 
 
 
 
 
 
 
 
207
  pdf.output(filename)
208
  return filename
209
 
210
  # ============================
211
- # E-BOOK JSON GENERATOR
212
  # ============================
213
  def generate_ebook_json(username, tier,
214
  goal, genre, tone, style,
215
  platform, length, chapters):
216
 
217
  goal = normalize(goal, "Islamic children's story about good manners.")
218
- genre = normalize(genre, "Islamic Children Story")
219
  tone = normalize(tone, "Friendly")
220
- style = normalize(style, "Storybook style")
221
  platform = normalize(platform, "KDP")
222
  length = normalize(length, "Medium (30–50 pages)")
223
 
@@ -231,7 +262,7 @@ def generate_ebook_json(username, tier,
231
  chapter_titles = [f"Bab {i}: Judul Bab {i}" for i in range(1, chapters + 1)]
232
 
233
  data = {
234
- "type": "ebook",
235
  "generated_at": now_iso(),
236
  "user": username,
237
  "tier": tier,
@@ -242,6 +273,7 @@ def generate_ebook_json(username, tier,
242
  "length": length,
243
  "goal": goal,
244
  "chapters": chapter_titles,
 
245
  }
246
 
247
  return json.dumps(data, ensure_ascii=False, indent=2)
@@ -272,25 +304,25 @@ with gr.Blocks() as demo:
272
 
273
  with gr.Group(visible=False) as main_ui:
274
 
275
- gr.Markdown("# 🌟 AIPromptLab β€” JSON & PDF E-Book Generator (Groq + Replicate)")
276
 
277
  with gr.Tabs():
278
 
279
- with gr.Tab("E-Book Prompt & PDF"):
280
 
281
- ebook_goal = gr.Textbox(label="Goal / Ide E-book")
282
  ebook_genre = gr.Dropdown(
283
  label="Genre",
284
  choices=[
285
- "Islamic Children Story",
286
- "Parenting",
287
- "Motivation",
288
  "Fantasy",
289
  "Education",
290
  "Adventure",
291
  "Mystery"
292
  ],
293
- value="Islamic Children Story"
294
  )
295
  ebook_tone = gr.Dropdown(
296
  label="Tone",
@@ -299,62 +331,61 @@ with gr.Blocks() as demo:
299
  "Inspirational",
300
  "Educational",
301
  "Storytelling",
302
- "Formal",
303
- "Casual"
304
  ],
305
  value="Friendly"
306
  )
307
  ebook_style = gr.Dropdown(
308
- label="Writing Style",
309
  choices=[
310
- "Storybook style",
311
- "Narrative",
312
- "Descriptive",
313
- "Persuasive",
314
- "Expository",
315
- "Dialog-based"
316
  ],
317
- value="Storybook style"
318
  )
319
  ebook_platform = gr.Dropdown(
320
  label="Target Platform",
321
  choices=[
322
  "KDP",
323
- "Wattpad",
324
- "Google Play Books",
325
- "PDF / E-Learning"
326
  ],
327
- value="KDP"
328
  )
329
  ebook_length = gr.Dropdown(
330
  label="Length",
331
  choices=[
332
- "Short (10–20 pages)",
333
- "Medium (30–50 pages)",
334
- "Long (80–120 pages)"
335
  ],
336
- value="Medium (30–50 pages)"
337
  )
338
 
339
  ebook_chapters = gr.Slider(
340
- label="Jumlah Bab (dengan ilustrasi)",
341
  minimum=1,
342
  maximum=MAX_CHAPTERS,
343
  step=1,
344
- value=5
345
  )
346
 
347
  ebook_cover_brief = gr.Textbox(
348
  label="Cover Illustration Brief",
349
- value="Cute pastel Islamic illustration of children reading together under warm light, soft colors, friendly style."
350
  )
351
 
352
- ebook_generate_btn = gr.Button("πŸš€ Generate E-book JSON")
353
- ebook_output = gr.Textbox(label="E-book JSON Output", lines=18)
354
 
355
- gr.Markdown("### πŸ“„ Generate PDF E-book (A4 + Cover + Ilustrasi Bab)")
356
- ebook_pdf_btn = gr.Button("Generate PDF E-book")
357
- ebook_pdf_file = gr.File(label="Download E-book PDF")
358
 
359
  def handle_login(username, password):
360
  ok, tier, msg = login(username, password)
@@ -399,12 +430,12 @@ with gr.Blocks() as demo:
399
  if not login_status:
400
  return None
401
 
402
- goal_ = normalize(goal, "Islamic children's story about good manners.")
403
- genre_ = normalize(genre, "Islamic Children Story")
404
  tone_ = normalize(tone, "Friendly")
405
- style_ = normalize(style, "Storybook style")
406
- length_ = normalize(length, "Medium (30–50 pages)")
407
- cover_ = normalize(cover_brief, "Pastel Islamic illustration of children reading together.")
408
 
409
  pdf_path = build_ebook_pdf_with_images(
410
  login_user, goal_, genre_, tone_, style_, length_, cover_, chapters
 
19
  client = Groq(api_key=GROQ_API_KEY)
20
 
21
  MAX_CHAPTERS = 10
22
+ PANELS_PER_CHAPTER = 4 # komik: 4 panel per bab
23
 
24
  # ============================
25
  # USER DB
 
48
  os.makedirs("outputs", exist_ok=True)
49
 
50
  # ============================
51
+ # AI TEXT GENERATOR (GROQ – KOMIK PANEL)
52
  # ============================
53
  def ai_generate(prompt):
54
  try:
55
  response = client.chat.completions.create(
56
  model="llama-3.3-70b-versatile",
57
  messages=[{"role": "user", "content": prompt}],
58
+ max_tokens=800
59
  )
60
  return response.choices[0].message.content
61
  except Exception as e:
62
  return f"AI gagal menghasilkan teks. Error: {str(e)}"
63
 
64
+ def generate_comic_panels(goal, style, tone, chapter_title, panels=PANELS_PER_CHAPTER):
65
  prompt = f"""
66
+ Kamu adalah penulis komik anak Islami berbahasa Indonesia.
67
+
68
+ Buatkan {panels} panel komik untuk satu bab cerita.
69
  Judul bab: {chapter_title}
70
  Tema utama: {goal}
71
  Gaya: {style}
72
  Tone: {tone}
73
+ Target: anak-anak SD, Islami, lembut, positif.
74
+
75
+ Format output HARUS seperti ini (tanpa penjelasan tambahan):
76
+
77
+ Panel 1: [deskripsi singkat adegan + dialog/narasi]
78
+ Panel 2: [deskripsi singkat adegan + dialog/narasi]
79
+ Panel 3: ...
80
+ Panel {panels}: ...
81
+
82
+ Jangan pakai bullet, jangan pakai tanda bintang, jangan pakai heading.
83
+ Hanya baris-baris Panel X: ...
84
  """
85
+ raw = ai_generate(prompt)
86
+ lines = [l.strip() for l in raw.split("\n") if l.strip()]
87
+ panels_text = []
88
+ for l in lines:
89
+ if l.lower().startswith("panel"):
90
+ panels_text.append(l)
91
+ if not panels_text:
92
+ panels_text = [f"Panel {i+1}: {raw}" for i in range(panels)]
93
+ return panels_text[:panels]
94
 
95
  # ============================
96
  # REPLICATE IMAGE MODELS
 
134
  return ""
135
 
136
  # ============================
137
+ # PDF BUILDER (KOMIK)
138
  # ============================
139
  class EbookPDF(FPDF):
140
  def header(self):
141
  if self.page_no() == 1:
142
  return
143
  self.set_font("Helvetica", "I", 9)
144
+ self.cell(0, 8, "AIPromptLab Comic", 0, 1, "R")
145
  self.ln(2)
146
 
147
  def footer(self):
 
156
  pdf = EbookPDF(format="A4")
157
  pdf.set_margins(15, 15, 15)
158
 
159
+ # COVER IMAGE (lebih realistik tapi tetap ramah anak)
160
+ cover_prompt = (
161
+ f"{cover_brief} | {goal} | {genre} | {style} | "
162
+ "realistic comic cover, soft lighting, kid-friendly, Islamic, high detail"
163
+ )
164
  cover_url = generate_image_flux(cover_prompt)
165
  cover_path = download_image(cover_url, f"cover_{uuid.uuid4().hex}.png")
166
 
 
183
  pdf.multi_cell(180, 10, safe_text(goal), 0)
184
 
185
  pdf.set_font("Helvetica", "", 12)
186
+ pdf.multi_cell(180, 7, safe_text(f"Genre: {genre} (Comic)"), 0)
187
  pdf.multi_cell(180, 7, safe_text(f"Tone: {tone} | Style: {style}"), 0)
188
 
189
  # TABLE OF CONTENTS
190
  pdf.add_page()
191
  pdf.set_font("Helvetica", "B", 18)
192
+ pdf.cell(0, 10, "Daftar Isi (Komik)", 0, 1)
193
  pdf.ln(5)
194
 
195
  pdf.set_font("Helvetica", "", 12)
 
199
  for i, ch in enumerate(chapters, start=1):
200
  pdf.cell(0, 8, safe_text(f"{i}. {ch}"), 0, 1)
201
 
202
+ # CHAPTERS β†’ KOMIK PANEL
203
  for idx, ch in enumerate(chapters, start=1):
204
  pdf.add_page()
205
  pdf.set_font("Helvetica", "B", 16)
206
  pdf.cell(0, 10, safe_text(ch), 0, 1)
207
  pdf.ln(4)
208
 
209
+ # Generate panel texts (Groq)
210
+ panels_text = generate_comic_panels(goal, style, tone, ch, PANELS_PER_CHAPTER)
211
+
212
+ # Untuk tiap panel: gambar + teks
213
+ for p_idx, panel in enumerate(panels_text, start=1):
214
+ # ILLUSTRATION (lebih realistik, gaya komik)
215
+ illus_prompt = (
216
+ f"Realistic comic panel illustration of an Islamic children's story about {goal}. "
217
+ f"Scene: {panel}. Style: semi-realistic, soft colors, expressive faces, "
218
+ f"cinematic lighting, kid-friendly, high detail."
219
+ )
220
+ illus_url = generate_image_flux(illus_prompt)
221
+ illus_path = download_image(illus_url, f"chapter_{idx}_panel_{p_idx}_{uuid.uuid4().hex}.png")
222
+
223
+ pdf.set_font("Helvetica", "B", 12)
224
+ pdf.cell(0, 8, safe_text(f"Panel {p_idx}"), 0, 1)
225
+ pdf.ln(1)
226
+
227
+ if illus_path:
228
+ y_start = pdf.get_y()
229
+ # Lebar panel komik
230
+ pdf.image(illus_path, x=20, y=y_start, w=170)
231
+ pdf.set_y(y_start + 80)
232
+
233
+ pdf.set_font("Helvetica", "", 11)
234
+ pdf.multi_cell(180, 6, safe_text(panel), 0)
235
+ pdf.ln(3)
236
+
237
+ filename = os.path.join("outputs", f"comic_{uuid.uuid4().hex}.pdf")
238
  pdf.output(filename)
239
  return filename
240
 
241
  # ============================
242
+ # E-BOOK JSON GENERATOR (MASIH BISA DIPAKAI)
243
  # ============================
244
  def generate_ebook_json(username, tier,
245
  goal, genre, tone, style,
246
  platform, length, chapters):
247
 
248
  goal = normalize(goal, "Islamic children's story about good manners.")
249
+ genre = normalize(genre, "Islamic Children Story (Comic)")
250
  tone = normalize(tone, "Friendly")
251
+ style = normalize(style, "Comic style")
252
  platform = normalize(platform, "KDP")
253
  length = normalize(length, "Medium (30–50 pages)")
254
 
 
262
  chapter_titles = [f"Bab {i}: Judul Bab {i}" for i in range(1, chapters + 1)]
263
 
264
  data = {
265
+ "type": "comic",
266
  "generated_at": now_iso(),
267
  "user": username,
268
  "tier": tier,
 
273
  "length": length,
274
  "goal": goal,
275
  "chapters": chapter_titles,
276
+ "panels_per_chapter": PANELS_PER_CHAPTER,
277
  }
278
 
279
  return json.dumps(data, ensure_ascii=False, indent=2)
 
304
 
305
  with gr.Group(visible=False) as main_ui:
306
 
307
+ gr.Markdown("# 🌟 AIPromptLab β€” Comic JSON & PDF Generator (Groq + Replicate)")
308
 
309
  with gr.Tabs():
310
 
311
+ with gr.Tab("Comic Prompt & PDF"):
312
 
313
+ ebook_goal = gr.Textbox(label="Goal / Ide Komik")
314
  ebook_genre = gr.Dropdown(
315
  label="Genre",
316
  choices=[
317
+ "Islamic Children Comic",
318
+ "Islamic Adventure",
319
+ "Islamic Moral Story",
320
  "Fantasy",
321
  "Education",
322
  "Adventure",
323
  "Mystery"
324
  ],
325
+ value="Islamic Children Comic"
326
  )
327
  ebook_tone = gr.Dropdown(
328
  label="Tone",
 
331
  "Inspirational",
332
  "Educational",
333
  "Storytelling",
334
+ "Humorous",
335
+ "Calm"
336
  ],
337
  value="Friendly"
338
  )
339
  ebook_style = gr.Dropdown(
340
+ label="Comic Style",
341
  choices=[
342
+ "Semi-realistic comic",
343
+ "Cartoon comic",
344
+ "Pastel Islamic comic",
345
+ "Manga-like",
346
+ "Webtoon style"
 
347
  ],
348
+ value="Semi-realistic comic"
349
  )
350
  ebook_platform = gr.Dropdown(
351
  label="Target Platform",
352
  choices=[
353
  "KDP",
354
+ "Webtoon",
355
+ "PDF / E-Learning",
356
+ "Print"
357
  ],
358
+ value="PDF / E-Learning"
359
  )
360
  ebook_length = gr.Dropdown(
361
  label="Length",
362
  choices=[
363
+ "Short (1–2 chapters)",
364
+ "Medium (3–5 chapters)",
365
+ "Long (6–10 chapters)"
366
  ],
367
+ value="Medium (3–5 chapters)"
368
  )
369
 
370
  ebook_chapters = gr.Slider(
371
+ label="Jumlah Bab Komik",
372
  minimum=1,
373
  maximum=MAX_CHAPTERS,
374
  step=1,
375
+ value=1
376
  )
377
 
378
  ebook_cover_brief = gr.Textbox(
379
  label="Cover Illustration Brief",
380
+ value="Realistic comic cover of Islamic children in adventure, soft colors, warm light, friendly faces."
381
  )
382
 
383
+ ebook_generate_btn = gr.Button("πŸš€ Generate Comic JSON")
384
+ ebook_output = gr.Textbox(label="Comic JSON Output", lines=18)
385
 
386
+ gr.Markdown("### πŸ“„ Generate PDF Komik (A4 + Cover + Panel Komik)")
387
+ ebook_pdf_btn = gr.Button("Generate Comic PDF")
388
+ ebook_pdf_file = gr.File(label="Download Comic PDF")
389
 
390
  def handle_login(username, password):
391
  ok, tier, msg = login(username, password)
 
430
  if not login_status:
431
  return None
432
 
433
+ goal_ = normalize(goal, "Islamic children's comic about good manners.")
434
+ genre_ = normalize(genre, "Islamic Children Comic")
435
  tone_ = normalize(tone, "Friendly")
436
+ style_ = normalize(style, "Semi-realistic comic")
437
+ length_ = normalize(length, "Medium (3–5 chapters)")
438
+ cover_ = normalize(cover_brief, "Realistic Islamic children comic cover.")
439
 
440
  pdf_path = build_ebook_pdf_with_images(
441
  login_user, goal_, genre_, tone_, style_, length_, cover_, chapters