PHOENIXREBORNAGAIN commited on
Commit
6b4926b
·
verified ·
1 Parent(s): a0febfa

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +42 -52
app.py CHANGED
@@ -17,58 +17,62 @@ body, .gradio-container {
17
  footer { display: none !important; }
18
  .header-block {
19
  background: linear-gradient(135deg, #1b6ca8 0%, #19a88a 100%);
20
- border-radius: 16px;
21
- padding: 32px 36px 28px;
22
- margin-bottom: 24px;
23
  }
24
  button.primary {
25
  background: linear-gradient(135deg, #1b6ca8, #19a88a) !important;
26
- color: #fff !important;
27
- border: none !important;
28
- border-radius: 12px !important;
29
- font-size: 17px !important;
30
- font-weight: 700 !important;
31
- padding: 16px 0 !important;
32
- width: 100% !important;
33
- cursor: pointer !important;
34
  box-shadow: 0 4px 16px rgba(25,168,138,0.3) !important;
35
  }
36
  button.primary:hover { opacity: .87 !important; }
37
  textarea, input[type="text"] {
38
- background: #f5fbf9 !important;
39
- border: 1.5px solid #b2ddd1 !important;
40
- border-radius: 10px !important;
41
- color: #1a3a3a !important;
42
- font-size: 14px !important;
43
  }
44
  input[type="range"] { accent-color: #19a88a !important; }
45
  .status-ok {
46
- background: #e6f7f2; border: 1px solid #a8dfd0;
47
- border-radius: 10px; padding: 12px 18px;
48
- font-size: 14px; color: #1a5a4a; margin-bottom: 8px;
49
  }
50
  .status-wait {
51
- background: #f0f7ff; border: 1px solid #b2cfe8;
52
- border-radius: 10px; padding: 12px 18px;
53
- font-size: 14px; color: #1a3a6a; margin-bottom: 8px;
54
  }
 
 
 
 
 
 
 
 
 
 
 
 
55
  """
56
 
57
 
58
- def format_preview(data: dict) -> str:
59
- lines = [f"# {data.get('title', '')}", ""]
60
  if data.get("subtitle"):
61
  lines += [f"*{data['subtitle']}*", ""]
62
  lines.append("---")
63
  for slide in data.get("slides", []):
64
  num = slide.get("slide_number", "")
65
  title = slide.get("title", "")
 
66
  if slide.get("type") == "title":
67
  lines.append(f"\n### 🎯 Slide {num} — {title}")
68
  if slide.get("subtitle"):
69
  lines.append(f"> {slide['subtitle']}")
70
  else:
71
  lines.append(f"\n### 📄 Slide {num} — {title}")
 
 
72
  for b in slide.get("bullets", []):
73
  lines.append(f"- {b}")
74
  if slide.get("speaker_notes"):
@@ -85,25 +89,20 @@ def generate_and_download(topic, audience, style, num_slides, key_points,
85
  try:
86
  progress(0.1, desc="AI is writing your slides…")
87
  data = generate_presentation(
88
- topic=topic.strip(), style=style,
89
- num_slides=int(num_slides),
90
- audience=audience.strip(),
91
- key_points=key_points.strip(),
92
  )
93
- progress(0.75, desc="Building PPTX…")
94
  pptx_bytes = build_pptx(data, style)
95
-
96
  tmp_dir = tempfile.mkdtemp()
97
  safe = topic[:30].replace(" ", "_").replace("/", "-")
98
  out_path = os.path.join(tmp_dir, f"{safe}.pptx")
99
  with open(out_path, "wb") as f:
100
  f.write(pptx_bytes)
101
-
102
  progress(1.0, desc="Done!")
103
  n = len(data.get("slides", []))
104
- status = f"<div class='status-ok'>✅ <strong>{n} slides</strong> ready — download below!</div>"
105
  return format_preview(data), out_path, status
106
-
107
  except gr.Error:
108
  raise
109
  except Exception:
@@ -111,42 +110,33 @@ def generate_and_download(topic, audience, style, num_slides, key_points,
111
 
112
 
113
  with gr.Blocks(title="SlideAI", css=CSS) as demo:
114
-
115
  gr.HTML("""
116
  <div class="header-block">
117
  <h1 style="margin:0;font-size:28px;font-weight:800;color:#fff;">SlideAI</h1>
118
  <p style="margin:6px 0 0;font-size:14px;color:rgba(255,255,255,.88);">
119
- Turn any topic into a polished, download-ready presentation — in seconds.
120
  </p>
121
  </div>""")
122
 
123
  with gr.Row():
124
  with gr.Column(scale=1, min_width=300):
125
- topic = gr.Textbox(label="Topic *",
126
- placeholder="e.g. Climate Change, AI in Medicine…", lines=2)
127
- audience = gr.Textbox(label="Target Audience *",
128
- placeholder="e.g. Investors, Students…", lines=1)
129
  with gr.Row():
130
- style = gr.Dropdown(choices=STYLES, value="Professional",
131
- label="Style", scale=1)
132
- num_slides = gr.Slider(minimum=5, maximum=15, step=1, value=8,
133
- label="Slides", scale=1)
134
  key_points = gr.Textbox(label="Key Points (optional)",
135
  placeholder="Specific facts or ideas to include…", lines=2)
136
  btn = gr.Button("✨ Generate Presentation", variant="primary", size="lg")
137
 
138
  with gr.Column(scale=2, min_width=380):
139
- status = gr.HTML(
140
- "<div class='status-wait'>Fill in the form on the left and hit <strong>Generate</strong>.</div>"
141
- )
142
- preview = gr.Markdown()
143
  download = gr.File(label="📥 Download your PPTX", interactive=False)
144
 
145
- btn.click(
146
- fn=generate_and_download,
147
- inputs=[topic, audience, style, num_slides, key_points],
148
- outputs=[preview, download, status],
149
- )
150
 
151
  if __name__ == "__main__":
152
  demo.launch()
 
17
  footer { display: none !important; }
18
  .header-block {
19
  background: linear-gradient(135deg, #1b6ca8 0%, #19a88a 100%);
20
+ border-radius: 16px; padding: 32px 36px 28px; margin-bottom: 24px;
 
 
21
  }
22
  button.primary {
23
  background: linear-gradient(135deg, #1b6ca8, #19a88a) !important;
24
+ color: #fff !important; border: none !important;
25
+ border-radius: 12px !important; font-size: 17px !important;
26
+ font-weight: 700 !important; padding: 16px 0 !important;
27
+ width: 100% !important; cursor: pointer !important;
 
 
 
 
28
  box-shadow: 0 4px 16px rgba(25,168,138,0.3) !important;
29
  }
30
  button.primary:hover { opacity: .87 !important; }
31
  textarea, input[type="text"] {
32
+ background: #f5fbf9 !important; border: 1.5px solid #b2ddd1 !important;
33
+ border-radius: 10px !important; color: #1a3a3a !important; font-size: 14px !important;
 
 
 
34
  }
35
  input[type="range"] { accent-color: #19a88a !important; }
36
  .status-ok {
37
+ background: #e6f7f2; border: 1px solid #a8dfd0; border-radius: 10px;
38
+ padding: 12px 18px; font-size: 14px; color: #1a5a4a; margin-bottom: 8px;
 
39
  }
40
  .status-wait {
41
+ background: #f0f7ff; border: 1px solid #b2cfe8; border-radius: 10px;
42
+ padding: 12px 18px; font-size: 14px; color: #1a3a6a; margin-bottom: 8px;
 
43
  }
44
+ .preview-md, .preview-md p, .preview-md li,
45
+ .preview-md h1, .preview-md h2, .preview-md h3 { color: #0d1b2a !important; }
46
+ .preview-md {
47
+ background: #f5fbf9 !important; border: 1px solid #c8e8df !important;
48
+ border-radius: 12px !important; padding: 16px 20px !important;
49
+ min-height: 220px !important; max-height: 420px !important;
50
+ overflow-y: auto !important; font-size: 14px !important; line-height: 1.75 !important;
51
+ }
52
+ .preview-md h1 { color: #1b6ca8 !important; font-size: 18px !important; }
53
+ .preview-md h3 { color: #19a88a !important; font-size: 14px !important; margin: 10px 0 4px !important; }
54
+ .preview-md blockquote { border-left: 3px solid #19a88a; padding-left: 10px; }
55
+ .preview-md em { color: #5a8a8a !important; font-size: 12px !important; }
56
  """
57
 
58
 
59
+ def format_preview(data):
60
+ lines = [f"# {data.get('title','')}", ""]
61
  if data.get("subtitle"):
62
  lines += [f"*{data['subtitle']}*", ""]
63
  lines.append("---")
64
  for slide in data.get("slides", []):
65
  num = slide.get("slide_number", "")
66
  title = slide.get("title", "")
67
+ kw = slide.get("image_keyword", "")
68
  if slide.get("type") == "title":
69
  lines.append(f"\n### 🎯 Slide {num} — {title}")
70
  if slide.get("subtitle"):
71
  lines.append(f"> {slide['subtitle']}")
72
  else:
73
  lines.append(f"\n### 📄 Slide {num} — {title}")
74
+ if kw:
75
+ lines.append(f"*📸 Image: {kw}*")
76
  for b in slide.get("bullets", []):
77
  lines.append(f"- {b}")
78
  if slide.get("speaker_notes"):
 
89
  try:
90
  progress(0.1, desc="AI is writing your slides…")
91
  data = generate_presentation(
92
+ topic=topic.strip(), style=style, num_slides=int(num_slides),
93
+ audience=audience.strip(), key_points=key_points.strip(),
 
 
94
  )
95
+ progress(0.65, desc="Fetching images & building PPTX…")
96
  pptx_bytes = build_pptx(data, style)
 
97
  tmp_dir = tempfile.mkdtemp()
98
  safe = topic[:30].replace(" ", "_").replace("/", "-")
99
  out_path = os.path.join(tmp_dir, f"{safe}.pptx")
100
  with open(out_path, "wb") as f:
101
  f.write(pptx_bytes)
 
102
  progress(1.0, desc="Done!")
103
  n = len(data.get("slides", []))
104
+ status = f"<div class='status-ok'>✅ <strong>{n} slides</strong> with images — download below!</div>"
105
  return format_preview(data), out_path, status
 
106
  except gr.Error:
107
  raise
108
  except Exception:
 
110
 
111
 
112
  with gr.Blocks(title="SlideAI", css=CSS) as demo:
 
113
  gr.HTML("""
114
  <div class="header-block">
115
  <h1 style="margin:0;font-size:28px;font-weight:800;color:#fff;">SlideAI</h1>
116
  <p style="margin:6px 0 0;font-size:14px;color:rgba(255,255,255,.88);">
117
+ Turn any topic into a polished, image-rich, download-ready presentation.
118
  </p>
119
  </div>""")
120
 
121
  with gr.Row():
122
  with gr.Column(scale=1, min_width=300):
123
+ topic = gr.Textbox(label="Topic *", placeholder="e.g. Climate Change…", lines=2)
124
+ audience = gr.Textbox(label="Target Audience *", placeholder="e.g. Students…", lines=1)
 
 
125
  with gr.Row():
126
+ style = gr.Dropdown(choices=STYLES, value="Professional", label="Style", scale=1)
127
+ num_slides = gr.Slider(minimum=5, maximum=15, step=1, value=8, label="Slides", scale=1)
 
 
128
  key_points = gr.Textbox(label="Key Points (optional)",
129
  placeholder="Specific facts or ideas to include…", lines=2)
130
  btn = gr.Button("✨ Generate Presentation", variant="primary", size="lg")
131
 
132
  with gr.Column(scale=2, min_width=380):
133
+ status = gr.HTML("<div class='status-wait'>Fill in the form and hit <strong>Generate</strong>.</div>")
134
+ preview = gr.Markdown(elem_classes=["preview-md"])
 
 
135
  download = gr.File(label="📥 Download your PPTX", interactive=False)
136
 
137
+ btn.click(fn=generate_and_download,
138
+ inputs=[topic, audience, style, num_slides, key_points],
139
+ outputs=[preview, download, status])
 
 
140
 
141
  if __name__ == "__main__":
142
  demo.launch()