usmanyousaf commited on
Commit
8f51465
·
verified ·
1 Parent(s): 48e8fe9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -49
app.py CHANGED
@@ -15,6 +15,7 @@ st.set_page_config(page_title="PPTX Smart Enhancer", layout="wide")
15
  # Configuration
16
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
17
  MODEL_NAME = "gemma2-9b-it"
 
18
  # Style Options
19
  FONT_CHOICES = {
20
  "Arial": "Arial",
@@ -41,19 +42,21 @@ COLOR_PALETTES = {
41
  }
42
 
43
  def get_custom_colors():
44
- """Get custom colors from user input"""
45
- col1, col2, col3 = st.columns(3)
46
  with col1:
47
  primary = st.color_picker("Primary Color", "#2B579A")
48
  with col2:
49
  secondary = st.color_picker("Secondary Color", "#5B9BD5")
50
  with col3:
51
  text = st.color_picker("Text Color", "#000000")
 
 
52
  return {
53
  "primary": primary,
54
  "secondary": secondary,
55
  "text": text,
56
- "background": "#FFFFFF" # Default background for custom
57
  }
58
 
59
  def get_ai_response(prompt: str) -> str:
@@ -87,10 +90,10 @@ def extract_slide_text(slide) -> str:
87
  def split_formatted_runs(text):
88
  """Split text into formatted runs removing markdown."""
89
  formatted_segments = []
90
- # Split bold first
91
  bold_parts = re.split(r'(\*\*)', text)
92
  bold = False
93
  current_text = []
 
94
  for part in bold_parts:
95
  if part == '**':
96
  if current_text:
@@ -98,25 +101,19 @@ def split_formatted_runs(text):
98
  current_text = []
99
  bold = not bold
100
  else:
101
- # Split italic within non-bold sections
102
- if not bold:
103
- italic_parts = re.split(r'(\*)', part)
104
- italic = False
105
- for italic_part in italic_parts:
106
- if italic_part == '*':
107
- if current_text:
108
- formatted_segments.append({'text': ''.join(current_text), 'bold': False, 'italic': italic})
109
- current_text = []
110
- italic = not italic
111
- else:
112
- current_text.append(italic_part)
113
- if current_text:
114
- formatted_segments.append({'text': ''.join(current_text), 'bold': False, 'italic': italic})
115
- current_text = []
116
- else:
117
- current_text.append(part)
118
- if current_text:
119
- formatted_segments.append({'text': ''.join(current_text), 'bold': bold, 'italic': False})
120
  return formatted_segments
121
 
122
  def apply_formatting(text_frame, content, design_settings):
@@ -125,10 +122,8 @@ def apply_formatting(text_frame, content, design_settings):
125
  paragraphs = [p for p in content.split('\n') if p.strip()]
126
 
127
  for para in paragraphs:
128
- # Remove any markdown headers completely
129
  clean_para = re.sub(r'^#+\s*', '', para).strip()
130
 
131
- # Handle section headers (original markdown headers become bold titles)
132
  if re.match(r'^(What is|Understanding|What\'s|Drive Theory|Incentive Theory)', clean_para, re.IGNORECASE):
133
  p = text_frame.add_paragraph()
134
  p.text = clean_para
@@ -137,7 +132,6 @@ def apply_formatting(text_frame, content, design_settings):
137
  p.space_after = Pt(12)
138
  continue
139
 
140
- # Handle bullet points
141
  if re.match(r'^[\•\-\*] ', clean_para):
142
  p = text_frame.add_paragraph()
143
  p.level = 0
@@ -151,7 +145,6 @@ def apply_formatting(text_frame, content, design_settings):
151
  p.font.size = Pt(design_settings["body_size"])
152
  continue
153
 
154
- # Regular paragraph with clean formatting
155
  p = text_frame.add_paragraph()
156
  segments = split_formatted_runs(clean_para)
157
  for seg in segments:
@@ -161,18 +154,16 @@ def apply_formatting(text_frame, content, design_settings):
161
  run.font.italic = seg['italic']
162
  p.font.size = Pt(design_settings["body_size"])
163
  p.space_after = Pt(6)
164
-
165
  def enhance_slide(slide, user_prompt, design_settings):
166
  """Enhance slide content with proper formatting."""
167
  original_text = extract_slide_text(slide)
168
  if not original_text.strip():
169
  return
170
 
171
- # Get enhanced content
172
  prompt = f"Improve this slide content:\n{original_text}\n\nInstructions: {user_prompt}"
173
  enhanced_content = get_ai_response(prompt)
174
 
175
- # Clear existing content (keep title if exists)
176
  title_shape = getattr(slide.shapes, 'title', None)
177
  shapes_to_remove = [s for s in slide.shapes if s != title_shape]
178
 
@@ -180,7 +171,6 @@ def enhance_slide(slide, user_prompt, design_settings):
180
  sp = shape._element
181
  sp.getparent().remove(sp)
182
 
183
- # Add formatted content
184
  left = Inches(1) if title_shape else Inches(0.5)
185
  top = Inches(1.5) if title_shape else Inches(0.5)
186
  textbox = slide.shapes.add_textbox(left, top, Inches(8), Inches(5))
@@ -192,7 +182,7 @@ def enhance_slide(slide, user_prompt, design_settings):
192
 
193
  def apply_design(slide, design_settings):
194
  """Apply visual design to slide."""
195
- colors = COLOR_PALETTES[design_settings["color_palette"]]
196
 
197
  for shape in slide.shapes:
198
  if hasattr(shape, "text_frame"):
@@ -201,7 +191,6 @@ def apply_design(slide, design_settings):
201
  run.font.name = design_settings["font"]
202
  run.font.color.rgb = RGBColor.from_string(colors["text"][1:])
203
 
204
- # Title styling
205
  if shape == getattr(slide.shapes, 'title', None):
206
  run.font.color.rgb = RGBColor.from_string(colors["primary"][1:])
207
  run.font.size = Pt(design_settings["title_size"])
@@ -209,7 +198,7 @@ def apply_design(slide, design_settings):
209
 
210
  if design_settings["set_background"]:
211
  slide.background.fill.solid()
212
- slide.background.fill.fore_color.rgb = RGBColor.from_string(colors["secondary"][1:])
213
 
214
  def process_presentation(uploaded_file, user_prompt, design_settings):
215
  """Process and enhance the entire presentation."""
@@ -220,7 +209,7 @@ def process_presentation(uploaded_file, user_prompt, design_settings):
220
  prs = Presentation(tmp_path)
221
 
222
  with st.spinner("Enhancing slides..."):
223
- for i, slide in enumerate(prs.slides):
224
  enhance_slide(slide, user_prompt, design_settings)
225
 
226
  os.unlink(tmp_path)
@@ -229,17 +218,13 @@ def process_presentation(uploaded_file, user_prompt, design_settings):
229
  def main():
230
  st.title("Professional PPTX Enhancer")
231
 
232
- # File upload
233
  uploaded_file = st.file_uploader("Upload PowerPoint", type=["pptx"])
234
-
235
- # Content settings
236
  user_prompt = st.text_area(
237
  "Enhancement Instructions",
238
  placeholder="Example: 'Make headings clear and add bullet points for key items'",
239
  height=100
240
  )
241
 
242
- # Enhanced Design settings
243
  with st.expander("🎨 Design Options", expanded=True):
244
  tab1, tab2 = st.tabs(["Preset Themes", "Custom Colors"])
245
 
@@ -259,17 +244,10 @@ def main():
259
  custom_colors = get_custom_colors()
260
  use_custom = st.checkbox("Use Custom Colors")
261
 
262
- # Prepare design settings
263
- if use_custom:
264
- colors = custom_colors
265
- color_palette = "Custom"
266
- else:
267
- colors = COLOR_PALETTES[color_palette]
268
-
269
  design_settings = {
270
  "font": FONT_CHOICES[font],
271
- "colors": colors,
272
- "color_palette": color_palette,
273
  "title_size": title_size,
274
  "heading_size": heading_size,
275
  "body_size": body_size,
@@ -278,9 +256,12 @@ def main():
278
 
279
  if st.button("Enhance Presentation") and uploaded_file and user_prompt:
280
  try:
 
 
 
 
281
  enhanced_prs = process_presentation(uploaded_file, user_prompt, design_settings)
282
 
283
- # Create download
284
  buffer = io.BytesIO()
285
  enhanced_prs.save(buffer)
286
  buffer.seek(0)
 
15
  # Configuration
16
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
17
  MODEL_NAME = "gemma2-9b-it"
18
+
19
  # Style Options
20
  FONT_CHOICES = {
21
  "Arial": "Arial",
 
42
  }
43
 
44
  def get_custom_colors():
45
+ """Get custom colors from user input with background option"""
46
+ col1, col2, col3, col4 = st.columns(4)
47
  with col1:
48
  primary = st.color_picker("Primary Color", "#2B579A")
49
  with col2:
50
  secondary = st.color_picker("Secondary Color", "#5B9BD5")
51
  with col3:
52
  text = st.color_picker("Text Color", "#000000")
53
+ with col4:
54
+ background = st.color_picker("Background Color", "#FFFFFF")
55
  return {
56
  "primary": primary,
57
  "secondary": secondary,
58
  "text": text,
59
+ "background": background
60
  }
61
 
62
  def get_ai_response(prompt: str) -> str:
 
90
  def split_formatted_runs(text):
91
  """Split text into formatted runs removing markdown."""
92
  formatted_segments = []
 
93
  bold_parts = re.split(r'(\*\*)', text)
94
  bold = False
95
  current_text = []
96
+
97
  for part in bold_parts:
98
  if part == '**':
99
  if current_text:
 
101
  current_text = []
102
  bold = not bold
103
  else:
104
+ italic_parts = re.split(r'(\*)', part)
105
+ italic = False
106
+ for italic_part in italic_parts:
107
+ if italic_part == '*':
108
+ if current_text:
109
+ formatted_segments.append({'text': ''.join(current_text), 'bold': bold, 'italic': italic})
110
+ current_text = []
111
+ italic = not italic
112
+ else:
113
+ current_text.append(italic_part)
114
+ if current_text:
115
+ formatted_segments.append({'text': ''.join(current_text), 'bold': bold, 'italic': italic})
116
+ current_text = []
 
 
 
 
 
 
117
  return formatted_segments
118
 
119
  def apply_formatting(text_frame, content, design_settings):
 
122
  paragraphs = [p for p in content.split('\n') if p.strip()]
123
 
124
  for para in paragraphs:
 
125
  clean_para = re.sub(r'^#+\s*', '', para).strip()
126
 
 
127
  if re.match(r'^(What is|Understanding|What\'s|Drive Theory|Incentive Theory)', clean_para, re.IGNORECASE):
128
  p = text_frame.add_paragraph()
129
  p.text = clean_para
 
132
  p.space_after = Pt(12)
133
  continue
134
 
 
135
  if re.match(r'^[\•\-\*] ', clean_para):
136
  p = text_frame.add_paragraph()
137
  p.level = 0
 
145
  p.font.size = Pt(design_settings["body_size"])
146
  continue
147
 
 
148
  p = text_frame.add_paragraph()
149
  segments = split_formatted_runs(clean_para)
150
  for seg in segments:
 
154
  run.font.italic = seg['italic']
155
  p.font.size = Pt(design_settings["body_size"])
156
  p.space_after = Pt(6)
157
+
158
  def enhance_slide(slide, user_prompt, design_settings):
159
  """Enhance slide content with proper formatting."""
160
  original_text = extract_slide_text(slide)
161
  if not original_text.strip():
162
  return
163
 
 
164
  prompt = f"Improve this slide content:\n{original_text}\n\nInstructions: {user_prompt}"
165
  enhanced_content = get_ai_response(prompt)
166
 
 
167
  title_shape = getattr(slide.shapes, 'title', None)
168
  shapes_to_remove = [s for s in slide.shapes if s != title_shape]
169
 
 
171
  sp = shape._element
172
  sp.getparent().remove(sp)
173
 
 
174
  left = Inches(1) if title_shape else Inches(0.5)
175
  top = Inches(1.5) if title_shape else Inches(0.5)
176
  textbox = slide.shapes.add_textbox(left, top, Inches(8), Inches(5))
 
182
 
183
  def apply_design(slide, design_settings):
184
  """Apply visual design to slide."""
185
+ colors = design_settings["colors"]
186
 
187
  for shape in slide.shapes:
188
  if hasattr(shape, "text_frame"):
 
191
  run.font.name = design_settings["font"]
192
  run.font.color.rgb = RGBColor.from_string(colors["text"][1:])
193
 
 
194
  if shape == getattr(slide.shapes, 'title', None):
195
  run.font.color.rgb = RGBColor.from_string(colors["primary"][1:])
196
  run.font.size = Pt(design_settings["title_size"])
 
198
 
199
  if design_settings["set_background"]:
200
  slide.background.fill.solid()
201
+ slide.background.fill.fore_color.rgb = RGBColor.from_string(colors["background"][1:])
202
 
203
  def process_presentation(uploaded_file, user_prompt, design_settings):
204
  """Process and enhance the entire presentation."""
 
209
  prs = Presentation(tmp_path)
210
 
211
  with st.spinner("Enhancing slides..."):
212
+ for slide in prs.slides:
213
  enhance_slide(slide, user_prompt, design_settings)
214
 
215
  os.unlink(tmp_path)
 
218
  def main():
219
  st.title("Professional PPTX Enhancer")
220
 
 
221
  uploaded_file = st.file_uploader("Upload PowerPoint", type=["pptx"])
 
 
222
  user_prompt = st.text_area(
223
  "Enhancement Instructions",
224
  placeholder="Example: 'Make headings clear and add bullet points for key items'",
225
  height=100
226
  )
227
 
 
228
  with st.expander("🎨 Design Options", expanded=True):
229
  tab1, tab2 = st.tabs(["Preset Themes", "Custom Colors"])
230
 
 
244
  custom_colors = get_custom_colors()
245
  use_custom = st.checkbox("Use Custom Colors")
246
 
 
 
 
 
 
 
 
247
  design_settings = {
248
  "font": FONT_CHOICES[font],
249
+ "colors": custom_colors if use_custom else COLOR_PALETTES[color_palette],
250
+ "color_palette": "Custom" if use_custom else color_palette,
251
  "title_size": title_size,
252
  "heading_size": heading_size,
253
  "body_size": body_size,
 
256
 
257
  if st.button("Enhance Presentation") and uploaded_file and user_prompt:
258
  try:
259
+ if not GROQ_API_KEY:
260
+ st.error("GROQ API key not found! Please set it in Space settings.")
261
+ st.stop()
262
+
263
  enhanced_prs = process_presentation(uploaded_file, user_prompt, design_settings)
264
 
 
265
  buffer = io.BytesIO()
266
  enhanced_prs.save(buffer)
267
  buffer.seek(0)